Vector3 GetLookAtPoint(ref CameraState state)
        {
            var fwd         = state.CorrectedOrientation * Vector3.forward;
            var camPos      = state.CorrectedPosition;
            var aimDistance = AimDistance;

            // We don't want to hit targets behind the player
            var player = VirtualCamera.Follow;

            if (player != null)
            {
                var playerPos = Quaternion.Inverse(state.CorrectedOrientation) * (player.position - camPos);
                if (playerPos.z > 0)
                {
                    camPos      += fwd * playerPos.z;
                    aimDistance -= playerPos.z;
                }
            }

            aimDistance = Mathf.Max(1, aimDistance);
            bool hasHit = RuntimeUtility.RaycastIgnoreTag(
                new Ray(camPos, fwd),
                out RaycastHit hitInfo, aimDistance, AimCollisionFilter, IgnoreTag);

            return(hasHit ? hitInfo.point : camPos + fwd * aimDistance);
        }
        Vector3 ResolveCollisions(Vector3 root, Vector3 tip, float cameraRadius)
        {
#if CINEMACHINE_PHYSICS
            var dir = tip - root;
            var len = dir.magnitude;
            dir /= len;

            var   result            = tip;
            float desiredCorrection = 0;

            if (RuntimeUtility.SphereCastIgnoreTag(
                    root, cameraRadius, dir, out RaycastHit hitInfo,
                    len, CameraCollisionFilter, IgnoreTag))
            {
                var desiredResult = hitInfo.point + hitInfo.normal * cameraRadius;
                desiredCorrection = (desiredResult - tip).magnitude;
            }

            // Apply the correction
            if (desiredCorrection > Epsilon)
            {
                result -= dir * desiredCorrection;
            }

            return(result);
#else
            return(tip);
#endif
        }
        /// <summary>Add a component to the cinemachine pipeline.</summary>
        public T AddCinemachineComponent <T>() where T : CinemachineComponentBase
        {
            // Get the existing components
            Transform owner = GetComponentOwner();

            CinemachineComponentBase[] components = owner.GetComponents <CinemachineComponentBase>();

            T component = owner.gameObject.AddComponent <T>();

            if (component != null && components != null)
            {
                // Remove the existing components at that stage
                CinemachineCore.Stage stage = component.Stage;
                for (int i = components.Length - 1; i >= 0; --i)
                {
                    if (components[i].Stage == stage)
                    {
                        components[i].enabled = false;
                        RuntimeUtility.DestroyObject(components[i]);
                    }
                }
            }
            InvalidateComponentPipeline();
            return(component);
        }
示例#4
0
        /// <summary>Destroy any existing pipeline container.</summary>
        private void DestroyPipeline()
        {
            List <Transform> oldPipeline = new List <Transform>();

            foreach (Transform child in transform)
            {
                if (child.GetComponent <CinemachinePipeline>() != null)
                {
                    oldPipeline.Add(child);
                }
            }

            if (!RuntimeUtility.IsPrefab(gameObject))
            {
                foreach (Transform child in oldPipeline)
                {
                    if (DestroyPipelineOverride != null)
                    {
                        DestroyPipelineOverride(child.gameObject);
                    }
                    else
                    {
                        Destroy(child.gameObject);
                    }
                }
                m_ComponentOwner = null;
            }
            PreviousStateIsValid = false;
        }
 static void OnUndoRedoPerformed()
 {
     if (sCanvasesAndTheirOwners != null)
     {
         List <UnityEngine.Object> toDestroy = null;
         foreach (var v in sCanvasesAndTheirOwners)
         {
             if (v.Value == null)
             {
                 if (toDestroy == null)
                 {
                     toDestroy = new List <UnityEngine.Object>();
                 }
                 toDestroy.Add(v.Key);
             }
         }
         if (toDestroy != null)
         {
             foreach (var o in toDestroy)
             {
                 RemoveCanvas(o);
                 RuntimeUtility.DestroyObject(o);
             }
         }
     }
 }
