/// <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 than 0, no damping is done.</param> public override void MutateCameraState(ref CameraState curState, float deltaTime) { InitPrevFrameStateInfo(ref curState, deltaTime); // Update the heading if (FollowTarget != PreviousTarget) { PreviousTarget = FollowTarget; mTargetRigidBody = (PreviousTarget == null) ? null : PreviousTarget.GetComponent <Rigidbody>(); mLastTargetPosition = (PreviousTarget == null) ? Vector3.zero : PreviousTarget.position; mHeadingTracker = null; } LastHeading = HeadingUpdater(this, deltaTime, curState.ReferenceUp); float heading = LastHeading; if (IsValid) { // Calculate the heading if (m_BindingMode != BindingMode.SimpleFollowWithWorldUp) { heading += m_Heading.m_Bias; } Quaternion headingRot = Quaternion.AngleAxis(heading, Vector3.up); Vector3 rawOffset = EffectiveOffset; Vector3 offset = headingRot * rawOffset; // Track the target, with damping TrackTarget(deltaTime, curState.ReferenceUp, offset, out Vector3 pos, out Quaternion orient); // Place the camera offset = orient * offset; curState.ReferenceUp = orient * Vector3.up; // Respect minimum target distance on XZ plane var targetPosition = FollowTargetPosition; pos += GetOffsetForMinimumTargetDistance( pos, offset, curState.RawOrientation * Vector3.forward, curState.ReferenceUp, targetPosition); curState.RawPosition = pos + offset; if (deltaTime >= 0 && VirtualCamera.PreviousStateIsValid) { var lookAt = targetPosition; if (LookAtTarget != null) { lookAt = LookAtTargetPosition; } var dir0 = mLastCameraPosition - lookAt; var dir1 = curState.RawPosition - lookAt; if (dir0.sqrMagnitude > 0.01f && dir1.sqrMagnitude > 0.01f) { curState.PositionDampingBypass = UnityVectorExtensions.SafeFromToRotation( dir0, dir1, curState.ReferenceUp).eulerAngles; } } mLastTargetPosition = targetPosition; mLastCameraPosition = curState.RawPosition; } }
/// <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 than 0, no damping is done.</param> public override void MutateCameraState(ref CameraState curState, float deltaTime) { InitPrevFrameStateInfo(ref curState, deltaTime); // Update the heading if (FollowTarget != PreviousTarget) { PreviousTarget = FollowTarget; mTargetRigidBody = (PreviousTarget == null) ? null : PreviousTarget.GetComponent <Rigidbody>(); mLastTargetPosition = (PreviousTarget == null) ? Vector3.zero : PreviousTarget.position; mHeadingTracker = null; } LastHeading = HeadingUpdater(this, deltaTime, curState.ReferenceUp); float heading = LastHeading; if (IsValid) { mLastTargetPosition = FollowTargetPosition; // Calculate the heading if (m_BindingMode != BindingMode.SimpleFollowWithWorldUp) { heading += m_Heading.m_Bias; } Quaternion headingRot = Quaternion.AngleAxis(heading, Vector3.up); // Track the target, with damping Vector3 offset = EffectiveOffset; Vector3 pos; Quaternion orient; TrackTarget(deltaTime, curState.ReferenceUp, headingRot * offset, out pos, out orient); // Place the camera curState.ReferenceUp = orient * Vector3.up; if (deltaTime >= 0) { Vector3 bypass = (headingRot * offset) - mHeadingPrevFrame * mOffsetPrevFrame; bypass = orient * bypass; curState.PositionDampingBypass = bypass; } orient = orient * headingRot; curState.RawPosition = pos + orient * offset; mHeadingPrevFrame = (m_BindingMode == BindingMode.SimpleFollowWithWorldUp) ? Quaternion.identity : headingRot; mOffsetPrevFrame = offset; } }