You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity打开项目时如何仅执行一次脚本 避免停止播放后重复触发

问题根因

原代码重复执行的核心原因是Unity默认开启*域重载(Domain Reload)*机制:每次进入/退出播放模式、脚本编译完成时,编辑器会重置所有脚本的运行时状态,重新执行所有标记[InitializeOnLoad]类的静态构造函数,原逻辑没有跨域的状态标记,会重复把初始化逻辑绑定到EditorApplication.update回调上,导致每次退出播放模式后面板重复弹出。

修复实现

用Unity提供的SessionState做会话级标记即可解决问题,该存储的生命周期和当前编辑器打开项目的会话绑定,不会因为域重载、脚本编译丢失数据,关闭编辑器/切换项目时自动重置,完全匹配「仅项目打开加载时执行一次」的需求。

using UnityEditor;

[InitializeOnLoad]
public class PackageInitAutorun
{
    private const string InitDoneFlag = "CustomPackage_InitPanelExecuted";

    static PackageInitAutorun()
    {
        // 本次会话已经执行过初始化,直接跳过
        if (SessionState.GetBool(InitDoneFlag, false)) return;
        
        EditorApplication.update += RunOnceOnProjectLoad;
    }

    private static void RunOnceOnProjectLoad()
    {
        EditorApplication.update -= RunOnceOnProjectLoad;
        // 写入会话标记,后续域重载不会再触发初始化逻辑
        SessionState.SetBool(InitDoneFlag, true);
        
        // 自定义初始化面板逻辑
        Panel.Init();
    }
}
注意事项
  • 不要用普通静态变量做执行标记:静态变量会在域重载时被重置,无法跨域保留状态,和原方案一样会出现重复执行问题
  • 不要用EditorPrefs做标记:EditorPrefs数据会持久化到本地磁盘,下次启动Unity打开项目时标记仍然存在,会导致初始化面板永远不弹出
  • 如果关闭了Unity的域重载功能(Enter Play Mode Options里禁用Reload Domain),该方案依然可以正常工作

内容的提问来源于stack exchange,提问作者KiynL

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 12:27:24