示例#6
0
        private void UpdateRigCache()
        {
            if (mIsDestroyed)
            {
                return;
            }

            bool isPrefab = RuntimeUtility.IsPrefab(gameObject);

#if UNITY_EDITOR
            // Special condition: Did we just get copy/pasted?
            if (m_Rigs != null && m_Rigs.Length == 3 &&
                m_Rigs[0] != null && m_Rigs[0].transform.parent != transform)
            {
                if (!isPrefab) // can't paste to a prefab
                {
                    var copyFrom = m_Rigs;
                    DestroyRigs();
                    m_Rigs = CreateRigs(copyFrom);
                }
            }
#endif

            // Early out if we're up to date
            if (mOrbitals != null && mOrbitals.Length == 3)
            {
                return;
            }

            // Locate existing rigs, and recreate them if any are missing
            if (LocateExistingRigs(RigNames, false) != 3 && !isPrefab)
            {
                DestroyRigs();
                m_Rigs = CreateRigs(null);
                LocateExistingRigs(RigNames, true);
            }

#if UNITY_EDITOR
            foreach (var rig in m_Rigs)
            {
                // Configure the UI
                if (rig == null)
                {
                    continue;
                }
                rig.m_ExcludedPropertiesInInspector = m_CommonLens
                    ? new string[] { "m_Script", "Header", "Extensions", "m_Priority", "m_Transitions", "m_Follow", "m_StandbyUpdate", "m_Lens" }
                    : new string[] { "m_Script", "Header", "Extensions", "m_Priority", "m_Transitions", "m_Follow", "m_StandbyUpdate" };
                rig.m_LockStageInInspector = new CinemachineCore.Stage[] { CinemachineCore.Stage.Body };
            }
#endif

            // Create the blend objects
            mBlendA = new CinemachineBlend(m_Rigs[1], m_Rigs[0], AnimationCurve.Linear(0, 0, 1, 1), 1, 0);
            mBlendB = new CinemachineBlend(m_Rigs[2], m_Rigs[1], AnimationCurve.Linear(0, 0, 1, 1), 1, 0);
        }
示例#7
0
        Vector3 GetLookAtPoint(ref CameraState state)
        {
            var  fwd    = state.CorrectedOrientation * Vector3.forward;
            var  camPos = state.CorrectedPosition;
            bool hasHit = RuntimeUtility.RaycastIgnoreTag(
                new Ray(camPos, fwd),
                out RaycastHit hitInfo, AimDistance, AimCollisionFilter, IgnoreTag);

            return(hasHit ? hitInfo.point : camPos + fwd * AimDistance);
        }
示例#8
0
 static void DestroyCollider()
 {
     if (mCameraColliderGameObject != null)
     {
         mCameraColliderGameObject.SetActive(false);
         RuntimeUtility.DestroyObject(mCameraColliderGameObject.GetComponent <Rigidbody>());
     }
     RuntimeUtility.DestroyObject(mCameraCollider);
     RuntimeUtility.DestroyObject(mCameraColliderGameObject);
     mCameraColliderGameObject = null;
     mCameraCollider           = null;
 }
示例#9
0
        void Reset()
        {
#if UNITY_EDITOR
            if (RuntimeUtility.IsPrefab(gameObject))
            {
                Debug.Log("You cannot reset a prefab instance.  "
                          + "First disconnect this instance from the prefab, or enter Prefab Edit mode");
                return;
            }
#endif
            DestroyRigs();
        }
        Vector3 ComputeAimTarget(Vector3 cameraLookAt, Transform player)
        {
            // Adjust for actual player aim target (may be different due to offset)
            var playerPos = player.position;
            var dir       = cameraLookAt - playerPos;

            if (RuntimeUtility.RaycastIgnoreTag(new Ray(playerPos, dir),
                                                out RaycastHit hitInfo, dir.magnitude, AimCollisionFilter, IgnoreTag))
            {
                return(hitInfo.point);
            }
            return(cameraLookAt);
        }
