直接添加到相机,并调节参数:
Target单独创建一个空对象。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public enum CamState
{
Step1,
Step2,
}
public class CameraController : MonoBehaviour
{
public static CameraController instance;
public Transform target; //沿着旋转的目标物体
public LayerMask mask;//选择渲染的层
public float targetHeight = 0f; //可调节的高度
public float distance = 0f;//当前与目标物体的距离
public float maxDistance = 500; //距离目标物体的最大距离
public float minDistance = 0f; //距离目标物体的最小距离
public float xSpeed = 250.0f; //x轴旋转速度
public float ySpeed = 120.0f; //y轴旋转速度
public float yMinLimit = 15; //Y轴的最低限位
public float yMaxLimit = 80; //Y轴的最高限位
public float zoomRate = 20; //缩放的速度
public float rotationDampening = 2.0f; //旋转抑制
[HideInInspector]
public float x = 0.0f; //x旋转
[HideInInspector]
public float y = 0.0f; //Y旋转
private float xDampMove = 0;//X轴旋转缓动
private float yDampMove = 0;//Y轴旋转缓动
private float targetDistance = 0;
bool isMove; //平移
public float moveSpeed = 5; //平移速度
private float minSpeed = 1f; //旋转和移动算法中用到的最小距离
/// <summary>
/// 判断是否执行摄像机旋转移动等控制功能
/// </summary>
public bool isExecutiveControl = false;
void Awake()
{
instance = this;
Vector3 angles = transform.eulerAngles;
x = angles.y;
y = angles.x;
if (GetComponent<Rigidbody>())
GetComponent<Rigidbody>().freezeRotation = true;
targetDistance = distance;
}
/// <summary>
/// 获得当前点击到的UI物体
/// </summary>
public bool Skode_GetCurrentSelect()
{
//GameObject obj = null;
GraphicRaycaster[] graphicRaycasters = FindObjectsOfType<GraphicRaycaster>();
PointerEventData eventData = new PointerEventData(EventSystem.current);
eventData.pressPosition = Input.mousePosition;
eventData.position = Input.mousePosition;
List<RaycastResult> list = new List<RaycastResult>();
foreach (var item in graphicRaycasters)
{
item.Raycast(eventData, list);
if (list.Count > 0)
{
return true;
}
}
return false;
}
void LateUpdate()
{
if (isExecutiveControl)
return;
// if (Skode_GetCurrentSelect()) {
// //Debug.Log("0000");
// return;
// }
if (!target)
return;
if (distance <= 5)
minSpeed = 100;
else
minSpeed = distance;
//将目标物体的旋转进行实时赋值,为平移功能做铺垫
target.transform.eulerAngles = new Vector3(target.transform.eulerAngles.x, transform.eulerAngles.y, target.transform.eulerAngles.z);
if (Input.GetMouseButton(2))
{
//平移
target.transform.Translate(-Input.GetAxis("Mouse X") * 0.1f * minSpeed * moveSpeed * Time.deltaTime, 0, -Input.GetAxis("Mouse Y") * minSpeed * 0.1f * moveSpeed * Time.deltaTime);
}
if (Input.GetMouseButton(1))
{
if (!Input.GetMouseButton(2))
{
xDampMove = Input.GetAxis("Mouse X") * xSpeed;
yDampMove = Input.GetAxis("Mouse Y") * ySpeed;
}
}
xDampMove = Mathf.Clamp(xDampMove, -xSpeed, xSpeed);
yDampMove = Mathf.Clamp(yDampMove, -ySpeed, ySpeed);
x += xDampMove * Time.deltaTime;
y -= yDampMove * Time.deltaTime;
//Debug.Log("xDampMove: " + xDampMove + " yDampMove : " + yDampMove);
//if (Input.GetKey("q"))
// distance -= zoomRate * 0.25f * Time.deltaTime;
//if (Input.GetKey("e"))
// distance += zoomRate * 0.25f * Time.deltaTime;
distance -= (Input.GetAxis("Mouse ScrollWheel") * Time.deltaTime) * zoomRate * Mathf.Abs(minSpeed);
//Debug.Log("targetDistance " + distance + " " + targetDistance);
distance = Mathf.Clamp(distance, minDistance, maxDistance);
targetDistance = Mathf.Lerp(targetDistance, distance, 2 * Time.deltaTime);
//Debug.Log("targetDistance " + distance + " " + targetDistance);
y = ClampAngle(y, yMinLimit, yMaxLimit);
Quaternion rotation = Quaternion.Euler(y, x, 0);
Vector3 position = rotation * Vector3.forward * -targetDistance + target.position + new Vector3(0, targetHeight, 0);
xDampMove = Mathf.Lerp(xDampMove, 0, rotationDampening * Time.deltaTime);
yDampMove = Mathf.Lerp(yDampMove, 0, rotationDampening * Time.deltaTime);
//checkLineOfSign and Collision
position = SignUpdate(target.position + Vector3.up * targetHeight, position, 0.3f, distance, 0.6f, mask);
transform.rotation = rotation;
transform.position = position;
}
public void chenge_dis(float dis)
{
if (dis > 0)
{
distance -= zoomRate * Time.deltaTime;
}
else
{
distance += zoomRate * Time.deltaTime;
}
}
static float ClampAngle(float angle, float min, float max)
{
if (angle < -360)
angle += 360;
if (angle > 360)
angle -= 360;
return Mathf.Clamp(angle, min, max);
}
Vector3 SignUpdate(Vector3 targetPoint, Vector3 selfPosition, float checkRadios, float maxDis, float stepDis, LayerMask s_mask)
{
Ray ray = new Ray(targetPoint, selfPosition - targetPoint);
RaycastHit hit;
if (Physics.SphereCast(ray, checkRadios, out hit, maxDis, s_mask))
{
return ray.GetPoint(hit.distance - stepDis);
}
return selfPosition;
}
public CameraController Clone()
{
return new CameraController
{
target = target,
targetHeight = targetHeight,
distance = distance,
maxDistance = maxDistance,
minDistance = minDistance,
xSpeed = xSpeed,
ySpeed = ySpeed,
yMinLimit = yMinLimit,
yMaxLimit = yMaxLimit,
zoomRate = zoomRate,
rotationDampening = rotationDampening,
moveSpeed = moveSpeed
};
}
/// <summary>
/// 重置查看的目标坐标和摄像机与目标物体的距离,重置摄像机参数
/// </summary>
/// <param name="targetTrans"></param>
/// <param name="distance"></param>
public void ResetData(Transform targetTrans, float distance)
{
//Debug.Log("重置参数");
target = GameObject.Find("cameraTarget").transform;
target.transform.position = targetTrans.position;
target.transform.rotation = targetTrans.rotation;
Vector3 angles = transform.eulerAngles;
x = angles.y;
y = angles.x;
xDampMove = 0;
yDampMove = 0;
targetDistance = distance;
this.distance = distance;
}
public void ExecutiveControlTrue()
{
isExecutiveControl = true;
}
public void ExecutiveControlFalse()
{
isExecutiveControl = false;
}
}
|