Unity-LeapMotion:如何使用附加的 InteractionBehavior 脚本使用 C# 设置事件

Unity-LeapMotion: How to setup an event with an attached InteractionBehavior script with c#

要通过 LeapMotion 控制器与 Unity 中的对象交互,您需要附加 "IneractionBehavior" 脚本。使用此脚本,您可以使用统一 GUI 创建新的交互事件。

我想要的是生成几个带有附加 InteractionBehavior 脚本的游戏对象,我想通过 C# 代码添加这些类型的事件。

例如,我想自动生成一个带有附加 InteractionBehavior 脚本的对象,并希望根据代码定义该对象通过 BeginContact 变为红色。

我使用: - 统一版本 2019.1.10 - LeapMotion 核心资产 v4.4.0 - LeapMotion InteractionEngine v1.2.0 - HTC Vive Pro

如果可能的话,我想知道如何使用 C# 将交互事件添加到附加的 InteractionBehavior 脚本

这是InteractionBehaviourBeginContact的实现:

public void BeginContact(List<InteractionController> controllers) 
{
    foreach (var controller in controllers) 
    {
        _contactingControllers.Add(controller);

        OnPerControllerContactBegin(controller);
    }

    if (_contactingControllers.Count == controllers.Count) 
    {
        OnContactBegin();
    }
}

如您所见,调用的相应操作是

public Action OnContactBegin;
public Action<InteractionController> OnPerControllerContactBegin;

所以根据您的需要

直接通过脚本添加回调

例如使用

private void Awake()
{
    var interactionBehaviour= objectReference.GetComponent<InteractionBehaviour>();

    // either as Lambda Expression
    interactionBehaviour.OnContactBegin += () =>
        {
            // do something here
        };

    // or with a method
    // use this if you also want to be able to remove callbacks later!
    // it is always save to remove a callback before adding it
    // even if it's not there yet. Makes sure it is only added exactly once
    interactionBehaviour.OnContactBegin -= DoSomething;
    interactionBehaviour.OnContactBegin += DoSomething;
}

// make sure to always remove any callbacks as soon as possible or when they are not needed anymore
private void OnDestroy()
{
    interactionBehaviour.OnContactBegin -= DoSomething;
}


private void DoSomething()
{
    // do something here e.g. turn red
    // for efficiency you would ofcourse move the GetComponent
    // call to Awake as well. Just wanted to keep the example clean
    GetComponent<Renderer>().material.color = Color.red;
}

或者让它更通用

从脚本继承并使用 UnityEvents which bring their own Inspector visiable interface (exactly like the Button.onClick 事件对其进行自定义。

理论上,您可以为每个可用的 Action 添加 UnityEvent。我将只为以上两个添加。

[Serializeable]
public class InteractionControllerEvent : UnityEvent<InteractionController> { }

public class ExtendedInteractionBehaviour : InteractionBehaviour
{
    public UnityEvent OnContactBeginEvent;
    public InteractionControllerEvent OnPerControllerContactBegin;

    // and just as before add those as callbacks to the actions
    private void Awake()
    {
        OnContactBegin -= OnContactBeginInvokeEvent;
        OnContactBegin += OnContactBeginInvokeEvent;

        OnPerControllerContactBegin -= OnPerControllerContactBeginInvokeEvent;
        OnPerControllerContactBegin += OnPerControllerContactBeginInvokeEvent;
    }

    private void OnDestroy()
    {
        OnContactBegin -= OnContactBeginInvokeEvent;
        OnPerControllerContactBegin -= OnPerControllerContactBeginInvokeEvent;
    }

    private void OnContactBeginInvokeEvent()
    {
        OnContactBeginEvent?.Invoke();
    }

    private void OnPerControllerContactBeginInvokeEvent(InteractionController controller)
    {
        OnPerControllerContactBegin?.Invoke(controller);
    }
}

现在您可以通过 Inspector 简单地引用 GameObjects 及其组件和方法,正如您可能从提到的 UI.Button.onClick 事件中了解到的那样(它也是一个 UnityEvent)。

特别是 InteractionControllerEvent 是一个允许使用 dynamic 参数调用的示例,这意味着相应的 InteractionController 引用可以传递给以 InteractionController 作为参数的引用方法。