W_WuHuVR/Medicine/Assets/Scr/Touch_obj/CameraMove.cs

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
}