Unity3D 编辑器对象锁定工具

在实际的 Unity 项目里,有很多对象是运行时自动生成的、由系统维护的或者依赖复杂逻辑的。如果能随便改它们,很容易导致数据错乱、功能失效,甚至场景崩掉。所以,Unity 提供了 HideFlags 这套机制来"保护现场"。

保护对象

cs 复制代码
HideFlags.NotEditable        // 不能编辑
HideFlags.HideInHierarchy    // 在层级里隐藏
HideFlags.DontSave           // 不保存到场景
HideFlags.HideAndDontSave    // 完全隐身+不保存

组合起来可以实现:

  • "你看不见"

  • "你看得见但不能动"

  • "运行完就消失"

示例代码

cs 复制代码
#if UNITY_EDITOR
using UnityEditor;
#endif
using UnityEngine;

[ExecuteInEditMode]
public class LockTest : MonoBehaviour
{
    void Update()
    {
        if (GameObject.Find("LockedObject") == null)
        {
            GameObject obj = new GameObject("LockedObject");
            obj.hideFlags = HideFlags.None;

            // obj.hideFlags = HideFlags.NotEditable;
        }
    }
}

说明:在编辑器状态(没点 Play)也会执行,每一帧都在检查,如果没有这个物体 → 就创建一个。 编辑器守护进程:

  • 你删掉对象 → 下一帧给你补回来

  • 你改名字 → 逻辑可能失效再生成

  • 你清空场景 → 它又生成

HideFlags 到底是什么

它本质是一个位标记(bitmask),可以理解为给 GameObject 打标签,告诉 Unity:"这个东西该怎么对待"。

通用工具

cs 复制代码
using UnityEditor;
using UnityEngine;

public class EditableControlMenu
{
    // =========================
    // 锁定选中对象(包含子物体)
    // =========================
    [MenuItem("Tools/Lock Selected %#l")] // Ctrl+Shift+L
    static void LockSelected()
    {
        var selection = Selection.gameObjects;

        if (selection.Length == 0)
        {
            Debug.LogWarning("No GameObject selected.");
            return;
        }

        int count = 0;

        foreach (var obj in selection)
        {
            // 避免锁 Prefab Root(重要)
            if (PrefabUtility.IsAnyPrefabInstanceRoot(obj))
            {
                Debug.LogWarning($"Skip Prefab Root: {obj.name}");
                continue;
            }

            count += ApplyToHierarchy(obj, true);
        }

        Debug.Log($"Locked {count} objects.");
    }

    // =========================
    // 解锁选中对象(包含子物体)
    // =========================
    [MenuItem("Tools/Unlock Selected %#u")] // Ctrl+Shift+U
    static void UnlockSelected()
    {
        var selection = Selection.gameObjects;

        if (selection.Length == 0)
        {
            Debug.LogWarning("No GameObject selected.");
            return;
        }

        int count = 0;

        foreach (var obj in selection)
        {
            count += ApplyToHierarchy(obj, false);
        }

        Debug.Log($"Unlocked {count} objects.");
    }

    // =========================
    // 一键解锁所有对象(救命按钮)
    // =========================
    [MenuItem("Tools/Force Unlock ALL")]
    static void UnlockAll()
    {
        var all = Object.FindObjectsOfType<GameObject>(true);
        int count = 0;

        foreach (var obj in all)
        {
            if (obj.hideFlags != HideFlags.None)
            {
                Undo.RecordObject(obj, "Force Unlock");
                obj.hideFlags = HideFlags.None;
                EditorUtility.SetDirty(obj);
                count++;
            }
        }

        Debug.Log($"Force Unlocked {count} objects (ALL).");
    }

    // =========================
    // 核心逻辑:递归处理层级
    // =========================
    static int ApplyToHierarchy(GameObject root, bool lockState)
    {
        int count = 0;

        var transforms = root.GetComponentsInChildren<Transform>(true);

        foreach (var t in transforms)
        {
            var obj = t.gameObject;

            // 已经是目标状态就跳过
            if (lockState && obj.hideFlags == HideFlags.NotEditable)
                continue;

            if (!lockState && obj.hideFlags == HideFlags.None)
                continue;

            Undo.RecordObject(obj, lockState ? "Lock Object" : "Unlock Object");

            obj.hideFlags = lockState ? HideFlags.NotEditable : HideFlags.None;

            EditorUtility.SetDirty(obj);

            count++;
        }

        return count;
    }
}

快捷键

  • Ctrl + Shift + L → 锁定对象

  • Ctrl + Shift + U → 解锁对象

注意事项

  • 仅在 Unity Editor 中有效

  • 不影响打包运行

  • 不建议锁定 Prefab Root

  • Force Unlock 会影响所有隐藏对象,请谨慎使用

获取链接

GitHub 链接

Gitee 链接

飞书云文档

Unity3D 编辑器对象锁定工具

相关推荐
保持当下11 天前
分享一些程序员很棘手但是却又简单的工具
程序员·免费·js·工具
VidDown11 天前
VidDown 工具站:免费、本地优先的开发者工具箱
javascript·编辑器·音视频·视频编解码·视频
VidDown11 天前
显卡处理视频技术详解:从硬解码到 NVENC,GPU 如何让视频处理起飞?
javascript·编辑器·音视频·视频编解码·视频
夜猫逐梦11 天前
【UE基础】03.蓝图与编辑器工作流
编辑器·ue·蓝图·ue编辑器
VidDown11 天前
视频帧率技术详解:从 24fps 到 120fps,帧率如何影响你的观看体验?
网络·网络协议·编辑器·音视频·视频编解码·视频
叶帆11 天前
【YFIOs】用C#开发硬件之设备上云
开发语言·unity·c#
爱就是恒久忍耐11 天前
VSCode里如何比较2个branch
ide·vscode·编辑器
私人珍藏库11 天前
[Android] FX Player-安卓全格式播放器-比MX播放器好用
android·学习·工具·软件·多功能
久数君11 天前
AI三维建模工具“造形家”:地理场景三维化的高效解决方案
unity·glb·ai算法·ai三维建模工具·地图框选·造形家·城市建筑模型
bloglin9999911 天前
vscode中可视化的合并分支,在“合并编辑器中解析”中“与基线进行比较”是什么意思
ide·vscode·编辑器