• 使用鼠标左键事件实现VR中的Eye Gaze Input


    1.光标以及光标动画的显示

     1 using System.Collections;
     2 using System.Collections.Generic;
     3 using UnityEngine;
     4 using UnityEngine.UI;
     5 
     6 [ExecuteInEditMode]
     7 public class Pointer : MonoBehaviour
     8 {
     9     public Transform ArrowNormal;
    10     public Image ArrowActive;
    11 
    12     // Use this for initialization
    13     void Start ()
    14     {
    15         ArrowNormal = transform.Find("ArrowNormal");
    16         ArrowActive = transform.Find("ArrowNormal/ArrowActive").GetComponent<Image>();
    17     }
    18 }

    2.头盔相机射线确定光标位置以及点击逻辑的实现

      1 using System.Collections;
      2 using System.Collections.Generic;
      3 using UnityEngine;
      4 using UnityEngine.EventSystems;
      5 using UnityEngine.UI;
      6 
      7 [RequireComponent(typeof(Pointer))]
      8 public class PointerCaster : MonoBehaviour
      9 {
     10     private GameObject currentTarget;
     11     private GameObject lastActivedTarget;
     12     private PointerEventData pointerEventData;
     13 
     14     private Pointer pointer;
     15     [SerializeField]
     16     private float clickedDelta;
     17     private float nextfocusTime;
     18 
     19     // Use this for initialization
     20     void Start ()
     21     {
     22         // 如果没有开启XR的支持关闭些模块
     23         if (!UnityEngine.XR.XRSettings.enabled)
     24             gameObject.SetActive(false);
     25         else
     26         {
     27             pointer = GetComponent<Pointer>();
     28             nextfocusTime = Time.time + clickedDelta;
     29             pointerEventData = new PointerEventData(EventSystem.current);
     30         }
     31     }
     32 
     33     private void SimulateInput(PointerEventData pointerData)
     34     {
     35         List<RaycastResult> raycastResults = new List<RaycastResult>();
     36         EventSystem.current.RaycastAll(pointerData, raycastResults);
     37         if (raycastResults.Count > 0)
     38         {
     39             if (currentTarget == raycastResults[0].gameObject &&
     40                 currentTarget != lastActivedTarget)
     41             {
     42                 // 进度条的展示
     43                 pointer.ArrowActive.fillAmount = Mathf.Lerp(1, 0, (nextfocusTime - Time.time) / clickedDelta);
     44 
     45                 if (currentTarget.GetComponent<Selectable>())
     46                     currentTarget.GetComponent<Selectable>().OnPointerEnter(pointerData);
     47 
     48                 if (Time.time >= nextfocusTime)
     49                 {
     50                     lastActivedTarget = currentTarget;
     51                     // 鼠标左键点击
     52                     if (currentTarget.GetComponent<ISubmitHandler>() != null)
     53                     {
     54                         // 点击后重置[可以进行下一次点击]
     55                         lastActivedTarget = null;
     56                         nextfocusTime = Time.time + clickedDelta;
     57                         currentTarget.GetComponent<ISubmitHandler>().OnSubmit(pointerData);
     58                     }
     59                     else if (currentTarget.GetComponentInParent<ISubmitHandler>() != null)
     60                     {
     61                         // 点击后重置[可以进行下一次点击]
     62                         lastActivedTarget = null;
     63                         nextfocusTime = Time.time + clickedDelta;
     64                         currentTarget.GetComponentInParent<ISubmitHandler>().OnSubmit(pointerData);
     65                     }
     66                 }
     67             }
     68             // 当前对象不是currentTarget
     69             // 或者当前对象已经触发点击[currentTarget=lastActivedTarget]
     70             else
     71             {
     72                 if (currentTarget && currentTarget.GetComponent<Selectable>())
     73                     currentTarget.GetComponent<Selectable>().OnPointerExit(pointerData);
     74 
     75                 if (currentTarget != raycastResults[0].gameObject)
     76                 {
     77                     currentTarget = raycastResults[0].gameObject;
     78                     pointer.ArrowActive.fillAmount = 0;
     79                     nextfocusTime = Time.time + clickedDelta;
     80                 }
     81             }
     82         }
     83         // 没有目标状态重置
     84         else
     85         {
     86             lastActivedTarget = null;
     87             if (currentTarget && currentTarget.GetComponent<Selectable>())
     88                 currentTarget.GetComponent<Selectable>().OnPointerExit(pointerData);
     89 
     90             currentTarget = null;
     91             pointer.ArrowActive.fillAmount = 0;
     92             nextfocusTime = Time.time + clickedDelta;
     93         }
     94     }
     95 
     96     // Update is called once per frame
     97     void Update ()
     98     {
     99         RaycastHit hit;
    100         Ray ray = new Ray(Camera.main.transform.position, Camera.main.transform.forward);
    101         if (Physics.Raycast(ray, out hit, 20))
    102         {
    103             //pointer.ArrowNormal.position = hit.point;
    104             //Debug.LogWarning(hit.point);
    105             var sp = Camera.main.WorldToScreenPoint(hit.point);
    106             pointerEventData.position = sp;
    107             pointerEventData.button = PointerEventData.InputButton.Left;
    108             // 模拟输入处理
    109             SimulateInput(pointerEventData);
    110         }
    111     }
    112 }

    3.射线碰撞面的大小适应

     1 using System.Collections;
     2 using System.Collections.Generic;
     3 using UnityEngine;
     4 
     5 [RequireComponent(typeof(BoxCollider))]
     6 public class ScreenAdapter : MonoBehaviour
     7 {
     8     private BoxCollider bc;
     9     // Use this for initialization
    10     void Start ()
    11     {
    12         bc = GetComponent<BoxCollider>();
    13         bc.size = transform.parent.GetComponent<RectTransform>().sizeDelta;
    14         bc.size += new Vector3(200, 0);
    15     }
    16     
    17     // Update is called once per frame
    18     void Update () {
    19         
    20     }
    21 }

    4.unity3d的层次结构

     

  • 相关阅读:
    POJ 2411 Mondriaan's Dream -- 状压DP
    codeforces 792A-D
    codeforces 796A-D
    Acdream1201 SuSu's Power
    HDU 2818 Building Block
    C# NetStream
    基于Duff's Device的C简易无栈协程实现
    CentOS 多版本 GCC 共存
    2017杭电多校第一场
    2019杭电多校第十场
  • 原文地址:https://www.cnblogs.com/linxmouse/p/9430871.html
Copyright © 2020-2023  润新知