【问题标题】:Awake function issues in relation to Singleton与 Singleton 相关的唤醒功能问题
【发布时间】:2021-10-08 00:34:59
【问题描述】:

因此,我正在考虑通过在我的 PlayerController 脚本中重新编写代码来将新的 Unity 输入系统实施到我的游戏中,但很早就陷入了困境。

这是导致问题的代码:

private PlayerInput playerInputController;

private void Awake()
    {
        playerInputController = new PlayerInput();
    }

'Awake()' 位下方出现一条绿色的涂鸦线。

代码本身确实有效,但它会导致许多其他问题,这会导致出现一堆错误消息:

NullReferenceException: Object reference not set to an instance of an object

错误消息都导致我在其他脚本中使用了类似这样的代码行,以从我的 PlayerController 脚本中获取变量和方法:

if (PlayerController.instance.isGroundedPhys)

最后,这是我的单例脚本,因为它可能是相关的,因为它连接到我的 PlayerController 脚本并允许从其他脚本访问它:

    using UnityEngine;

public class Singleton<Instance> : MonoBehaviour where Instance : Singleton<Instance>
{
    public static Instance instance;

    public virtual void Awake()
    {
        if (!instance)
        {
            instance = this as Instance;
        }
        else
        {
            Destroy(gameObject);
        }
    }
}

此位位于我的 PlayerController 脚本的顶部,以便其他脚本可以访问它:

    public class PlayerController : Singleton<PlayerController>
{

我一直在四处寻找,找不到任何人谈论类似的问题。我认为这与我的单例脚本有关,但我无法弄清楚。 :[

[编辑]:

我刚刚发现它也在 Unity 控制台中给出了这个警告:

warning CS0114: 'PlayerController.Awake()' hides inherited member 'Singleton<PlayerController>.Awake()'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword.

【问题讨论】:

  • 在给实际初始化PlayerInput 变量的脚本的Awake 提供机会之前,它只是调用了一个脚本的Awake。以我的拙见,避免使用 Singleton 并学习一些关于 SOLID 原则的知识。 Unite Austin 2017 SOLID talk link。此外,我没有看到,在您粘贴的任何 sn-ps 中,您提到的任何 Singleton 脚本的使用都可能是相关的。
  • 它出现了,而不是调用new PlayerInput (),您需要以某种方式使用此Singleton &lt;Instance &gt; 脚本来获取PlayerInput 实例的引用,您未能做到这一点。
  • 啊,对不起。我认为我不是最擅长收集所有必要信息来获得全貌的人。我有一个 PlayerController 脚本,Singleton 脚本可以从任何其他脚本全局访问该脚本。我这样做的方式是写出“PlayerController.instance.'whatever variable or method I need'” 这是为了避免一直拖拽引用到编辑器。不过,我会看看你发送的链接。谢谢:)
  • 为什么需要这样写: playerInputController = new PlayerInput(); ?
  • 哪个类实现了 Singleton

标签: c# unity3d singleton


【解决方案1】:

PlayerInputMonoBehaviour

不认真,这是“不允许”,您实际上应该在控制台中给您一个相应的警告。

MonoBehaviour“can”/应该只存在于附加到相应的GameObject 并且始终由底层c++ 框架创建。这是 c# 的事情,Unity 无法完全阻止您使用 new 创建一个。

创建MonoBehaviour 实例的唯一有效方法是

  • Instantiate 附加组件的预制件
  • 在现有的GameObject 上使用AddComponent
  • 使用GameObject的构造函数并传入相应的组件类型

或者您可能更愿意使用例如GetComponentFindObjectOfType 以获取对现有 PlayerInput 实例的引用。


然后另一个警告意味着你实施了

public void Awake()
{
    // ...
}

或您的PlayerController 课程中的类似内容。警告已经告诉你应该做什么:

// Use "override" in order to not hide the already existing implementation
// of "Awake" in the base class
public override void Awake()
{
    // Make sure the base class behavior is executed
    // this will initialize the Singleton thing
    base.Awake();

    // ... your additional behavior here
}

【讨论】:

  • 啊,谢谢!它现在似乎可以完美运行,没有任何问题! :D 关于你帖子的第一部分。为什么不能在 MonoBehaviour 中使用“new”? Tbh,我没有遇到“PlayerInput”位的任何问题,它可以正常工作。我遵循了有关如何使用新输入系统的教程,这就是他们的做法。当我在另一个项目中从头开始对其进行测试时,一切都很顺利,而且它也没有任何警告或错误消息。
  • 但是再次感谢您的回答! :D
  • @Aequus 说你可以使用new,因为这只是c# ..但是它会导致不当行为和错误。例如。对固有属性的任何访问,例如gameObjecttransformname 以及像 GetComponent 等任何方法调用都会导致错误,因为它没有附加到 GameObject,因此组件的无效僵尸实例;)
猜你喜欢
  • 1970-01-01
  • 2020-08-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-23
  • 2014-04-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多