c# - 统一游戏管理器。脚本只工作一次

标签 c# unity3d

我正在制作简单的游戏管理器。我有一个脚本,可以从游戏中的所有场景访问。我需要在加载新场景后检查其变量的值。但是我的代码在开始模拟后只运行一次,而所有场景中都存在带有此脚本的对象。怎么了?为什么加载新场景后不起作用?

最佳答案

在每个 Unity 项目中,您都必须有一个预加载场景。
Unity 没有“内置”预加载场景,这一点非常令人困惑。
他们将来会添加这个概念。
Fort 现在你必须点击自己添加一个预加载场景。
对于尝试 Unity 的新程序员来说,这是一个最大的误解!

幸运的是,预加载场景非常容易。
第 1 步。
制作一个名为“预加载”的场景。必须是 场景 0 在构建管理器中。
enter image description here
第 2 步。
在“预加载”场景中,创建一个名为“__app”的空游戏对象。
简单地说,把DontDestroyOnLoad在“__app”上。
笔记:
这是整个项目唯一的地方您使用 DontDestroyOnLoad .
就这么简单。
enter image description here
在示例中:开发人员制作了一个单行 DDOL 脚本。
将该脚本放在“__app”对象上。
您永远不必再考虑 DDOL。
步骤 3
您的应用将具有(许多)“一般行为”。因此,诸如数据库连接、音效、评分等。
您必须并且只能将您的一般行为放在“_app”上。
真的就是这么简单。
一般行为是 - 当然 - 在项目的任何地方、任何时间和所有场景中都可用 .
你还能怎么做?
在上面的图像示例中,请注意“Iap”(“应用内购买”)和其他。
您所有的“通常需要的行为”——音效、评分等等——都在那个对象上。
重要的...
这意味着——当然,自然——
...您的一般行为将具有普通的检查员,就像 Unity 中的其他所有内容一样。
您可以使用 Unity 的所有常用功能,这些功能可用于其他所有游戏对象。检查器变量、拖动连接、设置等。
(事实上​​:假设你受雇从事一个现有项目。你要做的第一件事就是看一下预加载场景。你会看到预加载场景中的所有“一般行为”——音效、评分、AI等。您将立即看到所有 设置 作为检查器变量...语音音量,Playstore ID 等)
这是“音效”一般行为的示例:
enter image description here
看起来还有“声音”一般行为和“音乐”一般行为”。
重复。关于你的“一般行为”。 (音效、评分、社交等)这些 只能去在预加载场景中的游戏对象上。
这不是可选的:别无选择!
就这么简单。
有时来自其他环境的工程师会对此感到困惑,因为这似乎“不可能那么容易”。
再说一遍,Unity 只是简单地忘记了“内置”预加载场景。因此,您只需单击即可添加预加载场景。不要忘记添加DDOL。
所以,在开发过程中:
始终从预加载场景开始游戏。
就这么简单。
重要提示:您的应用肯定会有“早期”场景。例子:

  • “闪屏”
  • “菜单”

  • 笔记。投 不能使用启动画面或菜单作为预加载场景。你必须真正拥有 单独的预加载场景 .
    预加载场景然后将加载 您的启动画面或菜单或其他早期场景。

    核心问题:从其他脚本中“找到”那些:
    所以你有一个预加载场景。
    您所有的“一般行为”都只是在预加载场景中。
    您接下来遇到的问题很简单,就是说“SoundEffects”。
    您必须能够从任何脚本、任何游戏对象、任何场景中轻松找到它们。
    幸运的是,这很容易,只需一行代码。
    Sound sound = Object.FindObjectOfType<Sound>();
    Game game = Object.FindObjectOfType<Game>();
    
    Awake 中执行此操作,对于任何需要它的脚本。
    老实说就是这么简单。这里的所有都是它的。Sound sound = Object.FindObjectOfType<Sound>();由于在网上看到的 100 多个绝对错误的代码示例,造成了巨大的困惑。
    真的就是这么简单——诚实!
    奇怪的是 Unity 忘记添加一个内置的“预加载场景”——在某个地方连接你的系统,比如 SoundEffects、GameManager 等。这只是 Unity 的一些奇怪的事情之一。因此,您在任何 Unity 项目中做的第一件事就是单击一次以制作预加载场景。
    就是这样!

    一个细节...
    请注意,如果您真的想输入更少的 (!) 代码行,这非常简单 - 您只需为这些内容中的每一个使用全局!
    这个有详细解释here (您可以使用我流行的 Grid.cs 脚本)和下面的 @Frits 答案。
    (无论您是使用全局变量,还是在需要该特定组件的每个组件中都有一个局部变量,这只是代码风格的问题。在非常不寻常的情况下,“全局”方法可能是高效的(与任何全局变量一样)。)

    DylanB 问道:“ 在开发过程中 每次点击“播放”之前都要点击预加载场景,这很烦人。这可以自动化吗?
    当然,每个团队都有不同的方法来做到这一点。这是一个简单的例子:
    // this should run absolutely first; use script-execution-order to do so.
    // (of course, normally never use the script-execution-order feature,
    // this is an unusual case, just for development.)
    ...
    public class DevPreload:MonoBehaviour
     {
     void Awake()
      {
      GameObject check = GameObject.Find("__app");
      if (check==null)
       { UnityEngine.SceneManagement.SceneManager.LoadScene("_preload"); }
      }
     }
    
    但不要忘记:你还能做什么? 游戏必须从预加载场景开始。 除了点击进入预加载场景,你还能做什么?有人可能会问“启动 Unity 运行 Unity 很烦人——如何避免启动 Unity?!”当然,游戏绝对必须从预加载场景开始——否则怎么办?可以肯定的是,在 Unity 中工作时,您必须“在单击播放之前单击预加载场景”——否则怎么办?

    关于c# - 统一游戏管理器。脚本只工作一次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35890932/

    相关文章:

    c# - 使用自定义 JsonConverter 和自定义 ContractResolver 时出现 StackOverflow 异常

    c# - 如何使用 Haxe 的 C# 参数修饰符?

    c# - 如何在 Unity3D 上为 android 显示 Google Play 游戏 "Welcome Back"toast?

    c# - 在 Visual Studio 中调试时出现“驱动器中没有磁盘”错误

    c# - ASP .NET CORE 找不到包含自定义程序集的文件或程序集

    c# - 在后台线程上创建位图会停止渲染线程

    c# - 统一公共(public)变量未与 gameObject.find 一起显示

    unity3d - 如何避免两个 NavMeshAgent 在 Unity 中相互推开?

    c# - 从 C++ 更新 Texture2D 像素

    android - 过多的字段引用:70613;最大值是65536