示例#11
0
        public float m_PropagationSpeed = 343;  // speed of sound


        /// <summary>Call this from your behaviour's OnValidate to validate the fields here</summary>
        public void OnValidate()
        {
            RuntimeUtility.NormalizeCurve(m_CustomImpulseShape, true, false);
            m_ImpulseDuration     = Mathf.Max(UnityVectorExtensions.Epsilon, m_ImpulseDuration);
            m_DissipationDistance = Mathf.Max(UnityVectorExtensions.Epsilon, m_DissipationDistance);
            m_DissipationRate     = Mathf.Clamp01(m_DissipationRate);
            m_PropagationSpeed    = Mathf.Max(1, m_PropagationSpeed);

            // legacy
            m_ImpactRadius = Mathf.Max(0, m_ImpactRadius);
            m_TimeEnvelope.Validate();
            m_PropagationSpeed = Mathf.Max(1, m_PropagationSpeed);
        }
        /// <summary>Add a component to the cinemachine pipeline.</summary>
        public T AddCinemachineComponent <T>() where T : CinemachineComponentBase
        {
            T   c          = gameObject.AddComponent <T>();
            var components = ComponentCache;
            var oldC       = components[(int)c.Stage];

            if (oldC != null)
            {
                oldC.enabled = false;
                RuntimeUtility.DestroyObject(oldC);
            }
            InvalidateComponentCache();
            return(c);
        }
        /// <summary>Remove a component from the cinemachine pipeline.</summary>
        public void DestroyCinemachineComponent <T>() where T : CinemachineComponentBase
        {
            var components = ComponentCache;

            foreach (var c in components)
            {
                if (c is T)
                {
                    c.enabled = false;
                    RuntimeUtility.DestroyObject(c);
                    InvalidateComponentCache();
                    return;
                }
            }
        }
 /// <summary>Remove a component from the cinemachine pipeline.</summary>
 public void DestroyCinemachineComponent <T>() where T : CinemachineComponentBase
 {
     CinemachineComponentBase[] components = GetComponentPipeline();
     if (components != null)
     {
         foreach (var c in components)
         {
             if (c is T)
             {
                 c.enabled = false;
                 RuntimeUtility.DestroyObject(c);
                 InvalidateComponentPipeline();
             }
         }
     }
 }
        void DestroyCanvas()
        {
            int numBrains = CinemachineCore.Instance.BrainCount;

            for (int i = 0; i < numBrains; ++i)
            {
                LocateMyCanvas(CinemachineCore.Instance.GetActiveBrain(i), false);
                if (mCanvas != null)
                {
                    RuntimeUtility.DestroyObject(mCanvas);
#if UNITY_EDITOR
                    // Workaround for Unity bug case Case 1004117
                    CanvasesAndTheirOwners.RemoveCanvas(mCanvas);
#endif
                }
                mCanvas = null;
            }
        }
        Vector3 ComputeLookAtPoint(Vector3 camPos, Transform player)
        {
            // We don't want to hit targets behind the player
            var aimDistance       = AimDistance;
            var playerOrientation = player.rotation;
            var fwd       = playerOrientation * Vector3.forward;
            var playerPos = Quaternion.Inverse(playerOrientation) * (player.position - camPos);

            if (playerPos.z > 0)
            {
                camPos      += fwd * playerPos.z;
                aimDistance -= playerPos.z;
            }

            aimDistance = Mathf.Max(1, aimDistance);
            bool hasHit = RuntimeUtility.RaycastIgnoreTag(new Ray(camPos, fwd),
                                                          out RaycastHit hitInfo, aimDistance, AimCollisionFilter, IgnoreTag);

            return(hasHit ? hitInfo.point : camPos + fwd * aimDistance);
        }
