其中Target是摄像机的参考点,每一次平移都是通过移动他的位置来实现摄像机的移动,某个物体居中显示就是把target移动到这个物体的位置上
1.主控制脚本
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
public class TestFocus : MonoBehaviour
{
public Text tex;
public Transform kTarget; //摄像机参考点
public float initDistance = 13.7f; //摄像机与参考点的默认距离
public float distanceMax = 30f; //摄像机与参考点的最大距离
public float desiredDistance; //每次操作中期望的摄像机距离
public float scrollSpeed = 12f; //滚轮移动速度
public float rotateSpeed = 8f; //摄像机旋转速度
public float panSpeed = 0.3f; //拖拽摄像机参照物的移动速度
private float DPI = 0; //不同分辨率的速度移动参数
private float currentDistance = 0f; //摄像机距离参照物的当前距离
private float mouseX = 0f; //旋转摄像机x周的速度
private float mouseY = 0f; //旋转摄像机y轴的速度
private Vector3 velocity = Vector3.zero; //摄像机参照点移动向量
private float velocityZ = 0f; //摄像机移动到目标距离点的速度向量
private float delayZ = 0.3f; //摄像机移动缓冲时间
private Quaternion currentRotation; //摄像机当前旋转角度
private Quaternion desiredRotation; //摄像机期望达到的角度
private float lastDistance; //实现距离拉近拉远的平滑效果,上一次相机停留点
private float perDistance; //实现距离拉近拉远的平滑效果,每一帧相机要移动到的位置
private Vector2 endone; //用来记录缩放趋势
private Vector2 endtwo;
private bool isTouch = false; //是否是触屏
RaycastHit hit;
bool _isFocus = false;
Transform mTrans;
void Awake()
{
mTrans = this.transform;
}
// Use this for initialization
void Start ()
{
DPI = Screen.height / 1080f;
initDistance = Mathf.Clamp(initDistance, 1.25f, distanceMax);
currentDistance = desiredDistance = initDistance;
}
// Update is called once per frame
void LateUpdate()
{
if (_isFocus)
{
kTarget.position = Vector3.SmoothDamp(kTarget.position, hit.transform.position, ref velocity, delayZ - 0.1f);
desiredDistance = initDistance;
if (Vector3.Distance(kTarget.position, hit.transform.position) < 0.0005f)
{
_isFocus = false;
}
}
}
void Update()
{
if (Input.GetMouseButtonUp(0))
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hit))
{
if (hit.collider != null)
{
_isFocus = true;
}
}
}
if (Input.touchCount > 0)
{
if (Input.touchCount == 1 && Input.GetTouch(0).phase == TouchPhase.Moved)
{
mouseX += Input.GetTouch(0).deltaPosition.x * rotateSpeed * DPI * 0.3f;
mouseY -= Input.GetTouch(0).deltaPosition.y * rotateSpeed * DPI * 0.3f;
tex.text = "旋转中";
}
//触屏缩放
if (Input.touchCount == 2)
{
if (Input.GetTouch(0).phase == TouchPhase.Moved && Input.GetTouch(1).phase == TouchPhase.Moved)
{
Vector2 startone = Input.GetTouch(0).position;
Vector2 starttwo = Input.GetTouch(1).position;
if (isEnlarge(startone, starttwo, endone, endtwo))
{
tex.text = "缩放中";
if (desiredDistance < distanceMax)
desiredDistance += DPI * 1f;
}
else
{
tex.text = "放大中";
if (desiredDistance > 5f)
desiredDistance -= DPI * 1f;
}
endone = startone;
endtwo = starttwo;
}
}
//触屏实现拖拽
if (Input.touchCount == 3)
{
if (Input.GetTouch(0).phase == TouchPhase.Moved && Input.GetTouch(1).phase == TouchPhase.Moved
&& Input.GetTouch(2).phase == TouchPhase.Moved)
{
tex.text = "触屏拖动中";
kTarget.rotation = mTrans.rotation;
kTarget.Translate(Vector2.right * -Input.GetTouch(0).deltaPosition.x * panSpeed);
kTarget.Translate(mTrans.up * -Input.GetTouch(0).deltaPosition.y * panSpeed);
}
}
isTouch = true;
}
else
{
isTouch = false;
}
//键盘操作,旋转和拖拽
if (Input.GetMouseButton(0) && !isTouch)
{
_isFocus = false;
mouseX += Input.GetAxis("Mouse X") * rotateSpeed;
mouseY -= Input.GetAxis("Mouse Y") * rotateSpeed;
tex.text = "键盘旋转中";
}
if (Input.GetMouseButton(1) && !isTouch)
{
_isFocus = false;
kTarget.rotation = mTrans.rotation;
kTarget.Translate(Vector2.right * -Input.GetAxis("Mouse X") * panSpeed);
kTarget.Translate(mTrans.up * -Input.GetAxis("Mouse Y") * panSpeed, Space.World);
}
kTarget.position = new Vector3(Mathf.Clamp(kTarget.position.x, -15f, 15f), Mathf.Clamp(kTarget.position.y, -10f, 10f), Mathf.Clamp(kTarget.position.z, -30f, 30f));
mouseY = ClampAngle(mouseY, -30f, 30f);
//键盘沿Z轴缩放
float scrollValue = Input.GetAxis("Mouse ScrollWheel");
if (scrollValue != 0)
{
//_isFocus = false;
desiredDistance -= scrollValue * scrollSpeed;
tex.text = "键盘控制距离拉近或拉远";
}
//限制距离
if (desiredDistance > distanceMax)
desiredDistance = distanceMax;
if (desiredDistance < 1.25f)
{
desiredDistance = 1.25f;
}
currentRotation = mTrans.rotation;
desiredRotation = Quaternion.Euler(mouseY, mouseX, 0);
Quaternion rotation = Quaternion.Slerp(currentRotation, desiredRotation, Time.deltaTime * 15f);
perDistance = desiredDistance;
perDistance = Mathf.SmoothDamp(lastDistance, perDistance, ref velocityZ, delayZ);
lastDistance = perDistance;
Vector3 position = rotation * new Vector3(0f, 0f, -perDistance) + kTarget.position;
mTrans.rotation = rotation;
mTrans.position = position;
}
float ClampAngle(float angle, float min, float max)
{
if (angle < -360)
angle += 360;
if (angle > 360)
angle -= 360;
return Mathf.Clamp(angle, min, max);
}
bool isEnlarge(Vector2 oP1, Vector2 oP2, Vector2 nP1, Vector2 nP2)
{
float length1 = Mathf.Sqrt((oP1.x - oP2.x) * (oP1.x - oP2.x) + (oP1.y - oP2.y) * (oP1.y - oP2.y));
float length2 = Mathf.Sqrt((nP1.x - nP2.x) * (nP1.x - nP2.x) + (nP1.y - nP2.y) * (nP1.y - nP2.y));
if (length1 < length2)
{
return true;
}
else
{
return false;
}
}
}