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 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
| using System; using NaughtyAttributes; using UnityEngine; namespace _Scripts { public class CameraController : MonoBehaviour { [SerializeField,Header("玩家")] private Transform player; [SerializeField,Header("平滑速度")] private float smooth = 10f; [SerializeField,Header("h轴偏转速度")] private float hSpeed = 6f; [SerializeField,Header("v轴偏转速度")] private float vSpeed = 6f;
[SerializeField,Header("相机位置偏移")] private Vector3 camOffset; [SerializeField,Header("锚点位置偏移")] private Vector3 pivotOffset; [MinMaxSlider(-100, 100), SerializeField,Header("偏转角范围")] private Vector2 minMaxVAngle;
private float targetFov; private Vector3 targetPivotOffset; private Vector3 targetCamOffset;
private Transform cam; private Camera myCamera;
private Vector3 smoothPivotOffset; private Vector3 smoothCamOffset;
private float defaultFov; private float relCameraPosMag; private float angleH, angleV;
private void Awake() { cam = transform; myCamera = GetComponent<Camera>(); defaultFov = myCamera.fieldOfView; cam.position = player.position + Quaternion.identity * pivotOffset + Quaternion.identity * camOffset; cam.rotation = Quaternion.identity;
smoothPivotOffset = pivotOffset; smoothCamOffset = camOffset; angleH = player.eulerAngles.y;
relCameraPosMag = (transform.position - player.position).magnitude - 0.5f;
ResetTargetOffsets (); ResetFov (); }
private void Update() { angleH += Input.GetAxis($"Mouse X") * hSpeed; angleV += Input.GetAxis($"Mouse Y") * vSpeed; angleV = Mathf.Clamp(angleV, minMaxVAngle.x, minMaxVAngle.y); var aimRotation = Quaternion.Euler(-angleV, angleH, 0); cam.rotation = Quaternion.Euler(-angleV, angleH, 0); var camYRotation = Quaternion.Euler(0, angleH, 0);
myCamera.fieldOfView = Mathf.Lerp(myCamera.fieldOfView, targetFov, Time.deltaTime); var baseTempPosition = player.position + camYRotation * targetPivotOffset; var noCollisionOffset = targetCamOffset; for (var zOffset = targetCamOffset.z; zOffset <= 0; zOffset+=0.5f) { noCollisionOffset.z = zOffset; if (PosCheck(baseTempPosition+aimRotation*noCollisionOffset,Mathf.Abs(zOffset))) { break; } } smoothPivotOffset = Vector3.Lerp(smoothPivotOffset, targetPivotOffset, smooth * Time.deltaTime); smoothCamOffset = Vector3.Lerp(smoothCamOffset, noCollisionOffset, smooth * Time.deltaTime);
cam.position = player.position + camYRotation * smoothPivotOffset + aimRotation * smoothCamOffset; } public void ResetTargetOffsets() { targetPivotOffset = pivotOffset; targetCamOffset = camOffset; } public void ResetFov() { targetFov = defaultFov; } private bool PosCheck(Vector3 checkPos, float offset) { var playerH=player.GetComponent<CapsuleCollider>().height * 0.75f > 0 ? player.GetComponent<CapsuleCollider>().height * 0.75f : player.GetComponent<CharacterController>().height * 0.75f; return ViewPosCheck(checkPos, playerH) && ReverseViewPosCheck(checkPos,playerH,offset); } private bool ViewPosCheck(Vector3 checkPos, float playerH) { var target = player.position + (Vector3.up * playerH); if (Physics.SphereCast(checkPos,0.2f,target-checkPos,out RaycastHit hit,relCameraPosMag)) { if (hit.transform!=player&&!hit.transform.GetComponent<Collider>().isTrigger) { return false; } }
return true; } private bool ReverseViewPosCheck(Vector3 checkPos, float playerH, float maxDistance) { var origin = player.position + (Vector3.up * playerH); if (Physics.SphereCast(origin, 0.2f, checkPos - origin, out RaycastHit hit, maxDistance)) { if(hit.transform != player && hit.transform != transform && !hit.transform.GetComponent<Collider>().isTrigger) { return false; } } return true; } } }
|