示例#17
0
        Vector3 ResolveCollisions(
            Vector3 root, Vector3 tip, float deltaTime,
            float cameraRadius, ref float collisionCorrection)
        {
#if CINEMACHINE_PHYSICS
            if (CameraCollisionFilter.value == 0)
            {
                return(tip);
            }

            var dir = tip - root;
            var len = dir.magnitude;
            dir /= len;

            var   result            = tip;
            float desiredCorrection = 0;

            if (RuntimeUtility.SphereCastIgnoreTag(
                    root, cameraRadius, dir, out RaycastHit hitInfo,
                    len, CameraCollisionFilter, IgnoreTag))
            {
                var desiredResult = hitInfo.point + hitInfo.normal * cameraRadius;
                desiredCorrection = (desiredResult - tip).magnitude;
            }

            collisionCorrection += deltaTime < 0 ? desiredCorrection - collisionCorrection : Damper.Damp(
                desiredCorrection - collisionCorrection,
                desiredCorrection > collisionCorrection ? DampingIntoCollision : DampingFromCollision,
                deltaTime);

            // Apply the correction
            if (collisionCorrection > Epsilon)
            {
                result -= dir * collisionCorrection;
            }

            return(result);
#else
            return(tip);
#endif
        }
        Vector3 PullCameraInFrontOfNearestObstacle(
            Vector3 cameraPos, Vector3 lookAtPos, int layerMask, ref RaycastHit hitInfo)
        {
            Vector3 displacement   = Vector3.zero;
            Vector3 dir            = cameraPos - lookAtPos;
            float   targetDistance = dir.magnitude;

            if (targetDistance > Epsilon)
            {
                dir /= targetDistance;
                float minDistanceFromTarget = Mathf.Max(m_MinimumDistanceFromTarget, Epsilon);
                if (targetDistance < minDistanceFromTarget + Epsilon)
                {
                    displacement = dir * (minDistanceFromTarget - targetDistance);
                }
                else
                {
                    float rayLength = targetDistance - minDistanceFromTarget;
                    if (m_DistanceLimit > Epsilon)
                    {
                        rayLength = Mathf.Min(m_DistanceLimit, rayLength);
                    }

                    // Make a ray that looks towards the camera, to get the obstacle closest to target
                    Ray ray = new Ray(cameraPos - rayLength * dir, dir);
                    rayLength += k_PrecisionSlush;
                    if (rayLength > Epsilon)
                    {
                        if (RuntimeUtility.RaycastIgnoreTag(
                                ray, out hitInfo, rayLength, layerMask, m_IgnoreTag))
                        {
                            // Pull camera forward in front of obstacle
                            float adjustment = Mathf.Max(0, hitInfo.distance - k_PrecisionSlush);
                            displacement = ray.GetPoint(adjustment) - cameraPos;
                        }
                    }
                }
            }
            return(displacement);
        }
 bool CheckForTargetObstructions(CameraState state)
 {
     if (state.HasLookAt)
     {
         Vector3 lookAtPos = state.ReferenceLookAt;
         Vector3 pos       = state.CorrectedPosition;
         Vector3 dir       = lookAtPos - pos;
         float   distance  = dir.magnitude;
         if (distance < Mathf.Max(m_MinimumDistanceFromTarget, Epsilon))
         {
             return(true);
         }
         Ray ray = new Ray(pos, dir.normalized);
         if (RuntimeUtility.RaycastIgnoreTag(ray, out _,
                                             distance - m_MinimumDistanceFromTarget,
                                             m_CollideAgainst & ~m_TransparentLayers, m_IgnoreTag))
         {
             return(true);
         }
     }
     return(false);
 }
