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 编辑器对象锁定工具

相关推荐
ProcessOn官方账号1 天前
java函数式编程--入门基础
java·编程·函数式编程
魔士于安1 天前
unity 丑陋哥布林 哥布林有humannoid 动画没 带动画
unity·游戏引擎·材质·贴图·模型
codigger1 天前
我用 AI 做完整项目后,总结出一套把需求钉死的工作流
ai·程序员·编程·ai编程·#人工智能
weixin_464078071 天前
ppt转为draw.io方法
编辑器
小贺儿开发2 天前
Unity 家居视频遥控(细节优化)
科技·unity·程序员·udp·视频·工具·通信
淡海水2 天前
13-04-面试-源码级深度追问链
数据结构·unity·面试·c#·游戏引擎·源码·il2cpp
白猫不黑2 天前
网络安全面试题大全:22道高频题附解析与答案
web安全·计算机·网络安全·信息安全·渗透测试·编程·面试题
小小数媒成员2 天前
UGUI 性能优化(详细,全,深入)
开发语言·unity·游戏引擎
白猫不黑2 天前
网络安全和信息安全的区别:全方位解析与学习路径
计算机·网络安全·黑客·信息安全·程序员·渗透测试·编程
林川~013 天前
Unity新输入系统使用笔记
unity·input system