| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626 |
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEngine.Serialization;
- namespace Cinemachine
- {
- /// <summary>
- /// This behaviour is intended to be attached to an empty Transform GameObject,
- /// and it represents a Virtual Camera within the Unity scene.
- ///
- /// The Virtual Camera will animate its Transform according to the rules contained
- /// in its CinemachineComponent pipeline (Aim, Body, and Noise). When the virtual
- /// camera is Live, the Unity camera will assume the position and orientation
- /// of the virtual camera.
- ///
- /// A virtual camera is not a camera. Instead, it can be thought of as a camera controller,
- /// not unlike a cameraman. It can drive the Unity Camera and control its position,
- /// orientation, lens settings, and PostProcessing effects. Each Virtual Camera owns
- /// its own Cinemachine Component Pipeline, through which you provide the instructions
- /// for dynamically tracking specific game objects.
- ///
- /// A virtual camera is very lightweight, and does no rendering of its own. It merely
- /// tracks interesting GameObjects, and positions itself accordingly. A typical game
- /// can have dozens of virtual cameras, each set up to follow a particular character
- /// or capture a particular event.
- ///
- /// A Virtual Camera can be in any of three states:
- ///
- /// * **Live**: The virtual camera is actively controlling the Unity Camera. The
- /// virtual camera is tracking its targets and being updated every frame.
- /// * **Standby**: The virtual camera is tracking its targets and being updated
- /// every frame, but no Unity Camera is actively being controlled by it. This is
- /// the state of a virtual camera that is enabled in the scene but perhaps at a
- /// lower priority than the Live virtual camera.
- /// * **Disabled**: The virtual camera is present but disabled in the scene. It is
- /// not actively tracking its targets and so consumes no processing power. However,
- /// the virtual camera can be made live from the Timeline.
- ///
- /// The Unity Camera can be driven by any virtual camera in the scene. The game
- /// logic can choose the virtual camera to make live by manipulating the virtual
- /// cameras' enabled flags and their priorities, based on game logic.
- ///
- /// In order to be driven by a virtual camera, the Unity Camera must have a CinemachineBrain
- /// behaviour, which will select the most eligible virtual camera based on its priority
- /// or on other criteria, and will manage blending.
- /// </summary>
- /// <seealso cref="CinemachineVirtualCameraBase"/>
- /// <seealso cref="LensSettings"/>
- /// <seealso cref="CinemachineComposer"/>
- /// <seealso cref="CinemachineTransposer"/>
- /// <seealso cref="CinemachineBasicMultiChannelPerlin"/>
- [DocumentationSorting(DocumentationSortingAttribute.Level.UserRef)]
- [DisallowMultipleComponent]
- #if UNITY_2018_3_OR_NEWER
- [ExecuteAlways]
- #else
- [ExecuteInEditMode]
- #endif
- [ExcludeFromPreset]
- [AddComponentMenu("Cinemachine/CinemachineVirtualCamera")]
- [HelpURL(Documentation.BaseURL + "manual/CinemachineVirtualCamera.html")]
- public class CinemachineVirtualCamera : CinemachineVirtualCameraBase
- {
- /// <summary>The object that the camera wants to look at (the Aim target).
- /// The Aim component of the CinemachineComponent pipeline
- /// will refer to this target and orient the vcam in accordance with rules and
- /// settings that are provided to it.
- /// If this is null, then the vcam's Transform orientation will be used.</summary>
- [Tooltip("The object that the camera wants to look at (the Aim target). "
- + "If this is null, then the vcam's Transform orientation will define the camera's orientation.")]
- [NoSaveDuringPlay]
- [VcamTargetProperty]
- public Transform m_LookAt = null;
- /// <summary>The object that the camera wants to move with (the Body target).
- /// The Body component of the CinemachineComponent pipeline
- /// will refer to this target and position the vcam in accordance with rules and
- /// settings that are provided to it.
- /// If this is null, then the vcam's Transform position will be used.</summary>
- [Tooltip("The object that the camera wants to move with (the Body target). "
- + "If this is null, then the vcam's Transform position will define the camera's position.")]
- [NoSaveDuringPlay]
- [VcamTargetProperty]
- public Transform m_Follow = null;
- /// <summary>Specifies the LensSettings of this Virtual Camera.
- /// These settings will be transferred to the Unity camera when the vcam is live.</summary>
- [FormerlySerializedAs("m_LensAttributes")]
- [Tooltip("Specifies the lens properties of this Virtual Camera. This generally mirrors the "
- + "Unity Camera's lens settings, and will be used to drive the Unity camera when the vcam is active.")]
- [LensSettingsProperty]
- public LensSettings m_Lens = LensSettings.Default;
- /// <summary> Collection of parameters that influence how this virtual camera transitions from
- /// other virtual cameras </summary>
- public TransitionParams m_Transitions;
- /// <summary>Legacy support</summary>
- [SerializeField] [HideInInspector]
- [FormerlySerializedAs("m_BlendHint")]
- [FormerlySerializedAs("m_PositionBlending")] private BlendHint m_LegacyBlendHint;
-
- /// <summary>This is the name of the hidden GameObject that will be created as a child object
- /// of the virtual camera. This hidden game object acts as a container for the polymorphic
- /// CinemachineComponent pipeline. The Inspector UI for the Virtual Camera
- /// provides access to this pipleline, as do the CinemachineComponent-family of
- /// public methods in this class.
- /// The lifecycle of the pipeline GameObject is managed automatically.</summary>
- public const string PipelineName = "cm";
- /// <summary>The CameraState object holds all of the information
- /// necessary to position the Unity camera. It is the output of this class.</summary>
- override public CameraState State { get { return m_State; } }
- /// <summary>Get the LookAt target for the Aim component in the Cinemachine pipeline.
- /// If this vcam is a part of a meta-camera collection, then the owner's target
- /// will be used if the local target is null.</summary>
- override public Transform LookAt
- {
- get { return ResolveLookAt(m_LookAt); }
- set { m_LookAt = value; }
- }
- /// <summary>Get the Follow target for the Body component in the Cinemachine pipeline.
- /// If this vcam is a part of a meta-camera collection, then the owner's target
- /// will be used if the local target is null.</summary>
- override public Transform Follow
- {
- get { return ResolveFollow(m_Follow); }
- set { m_Follow = value; }
- }
- /// <summary>
- /// Query components and extensions for the maximum damping time.
- /// </summary>
- /// <returns>Highest damping setting in this vcam</returns>
- public override float GetMaxDampTime()
- {
- float maxDamp = base.GetMaxDampTime();
- UpdateComponentPipeline();
- if (m_ComponentPipeline != null)
- for (int i = 0; i < m_ComponentPipeline.Length; ++i)
- maxDamp = Mathf.Max(maxDamp, m_ComponentPipeline[i].GetMaxDampTime());
- return maxDamp;
- }
- /// <summary>Internal use only. Do not call this method.
- /// Called by CinemachineCore at the appropriate Update time
- /// so the vcam can position itself and track its targets. This class will
- /// invoke its pipeline and generate a CameraState for this frame.</summary>
- /// <param name="worldUp">Effective world up</param>
- /// <param name="deltaTime">Effective deltaTime</param>
- override public void InternalUpdateCameraState(Vector3 worldUp, float deltaTime)
- {
- // Update the state by invoking the component pipeline
- m_State = CalculateNewState(worldUp, deltaTime);
- ApplyPositionBlendMethod(ref m_State, m_Transitions.m_BlendHint);
- // Push the raw position back to the game object's transform, so it
- // moves along with the camera.
- if (!UserIsDragging)
- {
- if (Follow != null)
- transform.position = State.RawPosition;
- if (LookAt != null)
- transform.rotation = State.RawOrientation;
- }
- PreviousStateIsValid = true;
- }
- /// <summary>Make sure that the pipeline cache is up-to-date.</summary>
- override protected void OnEnable()
- {
- base.OnEnable();
- m_State = PullStateFromVirtualCamera(Vector3.up, ref m_Lens);
- InvalidateComponentPipeline();
- // Can't add components during OnValidate
- if (ValidatingStreamVersion < 20170927)
- {
- if (Follow != null && GetCinemachineComponent(CinemachineCore.Stage.Body) == null)
- AddCinemachineComponent<CinemachineHardLockToTarget>();
- if (LookAt != null && GetCinemachineComponent(CinemachineCore.Stage.Aim) == null)
- AddCinemachineComponent<CinemachineHardLookAt>();
- }
- }
- /// <summary>Calls the DestroyPipelineDelegate for destroying the hidden
- /// child object, to support undo.</summary>
- protected override void OnDestroy()
- {
- // Make the pipeline visible instead of destroying - this is to keep Undo happy
- foreach (Transform child in transform)
- if (child.GetComponent<CinemachinePipeline>() != null)
- child.gameObject.hideFlags
- &= ~(HideFlags.HideInHierarchy | HideFlags.HideInInspector);
- base.OnDestroy();
- }
- /// <summary>Enforce bounds for fields, when changed in inspector.</summary>
- protected override void OnValidate()
- {
- base.OnValidate();
- m_Lens.Validate();
- if (m_LegacyBlendHint != BlendHint.None)
- {
- m_Transitions.m_BlendHint = m_LegacyBlendHint;
- m_LegacyBlendHint = BlendHint.None;
- }
- }
- void OnTransformChildrenChanged()
- {
- InvalidateComponentPipeline();
- }
- void Reset()
- {
- #if UNITY_EDITOR
- if (UnityEditor.PrefabUtility.GetPrefabInstanceStatus(gameObject)
- != UnityEditor.PrefabInstanceStatus.NotAPrefab)
- {
- Debug.Log("You cannot reset a prefab instance. "
- + "First disconnect this instance from the prefab, or enter Prefab Edit mode");
- return;
- }
- #endif
- DestroyPipeline();
- }
- /// <summary>
- /// Override component pipeline creation.
- /// This needs to be done by the editor to support Undo.
- /// The override must do exactly the same thing as the CreatePipeline method in this class.
- /// </summary>
- public static CreatePipelineDelegate CreatePipelineOverride;
- /// <summary>
- /// Override component pipeline creation.
- /// This needs to be done by the editor to support Undo.
- /// The override must do exactly the same thing as the CreatePipeline method in
- /// the CinemachineVirtualCamera class.
- /// </summary>
- public delegate Transform CreatePipelineDelegate(
- CinemachineVirtualCamera vcam, string name, CinemachineComponentBase[] copyFrom);
- /// <summary>
- /// Override component pipeline destruction.
- /// This needs to be done by the editor to support Undo.
- /// </summary>
- public static DestroyPipelineDelegate DestroyPipelineOverride;
- /// <summary>
- /// Override component pipeline destruction.
- /// This needs to be done by the editor to support Undo.
- /// </summary>
- public delegate void DestroyPipelineDelegate(GameObject pipeline);
- /// <summary>Destroy any existing pipeline container.</summary>
- private void DestroyPipeline()
- {
- List<Transform> oldPipeline = new List<Transform>();
- foreach (Transform child in transform)
- if (child.GetComponent<CinemachinePipeline>() != null)
- oldPipeline.Add(child);
- if (!RuntimeUtility.IsPrefab(gameObject))
- {
- foreach (Transform child in oldPipeline)
- {
- if (DestroyPipelineOverride != null)
- DestroyPipelineOverride(child.gameObject);
- else
- Destroy(child.gameObject);
- }
- m_ComponentOwner = null;
- }
- PreviousStateIsValid = false;
- }
- /// <summary>Create a default pipeline container.
- /// Note: copyFrom only supported in Editor, not build</summary>
- private Transform CreatePipeline(CinemachineVirtualCamera copyFrom)
- {
- CinemachineComponentBase[] components = null;
- if (copyFrom != null)
- {
- copyFrom.InvalidateComponentPipeline(); // make sure it's up to date
- components = copyFrom.GetComponentPipeline();
- }
- Transform newPipeline = null;
- if (CreatePipelineOverride != null)
- newPipeline = CreatePipelineOverride(this, PipelineName, components);
- else
- {
- GameObject go = new GameObject(PipelineName);
- go.transform.parent = transform;
- go.AddComponent<CinemachinePipeline>();
- newPipeline = go.transform;
- }
- PreviousStateIsValid = false;
- return newPipeline;
- }
- /// <summary>
- /// Editor API: Call this when changing the pipeline from the editor.
- /// Will force a rebuild of the pipeline cache.
- /// </summary>
- public void InvalidateComponentPipeline() { m_ComponentPipeline = null; }
- /// <summary>Get the hidden CinemachinePipeline child object.</summary>
- /// <returns>The hidden CinemachinePipeline child object</returns>
- public Transform GetComponentOwner() { UpdateComponentPipeline(); return m_ComponentOwner; }
- /// <summary>Get the component pipeline owned by the hidden child pipline container.
- /// For most purposes, it is preferable to use the GetCinemachineComponent method.</summary>
- /// <returns>The component pipeline</returns>
- public CinemachineComponentBase[] GetComponentPipeline() { UpdateComponentPipeline(); return m_ComponentPipeline; }
- /// <summary>Get the component set for a specific stage.</summary>
- /// <param name="stage">The stage for which we want the component</param>
- /// <returns>The Cinemachine component for that stage, or null if not defined</returns>
- public CinemachineComponentBase GetCinemachineComponent(CinemachineCore.Stage stage)
- {
- CinemachineComponentBase[] components = GetComponentPipeline();
- if (components != null)
- foreach (var c in components)
- if (c.Stage == stage)
- return c;
- return null;
- }
- /// <summary>Get an existing component of a specific type from the cinemachine pipeline.</summary>
- /// <typeparam name="T">The type of component to get</typeparam>
- /// <returns>The component if it's present, or null</returns>
- public T GetCinemachineComponent<T>() where T : CinemachineComponentBase
- {
- CinemachineComponentBase[] components = GetComponentPipeline();
- if (components != null)
- foreach (var c in components)
- if (c is T)
- return c as T;
- return null;
- }
- /// <summary>Add a component to the cinemachine pipeline.
- /// Existing components at the new component's stage are removed</summary>
- /// <typeparam name="T">The type of component to add</typeparam>
- /// <returns>The new component</returns>
- public T AddCinemachineComponent<T>() where T : CinemachineComponentBase
- {
- // Get the existing components
- Transform owner = GetComponentOwner();
- if (owner == null)
- return null; // maybe it's a prefab
- CinemachineComponentBase[] components = owner.GetComponents<CinemachineComponentBase>();
- T component = owner.gameObject.AddComponent<T>();
- if (component != null && components != null)
- {
- // Remove the existing components at that stage
- CinemachineCore.Stage stage = component.Stage;
- for (int i = components.Length - 1; i >= 0; --i)
- {
- if (components[i].Stage == stage)
- {
- components[i].enabled = false;
- RuntimeUtility.DestroyObject(components[i]);
- }
- }
- }
- InvalidateComponentPipeline();
- return component;
- }
- /// <summary>Remove a component from the cinemachine pipeline if it's present.</summary>
- /// <typeparam name="T">The type of component to remove</typeparam>
- public void DestroyCinemachineComponent<T>() where T : CinemachineComponentBase
- {
- CinemachineComponentBase[] components = GetComponentPipeline();
- if (components != null)
- {
- foreach (var c in components)
- {
- if (c is T)
- {
- c.enabled = false;
- RuntimeUtility.DestroyObject(c);
- InvalidateComponentPipeline();
- }
- }
- }
- }
- /// <summary>API for the editor, to make the dragging of position handles behave better.</summary>
- public bool UserIsDragging { get; set; }
- CameraState m_State = CameraState.Default; // Current state this frame
- CinemachineComponentBase[] m_ComponentPipeline = null;
- [SerializeField][HideInInspector] private Transform m_ComponentOwner = null; // serialized to handle copy/paste
- void UpdateComponentPipeline()
- {
- bool isPrefab = RuntimeUtility.IsPrefab(gameObject);
- #if UNITY_EDITOR
- // Did we just get copy/pasted?
- if (m_ComponentOwner != null && m_ComponentOwner.parent != transform)
- {
- if (!isPrefab) // can't paste to a prefab
- {
- CinemachineVirtualCamera copyFrom = (m_ComponentOwner.parent != null)
- ? m_ComponentOwner.parent.gameObject.GetComponent<CinemachineVirtualCamera>() : null;
- DestroyPipeline();
- m_ComponentOwner = CreatePipeline(copyFrom);
- }
- }
- if (m_ComponentOwner != null)
- SetFlagsForHiddenChild(m_ComponentOwner.gameObject);
- #endif
- // Early out if we're up-to-date
- if (m_ComponentOwner != null && m_ComponentPipeline != null)
- return;
- m_ComponentOwner = null;
- List<CinemachineComponentBase> list = new List<CinemachineComponentBase>();
- foreach (Transform child in transform)
- {
- if (child.GetComponent<CinemachinePipeline>() != null)
- {
- m_ComponentOwner = child;
- CinemachineComponentBase[] components = child.GetComponents<CinemachineComponentBase>();
- foreach (CinemachineComponentBase c in components)
- if (c.enabled)
- list.Add(c);
- }
- }
- // Make sure we have a pipeline owner
- if (m_ComponentOwner == null && !isPrefab)
- m_ComponentOwner = CreatePipeline(null);
- // Make sure the pipeline stays hidden, even through prefab
- if (m_ComponentOwner != null)
- SetFlagsForHiddenChild(m_ComponentOwner.gameObject);
- if (m_ComponentOwner != null && m_ComponentOwner.gameObject != null)
- {
- // Sort the pipeline
- list.Sort((c1, c2) => (int)c1.Stage - (int)c2.Stage);
- m_ComponentPipeline = list.ToArray();
- }
- }
- static internal void SetFlagsForHiddenChild(GameObject child)
- {
- if (child != null)
- {
- if (CinemachineCore.sShowHiddenObjects)
- child.hideFlags &= ~(HideFlags.HideInHierarchy | HideFlags.HideInInspector);
- else
- child.hideFlags |= (HideFlags.HideInHierarchy | HideFlags.HideInInspector);
- }
- }
- private Transform mCachedLookAtTarget;
- private CinemachineVirtualCameraBase mCachedLookAtTargetVcam;
- private CameraState CalculateNewState(Vector3 worldUp, float deltaTime)
- {
- FollowTargetAttachment = 1;
- LookAtTargetAttachment = 1;
- // Initialize the camera state, in case the game object got moved in the editor
- CameraState state = PullStateFromVirtualCamera(worldUp, ref m_Lens);
- Transform lookAtTarget = LookAt;
- if (lookAtTarget != mCachedLookAtTarget)
- {
- mCachedLookAtTarget = lookAtTarget;
- mCachedLookAtTargetVcam = null;
- if (lookAtTarget != null)
- mCachedLookAtTargetVcam = lookAtTarget.GetComponent<CinemachineVirtualCameraBase>();
- }
- if (lookAtTarget != null)
- {
- if (mCachedLookAtTargetVcam != null)
- state.ReferenceLookAt = mCachedLookAtTargetVcam.State.FinalPosition;
- else
- state.ReferenceLookAt = TargetPositionCache.GetTargetPosition(lookAtTarget);
- }
- // Update the state by invoking the component pipeline
- UpdateComponentPipeline(); // avoid GetComponentPipeline() here because of GC
- // Extensions first
- InvokePrePipelineMutateCameraStateCallback(this, ref state, deltaTime);
- // Then components
- if (m_ComponentPipeline == null)
- {
- state.BlendHint |= CameraState.BlendHintValue.IgnoreLookAtTarget;
- for (var stage = CinemachineCore.Stage.Body; stage <= CinemachineCore.Stage.Finalize; ++stage)
- InvokePostPipelineStageCallback(this, stage, ref state, deltaTime);
- }
- else
- {
- for (int i = 0; i < m_ComponentPipeline.Length; ++i)
- m_ComponentPipeline[i].PrePipelineMutateCameraState(ref state, deltaTime);
- int componentIndex = 0;
- CinemachineComponentBase postAimBody = null;
- for (var stage = CinemachineCore.Stage.Body; stage <= CinemachineCore.Stage.Finalize; ++stage)
- {
- var c = componentIndex < m_ComponentPipeline.Length
- ? m_ComponentPipeline[componentIndex] : null;
- if (c != null && stage == c.Stage)
- {
- ++componentIndex;
- if (stage == CinemachineCore.Stage.Body && c.BodyAppliesAfterAim)
- {
- postAimBody = c;
- continue; // do the body stage of the pipeline after Aim
- }
- c.MutateCameraState(ref state, deltaTime);
- }
- InvokePostPipelineStageCallback(this, stage, ref state, deltaTime);
- if (stage == CinemachineCore.Stage.Aim)
- {
- if (c == null)
- state.BlendHint |= CameraState.BlendHintValue.IgnoreLookAtTarget;
- // If we have saved a Body for after Aim, do it now
- if (postAimBody != null)
- {
- postAimBody.MutateCameraState(ref state, deltaTime);
- InvokePostPipelineStageCallback(this, CinemachineCore.Stage.Body, ref state, deltaTime);
- }
- }
- }
- }
- return state;
- }
- /// <summary>This is called to notify the vcam that a target got warped,
- /// so that the vcam can update its internal state to make the camera
- /// also warp seamlessy.</summary>
- /// <param name="target">The object that was warped</param>
- /// <param name="positionDelta">The amount the target's position changed</param>
- public override void OnTargetObjectWarped(Transform target, Vector3 positionDelta)
- {
- if (target == Follow)
- {
- transform.position += positionDelta;
- m_State.RawPosition += positionDelta;
- }
- UpdateComponentPipeline(); // avoid GetComponentPipeline() here because of GC
- if (m_ComponentPipeline != null)
- {
- for (int i = 0; i < m_ComponentPipeline.Length; ++i)
- m_ComponentPipeline[i].OnTargetObjectWarped(target, positionDelta);
- }
- base.OnTargetObjectWarped(target, positionDelta);
- }
- /// <summary>
- /// Force the virtual camera to assume a given position and orientation
- /// </summary>
- /// <param name="pos">Worldspace pposition to take</param>
- /// <param name="rot">Worldspace orientation to take</param>
- public override void ForceCameraPosition(Vector3 pos, Quaternion rot)
- {
- PreviousStateIsValid = true;
- transform.position = pos;
- transform.rotation = rot;
- m_State.RawPosition = pos;
- m_State.RawOrientation = rot;
- UpdateComponentPipeline(); // avoid GetComponentPipeline() here because of GC
- if (m_ComponentPipeline != null)
- for (int i = 0; i < m_ComponentPipeline.Length; ++i)
- m_ComponentPipeline[i].ForceCameraPosition(pos, rot);
- base.ForceCameraPosition(pos, rot);
- }
-
- // This is a hack for FreeLook rigs - to be removed
- internal void SetStateRawPosition(Vector3 pos) { m_State.RawPosition = pos; }
- /// <summary>If we are transitioning from another vcam, grab the position from it.</summary>
- /// <param name="fromCam">The camera being deactivated. May be null.</param>
- /// <param name="worldUp">Default world Up, set by the CinemachineBrain</param>
- /// <param name="deltaTime">Delta time for time-based effects (ignore if less than or equal to 0)</param>
- public override void OnTransitionFromCamera(
- ICinemachineCamera fromCam, Vector3 worldUp, float deltaTime)
- {
- base.OnTransitionFromCamera(fromCam, worldUp, deltaTime);
- InvokeOnTransitionInExtensions(fromCam, worldUp, deltaTime);
- bool forceUpdate = false;
- if (m_Transitions.m_InheritPosition && fromCam != null)
- {
- transform.position = fromCam.State.FinalPosition;
- //transform.rotation = fromCam.State.RawOrientation;
- PreviousStateIsValid = false;
- forceUpdate = true;
- }
- UpdateComponentPipeline(); // avoid GetComponentPipeline() here because of GC
- if (m_ComponentPipeline != null)
- {
- for (int i = 0; i < m_ComponentPipeline.Length; ++i)
- if (m_ComponentPipeline[i].OnTransitionFromCamera(
- fromCam, worldUp, deltaTime, ref m_Transitions))
- forceUpdate = true;
- }
- if (forceUpdate)
- {
- InternalUpdateCameraState(worldUp, deltaTime);
- InternalUpdateCameraState(worldUp, deltaTime);
- }
- else
- UpdateCameraState(worldUp, deltaTime);
- if (m_Transitions.m_OnCameraLive != null)
- m_Transitions.m_OnCameraLive.Invoke(this, fromCam);
- }
- }
- }
|