示例#20
0
 void DrawReticle(CinemachineBrain brain)
 {
     if (!brain.IsLive(VirtualCamera) || brain.OutputCamera == null)
     {
         CinemachineCore.CameraUpdatedEvent.RemoveListener(DrawReticle);
     }
     else
     {
         var player = VirtualCamera.Follow;
         if (AimTargetReticle != null && player != null)
         {
             // Adjust for actual player aim target (may be different due to offset)
             var playerPos = player.position;
             var aimTarget = VirtualCamera.State.ReferenceLookAt;
             var dir       = aimTarget - playerPos;
             if (RuntimeUtility.RaycastIgnoreTag(new Ray(playerPos, dir),
                                                 out RaycastHit hitInfo, dir.magnitude, AimCollisionFilter, IgnoreTag))
             {
                 aimTarget = hitInfo.point;
             }
             AimTargetReticle.position = brain.OutputCamera.WorldToScreenPoint(aimTarget);
         }
     }
 }
        void DestroyCanvas()
        {
            int numBrains = CinemachineCore.Instance.BrainCount;

            for (int i = 0; i < numBrains; ++i)
            {
                var parent      = CinemachineCore.Instance.GetActiveBrain(i);
                int numChildren = parent.transform.childCount;
                for (int j = 0; j < numChildren; ++j)
                {
                    RectTransform child = parent.transform.GetChild(j) as RectTransform;
                    if (child != null && child.name == CanvasName)
                    {
                        var canvas = child.gameObject;
                        RuntimeUtility.DestroyObject(canvas);
#if UNITY_EDITOR
                        // Workaround for Unity bug case Case 1004117
                        CanvasesAndTheirOwners.RemoveCanvas(canvas);
#endif
                    }
                }
            }
            mCanvasInfo.Clear();
        }
        Vector3 RespectCameraRadius(Vector3 cameraPos, Vector3 lookAtPos)
        {
            Vector3 result = Vector3.zero;

            if (m_CameraRadius < Epsilon || m_CollideAgainst == 0)
            {
                return(result);
            }

            Vector3 dir      = cameraPos - lookAtPos;
            float   distance = dir.magnitude;

            if (distance > Epsilon)
            {
                dir /= distance;
            }

            // Pull it out of any intersecting obstacles
            RaycastHit hitInfo;
            int        numObstacles = Physics.OverlapSphereNonAlloc(
                cameraPos, m_CameraRadius, s_ColliderBuffer,
                m_CollideAgainst, QueryTriggerInteraction.Ignore);

            if (numObstacles == 0 && m_TransparentLayers != 0 &&
                distance > m_MinimumDistanceFromTarget + Epsilon)
            {
                // Make sure the camera position isn't completely inside an obstacle.
                // OverlapSphereNonAlloc won't catch those.
                float   d         = distance - m_MinimumDistanceFromTarget;
                Vector3 targetPos = lookAtPos + dir * m_MinimumDistanceFromTarget;
                if (RuntimeUtility.RaycastIgnoreTag(new Ray(targetPos, dir),
                                                    out hitInfo, d, m_CollideAgainst, m_IgnoreTag))
                {
                    // Only count it if there's an incoming collision but not an outgoing one
                    Collider c = hitInfo.collider;
                    if (!c.Raycast(new Ray(cameraPos, -dir), out hitInfo, d))
                    {
                        s_ColliderBuffer[numObstacles++] = c;
                    }
                }
            }
            if (numObstacles > 0 && distance == 0 || distance > m_MinimumDistanceFromTarget)
            {
                var scratchCollider = RuntimeUtility.GetScratchCollider();
                scratchCollider.radius = m_CameraRadius;

                Vector3 newCamPos = cameraPos;
                for (int i = 0; i < numObstacles; ++i)
                {
                    Collider c = s_ColliderBuffer[i];
                    if (m_IgnoreTag.Length > 0 && c.CompareTag(m_IgnoreTag))
                    {
                        continue;
                    }

                    // If we have a lookAt target, move the camera to the nearest edge of obstacle
                    if (distance > m_MinimumDistanceFromTarget)
                    {
                        dir = newCamPos - lookAtPos;
                        float d = dir.magnitude;
                        if (d > Epsilon)
                        {
                            dir /= d;
                            var ray = new Ray(lookAtPos, dir);
                            if (c.Raycast(ray, out hitInfo, d + m_CameraRadius))
                            {
                                newCamPos = ray.GetPoint(hitInfo.distance) - (dir * k_PrecisionSlush);
                            }
                        }
                    }
                    if (Physics.ComputePenetration(
                            scratchCollider, newCamPos, Quaternion.identity,
                            c, c.transform.position, c.transform.rotation,
                            out var offsetDir, out var offsetDistance))
                    {
                        newCamPos += offsetDir * offsetDistance;
                    }
                }
                result = newCamPos - cameraPos;
            }

            // Respect the minimum distance from target - push camera back if we have to
            if (distance > Epsilon && m_MinimumDistanceFromTarget > Epsilon)
            {
                float   minDistance = Mathf.Max(m_MinimumDistanceFromTarget, m_CameraRadius) + k_PrecisionSlush;
                Vector3 newOffset   = cameraPos + result - lookAtPos;
                if (newOffset.magnitude < minDistance)
                {
                    result = lookAtPos - cameraPos + dir * minDistance;
                }
            }

            return(result);
        }
        Vector3 PushCameraBack(
            Vector3 currentPos, Vector3 pushDir, RaycastHit obstacle,
            Vector3 lookAtPos, Plane startPlane, float targetDistance, int iterations,
            ref VcamExtraState extra)
        {
            // Take a step along the wall.
            Vector3 pos = currentPos;
            Vector3 dir = Vector3.zero;

            if (!GetWalkingDirection(pos, pushDir, obstacle, ref dir))
            {
                return(pos);
            }

            Ray   ray      = new Ray(pos, dir);
            float distance = GetPushBackDistance(ray, startPlane, targetDistance, lookAtPos);

            if (distance <= Epsilon)
            {
                return(pos);
            }

            // Check only as far as the obstacle bounds
            float clampedDistance = ClampRayToBounds(ray, distance, obstacle.collider.bounds);

            distance = Mathf.Min(distance, clampedDistance + k_PrecisionSlush);

            if (RuntimeUtility.RaycastIgnoreTag(ray, out var hitInfo, distance,
                                                m_CollideAgainst & ~m_TransparentLayers, m_IgnoreTag))
            {
                // We hit something.  Stop there and take a step along that wall.
                float adjustment = hitInfo.distance - k_PrecisionSlush;
                pos = ray.GetPoint(adjustment);
                extra.AddPointToDebugPath(pos);
                if (iterations > 1)
                {
                    pos = PushCameraBack(
                        pos, dir, hitInfo,
                        lookAtPos, startPlane,
                        targetDistance, iterations - 1, ref extra);
                }

                return(pos);
            }

            // Didn't hit anything.  Can we push back all the way now?
            pos = ray.GetPoint(distance);

            // First check if we can still see the target.  If not, abort
            dir = pos - lookAtPos;
            float d = dir.magnitude;

            if (d < Epsilon || RuntimeUtility.RaycastIgnoreTag(
                    new Ray(lookAtPos, dir), out _, d - k_PrecisionSlush,
                    m_CollideAgainst & ~m_TransparentLayers, m_IgnoreTag))
            {
                return(currentPos);
            }

            // All clear
            ray = new Ray(pos, dir);
            extra.AddPointToDebugPath(pos);
            distance = GetPushBackDistance(ray, startPlane, targetDistance, lookAtPos);
            if (distance > Epsilon)
            {
                if (!RuntimeUtility.RaycastIgnoreTag(ray, out hitInfo, distance,
                                                     m_CollideAgainst & ~m_TransparentLayers, m_IgnoreTag))
                {
                    pos = ray.GetPoint(distance); // no obstacles - all good
                    extra.AddPointToDebugPath(pos);
                }
                else
                {
                    // We hit something.  Stop there and maybe take a step along that wall
                    float adjustment = hitInfo.distance - k_PrecisionSlush;
                    pos = ray.GetPoint(adjustment);
                    extra.AddPointToDebugPath(pos);
                    if (iterations > 1)
                    {
                        pos = PushCameraBack(
                            pos, dir, hitInfo, lookAtPos, startPlane,
                            targetDistance, iterations - 1, ref extra);
                    }
                }
            }
            return(pos);
        }
 void OnDestroy()
 {
     RuntimeUtility.DestroyScratchCollider();
 }
