团结游戏经理。 脚本只能运行一次

我正在做简单的游戏经理。 我有一个脚本,可以从游戏中的所有场景访问。 加载新场景后,我需要检查其variables的值。 但是我的代码在开始模拟之后只运行一次,而所有场景中都存在具有此脚本的对象。 哪里不对? 加载新场景后为什么不能运行?

在每个Unity项目中,你必须有一个预览场景。

Unity没有“内置”的预载场景是相当混乱的。

他们将在未来增加这个概念。

重复一下,你必须有一个预加载场景。

就这么简单。

这是尝试Unity的新程序员的最大错误!


幸运的是,有一个预加载场景是非常容易的。

步骤1。

制作一个名为“预加载”的场景。 在Build Manager中必须是场景0

在这里输入图像描述

第2步。

在“预加载”场景中,调用一个空的GameObject,例如“__app”。

简单地说,把DontDestroyOnLoad放在'__app'上。

注意:

这是您使用DontDestroyOnLoad 的整个项目中唯一的地方

就这么简单。

在这里输入图像描述

在这个例子中:开发者已经做出了一个单行的DDOL脚本。

把这个脚本放在“__app”对象上。

你再也不用考虑DDOL了。

第3步

你的应用程序将有“一般行为”。 所以,音效,评分等等。

你必须,也只能把你的一般行为放在“_app”上。

这真的很简单。

当然,在项目的任何地方,任何时候,在所有场景中,一般的行为都是可用的

你还能怎么做?

在上面的图像示例中,注意“IAP”(“应用程序内购买”)和其他。

所有的“通常需要的行为” – 音效,评分等等 – 就在那个对象上。

重要…

这意味着 – 当然,

……你的一般行为当然会像普通的一切一样拥有普通的检查员。

你可以使用Unity的所有常用function,你可以使用其他游戏对象。

当然,您可以使用通常的Inspectorvariables(拖动来连接),设置等等。

(事实上​​,假设你已经被雇佣到一个现有的项目上工作,你要做的第一件事就是看一下预压场景,你会看到项目的所有“一般行为”在一个地方。 AI,等等。你会立即看到所有的设置,如Inspectorvariables,语音音量,PlayStore ID等等。

下面是一个例子“音效”的一般行为:

在这里输入图像描述

看起来还有一个“声音在”一般的行为,一个“音乐”的一般行为。

重复。 关于你的“一般”行为。 (声音效果,得分,社交等)这些只能在预载场景中的游戏对象上进行。

不是可选的:没有其他的select!

你完成了。

说实话,这很简单。 实际上没有任何东西!

许多来自其他types的工程师都会永远认识到这一点很简单,因为它非常简单,容易“不可能”。

只要重复一遍:整个问题就是(奇怪的)统一只是简单地忘记了“预装”一个预载场景。 所以出于这个原因,你只需点击添加一个(不要忘记在预加载场景中添加DDOL)。

现在在开发中:

总是从Preload场景开始游戏。

就这么简单。

(一点:你的应用程序几乎肯定会有“早”的场景,例如“闪屏”或“菜单”,注意你不能使用“splash”或“menu”作为预加载场景,有一个单独的预加载场景,预加载场景将加载你的飞溅场景,菜单场景或任何你想要的。)


然后你就会遇到这样的问题:很简单,你可以从你的任何场景的脚本中find“SoundEffects”或“GameManager”。

幸运的是,它很容易 ,它是一行代码。

这是一个非问题:

 Sound sound = Object.FindObjectOfType<Sound>(); Game game = Object.FindObjectOfType<Game>(); 

Awake ,对于任何需要它的脚本来说。

说实话很简单。 这就是它的全部。

Sound sound = Object.FindObjectOfType<Sound>();

由于在线看到的绝对错误的代码示例有100多个,因此出现了巨大的混淆。 另外,新的Unity工程师“不敢相信”这是容易的!

这真的很简单 – 诚实!

Unity忘了添加一个内置的“预加载场景” – 在某个地方像SoundEffects,GameManager等附加你的系统,这真是奇怪。这只是Unity的奇怪之处之一。 所以,你在Unity项目中做的第一件事情就是点击一次来制作一个预载场景。


DylanB问道:“ 在开发过程中 ,每次点击”播放“之前都必须点击预加载场景,这是非常令人讨厌的。

当然,每个团队都有不同的方式来做到这一点。 这是一个简单的例子:

 // this should run absolutely first; use script execution order to do so. // (of course normally never, ever, 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中工作时,你必须“点击播放之前点击预加载场景 – 还有什么可能呢?

@Fattie:感谢所有这些,这太棒了! 有一点,人们正试图通过你,我也会放弃一下:

我们不希望我们的手机游戏中的每一个实例都为每个“全局类”做一个“FindObjectOfType”!

相反,你可以让它立即使用一个静态/单例实例化,而不用去查找它!

就像这样简单:把它写在你想从任何地方访问的类中,其中XXXXX是类的名字,例如“Sound”

 public static XXXXX Instance { get; private set; } void Awake() { if (Instance == null) { Instance = this; } else { Debug.Log("Warning: multiple " + this + " in scene!"); } } 

现在,而不是你的例子

 Sound sound = Object.FindObjectOfType<Sound>(); 

只要简单地使用它,不用看,也没有额外的variables,就像这样,从任何地方:

 Sound.Instance.someWickedFunction();