using UnityEngine;
public class ThirdCamera : MonoBehaviour
{
[SerializeField] private float rotateSpeed = 360;
[Header("拉近拉远的速度")]
[SerializeField] private float mouseScrollSpeed = 30;
[Header("当前相机到target的距离,不滑动中键的话可以手动调整")]
[HideInInspector] public float Distance = 3;
[Header("相机到target的最大距离,最小默认为0")]
public float MaxDistance = 3;
[Header("限制相机相对target的方向与水平面的角度")]
[SerializeField] private float clampAngle = 30;
/// <summary> 相机相对target的方向 </summary>
private Vector3 cameraDir = new Vector3(0, 4.3f,-9.8f);
[SerializeField] private Transform target;
public Vector3 TargetDir => cameraDir.normalized * Mathf.Clamp(Distance, 0, MaxDistance);
public Transform Target => target;
public void SetTargetStart(Transform target)
{
this.target = target;
}
void FixedUpdate()
{
if (!target)
return;
Rotate();
MouseScrollWheel();
Chuangqiang();
transform.position = target.transform.TransformPoint(TargetDir);
transform.localRotation = Quaternion.LookRotation(-transform.position + target.transform.position);
}
/// <summary> 旋转 </summary>
void Rotate()
{
if (!Input.GetMouseButton(0))
return;
float angleX = Input.GetAxis("Mouse X") * rotateSpeed * Time.deltaTime;
float angleY = Input.GetAxis("Mouse Y") * rotateSpeed * Time.deltaTime;
if (Mathf.Abs(angleX) > Mathf.Abs(angleY))
angleY = 0;
else
angleX = 0;
var euler = -transform.right * angleY + Vector3.up * angleX;
//记录
var lastDir = cameraDir;
cameraDir = Quaternion.Euler(euler) * cameraDir;
//计算角度
var dirProject = Vector3.ProjectOnPlane(cameraDir, Vector3.up);
float angle = Vector3.Angle(cameraDir, dirProject);
if (angle > clampAngle)
{
cameraDir = lastDir;
}
}
/// <summary> 防穿墙 </summary>
void Chuangqiang()
{
Ray ray = new Ray(target.transform.position, transform.position - target.transform.position);
target.gameObject.layer = 2;
gameObject.layer = 2;
if (Physics.Raycast(ray, out RaycastHit hit, 100))
{
float hitDistance = Vector3.Distance(hit.point, target.transform.position);
Distance = Mathf.Min(hitDistance, Distance);
}
target.gameObject.layer = 0;
gameObject.layer = 0;
}
/// <summary> 鼠标中键滚轮</summary>
void MouseScrollWheel()
{
float mouseScroll = Input.GetAxis("Mouse ScrollWheel");
if (mouseScroll != 0)
{
Distance -= mouseScroll * Time.deltaTime * mouseScrollSpeed;
Distance = Mathf.Clamp(Distance, 0, MaxDistance);
}
}
}
#region Editor
#if UNITY_EDITOR
namespace XPEditor
{
using UnityEditor;
[CustomEditor(typeof(ThirdCamera))]
public class ThirdCameraEditor : Editor
{
ThirdCamera thirdCamera;
private void Awake()
{
thirdCamera = target as ThirdCamera;
}
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
thirdCamera.Distance = EditorGUILayout.Slider( new GUIContent("当前距离"),thirdCamera.Distance,0,thirdCamera.MaxDistance);
serializedObject.ApplyModifiedProperties();
}
}
}
#endif
#endregion
第三人称防穿墙相机
猜你喜欢
转载自blog.csdn.net/weixin_44806700/article/details/120345967
今日推荐
周排行