示例#25
0
        [SerializeField][HideInInspector] private Transform m_ComponentOwner = null;   // serialized to handle copy/paste
        void UpdateComponentPipeline()
        {
            bool isPrefab = RuntimeUtility.IsPrefab(gameObject);

#if UNITY_EDITOR
            // Did we just get copy/pasted?
            if (m_ComponentOwner != null && m_ComponentOwner.parent != transform)
            {
                if (!isPrefab) // can't paste to a prefab
                {
                    CinemachineVirtualCamera copyFrom = (m_ComponentOwner.parent != null)
                        ? m_ComponentOwner.parent.gameObject.GetComponent <CinemachineVirtualCamera>() : null;
                    DestroyPipeline();
                    m_ComponentOwner = CreatePipeline(copyFrom);
                }
            }
            if (m_ComponentOwner != null)
            {
                SetFlagsForHiddenChild(m_ComponentOwner.gameObject);
            }
#endif
            // Early out if we're up-to-date
            if (m_ComponentOwner != null && m_ComponentPipeline != null)
            {
                return;
            }

            m_ComponentOwner = null;
            List <CinemachineComponentBase> list = new List <CinemachineComponentBase>();
            foreach (Transform child in transform)
            {
                if (child.GetComponent <CinemachinePipeline>() != null)
                {
                    m_ComponentOwner = child;
                    CinemachineComponentBase[] components = child.GetComponents <CinemachineComponentBase>();
                    foreach (CinemachineComponentBase c in components)
                    {
                        if (c.enabled)
                        {
                            list.Add(c);
                        }
                    }
                }
            }

            // Make sure we have a pipeline owner
            if (m_ComponentOwner == null && !isPrefab)
            {
                m_ComponentOwner = CreatePipeline(null);
            }

            // Make sure the pipeline stays hidden, even through prefab
            if (m_ComponentOwner != null)
            {
                SetFlagsForHiddenChild(m_ComponentOwner.gameObject);
            }
            if (m_ComponentOwner != null && m_ComponentOwner.gameObject != null)
            {
                // Sort the pipeline
                list.Sort((c1, c2) => (int)c1.Stage - (int)c2.Stage);
                m_ComponentPipeline = list.ToArray();
            }
        }
