话不多说,直接上代码
该脚本用于控制Pico手柄,调用事件
这个是根据在导入的sdk的demo中找到的一个脚本进行修改的。
public class Pvr_PicoCtrl : MonoBehaviour {
public GameObject HeadSetController; //pico预设上面的那个篮色的圈
public GameObject controller0; //手柄0 controller0 在pico的预设上面
public GameObject controller1; //手柄1 controller1
private GameObject currentController; // 当前手柄
private GameObject currentGameObject; //当前射线进入的物体
private GameObject lastGameObject; //上一个射线的物体
private Transform head; //头
private Ray ray; //射线
private RaycastHit hit;
private Pvr_ObjectEvent _ObjectEvent; // 射线进入的物体身上的事件脚本
// Use this for initialization
void Start () {
ray = new Ray();
hit = new RaycastHit();
//pico的一些事件,可能是连接头显用到的,demo中用到了,我也用了。
Pvr_ControllerManager.PvrServiceStartSuccessEvent += ServiceStartSuccess;
Pvr_ControllerManager.SetControllerStateChangedEvent += ControllerStateListener;
Pvr_ControllerManager.ControllerStatusChangeEvent += CheckControllerStateForGoblin;
head = HeadSetController.transform.parent.parent.Find("Head");
}
void OnDestroy()
{
Pvr_ControllerManager.PvrServiceStartSuccessEvent -= ServiceStartSuccess;
Pvr_ControllerManager.SetControllerStateChangedEvent -= ControllerStateListener;
Pvr_ControllerManager.ControllerStatusChangeEvent -= CheckControllerStateForGoblin;
}
// Update is called once per frame
void Update () {
if (HeadSetController.activeSelf)
{
//头显未激活 PC操作
//中间的蓝色光圈跟着屏幕旋转
HeadSetController.transform.parent.localRotation = Quaternion.Euler(Pvr_UnitySDKSensor.Instance.HeadPose.Orientation.eulerAngles.x, Pvr_UnitySDKSensor.Instance.HeadPose.Orientation.eulerAngles.y, 0);
ray.direction = HeadSetController.transform.position - head.position;
ray.origin = head.position;
if (Physics.Raycast(ray,out hit))
{
currentGameObject = hit.collider.gameObject;
//射线进入
if (currentGameObject != null && lastGameObject == null)
{
_ObjectEvent = currentGameObject.GetComponent<Pvr_ObjectEvent>();
if (_ObjectEvent != null)
{
_ObjectEvent.OnRayEnter();
}
}
//射线移动
if (currentGameObject != null && lastGameObject != null && currentGameObject !=lastGameObject)
{
_ObjectEvent = currentGameObject.GetComponent<Pvr_ObjectEvent>();
if (_ObjectEvent != null)
{
_ObjectEvent.OnRayEnter();
}
_ObjectEvent = lastGameObject.GetComponent<Pvr_ObjectEvent>();
if (_ObjectEvent != null)
{
_ObjectEvent.OnRayExit();
}
}
//射线滞留
if (currentGameObject != null && lastGameObject != null && currentGameObject == lastGameObject)
{
if (Input.GetMouseButtonDown(1) || Input.GetKeyDown(KeyCode.Joystick1Button0))
{
_ObjectEvent = currentGameObject.GetComponent<Pvr_ObjectEvent>();
if (_ObjectEvent != null)
{
_ObjectEvent.OnRayOnclick();
}
}
lastGameObject = currentGameObject;
_ObjectEvent = null;
}
else
{
currentGameObject = null;
if (lastGameObject != null)
{
_ObjectEvent = lastGameObject.GetComponent<Pvr_ObjectEvent>();
if (_ObjectEvent != null)
{
_ObjectEvent.OnRayExit();
}
}
lastGameObject = null;
_ObjectEvent = null;
}
}
}
else
{
//头显激活 在pico中的操作
if (currentController != null)
{
ray.direction = currentController.transform.forward - currentController.transform.up * 0.25f;
ray.origin = currentController.transform.Find("start").position;
if (Physics.Raycast(ray, out hit))
{
currentGameObject = hit.collider.gameObject;
//射线进入
if (currentGameObject != null && lastGameObject == null)
{
_ObjectEvent = currentGameObject.GetComponent<Pvr_ObjectEvent>();
if (_ObjectEvent != null)
{
_ObjectEvent.OnRayEnter();
}
}
//射线移动
if (currentGameObject != null && lastGameObject != null && currentGameObject != lastGameObject)
{
_ObjectEvent = currentGameObject.GetComponent<Pvr_ObjectEvent>();
if (_ObjectEvent != null)
{
_ObjectEvent.OnRayEnter();
}
_ObjectEvent = lastGameObject.GetComponent<Pvr_ObjectEvent>();
if (_ObjectEvent != null)
{
_ObjectEvent.OnRayExit();
}
}
//射线滞留
if (currentGameObject != null && lastGameObject != null && currentGameObject == lastGameObject)
{
if (Controller.UPvr_GetKeyDown(0,Pvr_KeyCode.TRIGGER) || Controller.UPvr_GetKeyDown(1, Pvr_KeyCode.TRIGGER))
{
_ObjectEvent = currentGameObject.GetComponent<Pvr_ObjectEvent>();
if (_ObjectEvent != null)
{
_ObjectEvent.OnRayOnclick();
}
}
lastGameObject = currentGameObject;
_ObjectEvent = null;
}
else
{
currentGameObject = null;
if (lastGameObject != null)
{
_ObjectEvent = lastGameObject.GetComponent<Pvr_ObjectEvent>();
if (_ObjectEvent != null)
{
_ObjectEvent.OnRayExit();
}
}
lastGameObject = null;
_ObjectEvent = null;
}
}
}
}
}
private void ServiceStartSuccess()
{
if (Controller.UPvr_GetControllerState(0) == ControllerState.Connected ||
Controller.UPvr_GetControllerState(1) == ControllerState.Connected)
{
HeadSetController.SetActive(false);
}
else
{
HeadSetController.SetActive(true);
}
if (Controller.UPvr_GetMainHandNess() == 0)
{
currentController = controller0;
}
if (Controller.UPvr_GetMainHandNess() == 1)
{
currentController = controller1;
}
}
private void ControllerStateListener(string data)
{
if (Controller.UPvr_GetControllerState(0) == ControllerState.Connected ||
Controller.UPvr_GetControllerState(1) == ControllerState.Connected)
{
HeadSetController.SetActive(false);
}
else
{
HeadSetController.SetActive(true);
}
if (Controller.UPvr_GetMainHandNess() == 0)
{
currentController = controller0;
}
if (Controller.UPvr_GetMainHandNess() == 1)
{
currentController = controller1;
}
}
private void CheckControllerStateForGoblin(string state)
{
HeadSetController.SetActive(Convert.ToInt16(state) != 1);
}
}
用于物体绑定事件,挂在需要操作的物体上面,UI可以,比如鼠标时进入放大
public class Pvr_ObjectEvent : MonoBehaviour {
Pvr_ObjectScale objectScale;
UnityEvent onRayEnter; //射线进入
UnityEvent onRayExit; //射线退出
UnityEvent onRayOnclick; //射线点击
void Awake()
{
if (objectScale == null && gameObject.GetComponent<Collider>() == null)
{
gameObject.AddComponent<Pvr_ObjectScale>();
BoxCollider bc = gameObject.AddComponent<BoxCollider>();
bc.size = Vector3.one;
}
objectScale = GetComponent<Pvr_ObjectScale>();
}
public void OnRayEnter()
{
if (onRayEnter != null && objectScale != null)
{
onRayEnter.Invoke();
objectScale.ScaleChange();
}
}
public void OnRayExit()
{
if (onRayExit != null && objectScale != null)
{
onRayExit.Invoke();
objectScale.ScaleReset();
}
}
public void OnRayOnclick()
{
if (onRayOnclick != null)
{
onRayOnclick.Invoke();
}
}
}
用于改变物体大小,UI物体或者3D物体都可以
public class Pvr_ObjectScale : MonoBehaviour
{
Transform tran;
RectTransform rectTran;
public float scale;
Vector3 startScale;
void Awake()
{
if (gameObject.layer == LayerMask.NameToLayer("UI"))
{
rectTran = GetComponent<RectTransform>();
startScale = rectTran.localScale;
}
else
{
tran = GetComponent<Transform>();
startScale = tran.localScale;
}
}
/// <summary>
/// 触发 改变物体的大小
/// </summary>
public void ScaleChange()
{
if (gameObject.layer == LayerMask.NameToLayer("UI"))
{
rectTran.localScale = startScale * scale;
}
else
{
tran.localScale = startScale * scale;
}
}
/// <summary>
/// 触发 还原物体的大小
/// </summary>
public void ScaleReset()
{
if (gameObject.layer == LayerMask.NameToLayer("UI"))
{
rectTran.localScale = startScale;
}
else
{
tran.localScale = startScale;
}
}
}