/// <summary>Positions the virtual camera according to the transposer rules.</summary>
        /// <param name="curState">The current camera state</param>
        /// <param name="deltaTime">Used for damping.  If less that 0, no damping is done.</param>
        public override void MutateCameraState(ref CameraState curState, float deltaTime)
        {
            // Init previous frame state info
            if (deltaTime < 0)
            {
                m_PreviousPathPosition   = m_PathPosition;
                m_PreviousCameraPosition = curState.RawPosition;
            }

            if (!IsValid)
            {
                return;
            }

            //UnityEngine.Profiling.Profiler.BeginSample("CinemachineTrackedDolly.MutateCameraState");
            // Get the new ideal path base position
            if (m_AutoDolly.m_Enabled && FollowTarget != null)
            {
                float prevPos = m_Path.ToNativePathUnits(m_PreviousPathPosition, m_PositionUnits);
                // This works in path units
                m_PathPosition = m_Path.FindClosestPoint(
                    FollowTargetPosition,
                    Mathf.FloorToInt(prevPos),
                    (deltaTime < 0 || m_AutoDolly.m_SearchRadius <= 0)
                        ? -1 : m_AutoDolly.m_SearchRadius,
                    m_AutoDolly.m_SearchResolution);
                m_PathPosition = m_Path.FromPathNativeUnits(m_PathPosition, m_PositionUnits);

                // Apply the path position offset
                m_PathPosition += m_AutoDolly.m_PositionOffset;
            }
            float newPathPosition = m_PathPosition;

            if (deltaTime >= 0)
            {
                // Normalize previous position to find the shortest path
                float maxUnit = m_Path.MaxUnit(m_PositionUnits);
                if (maxUnit > 0)
                {
                    float prev = m_Path.StandardizeUnit(m_PreviousPathPosition, m_PositionUnits);
                    float next = m_Path.StandardizeUnit(newPathPosition, m_PositionUnits);
                    if (m_Path.Looped && Mathf.Abs(next - prev) > maxUnit / 2)
                    {
                        if (next > prev)
                        {
                            prev += maxUnit;
                        }
                        else
                        {
                            prev -= maxUnit;
                        }
                    }
                    m_PreviousPathPosition = prev;
                    newPathPosition        = next;
                }

                // Apply damping along the path direction
                float offset = m_PreviousPathPosition - newPathPosition;
                offset          = Damper.Damp(offset, m_ZDamping, deltaTime);
                newPathPosition = m_PreviousPathPosition - offset;
            }
            m_PreviousPathPosition = newPathPosition;
            Quaternion newPathOrientation = m_Path.EvaluateOrientationAtUnit(newPathPosition, m_PositionUnits);

            // Apply the offset to get the new camera position
            Vector3 newCameraPos = m_Path.EvaluatePositionAtUnit(newPathPosition, m_PositionUnits);
            Vector3 offsetX      = newPathOrientation * Vector3.right;
            Vector3 offsetY      = newPathOrientation * Vector3.up;
            Vector3 offsetZ      = newPathOrientation * Vector3.forward;

            newCameraPos += m_PathOffset.x * offsetX;
            newCameraPos += m_PathOffset.y * offsetY;
            newCameraPos += m_PathOffset.z * offsetZ;

            // Apply damping to the remaining directions
            if (deltaTime >= 0)
            {
                Vector3 currentCameraPos = m_PreviousCameraPosition;
                Vector3 delta            = (currentCameraPos - newCameraPos);
                Vector3 delta1           = Vector3.Dot(delta, offsetY) * offsetY;
                Vector3 delta0           = delta - delta1;
                delta0       = Damper.Damp(delta0, m_XDamping, deltaTime);
                delta1       = Damper.Damp(delta1, m_YDamping, deltaTime);
                newCameraPos = currentCameraPos - (delta0 + delta1);
            }
            curState.RawPosition = m_PreviousCameraPosition = newCameraPos;

            // Set the orientation and up
            Quaternion newOrientation
                = GetCameraOrientationAtPathPoint(newPathOrientation, curState.ReferenceUp);

            if (deltaTime < 0)
            {
                m_PreviousOrientation = newOrientation;
            }
            else
            {
                if (deltaTime >= 0)
                {
                    Vector3 relative = (Quaternion.Inverse(m_PreviousOrientation)
                                        * newOrientation).eulerAngles;
                    for (int i = 0; i < 3; ++i)
                    {
                        if (relative[i] > 180)
                        {
                            relative[i] -= 360;
                        }
                    }
                    relative       = Damper.Damp(relative, AngularDamping, deltaTime);
                    newOrientation = m_PreviousOrientation * Quaternion.Euler(relative);
                }
                m_PreviousOrientation = newOrientation;
            }

            curState.RawOrientation = newOrientation;
            if (m_CameraUp != CameraUpMode.Default)
            {
                curState.ReferenceUp = curState.RawOrientation * Vector3.up;
            }
            //UnityEngine.Profiling.Profiler.EndSample();
        }