示例#26
0
        private Vector3 RespectCameraRadius(Vector3 cameraPos, ref CameraState state)
        {
            Vector3 result = Vector3.zero;

            if (m_CameraRadius < Epsilon || m_CollideAgainst == 0)
            {
                return(result);
            }

            Vector3 dir      = state.HasLookAt ? (cameraPos - state.ReferenceLookAt) : Vector3.zero;
            Ray     ray      = new Ray();
            float   distance = dir.magnitude;

            if (distance > Epsilon)
            {
                dir /= distance;
                ray  = new Ray(state.ReferenceLookAt, dir);
            }
            // Pull it out of any intersecting obstacles
            RaycastHit hitInfo;
            int        numObstacles = Physics.OverlapSphereNonAlloc(
                cameraPos, m_CameraRadius, mColliderBuffer,
                m_CollideAgainst, QueryTriggerInteraction.Ignore);

            if (numObstacles == 0 && m_TransparentLayers != 0 &&
                distance > m_MinimumDistanceFromTarget + Epsilon)
            {
                // Make sure the camera position isn't completely inside an obstacle.
                // OverlapSphereNonAlloc won't catch those.
                float   d         = distance - m_MinimumDistanceFromTarget;
                Vector3 targetPos = state.ReferenceLookAt + dir * m_MinimumDistanceFromTarget;
                if (RuntimeUtility.RaycastIgnoreTag(new Ray(targetPos, dir),
                                                    out hitInfo, d, m_CollideAgainst, m_IgnoreTag))
                {
                    // Only count it if there's an incoming collision but not an outgoing one
                    Collider c = hitInfo.collider;
                    if (!c.Raycast(new Ray(cameraPos, -dir), out hitInfo, d))
                    {
                        mColliderBuffer[numObstacles++] = c;
                    }
                }
            }
            if (numObstacles > 0 && distance == 0 || distance > m_MinimumDistanceFromTarget)
            {
                if (mCameraColliderGameObject == null)
                {
                    mCameraColliderGameObject                    = new GameObject("CinemachineCollider Collider");
                    mCameraColliderGameObject.hideFlags          = HideFlags.HideAndDontSave;
                    mCameraColliderGameObject.transform.position = Vector3.zero;
                    mCameraColliderGameObject.SetActive(true);
                    mCameraCollider           = mCameraColliderGameObject.AddComponent <SphereCollider>();
                    mCameraCollider.isTrigger = true;
                    var rb = mCameraColliderGameObject.AddComponent <Rigidbody>();
                    rb.detectCollisions = false;
                    rb.isKinematic      = true;
                }
                mCameraCollider.radius = m_CameraRadius;
                Vector3 offsetDir;
                float   offsetDistance;
                Vector3 newCamPos = cameraPos;
                for (int i = 0; i < numObstacles; ++i)
                {
                    Collider c = mColliderBuffer[i];
                    if (m_IgnoreTag.Length > 0 && c.CompareTag(m_IgnoreTag))
                    {
                        continue;
                    }

                    // If we have a lookAt target, move the camera to the nearest edge of obstacle
                    if (distance > m_MinimumDistanceFromTarget)
                    {
                        dir = newCamPos - state.ReferenceLookAt;
                        float d = dir.magnitude;
                        if (d > Epsilon)
                        {
                            dir /= d;
                            ray  = new Ray(state.ReferenceLookAt, dir);
                            if (c.Raycast(ray, out hitInfo, d + m_CameraRadius))
                            {
                                newCamPos = ray.GetPoint(hitInfo.distance) - (dir * PrecisionSlush);
                            }
                        }
                    }
                    if (Physics.ComputePenetration(
                            mCameraCollider, newCamPos, Quaternion.identity,
                            c, c.transform.position, c.transform.rotation,
                            out offsetDir, out offsetDistance))
                    {
                        newCamPos += offsetDir * offsetDistance;
                    }
                }
                result = newCamPos - cameraPos;
            }

            // Respect the minimum distance from target - push camera back if we have to
            if (distance > Epsilon)
            {
                float   minDistance = Mathf.Max(m_MinimumDistanceFromTarget, m_CameraRadius) + PrecisionSlush;
                Vector3 newOffset   = cameraPos + result - state.ReferenceLookAt;
                if (newOffset.magnitude < minDistance)
                {
                    result = state.ReferenceLookAt - cameraPos + dir * minDistance;
                }
            }

            return(result);
        }
示例#27
0
 private void CleanupCameraCollider()
 {
     RuntimeUtility.DestroyObject(mCameraColliderGameObject);
     mCameraColliderGameObject = null;
     mCameraCollider           = null;
 }
 /// <summary>
 /// Cleanup
 /// </summary>
 protected override void OnDestroy()
 {
     RuntimeUtility.DestroyScratchCollider();
     base.OnDestroy();
 }