【UnityEditor扩展】如何在 Unity 中创建棱柱体(用作VR安全区检测),同时在编辑器插件中实现与撤销/恢复功能

Unity 编辑器扩展:3D 空间中绘制安全区棱柱体(含撤销/恢复/保存/读取)

在虚拟现实(VR)和增强现实(AR)开发中,安全区 是保障用户安全的重要组成部分。通过精确控制用户活动范围,可以避免用户与虚拟环境中的物体发生碰撞,确保舒适的体验。在本篇博客中,我们将实现一个 Unity 编辑器插件 ,用来 在 3D 空间中交互式绘制安全区棱柱体,并支持撤销/恢复、保存/读取功能。

功能概述

主要功能:

  1. 在 XZ 平面中绘制闭合路径:用户通过鼠标点击在 Scene 视图中绘制安全区的边界。

  2. 设置高度范围:可以定义每个安全区的起始高度和结束高度,生成棱柱体。

  1. 撤销与恢复:支持撤销上一个绘制点,并恢复已撤销的点。

  2. 保存与加载:用户可以将绘制的数据保存为 JSON 格式,并从文件中加载。

  3. 生成 Mesh 与 Collider :通过绘制的点生成对应的 Mesh 和 MeshCollider,作为安全区的碰撞检测区域。

应用场景

  • XR 项目开发:在 VR 或 AR 环境中,安全区用于避免用户与虚拟物体发生碰撞或越界。
  • 游戏开发:某些游戏场景中需要限制玩家活动区域,例如在竞技场或战斗区域内定义活动边界。
  • 室内定位与导航:AR 导航应用中,为了确保用户的安全,通常会设置一个虚拟边界。

编辑器扩展插件实现

本教程将介绍如何使用 Unity 编辑器扩展功能,在 3D 空间中绘制一个安全区的棱柱体,并支持实时显示与编辑。

插件结构与设计

插件的核心功能是基于 EditorWindowSceneView 进行实现。我们将创建一个编辑器窗口,通过点击绘制点生成一个闭合的多边形,并根据用户设定的起始高度和结束高度生成棱柱体。

csharp 复制代码
public class LineDrawingTool : EditorWindow
{

    [MenuItem("Tools/线条绘制工具")]
    public static void ShowWindow() { ... }

    private void OnGUI() { ... } // 工具窗口 UI
    private void OnSceneGUI(SceneView sceneView) { ... } // Scene 绘制
    private void GeneratePrismMesh() { ... } // 生成 Mesh
    private void SaveData() { ... } // 保存数据
    private void LoadData() { ... } // 加载数据
}

编辑器窗口 UI

OnGUI 方法中,我们将使用 Unity 的 GUI 系统来构建一个简洁易用的界面。界面包括:

  • 开始/结束绘制:用户可以点击按钮开始绘制或结束当前绘制。
  • 撤销/恢复:支持撤销上一个点,并恢复已撤销的点。
  • 高度设置:输入框允许用户设置安全区的起始高度和结束高度。
  • 保存/加载:可以将绘制的数据保存为 JSON 文件,也可以从文件中加载数据。
  • 生成 Mesh:用户可以点击按钮生成 Mesh 和 MeshCollider。

以下是 OnGUI 方法的核心实现:

csharp 复制代码
private void OnGUI()
{
    GUILayout.Space(10);
    EditorGUILayout.LabelField("安全区棱柱绘制工具", EditorStyles.boldLabel);

    // 绘制状态控制
    if (GUILayout.Button(isDrawing ? "结束绘制" : "开始绘制", GUILayout.Height(30)))
    {
        isDrawing = !isDrawing;
        SceneView.RepaintAll();
    }

    // 撤销/恢复功能
    EditorGUILayout.BeginHorizontal();
    GUI.enabled = points.Count > 0;
    if (GUILayout.Button("撤销", GUILayout.Height(25)))
    {
        // 撤销上一个点
    }
    GUI.enabled = undoStack.Count > 0;
    if (GUILayout.Button("恢复", GUILayout.Height(25)))
    {
        // 恢复上次撤销的点
    }
    GUI.enabled = true;
    EditorGUILayout.EndHorizontal();

    // 高度设置
    EditorGUILayout.LabelField("高度范围", EditorStyles.boldLabel);
    float newStartHeight = EditorGUILayout.FloatField("起始高度", startHeight);
    float newEndHeight = EditorGUILayout.FloatField("结束高度", endHeight);
    if (!Mathf.Approximately(newStartHeight, startHeight) || !Mathf.Approximately(newEndHeight, endHeight))
    {
        startHeight = newStartHeight;
        endHeight = newEndHeight;
        SceneView.RepaintAll();
    }

    // 保存与读取
    if (GUILayout.Button("保存绘制数据"))
    {
        SaveData();
    }
    if (GUILayout.Button("读取绘制数据"))
    {
        LoadData();
    }
}

