/// <summary>
        /// Returns the current rotation of the target.
        /// </summary>
        /// <returns>The target's rotation.</returns>
        private Quaternion GetCurrentRotation()
        {
            if (!DetermineRotationFromMovement)
            {
                _previouslyDeterminedRotation = _target.Target.rotation;

                return(_target.Target.rotation);
            }
            else if (Vector3.Distance(_previousTargetState.Position, _target.Target.position) <= (DetermineTolerance == 0 ? FLOAT_TOLERANCE : DetermineTolerance))
            {
                return(_previouslyDeterminedRotation);
            }
            else
            {
                VirtualTransform temp = new VirtualTransform(_previousTargetState.Position);
                temp.LookAt(_target.Target.position);

                if (FlattenRotationWhenDeterminingFromMovement)
                {
                    // This will keep things level with the up vector.
                    // If you go up a ramp, you won't angle the camera up the ramp with this.
                    Vector3 up         = _target.Target.up.normalized;
                    Vector3 euler      = temp.EulerAngles;
                    Vector3 eliminated = new Vector3(euler.x * (up.x), euler.y * (up.y), euler.z * (up.z));
                    temp.Rotation = Quaternion.Euler(eliminated);
                }

                return(temp.Rotation);
            }
        }
Esempio n. 2
0
    void UpdateLookingDirection()
    {
        // Notice that I have to unattach the camera
        // That's because the camera is already rotated.
        // If I don't unattach it, the entire camera will rotate with the object as it rotates.
        Transform camParent = CameraController.Camera.transform.parent;

        CameraController.Camera.transform.parent = null;
        Vector3          forward = Flatten(CameraController.CameraTransform.Forward);
        VirtualTransform vt      = new VirtualTransform();

        vt.LookAt(forward);
        Transform.rotation = vt.Rotation;
        CameraController.Camera.transform.parent = camParent;
    }