示例#2
0
        /// <summary>Positions the virtual camera according to the transposer rules.</summary>
        /// <param name="curState">The current camera state</param>
        /// <param name="deltaTime">Used for damping.  If 0 or less, no damping is done.</param>
        public void MutateCameraState(ref CameraState curState, float deltaTime)
        {
            // Init previous frame state info
            if (deltaTime <= 0)
            {
                m_PreviousPathPosition   = m_PathPosition;
                m_PreviousCameraPosition = curState.RawPosition;
            }

            if (!IsValid)
            {
                return;
            }

            //UnityEngine.Profiling.Profiler.BeginSample("CinemachineTrackedDolly.MutateCameraState");
            // Get the new ideal path base position
            if (m_AutoDolly.m_Enabled && VirtualCamera.Follow != null)
            {
                float prevPos = m_PreviousPathPosition;
                if (m_PositionUnits == CinemachinePathBase.PositionUnits.Distance)
                {
                    prevPos = m_Path.GetPathPositionFromDistance(prevPos);
                }

                m_PathPosition = m_Path.FindClosestPoint(
                    VirtualCamera.Follow.transform.position,
                    Mathf.FloorToInt(prevPos),
                    (deltaTime <= 0 || m_AutoDolly.m_SearchRadius <= 0)
                        ? -1 : m_AutoDolly.m_SearchRadius,
                    m_AutoDolly.m_StepsPerSegment);
                if (m_PositionUnits == CinemachinePathBase.PositionUnits.Distance)
                {
                    m_PathPosition = m_Path.GetPathDistanceFromPosition(m_PathPosition);
                }

                // Apply the path position offset
                m_PathPosition += m_AutoDolly.m_PositionOffset;
            }
            float newPathPosition = m_PathPosition;

            if (deltaTime > 0)
            {
                // Normalize previous position to find the shortest path
                float maxUnit = m_Path.MaxUnit(m_PositionUnits);
                if (maxUnit > 0)
                {
                    float prev = m_Path.NormalizeUnit(m_PreviousPathPosition, m_PositionUnits);
                    float next = m_Path.NormalizeUnit(newPathPosition, m_PositionUnits);
                    if (m_Path.Looped && Mathf.Abs(next - prev) > maxUnit / 2)
                    {
                        if (next > prev)
                        {
                            prev += maxUnit;
                        }
                        else
                        {
                            prev -= maxUnit;
                        }
                    }
                    m_PreviousPathPosition = prev;
                    newPathPosition        = next;
                }

                // Apply damping along the path direction
                float offset = m_PreviousPathPosition - newPathPosition;
                if (Mathf.Abs(offset) > UnityVectorExtensions.Epsilon)
                {
                    offset *= deltaTime / Mathf.Max(m_ZDamping * kDampingScale, deltaTime);
                }
                newPathPosition = m_PreviousPathPosition - offset;
            }
            m_PreviousPathPosition = newPathPosition;
            Quaternion newPathOrientation = m_Path.EvaluateOrientationAtUnit(newPathPosition, m_PositionUnits);

            // Apply the offset to get the new camera position
            Vector3 newCameraPos = m_Path.EvaluatePositionAtUnit(newPathPosition, m_PositionUnits);
            Vector3 offsetX      = newPathOrientation * Vector3.right;
            Vector3 offsetY      = newPathOrientation * Vector3.up;
            Vector3 offsetZ      = newPathOrientation * Vector3.forward;

            newCameraPos += m_PathOffset.x * offsetX;
            newCameraPos += m_PathOffset.y * offsetY;
            newCameraPos += m_PathOffset.z * offsetZ;

            // Apply damping to the remaining directions
            if (deltaTime > 0)
            {
                Vector3 currentCameraPos = m_PreviousCameraPosition;
                Vector3 delta            = (currentCameraPos - newCameraPos);
                Vector3 delta1           = Vector3.Dot(delta, offsetY) * offsetY;
                Vector3 delta0           = delta - delta1;
                delta = delta0 * deltaTime / Mathf.Max(m_XDamping * kDampingScale, deltaTime)
                        + delta1 * deltaTime / Mathf.Max(m_YDamping * kDampingScale, deltaTime);
                newCameraPos = currentCameraPos - delta;
            }
            curState.RawPosition = m_PreviousCameraPosition = newCameraPos;

            // Set the orientation and up
            Quaternion newOrientation
                = GetTargetOrientationAtPathPoint(newPathOrientation, curState.ReferenceUp);

            if (deltaTime <= 0)
            {
                m_PreviousOrientation = newOrientation;
            }
            else
            {
                if (deltaTime > 0)
                {
                    Vector3 relative = (Quaternion.Inverse(m_PreviousOrientation)
                                        * newOrientation).eulerAngles;
                    Vector3 damping = AngularDamping;
                    for (int i = 0; i < 3; ++i)
                    {
                        if (relative[i] > 180)
                        {
                            relative[i] -= 360;
                        }
                        if (Mathf.Abs(relative[i]) > UnityVectorExtensions.Epsilon)
                        {
                            relative[i] *= deltaTime / Mathf.Max(damping[i], deltaTime);
                        }
                    }
                    newOrientation = m_PreviousOrientation * Quaternion.Euler(relative);
                }
                m_PreviousOrientation = newOrientation;
            }

            curState.RawOrientation = newOrientation;
            curState.ReferenceUp    = curState.RawOrientation * Vector3.up;
            //UnityEngine.Profiling.Profiler.EndSample();
        }