绘制与生成 Mesh

绘制路径的过程中,我们使用了 SceneView 中的 OnSceneGUI 方法实时监听鼠标输入,并在视图中绘制路径线条和当前点。

在用户设置好高度后,我们将顶面和底面按顶点生成三角形,侧面通过连接相邻的顶点来构建。

csharp 复制代码
private void GeneratePrismMesh()
{
    // 使用顶点生成顶面、底面和侧面
    Mesh mesh = new Mesh();
    mesh.vertices = vertices.ToArray();
    mesh.triangles = triangles.ToArray();
    mesh.RecalculateNormals();

    // 创建 GameObject 和 MeshCollider
    GameObject prism = new GameObject("SafeZone_Prism");
    prism.AddComponent<MeshFilter>().sharedMesh = mesh;
    prism.AddComponent<MeshRenderer>().sharedMaterial = ...;
    prism.AddComponent<MeshCollider>().sharedMesh = mesh;
}

数据保存与加载

为了持久化绘制的数据,我们将其保存为 JSON 格式。这使得用户可以方便地保存并恢复绘制的安全区。

csharp 复制代码
private void SaveData()
{
    LineDrawingData data = new LineDrawingData { points = points, startHeight = startHeight, endHeight = endHeight };
    string json = JsonUtility.ToJson(data, true);
    File.WriteAllText(path, json);
}

private void LoadData()
{
    string json = File.ReadAllText(path);
    LineDrawingData data = JsonUtility.FromJson<LineDrawingData>(json);
    points = data.points;
    startHeight = data.startHeight;
    endHeight = data.endHeight;
    SceneView.RepaintAll();
}

可扩展性与优化建议

这个插件提供了一个基础的框架,可以根据具体需求进一步扩展与优化:

  • 支持多区域绘制:可以支持多个安全区的绘制与管理。
  • 实时网格更新:在编辑过程中实时更新 Mesh 的预览。
  • 吸附网格与参考线:为绘制提供网格对齐和参考辅助线。
  • 导出为 ScriptableObject:将绘制的安全区作为资源保存,便于复用。

结论

通过本教程,你已经掌握了如何在 Unity 编辑器中创建一个交互式的安全区棱柱体绘制工具,并能够实现撤销、恢复、保存与读取功能。这个插件不仅可以帮助开发者快速创建安全区,还能方便地管理和重用已有的区域设置。

希望这篇博客能帮助你提高开发效率。如果你有其他问题或改进建议,欢迎在评论区留言交流!


源码与示例项目

项目源码可以通过以下链接获取(或留言):源码地址

后续还会分享更多关于 Unity 编辑器工具开发、XR 项目优化等内容,敬请关注!

相关推荐
mxwin7 小时前
Unity Shader FLOWMAP岩浆流动制作案例
unity·游戏引擎·shader·uv
小贺儿开发7 小时前
【Arduino与Unity交互探究】01 摇杆模块
科技·unity·游戏引擎·arduino·串口通信·摇杆·硬件交互
山峰哥9 小时前
SQL优化实战:从索引策略到执行计划的极致突破
数据库·sql·性能优化·编辑器·深度优先
Yasin Chen9 小时前
Unity TMP_SDF 分析(三)顶点着色器1
unity·游戏引擎·着色器
mxwin10 小时前
Unity Shader 使用 Noise 图 制作Shader 溶解效果
unity·游戏引擎
mxwin12 小时前
Unity Shader 用 Ramp 贴图实现薄膜干涉效果
unity·游戏引擎·贴图·shader·uv
魔士于安12 小时前
Unity星球资源,八大星球,带fps显示
游戏·unity·游戏引擎·贴图·模型
localbob13 小时前
Pico 4XVR 1.10.13安装包下载与安装教程 ico 4XVR最新版下载、4XVR 1.10.13 APK安装包、Pico VR看电影软件、4XVR完整版安装教程、Pico 4播放器推荐、V
android·vr·vr播放器·vr眼镜播放器下载·pico 4xvr·4xvr下载·pico 4xvr最新版安装包
Pursue Limits13 小时前
人形机器人之VR遥操作
机器人·vr
音源部落13 小时前
Cubase15 R2R/VR一键安装完整版本下载安装Nuendo 14最新版本下载安装支持Win/Mac 双系统版本加104G原厂音源Mac系统不关SIP安装编曲软件Cubase 15.0.10下载
macos·vr·cubase·cubase15·nuendo·nuendo14