选中ScriptableObject文件时如何在Scene View中绘制Gizmos?
问题:ScriptableObject的Scene View可视化不生效
我希望在编辑模式下可视化ResourceAreas的位置,编写了编辑器工具代码,但选中ResourceAreas ScriptableObject文件后,Scene View中并未显示对应的Gizmos。
编辑器代码
using UnityEngine; using UnityEditor; [CustomEditor(typeof(ResourceAreas))] public class ResourceAreasEditor : Editor { void OnSceneGUI() { ResourceAreas resourceAreas = (ResourceAreas)target; foreach (ResourceArea area in resourceAreas.resourceAreas) { Handles.color = Color.red; Handles.DrawWireDisc(area.center, new Vector3(0,1,0), area.radius); EditorGUI.BeginChangeCheck(); Vector3 newCenter = Handles.PositionHandle(area.center, Quaternion.identity); if (EditorGUI.EndChangeCheck()) { Undo.RecordObject(resourceAreas, "Move Resource Area Center"); area.center = newCenter; EditorUtility.SetDirty(resourceAreas); } } } }
ResourceAreas相关代码
using UnityEngine; [System.Serializable] public class ResourceArea { public string resourceName; public Vector3 center; // 地形空间中的中心点 public float radius; // 资源区域半径 public int resourceCount; } [CreateAssetMenu(fileName = "ResourceAreas", menuName = "ScriptableObjects/ResourceAreas", order = 1)] public class ResourceAreas : ScriptableObject { public ResourceArea[] resourceAreas; }
补充说明
Inspector中已正常显示ResourceAreas的数据:包含多个ResourceArea条目,每个条目有名称输入框、center坐标字段、radius数值框和resourceCount数值框,但Scene View无任何Gizmos显示。
解决方案
ScriptableObject并非场景内的GameObject,默认不会触发OnSceneGUI的绘制逻辑。要实现选中ScriptableObject时在Scene View显示Gizmos,需要修改编辑器代码,通过注册Scene View回调来主动触发绘制:
修改后的编辑器代码:
using UnityEngine; using UnityEditor; [CustomEditor(typeof(ResourceAreas))] [InitializeOnLoad] public class ResourceAreasEditor : Editor { static ResourceAreasEditor() { // 注册Scene View的绘制回调 SceneView.duringSceneGui += DrawResourceAreasInScene; } static void DrawResourceAreasInScene(SceneView sceneView) { // 仅在选中ResourceAreas对象时绘制 var selectedResourceAreas = Selection.activeObject as ResourceAreas; if (selectedResourceAreas == null) return; foreach (ResourceArea area in selectedResourceAreas.resourceAreas) { Handles.color = Color.red; Handles.DrawWireDisc(area.center, Vector3.up, area.radius); EditorGUI.BeginChangeCheck(); Vector3 newCenter = Handles.PositionHandle(area.center, Quaternion.identity); if (EditorGUI.EndChangeCheck()) { Undo.RecordObject(selectedResourceAreas, "Move Resource Area Center"); area.center = newCenter; EditorUtility.SetDirty(selectedResourceAreas); } } } void OnDisable() { // 移除回调避免内存泄漏 SceneView.duringSceneGui -= DrawResourceAreasInScene; } }
额外注意事项
- 确保Scene View顶部的Gizmos按钮处于开启状态
- 检查
center字段的坐标值是否在当前场景的可视范围内(比如如果是地形空间坐标,要确认地形存在且坐标对应)
内容的提问来源于stack exchange,提问作者sdfesgfsef
相关产品推荐
相关产品推荐

