Unity Action的解耦类
我在学习Unity,想知道如何避免依赖。我有这两个类,其中一个会生成一个事件:
public class ClickController : MonoBehaviour
{
public static event Action<ClickController> OnClickControllerEvent; // new
private void Update()
{
if (Input.GetMouseButtonDown(0))
OnLeftClick();
}
private void OnLeftClick()
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{
Debug.Log("The cube was clicked! Notifying subscribers!");
if (OnClickControllerEvent != null) // new
OnClickControllerEvent(this);
}
}
}
另一个类用于监听该事件:
public class HealthController : MonoBehaviour
{
[SerializeField] private int minHealth = 0;
[SerializeField] private int maxHealth = 100;
private int health = 100;
private void OnEnable() // new
{
ClickController.OnClickControllerEvent += TakeDamage;
}
private void OnDisable() // new
{
ClickController.OnClickControllerEvent -= TakeDamage;
}
private void TakeDamage(ClickController clickController) // changed
{
health -= 10;
if (health <= 0)
Debug.Log("I'm dead now! :(");
}
}
在这个示例中,类 HealthController 需要知道类 ClickController:
ClickController.OnClickControllerEvent += TakeDamage;
为了避免这种情况,我尝试使用一个接口:
using System;
interface IClickInterface
{
public static event Action OnClickControllerEvent;
}
但接口不支持静态成员。
让 HealthController 类知道 ClickController 类可以吗?
或者,还有其他实现方式吗?
解决方案
如果你使用的是静态事件,其实很难再有较高的抽象层。
静态事件也是一种全局变量,因此可变全局状态的所有缺点同样适用于静态事件。因此,只有在你绝对确定只会存在一个这样的事件时,才推荐使用这种做法。
标准做法是避免使用静态变量,而改用依赖注入,即类似如下的做法:
interface IClickInterface
{
event Action OnClickControllerEvent;
}
public class ClickController : MonoBehaviour, IClickInterface
{
public event Action OnClickControllerEvent;
private void OnLeftClick()
{
...
OnClickControllerEvent?.Invoke()
}
}
public class HealthController(IClickInterface clickController) : MonoBehaviour
{
...
private void OnEnable() => clickController.OnClickControllerEvent += TakeDamage;
private void OnDisable() => clickController.OnClickControllerEvent -= TakeDamage;
}
这种做法允许在需要时将 ClickController 替换为其他类。
你也可以考虑使用依赖注入容器来简化所有对象的创建。有几种替代方案,下面是一些示例:
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。