Exemplo n.º 1
0
        /// <summary>
        /// Update a single Cinemachine Virtual Camera if and only if it
        /// hasn't already been updated this frame.  Always update vcams via this method.
        /// Calling this more than once per frame for the same camera will have no effect.
        /// </summary>
        internal void UpdateVirtualCamera(
            CinemachineVirtualCameraBase vcam, Vector3 worldUp, float deltaTime)
        {
            if (vcam == null)
            {
                return;
            }

            bool isSmartUpdate = (CurrentUpdateFilter & UpdateFilter.Smart) == UpdateFilter.Smart;

            UpdateTracker.UpdateClock updateClock
                = (UpdateTracker.UpdateClock)(CurrentUpdateFilter & ~UpdateFilter.Smart);

            // If we're in smart update mode and the target moved, then we must examine
            // how the target has been moving recently in order to figure out whether to
            // update now
            if (isSmartUpdate)
            {
                Transform updateTarget = GetUpdateTarget(vcam);
                if (updateTarget == null)
                {
                    return;   // vcam deleted
                }
                if (UpdateTracker.GetPreferredUpdate(updateTarget) != updateClock)
                {
                    return;   // wrong clock
                }
            }

            // Have we already been updated this frame?
            if (mUpdateStatus == null)
            {
                mUpdateStatus = new Dictionary <CinemachineVirtualCameraBase, UpdateStatus>();
            }
            UpdateStatus status;

            if (!mUpdateStatus.TryGetValue(vcam, out status))
            {
                status = new UpdateStatus();
                mUpdateStatus.Add(vcam, status);
            }

            int frameDelta = (updateClock == UpdateTracker.UpdateClock.Late)
                ? Time.frameCount - status.lastUpdateFrame
                : FixedFrameCount - status.lastUpdateFixedFrame;

            if (deltaTime >= 0 && frameDelta == 0 && status.lastUpdateMode == updateClock)
            {
                return; // already updated
            }
            if (frameDelta != 1)
            {
                deltaTime = -1; // multiple frames - kill the damping
            }
//Debug.Log((vcam.ParentCamera == null ? "" : vcam.ParentCamera.Name + ".") + vcam.Name + ": frame " + Time.frameCount + "/" + status.lastUpdateFixedFrame + ", " + CurrentUpdateFilter + ", deltaTime = " + deltaTime);
            vcam.InternalUpdateCameraState(worldUp, deltaTime);
            status.lastUpdateFrame      = Time.frameCount;
            status.lastUpdateFixedFrame = FixedFrameCount;
            status.lastUpdateMode       = updateClock;
        }
        /// <summary>
        /// Update a single Cinemachine Virtual Camera if and only if it
        /// hasn't already been updated this frame.  Always update vcams via this method.
        /// Calling this more than once per frame for the same camera will have no effect.
        /// </summary>
        internal bool UpdateVirtualCamera(
            CinemachineVirtualCameraBase vcam, Vector3 worldUp, float deltaTime)
        {
            UpdateFilter filter        = CurrentUpdateFilter;
            bool         isSmartUpdate = filter != UpdateFilter.ForcedFixed &&
                                         filter != UpdateFilter.ForcedLate;
            bool isSmartLateUpdate = filter == UpdateFilter.Late;

            if (!isSmartUpdate)
            {
                if (filter == UpdateFilter.ForcedFixed)
                {
                    filter = UpdateFilter.Fixed;
                }
                if (filter == UpdateFilter.ForcedLate)
                {
                    filter = UpdateFilter.Late;
                }
            }

            if (mUpdateStatus == null)
            {
                mUpdateStatus = new Dictionary <CinemachineVirtualCameraBase, UpdateStatus>();
            }
            if (vcam.gameObject == null)
            {
                if (mUpdateStatus.ContainsKey(vcam))
                {
                    mUpdateStatus.Remove(vcam);
                }
                return(false); // camera was deleted
            }
            int          now = Time.frameCount;
            UpdateStatus status;

            if (!mUpdateStatus.TryGetValue(vcam, out status))
            {
                status = new UpdateStatus(now);
                mUpdateStatus.Add(vcam, status);
            }

            int subframes = isSmartLateUpdate ? 1 : CinemachineBrain.GetSubframeCount();

            if (status.lastUpdateFrame != now)
            {
                status.lastUpdateSubframe = 0;
            }

            // If we're in smart update mode and the target moved, then we must examine
            // how the target has been moving recently in order to figure out whether to
            // update now
            bool updateNow = !isSmartUpdate;

            if (isSmartUpdate)
            {
                Matrix4x4 targetPos;
                if (!GetTargetPosition(vcam, out targetPos))
                {
                    updateNow = isSmartLateUpdate; // no target
                }
                else
                {
                    updateNow = status.ChoosePreferredUpdate(now, targetPos, filter)
                                == filter;
                }
            }

            if (updateNow)
            {
                status.preferredUpdate = filter;
                while (status.lastUpdateSubframe < subframes)
                {
//Debug.Log((vcam.ParentCamera == null ? "" : vcam.ParentCamera.Name + ".") + vcam.Name + ": frame " + Time.frameCount + "." + status.lastUpdateSubframe + ", " + CurrentUpdateFilter + ", deltaTime = " + deltaTime);
                    vcam.InternalUpdateCameraState(worldUp, deltaTime);
                    ++status.lastUpdateSubframe;
                }
                status.lastUpdateFrame = now;
            }

            mUpdateStatus[vcam] = status;
            return(updateNow);
        }