【问题标题】:Programmatically define execution order of scripts以编程方式定义脚本的执行顺序
【发布时间】:2022-05-17 18:47:26
【问题描述】:

通过以编程方式将脚本添加到给定的游戏对象,这些脚本会按照它们添加的顺序执行吗?他们的事件会按照添加的顺序运行吗?

void Awake ()
{
    gameObject.AddComponent("Script_1");
    gameObject.AddComponent("Script_2");
}

【问题讨论】:

  • 根据我的经验,似乎按照脚本附加到游戏对象的顺序执行。我已经尝试了好几次,并且已经将它用于大量的非生产脚本。但是,由于没有官方文档,而且事情可能会发生变化,我不会一直指望这项工作。

标签: c# unity3d events


【解决方案1】:

你可以使用属性:

[DefaultExecutionOrder(100)]
public class SomeClass : MonoBehaviour
{
}

【讨论】:

  • 太棒了!如果您担心这没有做任何事情(就像我一样),因为它没有显示在“脚本执行顺序”窗口中,这显然是设计使然:forum.unity.com/threads/…
【解决方案2】:

简短回答:否。但您可以在设置中设置Script Execution Order(菜单:编辑 > 项目设置 > 脚本执行顺序)或从代码中更改:

// First you get the MonoScript of your MonoBehaviour
MonoScript monoScript = MonoScript.FromMonoBehaviour(yourMonoBehaviour);
 
// Getting the current execution order of that MonoScript
int currentExecutionOrder = MonoImporter.GetExecutionOrder(monoScript);
 
// Changing the MonoScript's execution order
MonoImporter.SetExecutionOrder(monoScript, x);
  1. Script Execution Order manipulation

  2. Changing Unity Scripts Execution Order from Code

  3. Change a script's execution order dynamically (from script)

附言这个答案是很久以前写的,在DefaultExecutionOrder 存在之前。除非您正在编写一些编辑器工具来操纵执行顺序,否则 DefaultExecutionOrder 属性可能是更简单/合适的解决方案。

【讨论】:

  • 你的“yourMonoBehaviour”句柄来自哪里?你分配一个新的?这只是返回 null。
  • 通常你在编辑器脚本中做这些事情,所以你可以将你的目标转换为 MonoBehaviour:MonoBehaviour yourMonoBehaviour = (MonoBehaviour)target; 如果你不熟悉编辑器脚本,看看一些教程,例如learn.unity.com/tutorial/editor-scripting
  • ic tnx。还发现 '[DefaultExecutionOrder(100)]' 对我来说是一个更好的解决方案。
【解决方案3】:

我在商店中看到的一些资产,例如 Cinemachine,在 .meta 文件中设置了 executionOrder 属性(例如,MyMonoBehavior.cs.meta)。我已经测试过,这确实有效(例如,将其从 0 更改为 200,然后右键单击并重新导入)。元文件似乎保存在包中,所以如果您要分发资产,将资产包与元一起放在商店中应该可以工作(https://docs.unity3d.com/Manual/AssetPackages.html)。

【讨论】:

  • 这正是我想要的。非常感谢!
【解决方案4】:

如上所述here

默认情况下,不同脚本的 Awake、OnEnable 和 Update 函数按照脚本加载的顺序(任意)被调用。但是,可以使用脚本执行顺序设置修改此顺序。

执行顺序设置参考here

【讨论】:

  • 对,但这并不能回答我关于非任意加载(非随机)的问题。那么,通过 awake 以编程方式加载脚本,它们是否按照添加的顺序运行并继续按该顺序运行?
  • 我认为你没有比这更好的答案了。没有定义它们执行的顺序。除非您使用脚本执行顺序设置修改顺序。执行顺序未定义可能是因为 unity 正在使用多个线程执行它们。在完成前一个函数之后,每个线程可能只是处理下一个尚未开始处理的函数。
【解决方案5】:

您也可以在编辑器脚本中实现这一点。添加在加载时初始化的类并动态设置 MonoScripts Order。

[InitializeOnLoad]
public class SetExecutionOrder{

    static SetExecutionOrder(){
        MonoScript[] scripts = (MonoScript[])Resources.FindObjectsOfTypeAll(typeof(MonoScript));
        int order = -100;  //Set this to whatever order you want
        foreach(MonoScript script in scripts){
            if(script.GetClass() == typeof(MyMonoScriptType)){  //The type of the MonoScript who's order you want to change
                MonoImporter.SetExecutionOrder(script , order);
            }
        }
    }

}

这还将在脚本执行顺序窗口中显示脚本。

【讨论】:

    猜你喜欢
    • 2011-05-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-27
    • 2010-10-07
    • 2017-12-18
    • 1970-01-01
    相关资源
    最近更新 更多