Esempio n. 3
0
        /// <summary>
        /// Performs a thickness check for whether or not a point passes the thickness check as defined by the thickness settings.
        /// The original point should be a point that already has been checked for collision and has collided with something.
        /// This method does not recheck the original position.
        /// </summary>
        /// <param name="startingPosition">The original starting point that triggered the thickness check</param>
        /// <param name="direction">Direction towards the camera</param>
        /// <param name="maxDistance">The original max distance of the camera that was passed</param>
        /// <returns>The thickness check at this point has found the hit object to be acceptable, and thus has no collision.</returns>
        private bool ThicknessCollisionViewRaycast(Vector3 startingPosition, Vector3 direction, float maxDistance)
        {
            // We check on both the left and right side of the starting position.
            // We store what "check" we found a hit on. So if we have 4 checks, we check each side 4 times.
            // If we found something on the 2/4 check and not the 3/4 check, then we know the thickest we're able to estimate is at the 2 position
            // [4, 3, 2, 1, 0, 1, 2, 3, 4]
            //             |--------|
            // Thus we find that in this case, that the object can be hit at 0 left, but not 1 left, and at 2 right, but not 3 right.
            // That makes the object in our estimate "2/4th the size of the acceptable width."
            // If we found that the left was actually at the 3 left marker, then we'd have "4/4th of the acceptable width point",
            // thus it's too thick and we'll return false.
            //
            // In reality, we do 2^(number of checks) increments, so it would look more like 8/16ths instead of 2/4ths (8 points out of 16 were determined to be collision)

            // Added: NumberOfAngles
            // At first I had approached this only check left and right. Later I quickly realized that if the camera was at a different angle, then
            // the thickness check could fail. NumberOfAngles will be used to increase the angles we check things at.
            // By default it will be set to 4, which means that we'll check [left/right], [up/down], [leftup/downright], and [rightup/leftdown]
            // It isn't recommended it go below that.
            // If any of these checks pass, then it is below the thickness threshhold and thus has no collision.

            int checks = (int)Mathf.Pow(2, ThicknessChecking.NumberOfChecks);

            float angle = 180f / ThicknessChecking.NumberOfAngles;

            var sideDirection = new VirtualTransform();

            sideDirection.LookAt(CameraTransform.Right);
            for (float currentAngle = 0; currentAngle < 180; currentAngle += angle)
            {
                sideDirection.Rotate(CameraTransform.Forward, angle);

                Debug.DrawRay(startingPosition, sideDirection.Forward, Color.cyan);
                Debug.DrawRay(startingPosition, sideDirection.Forward * -1, Color.cyan);

                int right = ThicknessCollisionViewRaycastCheckSide(sideDirection.Forward, startingPosition, direction, maxDistance);
                int left  = ThicknessCollisionViewRaycastCheckSide(sideDirection.Forward * -1, startingPosition, direction, maxDistance);

                // If any of the checks passes, then it is thin enough.
                if (right + left < checks)
                {
                    return(false);
                }
            }

            return(true);
        }
        public override void Initialize(CameraController cameraController)
        {
            base.Initialize(cameraController);
            _target = GetCameraComponent <TargetComponent>();

            _previouslyDeterminedRotation = _target.Target.rotation;
            _previousTargetState          = new VirtualTransform(_target.Target);

            _finishedAdjustment = true;
            _forceAdjustment    = false;

            FixOffsets();

            if (RotationLerpTransformer == null)
            {
                RotationLerpTransformer = new DoNothingLerpTransformer();
            }
        }
        /// <summary>
        /// Switches the active camera to the given index.
        /// </summary>
        /// <param name="index">Index in the list of cameras.</param>
        /// <param name="copyComponents">Whether or not components fields will be copied from the current camera to the next.</param>
        public void SwitchCamera(int index, bool copyComponents = false)
        {
            if (index < 0 || index > CameraControllers.Count - 1)
            {
                throw new ArgumentOutOfRangeException("The index: " + index + " is not a valid index for a Camera.");
            }

            CameraController previousCameraController = CameraControllers[_currentCameraIndex];

            // Setup out new index, and the position we left off of
            _switchTransform    = new VirtualTransform(CameraTransform);
            _currentCameraIndex = index;
            _switchBeginTime    = Time.time;

            // Copy the fields before we initialize
            if (copyComponents)
            {
                CameraControllers[_currentCameraIndex].CopyPublicFields(previousCameraController);
            }

            // We want the camera to initialize, but we don't want it actually updating. Enabling and disabling will do that.
            CameraControllers[_currentCameraIndex].enabled = true;
            CameraControllers[_currentCameraIndex].enabled = false;

            // Setting up the speed after the new camera has been initialized so that we have the correct position for measurements.
            // If we're at 0 or less, then set our position to the new camera's position immediately.
            if (SwitchSpeed <= 0)
            {
                // Snap if equal or less than 0
                _switchSpeed = float.MaxValue;
                CameraControllers[_currentCameraIndex].CameraTransform.ApplyTo(CameraTransform);
            }
            // Otherwise, we set up the speed.
            else
            {
                _switchSpeed = SwitchSpeed;
                if (ConstantSwitchSpeedInit)
                {
                    _switchSpeed = Vector3.Distance(_switchTransform.Position, CameraControllers[_currentCameraIndex].CameraTransform.Position) / SwitchSpeed;
                }
            }
        }
        public override void UpdateCamera()
        {
            // This was a public variable can switch the camera.
            if (CurrentIndex != _currentCameraIndex)
            {
                SwitchCamera(CurrentIndex);
            }

            CameraController cam = CameraControllers[_currentCameraIndex];

            cam.UpdateCamera();

            // Lerping, we have to calculate between positions.
            if (Time.time - _switchBeginTime < _switchSpeed)
            {
                float t  = (Time.time - _switchBeginTime) / _switchSpeed;
                float pt = PositionLerpTransformer.Process(t);
                float rt = RotationLerpTransformer.Process(t);

                var lerpVirtualTransform = new VirtualTransform();

                // Lerp position
                lerpVirtualTransform.Position = Vector3.Lerp(_switchTransform.Position, cam.CameraTransform.Position, pt);

                // Lerp rotation
                lerpVirtualTransform.Rotation = SwitchSlerpRotation ?
                                                Quaternion.Slerp(_switchTransform.Rotation, cam.CameraTransform.Rotation, rt) :
                                                Quaternion.Lerp(_switchTransform.Rotation, cam.CameraTransform.Rotation, rt);

                lerpVirtualTransform.ApplyTo(CameraTransform);
            }
            // Not Lerping, we just set the position.
            else
            {
                cam.CameraTransform.ApplyTo(CameraTransform);
            }
        }
Esempio n. 7
0
        /// <summary>
        /// If you override the Awake method, be sure to call the base.Awake() in the new awake method.
        /// </summary>
        protected void Awake()
        {
            IsInitialized = false;

            if (Camera != null)
            {
                CameraTransform = new VirtualTransform();
            }
            else
            {
                throw new MissingMemberException("The Camera was not set on this CameraController. Please add a Camera reference to this CameraController.");
            }

            if (!ComponentsAdded)
            {
                _components = new Dictionary <Type, CameraComponent>();

                AddCameraComponents();

                ComponentsAdded = true;
            }

            InitializeComponents();
        }