void Apply(Transform dummyTarget, Vector3 dummyCenter) { // Early out if we don't have a target if (!controller) { return; } Vector3 targetCenter = _target.position + centerOffset; Vector3 targetHead = _target.position + headOffset; // DebugDrawStuff(); // Calculate the current & target rotation angles float originalTargetAngle = _target.eulerAngles.y; float currentAngle = cameraTransform.eulerAngles.y; // Adjust real target angle when camera is locked float targetAngle = originalTargetAngle; // When pressing Fire2 (alt) the camera will snap to the target direction real quick. // It will stop snapping when it reaches the target if (Input.GetButton("Fire2")) { snap = true; } if (snap) { // We are close to the target, so we can stop snapping now! if (AngleDistance(currentAngle, originalTargetAngle) < 3.0f) { snap = false; } currentAngle = Mathf.SmoothDampAngle(currentAngle, targetAngle, ref angleVelocity, snapSmoothLag, snapMaxSpeed); } // Normal camera motion else { if (controller.GetLockCameraTimer() < lockCameraTimeout) { targetAngle = currentAngle; } // Lock the camera when moving backwards! // * It is really confusing to do 180 degree spins when turning around. if (AngleDistance(currentAngle, targetAngle) > 160 && controller.IsMovingBackwards()) { targetAngle += 180; } currentAngle = Mathf.SmoothDampAngle(currentAngle, targetAngle, ref angleVelocity, angularSmoothLag, angularMaxSpeed); } // When jumping don't move camera upwards but only down! if (controller.IsJumping()) { // We'd be moving the camera upwards, do that only if it's really high float newTargetHeight = targetCenter.y + height; if (newTargetHeight < targetHeight || newTargetHeight - targetHeight > 5) { targetHeight = targetCenter.y + height; } } // When walking always update the target height else { targetHeight = targetCenter.y + height; } // Damp the height float currentHeight = cameraTransform.position.y; currentHeight = Mathf.SmoothDamp(currentHeight, targetHeight, ref heightVelocity, heightSmoothLag); // Convert the angle into a rotation, by which we then reposition the camera Quaternion currentRotation = Quaternion.Euler(0, currentAngle, 0); // Set the position of the camera on the x-z plane to: // distance meters behind the target cameraTransform.position = targetCenter; cameraTransform.position += currentRotation * Vector3.back * distance; // Set the height of the camera cameraTransform.position = new Vector3(cameraTransform.position.x, currentHeight, cameraTransform.position.z); // Always look at the target SetUpRotation(targetCenter, targetHead); }