Unity3D官方VR教学学习笔记之事件event与委托delegate

来源:互联网 发布:人力资源分析软件 编辑:程序博客网 时间:2024/05/17 22:13

3.VR中的交互

VREyeRaycaster类

放入 maincamera 利用 raycast 检测 layer 来进行交互

寻找VRInteractiveItem 进行交互


Physics.Raycast(ray, out hit, m_RayLength, ~m_ExclusionLayers)        

~ 反选layer

VRInteractiveItem interactible = hit.collider.GetComponent<VRInteractiveItem>()

获取RaycastHit 物体的VRInteractiveItem


 private void HandleClick()
        {
            if (m_CurrentInteractible != null)
                m_CurrentInteractible.Click();
        }

利用VRInteractiveItem类 多态来执行获取物体的方法


 private void OnEnable()
        {
            m_VrInput.OnClick += HandleClick;
            m_VrInput.OnDoubleClick += HandleDoubleClick;
            m_VrInput.OnUp += HandleUp;
            m_VrInput.OnDown += HandleDown;
        }

事件系统,把函数委托加入event   算是一种策略设计模式?

  private void OnDisable ()
        {
            m_VrInput.OnClick -= HandleClick;
            m_VrInput.OnDoubleClick -= HandleDoubleClick;
            m_VrInput.OnUp -= HandleUp;
            m_VrInput.OnDown -= HandleDown;
        }

事件系统 OnEnable()和OnDisable() 同时 +=    -= 函数  注册和取消事件函数,防止内存泄漏。

 OnEnable()和OnDisable()   Script Lifecycle 

在该脚本Enable或者Disable时调用



VRInput  类

用来判断GearVR输入, swipes, taps, or double-taps

是一个EventManager


 public enum SwipeDirection
        {
            NONE,
            UP,
            DOWN,
            LEFT,
            RIGHT
        };

利用枚举增强程序可读性


 public event Action<SwipeDirection> OnSwipe;                // Called every frame passing in the swipe, including if there is no swipe.
        public event Action OnClick;                                // Called when Fire1 is released and it's not a double click.
        public event Action OnDown;                                 // Called when Fire1 is pressed.
        public event Action OnUp;                                   // Called when Fire1 is released.
        public event Action OnDoubleClick;                          // Called when a double click is detected.
        public event Action OnCancel;                               // Called when Cancel is pressed.

利用事件和函数委托,对输入与调用方法进行管理

namespace System
{
    public delegate void Action();
}

System.Action 一个函数委托。


C#中  delegate 委托,可以理解为存储 函数的变量 要求函数与委托返回值,参数相同。

delegate void MyDelegate(int num);

MyDelegate myDelegate;

委托创建后,还需要建立委托变量。(委托像个类,需要实例化来使用)

myDelegate =  PrintNum;

利用函数名给委托变量赋值,

委托可以在运行中(runtime)改变,利用一个委托,来调用不同的方法。

同一个委托可以有多个方法。

myDelegate +=  PrintNum;

myDelegate +=  DoubleNum;

myDelegate();

调用委托函数时,委托中注册的所有函数将会调用。

注意!

当委托中没有注册函数但调用时很危险的,再调用前要检查是否为空。

if (myDelegate != null)

{

myDelegate();

}


事件Event 是一种特殊的委托,用于当某个触发或其他类发生某个事件来进行响应。

是一种 public multicast delegate   是一种 广播系统  broadcast system  观察者模式

当事件发生,调用event ,调用event中注册的方法。

EventManager 用于创建event 中注册的 delegate 函数类型,

public delegate void MyDelegate();

public static event MyDelegate OnClicked;

static可以使事件直接调用,不需要实例化类。

与委托相同,事件函数的注册与取消需要同时,

事件系统 在OnEnable()和OnDisable()中 同时 +=    -= 函数  注册和取消事件函数,防止内存泄漏。

在EventManager 中编写事件触发的逻辑,和调用事件

EventManager 不需要知道所执行的方法是什么

  if(GUI.Button(new Rect(Screen.width / 2 - 50, 5, 100, 30), "Click"))        {            if(OnClicked != null)                OnClicked();        }
在其他类中 时把所需方法注册给事件,等待调用。 


比较public static event 与 public delegate

event的好处是更加安全,在event使用时,其他类只可以注册或取消event中的函数,

而对delegate可以,其他类可以随意调用delegate中所有的方法。


在类中没声明权限的变量,默认为private


   public float DoubleClickTime{ get { return m_DoubleClickTime; } }

没能理解C#中这么写得用意,

创建一个属性,属性只有get,为只读

但是这个属性并没有实际用,程序中用m_DoubleClickTime,

应该是为了其他类获取该类信息用



VRInteractiveItem 类

事件管理器,监听者模式,等待VREyeRaycaster 触发事件事件


对于VREyeRaycaster类如何在runtime改变所注册的函数!

1.OnEnable()和OnDisable() 只会调用一次

private void OnEnable()
        {
            m_VrInput.OnClick += HandleClick;
            m_VrInput.OnDoubleClick += HandleDoubleClick;
            m_VrInput.OnUp += HandleUp;
            m_VrInput.OnDown += HandleDown;
        }

调用时,是把HandleClick 函数注册给Input 中的OnClick  event

2.    当 输入 Click 时,就会调用HandleClick()函数

private void HandleClick()
        {
            if (m_CurrentInteractible != null)
                m_CurrentInteractible.Click();
        }

而,HandleClick()  永远执行 m_CurrentInteractible.Click();

所以 在Update()中 动态修改m_CurrentInteractible,就可以得到所要执行不同的函数。


真正改变的不是所注册给Input event 的函数,而是执行函数时所委托的不同的方法。

通过动态改变 m_CurrentInteractible类 所实时调取的实例对象,来获得不同方法,从而实现动态改变所执行的函数。



总结: 要自己动手去写代码!!!写代码!!!写代码!!! 很重要。 

看的同时要思考,思考很重要。但有些问题思考不出来的时候,自己动手写一下 试验一下,就会有结果了。






0 1
原创粉丝点击