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

如何在Unity Inspector窗口中显示可随变量变化的图表?

在Unity Inspector中实现动态后坐力图表的方法

方法一:自定义Editor扩展(最灵活)

这是完全贴合需求的方案,直接在Inspector内绘制随变量实时更新的图表,步骤如下:

  1. 编写后坐力数据脚本
    先创建存储后坐力曲线和实时子弹计数的脚本:

    using UnityEngine;
    
    [System.Serializable]
    public class RecoilData
    {
        public AnimationCurve recoilCurve; // 定义后坐力随子弹数变化的曲线
        [HideInInspector] public int currentBulletCount; // 当前已发射子弹数
    }
    
    public class WeaponRecoil : MonoBehaviour
    {
        public RecoilData recoilSettings;
    
        // 调用此方法模拟开枪
        public void FireBullet()
        {
            recoilSettings.currentBulletCount++;
            // 这里添加你的后坐力应用逻辑
        }
    }
    
  2. 编写自定义Editor脚本
    在项目的Editor文件夹下创建WeaponRecoilEditor.cs,用Unity的编辑器API绘制实时图表:

    using UnityEditor;
    using UnityEngine;
    
    [CustomEditor(typeof(WeaponRecoil))]
    public class WeaponRecoilEditor : Editor
    {
        private WeaponRecoil targetRecoil;
        private Rect chartRect = new Rect(10, 50, 300, 200); // 图表的显示区域
    
        private void OnEnable()
        {
            targetRecoil = (WeaponRecoil)target;
        }
    
        public override void OnInspectorGUI()
        {
            // 先绘制默认Inspector内容
            DrawDefaultInspector();
    
            // 图表标题
            GUILayout.Label("实时后坐力图表", EditorStyles.boldLabel);
            // 获取自适应的绘制区域
            chartRect = GUILayoutUtility.GetRect(300, 200);
    
            // 绘制图表背景
            EditorGUI.DrawRect(chartRect, new Color(0.2f, 0.2f, 0.2f, 0.5f));
    
            // 绘制坐标轴
            Handles.color = Color.white;
            Handles.DrawLine(new Vector3(chartRect.x, chartRect.yMax), new Vector3(chartRect.xMax, chartRect.yMax)); // X轴(子弹数)
            Handles.DrawLine(new Vector3(chartRect.x, chartRect.yMax), new Vector3(chartRect.x, chartRect.y)); // Y轴(后坐力强度)
    
            // 坐标轴标注
            GUI.Label(new Rect(chartRect.xMax - 30, chartRect.yMax + 5, 30, 20), "子弹数");
            GUI.Label(new Rect(chartRect.x - 30, chartRect.y + 80, 30, 20), "后坐力");
    
            // 绘制曲线和实时点
            if (targetRecoil.recoilSettings.recoilCurve != null)
            {
                AnimationCurve curve = targetRecoil.recoilSettings.recoilCurve;
                Vector2 prevPoint = Vector2.zero;
                bool isFirstPoint = true;
    
                // 采样曲线点绘制连线
                for (float x = curve.keys[0].time; x <= curve.keys[curve.length - 1].time; x += 0.5f)
                {
                    float y = curve.Evaluate(x);
                    // 将曲线坐标转换为Inspector窗口的像素坐标
                    Vector2 currentPoint = new Vector2(
                        chartRect.x + (x / curve.keys[curve.length - 1].time) * chartRect.width,
                        chartRect.yMax - (y / curve.keys[curve.length - 1].value) * chartRect.height
                    );
    
                    if (!isFirstPoint)
                    {
                        Handles.DrawLine(prevPoint, currentPoint);
                    }
                    prevPoint = currentPoint;
                    isFirstPoint = false;
                }
    
                // 绘制当前子弹数对应的后坐力红点
                if (targetRecoil.recoilSettings.currentBulletCount > 0)
                {
                    float currentX = targetRecoil.recoilSettings.currentBulletCount;
                    float currentY = curve.Evaluate(currentX);
                    Vector2 currentPoint = new Vector2(
                        chartRect.x + (currentX / curve.keys[curve.length - 1].time) * chartRect.width,
                        chartRect.yMax - (currentY / curve.keys[curve.length - 1].value) * chartRect.height
                    );
    
                    Handles.color = Color.red;
                    Handles.DrawSolidDisc(currentPoint, Vector3.forward, 4f);
                    // 标注当前数值
                    GUI.Label(new Rect(currentPoint.x + 5, currentPoint.y - 15, 100, 20), 
                        $"[{currentX}, {currentY:F2}]");
                }
            }
    
            // 重置子弹计数按钮
            if (GUILayout.Button("重置子弹计数"))
            {
                targetRecoil.recoilSettings.currentBulletCount = 0;
            }
        }
    }
    
  3. 使用效果
    将WeaponRecoil挂载到武器对象上,在Inspector中设置recoilCurve(比如X轴范围0-20对应20发子弹,Y轴0-5对应后坐力强度),每次调用FireBullet()方法时,图表会自动更新红色圆点,实时显示当前后坐力数值。

方法二:利用Unity GraphView(进阶交互)

如果需要支持缩放、拖拽等交互功能,可以用Unity的GraphView框架开发自定义Editor窗口,适合有编辑器开发经验的开发者,实现更专业的图表界面。

方法三:轻量插件替代

如果不想编写代码,可在Unity Asset Store选择免费轻量插件(如Inspector Graph类工具),直接绑定变量生成动态实时图表,无需自行编写Editor逻辑。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 21:15:31