506 lines
15 KiB
C#
506 lines
15 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
public class CameraMove : MonoBehaviour
|
|
{
|
|
|
|
public static CameraMove instance;
|
|
[Header("模型以及相机初始位置,自动初始化")]
|
|
public Vector3 cameraInitialPos;
|
|
public Vector3 cameraInitialRot;
|
|
public Vector3 modelInitialRot;
|
|
|
|
[Header("要控制的物体")]
|
|
[Tooltip("要控制的相机")]
|
|
public Camera myCamera;
|
|
[Tooltip("相机缩放的焦点")]
|
|
public Transform zoomTarget;
|
|
[Tooltip("要观察的模型")]
|
|
public Transform model;
|
|
|
|
[Header("设置的参数")]
|
|
[Tooltip("缩放速率")]
|
|
public int zoomRate = 40;
|
|
[Tooltip("最远观察距离")]
|
|
public float maxObservationDis;
|
|
[Tooltip("最近观察距离")]
|
|
public float minObservationDis;
|
|
[Tooltip("水平方向最大移动距离")]
|
|
public float maxDisH = 2f;
|
|
[Tooltip("竖直方向最大移动距离")]
|
|
public float maxDisV = 5f;
|
|
[Tooltip("水平竖直平面移动速度")]
|
|
public float deltaMoveSpeed = 2f;
|
|
[Tooltip("转动时的速度")]
|
|
public float rotSpeed = 2f;
|
|
[Tooltip("竖直方向最大旋转角度")]
|
|
public float maxRotV = 90f;
|
|
|
|
[Header("自动获取的变量,不需赋值")]
|
|
public float currentObservationDis;
|
|
public float mouseX;
|
|
public float mouseY;
|
|
public Vector3 zoomDir;
|
|
Vector3 mouseScreenPos;
|
|
Vector3 mouseWorldPos;
|
|
float rotV = 0f;
|
|
|
|
/// <summary>
|
|
/// 手指控制的时候各个变量
|
|
/// </summary>
|
|
Touch firstFinger;
|
|
Touch secondFinger;
|
|
TouchType touchType;
|
|
Vector2 deltaPos;
|
|
bool isStartIJudgeLongPress;
|
|
bool isStartIZoomByTwoFinger;
|
|
float twoFingerOldDis;
|
|
float twoFingerNewDis;
|
|
void Awake()
|
|
{
|
|
//Init();
|
|
}
|
|
// Update is called once per frame
|
|
void Update()
|
|
{
|
|
if (UI_manage.inst.FBX_obj.transform.childCount!=0)
|
|
{
|
|
model = UI_manage.inst.FBX_obj.transform.GetChild(0);
|
|
modelInitialRot = model.localEulerAngles;
|
|
MoveByFinger();
|
|
}
|
|
|
|
//PC端调用Move()方法,功能:鼠标左键控制相机平面移动,按住鼠标右键拖动鼠标相机围绕物体旋转,滚轮相机朝着鼠标位子缩放
|
|
//Move();
|
|
|
|
|
|
//安卓端调用此方法功能:一个手指活动屏幕模型旋转,一个手指长按屏幕后再滑动模型平面移动,两个手指实现模型朝着两手指中间放大缩小
|
|
//MoveByFinger();
|
|
}
|
|
/// <summary>
|
|
/// 初始化
|
|
/// </summary>
|
|
public void Init()
|
|
{
|
|
instance = this;
|
|
cameraInitialPos = myCamera.transform.position;
|
|
cameraInitialRot = myCamera.transform.localEulerAngles;
|
|
//modelInitialRot = model.localEulerAngles;
|
|
}
|
|
#region PC
|
|
/// <summary>
|
|
/// PC端鼠标控制移动方法
|
|
/// </summary>
|
|
private void Move()
|
|
{
|
|
MoveByMouse0();
|
|
ZoomByScrollWheel();
|
|
RotByMouse1();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 鼠标右键按住转动摄像机
|
|
/// </summary>
|
|
public void RotByMouse1()
|
|
{
|
|
if (Input.GetMouseButton(1))
|
|
{
|
|
|
|
mouseX = Input.GetAxis("Mouse X");
|
|
mouseY = Input.GetAxis("Mouse Y");
|
|
if (Mathf.Abs(mouseX) > Mathf.Abs(mouseY))
|
|
{
|
|
if (mouseX < 0)
|
|
{
|
|
model.Rotate(Vector3.up, rotSpeed);
|
|
//myCamera.transform.RotateAround(model.transform.position, Vector3.up, -rotSpeed);
|
|
}
|
|
else if (mouseX > 0)
|
|
{
|
|
model.Rotate(Vector3.up, -rotSpeed);
|
|
//myCamera.transform.RotateAround(model.transform.position, Vector3.up, rotSpeed);
|
|
|
|
}
|
|
}
|
|
else if (Mathf.Abs(mouseX) < Mathf.Abs(mouseY))
|
|
{
|
|
if (mouseY < 0)
|
|
{
|
|
if (rotV < maxRotV)
|
|
{
|
|
myCamera.transform.RotateAround(model.transform.position, Vector3.right, rotSpeed);
|
|
rotV += rotSpeed;
|
|
}
|
|
}
|
|
else if (mouseY > 0)
|
|
{
|
|
if (rotV > -maxRotV)
|
|
{
|
|
myCamera.transform.RotateAround(model.transform.position, Vector3.right, -rotSpeed);
|
|
rotV -= rotSpeed;
|
|
}
|
|
//if (myCamera.transform.localEulerAngles.x >=90)
|
|
//{
|
|
// myCamera.transform.RotateAround(model.transform.position, Vector3.right, -rotSpeed);
|
|
//}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 滑轮键缩放
|
|
/// </summary>
|
|
public void ZoomByScrollWheel()
|
|
{
|
|
float scrollWheel = Input.GetAxis("Mouse ScrollWheel");
|
|
if (scrollWheel != 0)
|
|
{
|
|
|
|
Vector3 zoomTargetScreenPos = myCamera.WorldToScreenPoint(zoomTarget.position);
|
|
mouseScreenPos = new Vector3(Input.mousePosition.x, Input.mousePosition.y, zoomTargetScreenPos.z);
|
|
zoomTarget.position = myCamera.ScreenToWorldPoint(mouseScreenPos);
|
|
Ray ray = myCamera.ScreenPointToRay(Input.mousePosition);
|
|
RaycastHit hitInfo;
|
|
if (Physics.Raycast(ray, out hitInfo))
|
|
{
|
|
zoomTarget.position = hitInfo.point;
|
|
}
|
|
}
|
|
currentObservationDis = (zoomTarget.position - myCamera.transform.position).magnitude;
|
|
zoomDir = (zoomTarget.position - myCamera.transform.position).normalized;
|
|
Zoom(zoomDir, scrollWheel * Time.deltaTime * zoomRate);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 按住鼠标左键拖动
|
|
/// </summary>
|
|
public void MoveByMouse0()
|
|
{
|
|
if (Input.GetMouseButton(0))
|
|
{
|
|
if (Input.GetAxis("Mouse X") < 0)
|
|
{
|
|
//SetMoveSpeed(2.0f);
|
|
MoveByDeltaDistance(true, true);
|
|
}
|
|
else if (Input.GetAxis("Mouse X") > 0)
|
|
{
|
|
//SetMoveSpeed(2.0f);
|
|
MoveByDeltaDistance(true, false);
|
|
|
|
}
|
|
|
|
if (Input.GetAxis("Mouse Y") < 0)
|
|
{
|
|
//SetMoveSpeed(2.0f);
|
|
MoveByDeltaDistance(false, true);
|
|
|
|
}
|
|
else if (Input.GetAxis("Mouse Y") > 0)
|
|
{
|
|
//SetMoveSpeed(2.0f);
|
|
MoveByDeltaDistance(false, false);
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 通过键盘或者方向键或者点击按钮来移动相机
|
|
/// </summary>
|
|
/// <param name="Hmoving" true表示水平移动></param>
|
|
/// <param name="positiveDir" true表示正向移动></param>
|
|
public void MoveByDeltaDistance(bool Hmoving, bool positiveDir)
|
|
{
|
|
//target.rotation = transform.rotation;
|
|
if (Hmoving)
|
|
{
|
|
|
|
|
|
if (positiveDir)
|
|
{
|
|
if (myCamera.transform.position.x < maxDisH)
|
|
{
|
|
myCamera.transform.Translate(Vector3.right * deltaMoveSpeed * Time.deltaTime, Space.Self);
|
|
//target.Translate(Vector3.right * deltaMoveSpeed * Time.deltaTime);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (myCamera.transform.position.x > -maxDisH)
|
|
{
|
|
myCamera.transform.Translate(Vector3.right * -deltaMoveSpeed * Time.deltaTime, Space.Self);
|
|
//target.Translate(Vector3.right * -deltaMoveSpeed * Time.deltaTime);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (positiveDir)
|
|
{
|
|
|
|
if (myCamera.transform.position.y < maxDisH)
|
|
{
|
|
myCamera.transform.Translate(transform.up * deltaMoveSpeed * Time.deltaTime, Space.World);
|
|
//target.Translate(transform.up * deltaMoveSpeed * Time.deltaTime, Space.World);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (myCamera.transform.position.y > -maxDisH)
|
|
{
|
|
myCamera.transform.Translate(transform.up * -deltaMoveSpeed * Time.deltaTime, Space.World);
|
|
//target.Translate(transform.up * -deltaMoveSpeed * Time.deltaTime, Space.World);
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
#endregion
|
|
|
|
/// <summary>
|
|
/// 安卓端通过手指控制
|
|
/// </summary>
|
|
private void MoveByFinger()
|
|
{
|
|
if (Input.touchCount == 0)
|
|
{
|
|
touchType = TouchType.NoneFinger;
|
|
StopAllCoroutines();
|
|
isStartIJudgeLongPress = false;
|
|
isStartIZoomByTwoFinger = false;
|
|
}
|
|
else if (Input.touchCount == 1)
|
|
{
|
|
|
|
if (touchType == TouchType.NoneFinger && !isStartIJudgeLongPress)
|
|
{
|
|
isStartIJudgeLongPress = true;
|
|
StartCoroutine(IJudgeLongPress());
|
|
firstFinger = Input.GetTouch(0);
|
|
}
|
|
}
|
|
else if (Input.touchCount == 2)
|
|
{
|
|
touchType = TouchType.TwoFingerZoom;
|
|
}
|
|
switch (touchType)
|
|
{
|
|
case TouchType.NoneFinger:
|
|
break;
|
|
case TouchType.OneFingerMove:
|
|
//MoveByOneFinger();
|
|
break;
|
|
case TouchType.OneFingerRot:
|
|
RotByOneFinger();
|
|
break;
|
|
case TouchType.TwoFingerZoom:
|
|
if (!isStartIZoomByTwoFinger)
|
|
{
|
|
isStartIZoomByTwoFinger = true;
|
|
StartCoroutine("IZoomByTwoFinger");
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
}
|
|
/// <summary>
|
|
/// 判断是否长按
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
IEnumerator IJudgeLongPress()
|
|
{
|
|
|
|
if (Input.touchCount != 0)
|
|
{
|
|
Vector2 firstPos = Input.GetTouch(0).position;
|
|
yield return new WaitForSeconds(0.2f);
|
|
if (Input.touchCount != 0)
|
|
{
|
|
Vector2 secondPos = Input.GetTouch(0).position;
|
|
if ((secondPos - firstPos).magnitude < 2f)
|
|
{
|
|
touchType = TouchType.OneFingerMove;
|
|
}
|
|
else
|
|
{
|
|
touchType = TouchType.OneFingerRot;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// 相机向物体移动
|
|
/// </summary>
|
|
/// <param name="zoomDir">移动方向</param>
|
|
/// <param name="zoomDis">移动距离</param>
|
|
public void Zoom(Vector3 zoomDir, float zoomDis)
|
|
{
|
|
//target.Translate(zoomDir * zoomDis, Space.World);
|
|
if (zoomDis < 0 && currentObservationDis > maxObservationDis)
|
|
{
|
|
return;
|
|
}
|
|
else if (zoomDis > 0 && currentObservationDis < minObservationDis)
|
|
{
|
|
return;
|
|
}
|
|
myCamera.transform.Translate(zoomDir * zoomDis, Space.World);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 一根手指拖动
|
|
/// </summary>
|
|
public void MoveByOneFinger()
|
|
{
|
|
|
|
firstFinger = Input.GetTouch(0);
|
|
|
|
if (firstFinger.phase == TouchPhase.Moved)
|
|
{
|
|
deltaPos = firstFinger.deltaPosition;
|
|
if (deltaPos.x < 0)
|
|
{
|
|
//SetMoveSpeed(2.0f);
|
|
MoveByDeltaDistance(true, true);
|
|
}
|
|
else if (deltaPos.x > 0)
|
|
{
|
|
//SetMoveSpeed(2.0f);
|
|
MoveByDeltaDistance(true, false);
|
|
|
|
}
|
|
|
|
if (deltaPos.y < 0)
|
|
{
|
|
//SetMoveSpeed(2.0f);
|
|
MoveByDeltaDistance(false, true);
|
|
|
|
}
|
|
else if (deltaPos.y > 0)
|
|
{
|
|
//SetMoveSpeed(2.0f);
|
|
MoveByDeltaDistance(false, false);
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 一根手指长按转动
|
|
/// </summary>
|
|
public void RotByOneFinger()
|
|
{
|
|
firstFinger = Input.GetTouch(0);
|
|
if (firstFinger.phase == TouchPhase.Moved)
|
|
{
|
|
deltaPos = firstFinger.deltaPosition;
|
|
mouseX = deltaPos.x;
|
|
mouseY = deltaPos.y;
|
|
if (Mathf.Abs(mouseX) > Mathf.Abs(mouseY))
|
|
{
|
|
if (mouseX < 0)
|
|
{
|
|
model.Rotate(Vector3.up, rotSpeed);
|
|
}
|
|
else if (mouseX > 0)
|
|
{
|
|
model.Rotate(Vector3.up, -rotSpeed);
|
|
|
|
}
|
|
}
|
|
else if (Mathf.Abs(mouseX) < Mathf.Abs(mouseY))
|
|
{
|
|
if (mouseY < 0)
|
|
{
|
|
if (rotV < maxRotV)
|
|
{
|
|
myCamera.transform.RotateAround(model.transform.position, Vector3.right, rotSpeed);
|
|
rotV += rotSpeed;
|
|
}
|
|
}
|
|
else if (mouseY > 0)
|
|
{
|
|
if (rotV > -maxRotV)
|
|
{
|
|
myCamera.transform.RotateAround(model.transform.position, Vector3.right, -rotSpeed);
|
|
rotV -= rotSpeed;
|
|
}
|
|
//if (myCamera.transform.localEulerAngles.x >=90)
|
|
//{
|
|
// myCamera.transform.RotateAround(model.transform.position, Vector3.right, -rotSpeed);
|
|
//}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 两根手指缩放协程
|
|
/// </summary>
|
|
public IEnumerator IZoomByTwoFinger()
|
|
{
|
|
Vector2 centerPos;
|
|
while (true)
|
|
{
|
|
firstFinger = Input.GetTouch(0);
|
|
secondFinger = Input.GetTouch(1);
|
|
twoFingerOldDis = Vector2.Distance(firstFinger.position, secondFinger.position);
|
|
centerPos = (firstFinger.position + secondFinger.position) / 2;
|
|
yield return 0;
|
|
firstFinger = Input.GetTouch(0);
|
|
secondFinger = Input.GetTouch(1);
|
|
twoFingerNewDis = Vector2.Distance(firstFinger.position, secondFinger.position);
|
|
float scrollWheel = twoFingerNewDis - twoFingerOldDis;
|
|
if (scrollWheel != 0)
|
|
{
|
|
|
|
Vector3 zoomTargetScreenPos = myCamera.WorldToScreenPoint(zoomTarget.position);
|
|
mouseScreenPos = new Vector3(centerPos.x, centerPos.y, zoomTargetScreenPos.z);
|
|
zoomTarget.position = myCamera.ScreenToWorldPoint(mouseScreenPos);
|
|
Ray ray = myCamera.ScreenPointToRay(centerPos);
|
|
RaycastHit hitInfo;
|
|
if (Physics.Raycast(ray, out hitInfo))
|
|
{
|
|
zoomTarget.position = hitInfo.point;
|
|
}
|
|
}
|
|
currentObservationDis = (zoomTarget.position - myCamera.transform.position).magnitude;
|
|
zoomDir = (zoomTarget.position - myCamera.transform.position).normalized;
|
|
Zoom(zoomDir, scrollWheel * Time.deltaTime * zoomRate * 0.1f);
|
|
if (Input.touchCount != 2)
|
|
{
|
|
isStartIZoomByTwoFinger = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// 复位方法
|
|
/// </summary>
|
|
public void Reset()
|
|
{
|
|
myCamera.transform.position = cameraInitialPos;
|
|
myCamera.transform.localEulerAngles = cameraInitialRot;
|
|
model.localEulerAngles = modelInitialRot;
|
|
rotV = 0;
|
|
}
|
|
}
|
|
public enum TouchType
|
|
{
|
|
NoneFinger,
|
|
OneFingerMove,
|
|
OneFingerRot,
|
|
TwoFingerZoom
|
|
} |