到目前为止,我正在学习有关接口和事件的知识,但是我只停留在一个问题上。
在使用C#接口的日子里,我习惯于声明要使用的接口,然后实现相关的方法,并在发生事件时自动获得回调。
例如Unity的IPointerClickHandler:
using UnityEngine; using UnityEngine.EventSystems;
public class Example : MonoBehaviour, IPointerClickHandler {
//Detect if a click occurs
public void OnPointerClick(PointerEventData pointerEventData)
{
//Output to console the clicked GameObject's name and the following message. You can replace this with your own actions for when clicking the GameObject.
Debug.Log(name + " Game Object Clicked!");
} }
现在,在查看有关如何使用事件和接口的示例时,我发现以下示例:
发布者类和接口
using UnityEngine;
using System.Collections;
public class Publisher : MonoBehaviour
{
public delegate void ClickAction();
public static event ClickAction OnClicked;
void Start()
{
OnClicked();
}
}
public interface IBallManager
{
void Teleport();
}
订户类别:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Subscriber : MonoBehaviour, IBallManager
{
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
void OnEnable()
{
Publisher.OnClicked += Teleport;
}
void OnDisable()
{
Publisher.OnClicked -= Teleport;
}
public void Teleport()
{
Debug.Log("EventTriggered");
}
}
我的问题如下:我如何构建无需手动订阅和取消订阅事件的界面?有没有一种方法可以实现一个界面,而不必使用Publisher.OnClicked + = Teleport; &Publisher.OnClicked-=传送;在每个使用IBallManager的类中?只需实现接口并在事件引发时获取自动回调,就像在Unity的IPointerClickHandler中一样。
谢谢!
答案 0 :(得分:2)
您不能自动订阅事件,但是可以将预订代码移至抽象类,并在要实现IBallManager
的每个类中继承它:
public abstract class BaseSubscriber: MonoBehaviour, IBallManager
{
public virtual void OnEnable()
{
Publisher.OnClicked += OnPublisherClicked;
}
public virtual void OnDisable()
{
Publisher.OnClicked -= OnPublisherClicked;
}
protected abstract void OnPublisherClicked();
}
像下面那样在您的具体订阅者中继承它,基类将为您完成订阅工作:
public class Subscriber: BaseSubscriber
{
public override void OnEnable()
{
// Do smth here
base.OnEnable();
}
public override void OnDisable()
{
// Do smth here
base.OnDisable();
}
protected override void OnPublisherClicked()
{
Debug.Log("EventTriggered");
}
}
答案 1 :(得分:1)
我将如何构建无需手动操作的界面 订阅和取消订阅活动?有没有办法实现 界面,而不必使用Publisher.OnClicked + = Teleport;只需实现接口并在事件引发时获取自动回调,就像在Unity的IPointerClickHandler中一样。
是的
您的示例界面:
public interface IClicker
{
void Click();
}
实现界面的类:
public class Clicker : MonoBehaviour, IClicker
{
public void Click()
{
}
}
要调用该函数,请在GameObject中找到具有实现该接口的脚本的脚本,并以GetComponent
获取该接口,如果不是null
,则调用其函数。如果是null
,则该类未实现该接口。
GameObject targetObj = GameObject.Find("Obj with Interface");
IClicker clicker = targetObj.GetComponent<IClicker>();
if (clicker != null)
clicker.Click();
您还可以使您的界面源自IEventSystemHandler
:
public interface IClicker : IEventSystemHandler
{
void Click();
}
然后使用ExecuteEvents.ValidateEventData
验证实现接口的类,并使用ExecuteEvents.Execute
执行事件。这比较困难,但值得一提。