diff --git a/Base/Editor/Editors/CinemachineHardLockToTargetEditor.cs b/Base/Editor/Editors/CinemachineHardLockToTargetEditor.cs index d80c8286d..28ac8b1a7 100644 --- a/Base/Editor/Editors/CinemachineHardLockToTargetEditor.cs +++ b/Base/Editor/Editors/CinemachineHardLockToTargetEditor.cs @@ -15,7 +15,7 @@ public override void OnInspectorGUI() MessageType.Warning); EditorGUI.BeginChangeCheck(); GUI.enabled = false; - EditorGUILayout.LabelField(" ", "Hard Lock has no settings", EditorStyles.miniLabel); + EditorGUILayout.LabelField(" ", "No additional settings", EditorStyles.miniLabel); GUI.enabled = true; DrawRemainingPropertiesInInspector(); } diff --git a/Base/Editor/Editors/CinemachineHardLookAtEditor.cs b/Base/Editor/Editors/CinemachineHardLookAtEditor.cs index c3c1df897..bcda65186 100644 --- a/Base/Editor/Editors/CinemachineHardLookAtEditor.cs +++ b/Base/Editor/Editors/CinemachineHardLookAtEditor.cs @@ -15,7 +15,7 @@ public override void OnInspectorGUI() MessageType.Warning); EditorGUI.BeginChangeCheck(); GUI.enabled = false; - EditorGUILayout.LabelField(" ", "Hard Look At has no settings", EditorStyles.miniLabel); + EditorGUILayout.LabelField(" ", "No additional settings", EditorStyles.miniLabel); GUI.enabled = true; DrawRemainingPropertiesInInspector(); } diff --git a/Base/Editor/Editors/CinemachineHardLookAtEditor.cs.meta b/Base/Editor/Editors/CinemachineHardLookAtEditor.cs.meta index 2596dea57..6f8815d73 100644 --- a/Base/Editor/Editors/CinemachineHardLookAtEditor.cs.meta +++ b/Base/Editor/Editors/CinemachineHardLookAtEditor.cs.meta @@ -1,8 +1,7 @@ fileFormatVersion: 2 guid: 9ce16cd7e31794b48b2843381cd87d31 -timeCreated: 1506541599 -licenseType: Pro MonoImporter: + externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 diff --git a/Base/Editor/Editors/CinemachineOrbitalTransposerEditor.cs b/Base/Editor/Editors/CinemachineOrbitalTransposerEditor.cs index 0064730b6..86d02c2f7 100644 --- a/Base/Editor/Editors/CinemachineOrbitalTransposerEditor.cs +++ b/Base/Editor/Editors/CinemachineOrbitalTransposerEditor.cs @@ -72,7 +72,7 @@ static void DrawTransposerGizmos(CinemachineOrbitalTransposer target, GizmoType CinemachineBrain brain = CinemachineCore.Instance.FindPotentialTargetBrain(target.VirtualCamera); if (brain != null) up = brain.DefaultWorldUp; - Vector3 pos = target.FollowTarget.position; + Vector3 pos = target.FollowTargetPosition; Quaternion orient = target.GetReferenceOrientation(up); up = orient * Vector3.up; diff --git a/Base/Editor/Editors/CinemachineSameAsFollowTargetEditor.cs b/Base/Editor/Editors/CinemachineSameAsFollowTargetEditor.cs new file mode 100644 index 000000000..9bc63aac6 --- /dev/null +++ b/Base/Editor/Editors/CinemachineSameAsFollowTargetEditor.cs @@ -0,0 +1,23 @@ +using UnityEditor; +using UnityEngine; + +namespace Cinemachine.Editor +{ + [CustomEditor(typeof(CinemachineSameAsFollowTarget))] + public sealed class CinemachineSameAsFollowTargetEditor : BaseEditor + { + public override void OnInspectorGUI() + { + BeginInspector(); + if (Target.FollowTarget == null) + EditorGUILayout.HelpBox( + "Same As Follow Target requires a Follow target. It will set the virtual camera's rotation to be the same as that of the Follow Target.", + MessageType.Warning); + EditorGUI.BeginChangeCheck(); + GUI.enabled = false; + EditorGUILayout.LabelField(" ", "No additional settings", EditorStyles.miniLabel); + GUI.enabled = true; + DrawRemainingPropertiesInInspector(); + } + } +} diff --git a/Base/Editor/Editors/CinemachineSameAsFollowTargetEditor.cs.meta b/Base/Editor/Editors/CinemachineSameAsFollowTargetEditor.cs.meta new file mode 100644 index 000000000..5def8f47d --- /dev/null +++ b/Base/Editor/Editors/CinemachineSameAsFollowTargetEditor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fc54afb14b6b01a4dabc4c8831cb7bf7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Base/Editor/Editors/CinemachineTransposerEditor.cs b/Base/Editor/Editors/CinemachineTransposerEditor.cs index 37dce4f24..39c1e6303 100644 --- a/Base/Editor/Editors/CinemachineTransposerEditor.cs +++ b/Base/Editor/Editors/CinemachineTransposerEditor.cs @@ -62,10 +62,10 @@ static void DrawTransposerGizmos(CinemachineTransposer target, GizmoType selecti CinemachineBrain brain = CinemachineCore.Instance.FindPotentialTargetBrain(target.VirtualCamera); if (brain != null) up = brain.DefaultWorldUp; - Vector3 targetPos = target.FollowTarget.position; + Vector3 targetPos = target.FollowTargetPosition; Vector3 desiredPos = target.GeTargetCameraPosition(up); Gizmos.DrawLine(targetPos, desiredPos); - Gizmos.DrawWireSphere(desiredPos, HandleUtility.GetHandleSize(desiredPos) / 20); + //Gizmos.DrawWireSphere(desiredPos, HandleUtility.GetHandleSize(desiredPos) / 20); Gizmos.color = originalGizmoColour; } } diff --git a/Base/Runtime/Behaviours/CinemachineVirtualCamera.cs b/Base/Runtime/Behaviours/CinemachineVirtualCamera.cs index 31e509d6e..b7946663d 100644 --- a/Base/Runtime/Behaviours/CinemachineVirtualCamera.cs +++ b/Base/Runtime/Behaviours/CinemachineVirtualCamera.cs @@ -403,13 +403,28 @@ void UpdateComponentPipeline() m_ComponentPipeline = list.ToArray(); } + private Transform mCachedLookAtTarget; + private CinemachineVirtualCameraBase mCachedLookAtTargetVcam; private CameraState CalculateNewState(Vector3 worldUp, float deltaTime) { // Initialize the camera state, in case the game object got moved in the editor CameraState state = PullStateFromVirtualCamera(worldUp); - if (LookAt != null) - state.ReferenceLookAt = LookAt.position; + Transform lookAtTarget = LookAt; + if (lookAtTarget != mCachedLookAtTarget) + { + mCachedLookAtTarget = lookAtTarget; + mCachedLookAtTargetVcam = null; + if (lookAtTarget != null) + mCachedLookAtTargetVcam = lookAtTarget.GetComponent(); + } + if (lookAtTarget != null) + { + if (mCachedLookAtTargetVcam != null) + state.ReferenceLookAt = mCachedLookAtTargetVcam.State.FinalPosition; + else + state.ReferenceLookAt = lookAtTarget.position; + } // Update the state by invoking the component pipeline CinemachineCore.Stage curStage = CinemachineCore.Stage.Body; diff --git a/Base/Runtime/Components/CinemachineComposer.cs b/Base/Runtime/Components/CinemachineComposer.cs index 49495067e..3f4689873 100644 --- a/Base/Runtime/Components/CinemachineComposer.cs +++ b/Base/Runtime/Components/CinemachineComposer.cs @@ -124,7 +124,7 @@ protected virtual Vector3 GetLookAtPointAndSetTrackedPoint(Vector3 lookAt) { Vector3 pos = lookAt; if (LookAtTarget != null) - pos += LookAtTarget.transform.rotation * m_TrackedObjectOffset; + pos += LookAtTargetRotation * m_TrackedObjectOffset; m_Predictor.Smoothing = m_LookaheadSmoothing; m_Predictor.AddPosition(pos); diff --git a/Base/Runtime/Components/CinemachineFramingTransposer.cs b/Base/Runtime/Components/CinemachineFramingTransposer.cs index 19d913278..91da756b6 100644 --- a/Base/Runtime/Components/CinemachineFramingTransposer.cs +++ b/Base/Runtime/Components/CinemachineFramingTransposer.cs @@ -311,7 +311,7 @@ public override void MutateCameraState(ref CameraState curState, float deltaTime //UnityEngine.Profiling.Profiler.BeginSample("CinemachineFramingTransposer.MutateCameraState"); Vector3 camPosWorld = m_PreviousCameraPosition; - curState.ReferenceLookAt = FollowTarget.position; + curState.ReferenceLookAt = FollowTargetPosition; m_Predictor.Smoothing = m_LookaheadSmoothing; m_Predictor.AddPosition(curState.ReferenceLookAt); TrackedPoint = (m_LookaheadTime > 0) diff --git a/Base/Runtime/Components/CinemachineHardLockToTarget.cs b/Base/Runtime/Components/CinemachineHardLockToTarget.cs index eed714eb9..b6f46a3a2 100644 --- a/Base/Runtime/Components/CinemachineHardLockToTarget.cs +++ b/Base/Runtime/Components/CinemachineHardLockToTarget.cs @@ -26,7 +26,7 @@ public class CinemachineHardLockToTarget : CinemachineComponentBase public override void MutateCameraState(ref CameraState curState, float deltaTime) { if (IsValid) - curState.RawPosition = FollowTarget.position; + curState.RawPosition = FollowTargetPosition; } } } diff --git a/Base/Runtime/Components/CinemachineOrbitalTransposer.cs b/Base/Runtime/Components/CinemachineOrbitalTransposer.cs index 7de105f2d..848c0e0e4 100644 --- a/Base/Runtime/Components/CinemachineOrbitalTransposer.cs +++ b/Base/Runtime/Components/CinemachineOrbitalTransposer.cs @@ -312,7 +312,7 @@ public override void MutateCameraState(ref CameraState curState, float deltaTime if (IsValid) { - mLastTargetPosition = FollowTarget.position; + mLastTargetPosition = FollowTargetPosition; // Calculate the heading if (m_BindingMode != BindingMode.SimpleFollowWithWorldUp) @@ -385,13 +385,13 @@ private float GetTargetHeading( switch (m_Heading.m_HeadingDefinition) { case Heading.HeadingDefinition.PositionDelta: - velocity = FollowTarget.position - mLastTargetPosition; + velocity = FollowTargetPosition - mLastTargetPosition; break; case Heading.HeadingDefinition.Velocity: velocity = mTargetRigidBody.velocity; break; case Heading.HeadingDefinition.TargetForward: - velocity = FollowTarget.forward; + velocity = FollowTargetRotation * Vector3.forward; break; default: case Heading.HeadingDefinition.WorldForward: diff --git a/Base/Runtime/Components/CinemachineSameAsFollowObject.cs b/Base/Runtime/Components/CinemachineSameAsFollowTarget.cs similarity index 69% rename from Base/Runtime/Components/CinemachineSameAsFollowObject.cs rename to Base/Runtime/Components/CinemachineSameAsFollowTarget.cs index dd9f409dc..28548ed63 100644 --- a/Base/Runtime/Components/CinemachineSameAsFollowObject.cs +++ b/Base/Runtime/Components/CinemachineSameAsFollowTarget.cs @@ -4,13 +4,13 @@ namespace Cinemachine { /// /// This is a CinemachineComponent in the Aim section of the component pipeline. - /// Its job is to aim the camera hard at the LookAt target. + /// Its job is to match the orientation of the Follow target. /// [DocumentationSorting(DocumentationSortingAttribute.Level.UserRef)] [AddComponentMenu("")] // Don't display in add component menu [RequireComponent(typeof(CinemachinePipeline))] [SaveDuringPlay] - public class CinemachineSameAsFollowObject : CinemachineComponentBase + public class CinemachineSameAsFollowTarget : CinemachineComponentBase { /// True if component is enabled and has a Follow target defined public override bool IsValid { get { return enabled && FollowTarget != null; } } @@ -19,14 +19,13 @@ public class CinemachineSameAsFollowObject : CinemachineComponentBase /// Always returns the Aim stage public override CinemachineCore.Stage Stage { get { return CinemachineCore.Stage.Aim; } } - /// Applies the composer rules and orients the camera accordingly + /// Orients the camera to match the Follow target's orientation /// The current camera state - /// Used for calculating damping. If less than - /// zero, then target will snap to the center of the dead zone. + /// Not used. public override void MutateCameraState(ref CameraState curState, float deltaTime) { if (IsValid) - curState.RawOrientation = FollowTarget.transform.rotation; + curState.RawOrientation = FollowTargetRotation; } } } diff --git a/Base/Runtime/Components/CinemachineSameAsFollowObject.cs.meta b/Base/Runtime/Components/CinemachineSameAsFollowTarget.cs.meta similarity index 100% rename from Base/Runtime/Components/CinemachineSameAsFollowObject.cs.meta rename to Base/Runtime/Components/CinemachineSameAsFollowTarget.cs.meta diff --git a/Base/Runtime/Components/CinemachineTrackedDolly.cs b/Base/Runtime/Components/CinemachineTrackedDolly.cs index 7158b9d1e..82297089d 100644 --- a/Base/Runtime/Components/CinemachineTrackedDolly.cs +++ b/Base/Runtime/Components/CinemachineTrackedDolly.cs @@ -170,7 +170,7 @@ public override void MutateCameraState(ref CameraState curState, float deltaTime prevPos = m_Path.GetPathPositionFromDistance(prevPos); // This works in path units m_PathPosition = m_Path.FindClosestPoint( - FollowTarget.transform.position, + FollowTargetPosition, Mathf.FloorToInt(prevPos), (deltaTime < 0 || m_AutoDolly.m_SearchRadius <= 0) ? -1 : m_AutoDolly.m_SearchRadius, @@ -278,11 +278,11 @@ private Quaternion GetTargetOrientationAtPathPoint(Quaternion pathOrientation, V return Quaternion.LookRotation(pathOrientation * Vector3.forward, up); case CameraUpMode.FollowTarget: if (FollowTarget != null) - return FollowTarget.rotation; + return FollowTargetRotation; break; case CameraUpMode.FollowTargetNoRoll: if (FollowTarget != null) - return Quaternion.LookRotation(FollowTarget.rotation * Vector3.forward, up); + return Quaternion.LookRotation(FollowTargetRotation * Vector3.forward, up); break; } return Quaternion.LookRotation(transform.rotation * Vector3.forward, up); diff --git a/Base/Runtime/Components/CinemachineTransposer.cs b/Base/Runtime/Components/CinemachineTransposer.cs index a55506888..8ab755b31 100644 --- a/Base/Runtime/Components/CinemachineTransposer.cs +++ b/Base/Runtime/Components/CinemachineTransposer.cs @@ -164,7 +164,7 @@ protected void InitPrevFrameStateInfo( { m_previousTarget = FollowTarget; m_targetOrientationOnAssign - = (m_previousTarget == null) ? Quaternion.identity : FollowTarget.rotation; + = (m_previousTarget == null) ? Quaternion.identity : FollowTargetRotation; } if (deltaTime < 0) { @@ -197,7 +197,7 @@ protected void TrackTarget( } m_PreviousReferenceOrientation = dampedOrientation; - Vector3 targetPosition = FollowTarget.position; + Vector3 targetPosition = FollowTargetPosition; Vector3 currentPosition = m_PreviousTargetPosition; Vector3 worldOffset = targetPosition - currentPosition; @@ -262,7 +262,7 @@ public Vector3 GeTargetCameraPosition(Vector3 worldUp) { if (!IsValid) return Vector3.zero; - return FollowTarget.position + GetReferenceOrientation(worldUp) * EffectiveOffset; + return FollowTargetPosition + GetReferenceOrientation(worldUp) * EffectiveOffset; } /// State information for damping @@ -276,7 +276,7 @@ public Quaternion GetReferenceOrientation(Vector3 worldUp) { if (FollowTarget != null) { - Quaternion targetOrientation = FollowTarget.rotation; + Quaternion targetOrientation = FollowTargetRotation; switch (m_BindingMode) { case BindingMode.LockToTargetOnAssign: @@ -289,7 +289,7 @@ public Quaternion GetReferenceOrientation(Vector3 worldUp) return targetOrientation; case BindingMode.SimpleFollowWithWorldUp: { - Vector3 dir = FollowTarget.position - VcamState.RawPosition; + Vector3 dir = FollowTargetPosition - VcamState.RawPosition; if (dir.AlmostZero()) break; return Uppify(Quaternion.LookRotation(dir, worldUp), worldUp); diff --git a/Base/Runtime/Core/CinemachineComponentBase.cs b/Base/Runtime/Core/CinemachineComponentBase.cs index 9e9d8c580..fcef07a8e 100644 --- a/Base/Runtime/Core/CinemachineComponentBase.cs +++ b/Base/Runtime/Core/CinemachineComponentBase.cs @@ -43,6 +43,100 @@ public Transform LookAtTarget } } + private Transform mCachedFollowTarget; + private CinemachineVirtualCameraBase mCachedFollowTargetVcam; + + /// Get the position of the Follow target. Special handling: If the Follow target is + /// a VirtualCamera, returns the vcam State's position, not the transform's position + public Vector3 FollowTargetPosition + { + get + { + Transform target = FollowTarget; + if (target != mCachedFollowTarget) + { + mCachedFollowTargetVcam = null; + mCachedFollowTarget = target; + if (target != null) + mCachedFollowTargetVcam = target.GetComponent(); + } + if (mCachedFollowTargetVcam != null) + return mCachedFollowTargetVcam.State.FinalPosition; + if (target != null) + return target.position; + return Vector3.zero; + } + } + + /// Get the rotation of the Follow target. Special handling: If the Follow target is + /// a VirtualCamera, returns the vcam State's rotation, not the transform's rotation + public Quaternion FollowTargetRotation + { + get + { + Transform target = FollowTarget; + if (target != mCachedFollowTarget) + { + mCachedFollowTargetVcam = null; + mCachedFollowTarget = target; + if (target != null) + mCachedFollowTargetVcam = target.GetComponent(); + } + if (mCachedFollowTargetVcam != null) + return mCachedFollowTargetVcam.State.FinalOrientation; + if (target != null) + return target.rotation; + return Quaternion.identity; + } + } + + private Transform mCachedLookAtTarget; + private CinemachineVirtualCameraBase mCachedLookAtTargetVcam; + + /// Get the position of the LookAt target. Special handling: If the LookAt target is + /// a VirtualCamera, returns the vcam State's position, not the transform's position + public Vector3 LookAtTargetPosition + { + get + { + Transform target = LookAtTarget; + if (target != mCachedLookAtTarget) + { + mCachedLookAtTargetVcam = null; + mCachedLookAtTarget = target; + if (target != null) + mCachedLookAtTargetVcam = target.GetComponent(); + } + if (mCachedLookAtTargetVcam != null) + return mCachedLookAtTargetVcam.State.FinalPosition; + if (target != null) + return target.position; + return Vector3.zero; + } + } + + /// Get the rotation of the LookAt target. Special handling: If the LookAt target is + /// a VirtualCamera, returns the vcam State's rotation, not the transform's rotation + public Quaternion LookAtTargetRotation + { + get + { + Transform target = LookAtTarget; + if (target != mCachedLookAtTarget) + { + mCachedLookAtTargetVcam = null; + mCachedLookAtTarget = target; + if (target != null) + mCachedLookAtTargetVcam = target.GetComponent(); + } + if (mCachedLookAtTargetVcam != null) + return mCachedLookAtTargetVcam.State.FinalOrientation; + if (target != null) + return target.rotation; + return Quaternion.identity; + } + } + /// Returns the owner vcam's CameraState. public CameraState VcamState { diff --git a/Base/Runtime/Core/CinemachineCore.cs b/Base/Runtime/Core/CinemachineCore.cs index 8bf68770b..62f18488d 100644 --- a/Base/Runtime/Core/CinemachineCore.cs +++ b/Base/Runtime/Core/CinemachineCore.cs @@ -13,7 +13,7 @@ public sealed class CinemachineCore public static readonly int kStreamingVersion = 20170927; /// Human-readable Cinemachine Version - public static readonly string kVersionString = "2.1"; + public static readonly string kVersionString = "2.1.10"; /// /// Stages in the Cinemachine Component pipeline, used for