示例#3
0
        /// <summary>Positions the virtual camera according to the transposer rules.</summary>
        /// <param name="curState">The current camera state</param>
        /// <param name="deltaTime">Used for damping.  If 0 or less, no damping is done.</param>
        public void MutateCameraState(ref CameraState curState, float deltaTime)
        {
            // Init previous frame state info
            if (deltaTime <= 0)
            {
                m_PreviousPathPosition   = m_PathPosition;
                m_PreviousCameraPosition = curState.RawPosition;
            }

            if (!IsValid)
            {
                return;
            }

            // Get the new ideal path base position
            if (m_AutoDolly.m_Enabled && VirtualCamera.Follow != null)
            {
                float prevPos = m_PreviousPathPosition;
                if (m_PositionUnits == CinemachinePathBase.PositionUnits.Distance)
                {
                    prevPos = m_Path.GetPathPositionFromDistance(prevPos);
                }

                m_PathPosition = m_Path.FindClosestPoint(
                    VirtualCamera.Follow.transform.position,
                    Mathf.FloorToInt(prevPos),
                    (deltaTime <= 0 || m_AutoDolly.m_SearchRadius <= 0)
                        ? -1 : m_AutoDolly.m_SearchRadius,
                    m_AutoDolly.m_StepsPerSegment);
                if (m_PositionUnits == CinemachinePathBase.PositionUnits.Distance)
                {
                    m_PathPosition = m_Path.GetPathDistanceFromPosition(m_PathPosition);
                }
            }
            float newPathPosition = m_PathPosition;

            if (deltaTime > 0)
            {
                // Normalize previous position to find the shortest path
                float maxUnit = m_Path.MaxUnit(m_PositionUnits);
                if (maxUnit > 0)
                {
                    float prev = m_Path.NormalizeUnit(m_PreviousPathPosition, m_PositionUnits);
                    float next = m_Path.NormalizeUnit(newPathPosition, m_PositionUnits);
                    if (m_Path.Looped && Mathf.Abs(next - prev) > maxUnit / 2)
                    {
                        if (next > prev)
                        {
                            prev += maxUnit;
                        }
                        else
                        {
                            prev -= maxUnit;
                        }
                    }
                    m_PreviousPathPosition = prev;
                    newPathPosition        = next;
                }

                // Apply damping along the path direction
                float offset = m_PreviousPathPosition - newPathPosition;
                if (Mathf.Abs(offset) > UnityVectorExtensions.Epsilon)
                {
                    offset *= deltaTime / Mathf.Max(m_ZDamping * kDampingScale, deltaTime);
                }
                newPathPosition = m_PreviousPathPosition - offset;
            }
            m_PreviousPathPosition = newPathPosition;
            Quaternion newPathOrientation = m_Path.EvaluateOrientationAtUnit(newPathPosition, m_PositionUnits);

            // Apply the offset to get the new camera position
            Vector3 newCameraPos = m_Path.EvaluatePositionAtUnit(newPathPosition, m_PositionUnits);

            Vector3[] offsetDir = new Vector3[3];
            offsetDir[2] = newPathOrientation * Vector3.forward;
            offsetDir[1] = newPathOrientation * Vector3.up;
            offsetDir[0] = Vector3.Cross(offsetDir[1], offsetDir[2]);
            for (int i = 0; i < 3; ++i)
            {
                newCameraPos += m_PathOffset[i] * offsetDir[i];
            }

            // Apply damping to the remaining directions
            if (deltaTime > 0)
            {
                Vector3 currentCameraPos = m_PreviousCameraPosition;
                Vector3 delta            = (currentCameraPos - newCameraPos);
                Vector3 delta1           = Vector3.Dot(delta, offsetDir[1]) * offsetDir[1];
                Vector3 delta0           = delta - delta1;
                delta = delta0 * deltaTime / Mathf.Max(m_XDamping * kDampingScale, deltaTime)
                        + delta1 * deltaTime / Mathf.Max(m_YDamping * kDampingScale, deltaTime);
                newCameraPos = currentCameraPos - delta;
            }
            curState.RawPosition = m_PreviousCameraPosition = newCameraPos;

            // Set the up
            switch (m_CameraUp)
            {
            default:
            case CameraUpMode.World:
                break;

            case CameraUpMode.Path:
                curState.ReferenceUp    = newPathOrientation * Vector3.up;
                curState.RawOrientation = newPathOrientation;
                break;

            case CameraUpMode.PathNoRoll:
                curState.RawOrientation = Quaternion.LookRotation(
                    newPathOrientation * Vector3.forward, Vector3.up);
                curState.ReferenceUp = curState.RawOrientation * Vector3.up;
                break;

            case CameraUpMode.FollowTarget:
                if (VirtualCamera.Follow != null)
                {
                    curState.RawOrientation = VirtualCamera.Follow.rotation;
                    curState.ReferenceUp    = curState.RawOrientation * Vector3.up;
                }
                break;

            case CameraUpMode.FollowTargetNoRoll:
                if (VirtualCamera.Follow != null)
                {
                    curState.RawOrientation = Quaternion.LookRotation(
                        VirtualCamera.Follow.rotation * Vector3.forward, Vector3.up);
                    curState.ReferenceUp = curState.RawOrientation * Vector3.up;
                }
                break;
            }
        }