123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369 |
-
- // =================================
- // Namespaces.
- // =================================
- using UnityEngine;
- // =================================
- // Define namespace.
- // =================================
- namespace MirzaBeig
- {
- namespace Demos
- {
- namespace TheLastParticle
- {
- // =================================
- // Classes.
- // =================================
- //[ExecuteInEditMode]
- [System.Serializable]
- public class CameraController : MonoBehaviour
- {
- // =================================
- // Nested classes and structures.
- // =================================
- // ...
- public struct ClipPlanePoints
- {
- public Vector3 UpperLeft;
- public Vector3 UpperRight;
- public Vector3 LowerLeft;
- public Vector3 LowerRight;
- }
- // =================================
- // Variables.
- // =================================
- // ...
- new Camera camera;
- // Transforms.
- [Header("Transforms")]
- public Transform target;
- public Transform offset;
- // Position.
- [Header("Position")]
- public float followTargetSpeed = 8.0f;
- // Rotation.
- [Header("Rotation")]
- Vector2 mouseInput;
- public float mouseRotateAmount = 5.0f;
- public float mouseRotateSpeed = 5.0f;
- public float rotateZSpeed = 1.0f;
- public float resetZRotationSpeed = 5.0f;
- public Vector2 lookUpDownRange = new Vector2(-80.0f, 80.0f);
- // Zoom.
- [Header("Zoom")]
- public float zoomDistance = 4.0f;
- public float mouseZoomAmount = 1.0f;
- public float mouseZoomSpeed = 5.0f;
- public float mouseZoomMin = 1.0f;
- public float mouseZoomMax = 5.0f;
- // ...
- [Header("Occlusion Zoom")]
- public float occlusionZoomSpeed = 8.0f;
- public float occlusionZoomOffset = 0.0f;
- public float occlusionRaycastDownDistance = 0.5f;
- public AnimationCurve occlisionRaycastDownCurve =
- new AnimationCurve(new Keyframe(0.0f, 1.0f), new Keyframe(1.0f, 0.0f));
- // Offset framing.
- [Header("Offset (Framing)")]
- public float offsetFramingAmount = 2.0f;
- public float offsetFramingSpeed = 1.0f;
- public float minPlayerSpeedForOffsetFraming = 1.0f;
- public float minMouseMoveForOffsetFraming = 1.0f;
- Vector3 offsetStartPosition;
- Vector3 offsetPositionTarget;
- Vector3 offsetMouseFramePosition;
- // Stored locally as euler because Quaternions take shortest
- // path around for rotation. By using euler, I don't run into
- // the problem of spinning the camera too quickly and causing
- // a sudden snap because the rotation exceeded 180 degrees.
- Vector3 rotationEuler;
- Vector3 targetRotationEuler;
- // Player.
- Player player;
- // =================================
- // Functions.
- // =================================
- // ...
- void Awake()
- {
- }
- // ...
- void Start()
- {
- lockMouse();
- camera = Camera.main;
- player = FindObjectOfType<Player>();
- zoomDistance = Vector3.Distance(camera.transform.position, target.position);
- offsetStartPosition = offset.localPosition;
- offsetPositionTarget = offsetStartPosition;
- }
- // ...
- void lockMouse()
- {
- Cursor.visible = false;
- Cursor.lockState = CursorLockMode.Locked;
- }
- void unlockMouse()
- {
- Cursor.visible = true;
- Cursor.lockState = CursorLockMode.None;
- }
- // ...
- void FixedUpdate()
- {
- }
- // ...
- void Update()
- {
- // Input.
- mouseInput.x = Input.GetAxis("Mouse X");
- mouseInput.y = Input.GetAxis("Mouse Y");
- if (Input.GetMouseButtonDown(0))
- {
- lockMouse();
- }
- else if (Input.GetKeyDown(KeyCode.Escape))
- {
- unlockMouse();
- }
- }
- // ...
- void LateUpdate()
- {
- // Follow position.
- transform.position = Damping.dampVector3(transform.position, target.position, followTargetSpeed, Time.deltaTime);
- if (Cursor.lockState == CursorLockMode.Locked)
- {
- // Rotation.
- // Can't get it to smooth when rotating, so I just set the physica time step to 0.01f (half of default).
- targetRotationEuler.y += mouseInput.x * mouseRotateAmount;
- targetRotationEuler.x += -mouseInput.y * mouseRotateAmount;
- targetRotationEuler.x = Mathf.Clamp(targetRotationEuler.x, lookUpDownRange.x, lookUpDownRange.y);
- targetRotationEuler.z += mouseInput.x * rotateZSpeed;
- rotationEuler = Damping.dampVector3(rotationEuler, targetRotationEuler, mouseRotateSpeed, Time.deltaTime);
- transform.eulerAngles = rotationEuler;
- //transform.rotation *= Quaternion.AngleAxis(mouseRotateSpeed * Time.deltaTime, Vector3.up);
- // Offset framing.
- float playerSpeed = player.rb.velocity.magnitude;
- if (playerSpeed < minPlayerSpeedForOffsetFraming)
- {
- offsetMouseFramePosition = offsetStartPosition;
- }
- else
- {
- if (mouseInput.x > minMouseMoveForOffsetFraming)
- {
- offsetMouseFramePosition.x = -offsetFramingAmount;
- }
- else if (mouseInput.x < -minMouseMoveForOffsetFraming)
- {
- offsetMouseFramePosition.x = offsetFramingAmount;
- }
- if (mouseInput.y > minMouseMoveForOffsetFraming)
- {
- offsetMouseFramePosition.y = -offsetFramingAmount;
- }
- else if (mouseInput.y < -minMouseMoveForOffsetFraming)
- {
- offsetMouseFramePosition.y = offsetFramingAmount;
- }
- }
- offsetPositionTarget = Damping.dampVector3(offsetPositionTarget, offsetMouseFramePosition, offsetFramingSpeed, Time.deltaTime);
- // Balance out rotation around Z back to 0.0f.
- targetRotationEuler.z = Damping.dampFloat(targetRotationEuler.z, 0.0f, resetZRotationSpeed, Time.deltaTime);
- // Zoom.
- // Scrolling happens as 0.1f increments. x10.0f to make it 1.0f.
- float scroll = Input.GetAxis("Mouse ScrollWheel") * 10.0f;
- zoomDistance -= scroll * mouseZoomAmount;
- zoomDistance = Mathf.Clamp(zoomDistance, mouseZoomMin, mouseZoomMax);
- // Player occlusion check and zoom.
- RaycastHit hitInfo;
- checkIfPlayerOccluded(out hitInfo);
- //float nearestDistance = checkCameraPoints(out hitInfo);
- Vector3 finalOffsetPositionTarget;
- RaycastHit hitInfo2;
- Transform cameraTransform = camera.transform;
- Vector3 directionToTarget = (target.position - cameraTransform.position).normalized;
- Vector3 end = target.position - (directionToTarget * (zoomDistance + occlusionZoomOffset));
- Physics.Raycast(end, Vector3.down, out hitInfo2, occlusionRaycastDownDistance);
- Debug.DrawLine(end, end + (Vector3.down * occlusionRaycastDownDistance), Color.white);
- if (hitInfo.collider)
- {
- //finalOffsetPositionTarget = offsetPositionTarget.normalized * nearestDistance;
- finalOffsetPositionTarget = offsetPositionTarget.normalized * hitInfo.distance;
- }
- //if (hitInfo2.collider)
- //{
- // float curveResult = 1.0f - occlisionRaycastDownCurve.Evaluate(hitInfo2.distance / occlusionRaycastDownDistance);
- // finalOffsetPositionTarget = (offsetPositionTarget.normalized * zoomDistance) * curveResult;
- //}
- //else if (hitInfo.collider)
- //{
- // finalOffsetPositionTarget = Vector3.zero;
- //}
- else
- {
- finalOffsetPositionTarget = offsetPositionTarget.normalized * zoomDistance;
- }
- offset.localPosition = Damping.dampVector3(offset.localPosition, finalOffsetPositionTarget, mouseZoomSpeed, Time.deltaTime);
- }
- }
- // ...
- void checkIfPlayerOccluded(out RaycastHit hitInfo)
- {
- if (!camera)
- {
- camera = Camera.main;
- }
- Transform cameraTransform = camera.transform;
- Vector3 directionToTarget = (target.position - cameraTransform.position).normalized;
- Vector3 start = target.position;
- Vector3 end = Application.isPlaying ?
- (target.position - (directionToTarget * (zoomDistance + occlusionZoomOffset))) :
- (offset.position + (-directionToTarget * occlusionZoomOffset));
- Physics.Linecast(start, end, out hitInfo);
- if (!Application.isPlaying)
- {
- Gizmos.color =
- hitInfo.collider ? Color.red : Color.green;
- Gizmos.DrawLine(start, end);
- }
- else
- {
- Debug.DrawLine(start, end, hitInfo.collider ? Color.red : Color.green);
- }
- }
- // ...
- void OnDrawGizmos()
- {
- RaycastHit hitInfo;
- checkIfPlayerOccluded(out hitInfo);
- //checkCameraPoints(out hitInfo);
- }
- // =================================
- // End functions.
- // =================================
- }
- // =================================
- // End namespace.
- // =================================
- }
- }
- }
- // =================================
- // --END-- //
- // =================================
|