/// <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); } }
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; }
/// <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); } }
/// <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(); }