c# - 在不继承 Monobehaviour 的情况下实例化预制件

标签 c# unity3d

我正在尝试为我在 Unity 3D 中制作的游戏制作主脚本。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

class Main
{
    public GameObject ship;

    [RuntimeInitializeOnLoadMethod]
    static void OnRuntimeMethodLoad()
    {
        GameObject player = Object.Instantiate (ship, transform.position, Quaternion.identity) as GameObject;
    }
}

但是,这给了我一个错误:非静态字段、方法或属性“Main.Ship”需要对象引用是否可以在不继承 MonoBehaviour 的情况下实例化对象?

最佳答案

正如前面的答案所解释的,您正在混合实例作用域和类(静态)作用域。

虽然已经提到了几种方法可以导致此脚本以您启动它的方式工作(您可以使用静态资源类来搜索 Assets 的文件名),但我还是建议以相反的方式进行,并使您的类(class)成为 MonoBehaviour。虽然这对于用 c 编写代码并且更喜欢有一个清晰的代码入口点的人来说可能听起来违反直觉,但在许多情况下它非常有用,可以习惯这样一个事实,即您需要添加一个包含您的主要内容的游戏对象在某处编写脚本。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

class ShipInstanceCreator: MonoBehaviour
{
    public GameObject ship;

    void Start()
    {
       GameObject player = Object.Instantiate (ship, transform.position,   transform.rotation) as GameObject;
   }

有什么好处? 第一个也是主要的好处是,从 MonoBehaviour 继承的任何东西都得到 UnityEditor 的完全支持 - 所以你可以获得免费的“检查器”窗口,你可以在其中拖放东西,免费使用 slider 等,你可以获得“启用/禁用”复选框,当启用/禁用状态改变时,你会得到回调,你会得到你的本地转换组件(这通常非常有用),你会得到碰撞等。

Unity 还可以在不手动执行的情况下序列化其状态,这意味着您将获得一个对象的完全定义的生命周期(当程序集的某些部分重新加载而某些部分不重新加载时,它在编辑器中的表现会非常时髦)吨)。

这样的脚本还可以实例化敌舰和小行星(在它自己的变换位置和方向),并且因为它们之间的功能差异可以(并且应该)作为特定于给定预制件的行为来实现,所以不需要您的实例化器类以了解它所实例化的任何其他信息,除了它应该是一个 GameObject

最后,在编写良好的 Unity 项目中很少有“主”类。如果您将职责拆分为单独的组件,并且它们之间的依赖性尽可能少(对 UnityEngine 的依赖性是可以的),则效果最好。您应该编写一个“InstantiatePlayerScript”,而不是“编写主脚本”,而且很可能已经快完成了,您可以继续编写另一个将定义另一种行为的脚本。这就是为什么它们被称为行为。实例化玩家是一种修改场景的行为,它应该像其他对象一样存在于场景中,而不是试图像上帝对象一样“坐在云端”,从高处监督一切。虽然完全有可能编写这样的游戏,但随着复杂性的增加,这种方式变得更加困难。

游戏的某些部分可以制作成全局性的(即 MusicManager - 一次只能播放一首音乐)但对于播放器之类的东西 - 如果有一天你想制作你的多人游戏?虽然单例模式(也就是在某处编写一个主类)在 Unity 中的很多事情上都可以正常工作,但它很容易过度。

关于c# - 在不继承 Monobehaviour 的情况下实例化预制件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56153946/

相关文章:

c# - 在特定位置删除 char,从字符串末尾开始计算

c# - Unity Animator Inspector 中的错误。看不到任何值

c# - 用于 html 解析的正则表达式(在 c# 中)

c# - 如何在 iTextSharp 中像 block 一样渲染 PdfContentByte

c# - 尽管有有效的 Token,为什么我仍会收到未授权的信息?

user-interface - 如何通过脚本访问OnClick事件

c# - 创建 IJob 失败

c# - 无法在 Visual Studio 的 Crystal Report 中加载数据库信息

c# - 异步等待直到加载表单以继续

background - Unity 中的 Kinect 游戏 : How to do background removal