/// <summary>Set the state's refeenceLookAt target to our lookAt, with some smarts
        /// in case our LookAt points to a vcam</summary>
        protected void SetReferenceLookAtTargetInState(ref CameraState state)
        {
            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);
                }
            }
        }
Example #2
0
        Vector3 CalculateAveragePosition(out float maxWeight)
        {
            Vector3 pos    = Vector3.zero;
            float   weight = 0;

            maxWeight = 0;
            for (int i = 0; i < m_Targets.Length; ++i)
            {
                if (m_Targets[i].target != null)
                {
                    weight += m_Targets[i].weight;
                    pos    += TargetPositionCache.GetTargetPosition(m_Targets[i].target)
                              * m_Targets[i].weight;
                    maxWeight = Mathf.Max(maxWeight, m_Targets[i].weight);
                }
            }
            if (weight > UnityVectorExtensions.Epsilon)
            {
                pos /= weight;
            }
            else
            {
                pos = transform.position;
            }
            return(pos);
        }
Example #3
0
        /// <summary>
        /// Create a camera state based on the current transform of this vcam
        /// </summary>
        /// <param name="worldUp">Current World Up direction, as provided by the brain</param>
        /// <param name="lens">Lens settings to serve as base, will be combined with lens from brain, if any</param>
        /// <returns></returns>
        protected CameraState PullStateFromVirtualCamera(Vector3 worldUp, ref LensSettings lens)
        {
            CameraState state = CameraState.Default;

            state.RawPosition    = TargetPositionCache.GetTargetPosition(transform);
            state.RawOrientation = TargetPositionCache.GetTargetRotation(transform);
            state.ReferenceUp    = worldUp;

            CinemachineBrain brain = CinemachineCore.Instance.FindPotentialTargetBrain(this);

            if (brain != null)
            {
                lens.SnapshotCameraReadOnlyProperties(brain.OutputCamera);
            }

            state.Lens = lens;
            return(state);
        }
Example #4
0
        private static BoundingSphere WeightedMemberBounds(
            Target t, Vector3 avgPos, float maxWeight)
        {
            float   w   = 0;
            Vector3 pos = avgPos;

            if (t.target != null)
            {
                pos = TargetPositionCache.GetTargetPosition(t.target);
                w   = Mathf.Max(0, t.weight);
                if (maxWeight > UnityVectorExtensions.Epsilon && w < maxWeight)
                {
                    w /= maxWeight;
                }
                else
                {
                    w = 1;
                }
            }
            return(new BoundingSphere(Vector3.Lerp(avgPos, pos, w), t.radius * w));
        }
Example #5
0
        Quaternion CalculateAverageOrientation()
        {
            if (mMaxWeight <= UnityVectorExtensions.Epsilon)
            {
                return(transform.rotation);
            }

            float      weightedAverage = 0;
            Quaternion r = Quaternion.identity;

            for (int i = 0; i < m_Targets.Length; ++i)
            {
                if (m_Targets[i].target != null)
                {
                    float scaledWeight = m_Targets[i].weight / mMaxWeight;
                    var   rot          = TargetPositionCache.GetTargetRotation(m_Targets[i].target);
                    r *= Quaternion.Slerp(Quaternion.identity, rot, scaledWeight);
                    weightedAverage += scaledWeight;
                }
            }
            return(Quaternion.Slerp(Quaternion.identity, r, 1.0f / weightedAverage));
        }
        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);
                }

                CinemachineComponentBase postAimBody = null;
                int componentIndex = 0;
                for (var stage = CinemachineCore.Stage.Body; stage <= CinemachineCore.Stage.Finalize; ++stage)
                {
                    if (stage == CinemachineCore.Stage.Finalize && postAimBody != null)
                    {
                        postAimBody.MutateCameraState(ref state, deltaTime);
                    }

                    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;
                        }
                        else
                        {
                            c.MutateCameraState(ref state, deltaTime);
                        }
                    }
                    else if (stage == CinemachineCore.Stage.Aim)
                    {
                        state.BlendHint |= CameraState.BlendHintValue.IgnoreLookAtTarget;
                    }

                    InvokePostPipelineStageCallback(this, stage, ref state, deltaTime);
                }
            }
            return(state);
        }