В продолжении рассмотрения камер от третьего лица были затронуты такие моменты, как:
- слежение камеры за персонажем
- вращение камеры при помощи мыши
- реагирование на препятствия
- реагирование на приближение к игроку
Для реализации этого был написан и рассмотрен нижеприведенный скрипт.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
using System.Collections; using UnityEngine; public class PlayerCameraController : MonoBehaviour { public Camera cam; public Transform target; public float speedX = 360f; public float speedy = 240f; public float limitY = 40f; public float minDistance = 1.5f; public float hideDistance = 2f; public LayerMask obstacles; public LayerMask noPlayer; private float _maxDistance; private Vector3 _localPosition; private float _currentYRotation; private LayerMask _camOrigin; private Vector3 _position { get { return transform.position; } set { transform.position = value; } } void Start () { _localPosition = target.InverseTransformPoint(_position); _maxDistance = Vector3.Distance(_position, target.position); _camOrigin = cam.cullingMask; } void LateUpdate () { _position = target.TransformPoint(_localPosition); CameraRotation(); ObstaclesReact(); PlayerReact(); _localPosition = target.InverseTransformPoint(_position); } void CameraRotation() { var mx = Input.GetAxis("Mouse X"); var my = Input.GetAxis("Mouse Y"); if (my != 0) { var tmp = Mathf.Clamp(_currentYRotation + my * speedy * Time.deltaTime, -limitY, limitY); if (tmp != _currentYRotation) { var rot = tmp - _currentYRotation; transform.RotateAround(target.position, transform.right, rot); _currentYRotation = tmp; } } if (mx != 0) { transform.RotateAround(target.position, Vector3.up, mx * speedX * Time.deltaTime); } transform.LookAt(target); } void ObstaclesReact() { var distance = Vector3.Distance(_position, target.position); RaycastHit hit; if (Physics.Raycast(target.position, transform.position - target.position, out hit, _maxDistance, obstacles)) { _position = hit.point; } else if (distance < _maxDistance && !Physics.Raycast(_position, -transform.forward, .1f, obstacles)) { _position -= transform.forward * .05f; } } void PlayerReact() { var distance = Vector3.Distance(_position, target.position); if (distance < hideDistance) cam.cullingMask = noPlayer; else cam.cullingMask = _camOrigin; } } |