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

如何基于选中GameObject在Scene/Inspector视图创建动态Snap Settings按钮

实现随选中GameObject动态切换的Snap Settings按钮

我完全懂手动切换Snap Settings有多麻烦,尤其是每个对象还要对应不同的预设。下面给你一套简单的Unity解决方案,能让你在Inspector和Scene视图里都能看到当前选中对象专属的Snap按钮,一键切换配置。

步骤1:创建对象专属的Snap配置组件

首先我们需要一个组件,用来存储每个GameObject对应的3种Snap预设。把下面的脚本存为ObjectSnapConfig.cs:

using UnityEngine;

[DisallowMultipleComponent]
public class ObjectSnapConfig : MonoBehaviour
{
    // 每个对象绑定3种Snap预设
    public SnapPreset[] snapPresets = new SnapPreset[3];

    // 定义单个Snap预设的结构
    [System.Serializable]
    public class SnapPreset
    {
        public string presetName = "Snap Preset";
        public Vector3 moveSnap = Vector3.one;
        public Vector3 rotateSnap = new Vector3(15, 15, 15);
        public Vector3 scaleSnap = Vector3.one;
    }
}

把这个组件挂到你的3个目标GameObject上,然后在Inspector里给每个对象配置3组不同的Snap参数(比如移动步长、旋转角度、缩放比例),自定义好预设名称方便识别。

步骤2:编写自定义编辑器实现动态按钮

接下来写一个编辑器脚本,用来绘制动态按钮,并监听选中对象的变化。把下面的脚本存为ObjectSnapConfigEditor.cs,放在Editor文件夹下(没有就新建一个):

using UnityEditor;
using UnityEngine;

[CustomEditor(typeof(ObjectSnapConfig))]
public class ObjectSnapConfigEditor : Editor
{
    private ObjectSnapConfig targetConfig;

    private void OnEnable()
    {
        targetConfig = (ObjectSnapConfig)target;
        // 监听选中对象变化,实时更新按钮显示
        Selection.selectionChanged += RefreshUI;
    }

    private void OnDisable()
    {
        Selection.selectionChanged -= RefreshUI;
    }

    private void RefreshUI()
    {
        Repaint();
        SceneView.RepaintAll();
    }

    // 扩展Inspector面板,显示Snap按钮
    public override void OnInspectorGUI()
    {
        // 先显示默认的配置字段
        DrawDefaultInspector();

        EditorGUILayout.Space();
        EditorGUILayout.LabelField("快速Snap切换", EditorStyles.boldLabel);

        // 遍历当前对象的3种预设,绘制按钮
        for (int i = 0; i < targetConfig.snapPresets.Length; i++)
        {
            var preset = targetConfig.snapPresets[i];
            if (GUILayout.Button(preset.presetName))
            {
                ApplySnapPreset(preset);
            }
        }
    }

    // 在Scene视图绘制悬浮按钮(选中对象时显示)
    [DrawGizmo(GizmoType.Selected)]
    static void DrawSceneSnapButtons(ObjectSnapConfig config, GizmoType gizmoType)
    {
        if (!Selection.Contains(config.gameObject)) return;

        // 在Scene视图右上角绘制按钮区域
        Handles.BeginGUI();
        GUILayout.BeginArea(new Rect(10, 10, 220, 160));
        GUILayout.Label($"[{config.gameObject.name}] Snap预设", EditorStyles.boldLabel);

        foreach (var preset in config.snapPresets)
        {
            if (GUILayout.Button(preset.presetName))
            {
                ApplySnapPreset(preset);
            }
        }

        GUILayout.EndArea();
        Handles.EndGUI();
    }

    // 统一应用Snap预设到Unity编辑器
    private static void ApplySnapPreset(ObjectSnapConfig.SnapPreset preset)
    {
        // 修改Unity全局的Snap配置(存在EditorPrefs里)
        EditorPrefs.SetFloat("MoveSnapX", preset.moveSnap.x);
        EditorPrefs.SetFloat("MoveSnapY", preset.moveSnap.y);
        EditorPrefs.SetFloat("MoveSnapZ", preset.moveSnap.z);

        EditorPrefs.SetFloat("RotateSnapX", preset.rotateSnap.x);
        EditorPrefs.SetFloat("RotateSnapY", preset.rotateSnap.y);
        EditorPrefs.SetFloat("RotateSnapZ", preset.rotateSnap.z);

        EditorPrefs.SetFloat("ScaleSnapX", preset.scaleSnap.x);
        EditorPrefs.SetFloat("ScaleSnapY", preset.scaleSnap.y);
        EditorPrefs.SetFloat("ScaleSnapZ", preset.scaleSnap.z);

        // 刷新Scene视图,让Snap设置立即生效
        SceneView.RepaintAll();
    }
}

使用方式

  1. 给每个需要自定义Snap的GameObject挂上ObjectSnapConfig组件,配置好3组专属的Snap参数;
  2. 选中任意一个配置过的对象:
    • 在Inspector面板底部会看到对应的3个Snap切换按钮;
    • 在Scene视图的右上角也会弹出悬浮按钮区域,显示当前对象的预设;
  3. 点击按钮就能一键切换到该对象对应的Snap设置,完全不需要手动去调编辑器的Snap面板。

这个方案的好处是完全跟随选中对象动态更新,只会显示当前选中对象的专属Snap按钮,完美解决你手动切换的繁琐问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 03:13:45