unity3d 我想在Start()中调用的可选方法的最佳实践?

rnmwe5a2  于 2022-11-15  发布在  其他
关注(0)|答案(2)|浏览(126)

我创建了一个名为PlayerComponent的抽象类,用于所有需要与我的PlayerController交互以从中继承的组件。该类包含对PlayerControllerPlayer(负责输入)的引用,我希望通过设置一个方法来添加一些功能,当PlayerController“着陆”时触发该方法。

public abstract class PlayerComponent : MonoBehaviour
{
    protected static PlayerController playerController;
    protected Player player; //the Rewired player

    protected void Start()
    {
        player = ReInput.players.GetPlayer(0);

        if (playerController == null)
            playerController = FindObjectOfType<PlayerController>();

        playerController.onLanding.AddListener(OnPlayerLanding);
    }

    public abstract void OnPlayerLanding();
}

Start()中,我为UnityEvent订阅了一个抽象方法,PlayerController在登陆时调用它。它运行得很好,我很喜欢我的结构,* 但是 * 在实践中,我最终创建了一些根本不需要OnPlayerLanding方法的PlayerComponent。由于它是一个抽象方法,这些PlayerComponent需要有这个空的方法,并且可能通过被调用而占用资源(如果这是真,是吗?)。有没有最佳实践可以让这个方法成为可选的?我是否应该另外安排一个班级,在负责发出登陆呼叫的2个班级之间进行操作?并且只让需要它的组件从它继承?我有点超出了我的舒适区,但我正在努力学习如何做得又好又整洁。

px9o7tmv

px9o7tmv1#

通过虚拟方式创建方法,并根据继承者需要重写该方法

public abstract class SomeClass : MonoBehaviour
    {
        public virtual void Start()
        {
            // Base code
        }

        public virtual void Mehtod()
        {
            //
        }
    }

也将Start()设为虚拟。若要在必要时调用该方法,请使用基实现重写Start()并完成订阅

public abstract class SomeHeir : SomeClass
    {
        protected static PlayerController playerController;

        public override void Start()
        {
            base.Start();

            playerController.onLanding.AddListener(OnPlayerLanding);
        }
    }

您可以虚拟化所有MonoBenaviour方法

ni65a41a

ni65a41a2#

你想用Awake来初始化它自己,而不是用start。如果你只用start来初始化它,并且你依赖于另一个类,你很有可能会出现null异常错误。
Start意味着用于另一个类的依赖关系,因为任何Start方法都将在调用所有awake方法之后被调用。
只需将Awake虚拟化并覆盖它即可。
大多数时候,你会希望订阅OnEnableOnDisable的事件,因为禁用的GameObject仍然会被调用,除非它从来没有打算禁用。
检查Order of execution for event functions

相关问题