123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274 |
- using System.Collections;
- using System.Collections.Generic;
- using System.Runtime.InteropServices;
- using UnityEngine;
- namespace EZXR.Glass.Inputs
- {
- [RequireComponent(typeof(HandInfo))]
- public class RotateUseHandle : MonoBehaviour
- {
- HandInfo handInfo;
- TransformWithBounds transformUseBounds;
- /// <summary>
- /// 射线上次射击到的Collider,用于将射线结果转化成OnTriggerStay和OnTriggerExit
- /// </summary>
- Collider lastRayCastResult = null;
- //public LayerMask layerMask;
- /// <summary>
- /// 要被旋转的目标物体
- /// </summary>
- Transform target;
- /// <summary>
- /// 当前控制的是哪个旋转手柄
- /// </summary>
- Transform curHandle;
- /// <summary>
- /// 旋转手柄被捏住一瞬间的手柄的position
- /// </summary>
- Vector3 curHandlePos;
- /// <summary>
- /// 旋转手柄被捏住一瞬间,手柄与射线起始点的偏移量
- /// </summary>
- Vector3 offset;
- /// <summary>
- /// 旋转手柄被捏住一瞬间的localRotation
- /// </summary>
- Quaternion curTargetRotation;
- /// <summary>
- /// 用户是否捏合了手指(等于按住鼠标)
- /// </summary>
- bool press;
- /// <summary>
- /// 抓取状态,0为没有手进入此物体的Trigger区域,1为手已经进入了Trigger区域(待抓取),2为已经被左手抓起来了
- /// </summary>
- int grabState;
- /// <summary>
- /// 当前握住的手柄所在平面的法线
- /// </summary>
- Vector3 normal;
- /// <summary>
- /// 目标物体中心到射线发射点的向量在手柄所在平面的投影向量
- /// </summary>
- Vector3 projectedPos;
- /// <summary>
- /// 用于计算手柄所在平面所需要的另外一个点,连同物体中心点这三个点才能组成一个平面
- /// </summary>
- Vector3 anotherPoint;
- // Start is called before the first frame update
- void Start()
- {
- handInfo = GetComponent<HandInfo>();
- //用于得到当前手的射线检测的结果
- handInfo.Event_GetRayCastResult += OnRayCastHit;
- }
- private void OnDisable()
- {
- grabState = 0;
- if (curHandle != null)
- {
- curHandle.GetComponent<Renderer>().material.color = Color.white;
- curHandle = null;
- }
- target = null;
- }
- // Update is called once per frame
- void Update()
- {
- switch (grabState)
- {
- case 1:
- if (handInfo.isPinching)
- {
- curHandlePos = curHandle.position;
- //算出旋转手柄被捏住一瞬间,手柄与射线起始点的偏移量
- offset = curHandle.position - handInfo.rayPoint_Start;
- curTargetRotation = target.localRotation;
- //得到当前手柄与target以及同轴面上另外一个手柄所在平面的法线
- normal = GetPlaneNormal();
- grabState = 2;
- }
- break;
- case 2:
- if (handInfo.isPinching)
- {
- //算出手柄的实时位置,要加上刚被握住时候的偏移量
- NativeSwapManager.Point3 temp = new NativeSwapManager.Point3(handInfo.rayPoint_Start + offset);
- NativeSwapManager.filterPoint(ref temp, curHandle.GetInstanceID());
- projectedPos = target.position + Vector3.ProjectOnPlane(new Vector3(temp.x, temp.y, temp.z) - target.position, normal);
- target.localRotation = Quaternion.FromToRotation(curHandlePos - target.position, projectedPos - target.position) * curTargetRotation;
- }
- else
- {
- grabState = 0;
- curHandle.GetComponent<Renderer>().material.color = Color.white;
- curHandle = null;
- target = null;
- }
- break;
- }
- }
- //private void OnDrawGizmos()
- //{
- // Gizmos.DrawCube(anotherPoint, Vector3.one * 0.05f);
- // if (target != null)
- // {
- // Gizmos.DrawLine(target.position, curHandlePos);
- // Gizmos.DrawLine(target.position, target.position + normal);
- // Gizmos.DrawLine(target.position, projectedPos);
- // }
- //}
- /// <summary>
- /// 获得射线检测结果,转化成OnTriggerStay和OnTriggerExit
- /// </summary>
- public void OnRayCastHit(Collider other, bool isUI)
- {
- if (enabled)
- {
- //触发和OnTriggerExit基本一致的逻辑
- if (lastRayCastResult != other)
- {
- if (lastRayCastResult != null)
- {
- //OnTriggerExit(lastRayCastResult);
- if (!handInfo.isPinching)
- {
- if (other != null && other.tag == "SpatialHandler" && lastRayCastResult.name == "RotateHandle(Clone)")
- {
- grabState = 0;
- if (curHandle != null)
- {
- curHandle.GetComponent<Renderer>().material.color = Color.white;
- }
- curHandle = null;
- target = null;
- }
- }
- }
- lastRayCastResult = other;
- }
- //触发和OnTriggerStay基本一致的逻辑
- if (other != null)
- {
- if (!handInfo.isPinching && !handInfo.IsCloseContacting)
- {
- if (other.tag == "SpatialHandler" && other.name == "RotateHandle(Clone)")
- {
- grabState = 1;
- curHandle = other.transform;
- curHandle.GetComponent<Renderer>().material.color = Color.red;
- //设置要被旋转的目标物体
- target = other.transform.parent;
- transformUseBounds = target.GetComponent<TransformWithBounds>();
- }
- }
- }
- }
- }
- public void ForOnTriggerEnter(Collider other)
- {
- ForOnTriggerStay(other);
- }
- public void ForOnTriggerStay(Collider other)
- {
- if (enabled && other.name == "RotateHandle(Clone)")
- {
- grabState = 1;
- curHandle = other.transform;
- curHandle.GetComponent<Renderer>().material.color = Color.red;
- //设置要被旋转的目标物体
- target = other.transform.parent;
- transformUseBounds = target.GetComponent<TransformWithBounds>();
- }
- }
- public void ForOnTriggerExit(Collider other)
- {
- if (enabled && other.name == "RotateHandle(Clone)")
- {
- grabState = 0;
- curHandle.GetComponent<Renderer>().material.color = Color.white;
- curHandle = null;
- target = null;
- }
- }
- /// <summary>
- /// 得到当前手柄与target以及同轴面上另外一个手柄所在平面的法线
- /// </summary>
- /// <returns></returns>
- Vector3 GetPlaneNormal()
- {
- bool gotIt = false;
- anotherPoint = Vector3.zero;
- for (int i = 0; i < transformUseBounds.rotate_X.Length; i++)
- {
- if (transformUseBounds.rotate_X[i] == curHandle)
- {
- gotIt = true;
- if (i < 3)
- {
- anotherPoint = transformUseBounds.rotate_X[i + 1].position;
- }
- else
- {
- anotherPoint = transformUseBounds.rotate_X[i - 1].position;
- }
- }
- }
- if (!gotIt)
- {
- for (int i = 0; i < transformUseBounds.rotate_Y.Length; i++)
- {
- if (transformUseBounds.rotate_Y[i] == curHandle)
- {
- gotIt = true;
- if (i < 3)
- {
- anotherPoint = transformUseBounds.rotate_Y[i + 1].position;
- }
- else
- {
- anotherPoint = transformUseBounds.rotate_Y[i - 1].position;
- }
- }
- }
- }
- if (!gotIt)
- {
- for (int i = 0; i < transformUseBounds.rotate_Z.Length; i++)
- {
- if (transformUseBounds.rotate_Z[i] == curHandle)
- {
- gotIt = true;
- if (i < 3)
- {
- anotherPoint = transformUseBounds.rotate_Z[i + 1].position;
- }
- else
- {
- anotherPoint = transformUseBounds.rotate_Z[i - 1].position;
- }
- }
- }
- }
- if (gotIt)
- {
- return Vector3.Cross(curHandlePos - target.position, anotherPoint - target.position);
- }
- else
- {
- return anotherPoint;
- }
- }
- }
- }
|