开发者社区> jamesjxiao> 正文

Scene视图辅助线绘制

简介:   有时候需要在Scene视图中绘制一些辅助线,方便进行一些编辑的工作,可以通过如下类和函数完成:   绘制辅助线,相关类:   Gizmos类:用于在Scene视图中绘制调试信息或辅助线,这些辅助线只有在Scene中能看到,Game视图中看不到。
+关注继续查看

  有时候需要在Scene视图中绘制一些辅助线,方便进行一些编辑的工作,可以通过如下类和函数完成:

  绘制辅助线,相关类:

  Gizmos类:用于在Scene视图中绘制调试信息或辅助线,这些辅助线只有在Scene中能看到,Game视图中看不到。

  Handles类:绘制各种东西,可以绘制一些3D gizmo、2D GUI、进行坐标系统转换等。

  相关函数(MonoBehaviour类):

  OnDrawGizmos:每帧调用,所绘gizmos可用于对对应物体拾取选中;

  OnDrawGizmosSelected :在物体被选中时绘制。

  下面的代码用于绘制一个Sphere的辅助线:

 

using UnityEngine;
using System.Collections;

#if UNITY_EDITOR
using UnityEditor;
#endif

public class CylinderHelper : MonoBehaviour 
{

    public void OnDrawGizmos()
    {
        Gizmos.color = Color.blue;
        Gizmos.DrawSphere(transform.position, 0.3f);

#if UNITY_EDITOR
        Handles.color = Color.blue;
        Handles.ArrowCap(0, transform.position, transform.rotation, transform.localScale.z);
        Handles.Disc(transform.rotation, transform.position, Vector3.up, transform.localScale.z * 0.5f, false, 1);
#endif

    }

    public void OnDrawGizmosSelected()
    {
#if UNITY_EDITOR
        Handles.color = new Color(1f, 0f, 0f, 0.2f);
        Handles.DrawSolidDisc(transform.position, Vector3.up, transform.localScale.z * 0.5f);
#endif
    }

}

  未选中和选中的效果图分别如下所示:

未选中:       选中:

  这其中有一个问题值得一提的,看绘制立方体的接口:

  public static void DrawCube(Vector3 center, Vector3 size);

  可以看出参数值传入了位置和缩放,没有旋转参数,也就是该函数不支持旋转,咋办呢,不着急,可以通过设置Gizmos.matrix或Handles.matrix来实现:

public class CubeHelper : MonoBehaviour 
{
    public void OnDrawGizmos()
    {
        Gizmos.color = Color.blue;
        Gizmos.DrawSphere(transform.position, 0.3f);

        // 设置旋转矩阵
        Matrix4x4 rotationMatrix = Matrix4x4.TRS(Vector3.zero, transform.rotation, Vector3.one);
        Gizmos.matrix = transform.localToWorldMatrix;
        // 在Local坐标原点绘制标准尺寸的对象
        Gizmos.color = new Color(1f, 0f, 0f, 0.8f);
        Gizmos.DrawCube(Vector3.zero, Vector3.one);
        Gizmos.color = Color.black;
        Gizmos.DrawWireCube(Vector3.zero, Vector3.one);
        
#if UNITY_EDITOR
        Handles.color = Color.blue;
        Handles.ArrowCap(0, transform.position, transform.rotation, transform.localScale.x);
#endif
    }        

}

  上面的代码支持Gizmos的旋转,原理很简单,不赘述。

   Handles类也支持手动设置变换矩阵,我们再来看一个稍微复杂点的例子。在使用NavMeshObstacle时,因为阻挡区域是一个圆柱体形状(cylinder),在给这个cylinder绘制辅助线时,最合适的是Handles.CylinderCap函数。但该函数默认绘制的圆柱体和碰撞区域是不吻合的,不只是大小、位置,宁方向都不一致,所以这里面要做一些变换,代码如下所示:

using UnityEngine;
using System.Collections;

#if UNITY_EDITOR
using UnityEditor;
#endif

// NavMesh阻挡物的绘制
[ExecuteInEditMode]
public class ObstacleHelper : MonoBehaviour 
{
    private NavMeshObstacle obstacle;

    void Start()
    {
        obstacle = transform.GetComponent<NavMeshObstacle>();
    }

    public void OnDrawGizmos()
    {
#if UNITY_EDITOR

        Handles.color = new Color(Color.blue.r, Color.blue.g, Color.blue.b, 0.5f);

        // 圆柱体网上平移height * 0.5
        Vector3 vecUpOffset = transform.TransformDirection(transform.up);
        vecUpOffset.Normalize();
        vecUpOffset *= obstacle.height * 0.5f * transform.lossyScale.y;

        // 缩放,只能绘制圆形不能绘制椭圆
        Vector3 vecScale = Vector3.one;
        vecScale.x = Mathf.Max(transform.lossyScale.x, transform.lossyScale.z);     
        vecScale.y = vecScale.x;
        vecScale.z = transform.lossyScale.y * obstacle.height;
        // 乘以碰撞半径
        vecScale.x *= obstacle.radius * 2f;
        vecScale.y *= obstacle.radius * 2f;

        // 设置变换矩阵
        Matrix4x4 cylinderMatrix = Matrix4x4.TRS(transform.position + vecUpOffset, transform.rotation * Quaternion.Euler(90f, 0f, 0f), vecScale);
        Handles.matrix = cylinderMatrix;
        Handles.CylinderCap(0, Vector3.zero, Quaternion.identity, 1f);
        Handles.matrix = Matrix4x4.identity;

#endif
    }    

}

  效果图如下所示,辅助线可以自由适应gameobject和Obstacle参数的变化:

        

  上面的代码一眼很难看懂,所以可以逐个变换来理解。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
自定义 View | 画板
自定义 View | 画板
44 0
自定义 View | 时间轴
自定义 View | 时间轴
49 0
Core Animation -图层与视图
Core Animation -图层与视图
15 0
Blender突然无法平移视图
Blender突然无法平移视图
805 0
136.绘制正多边形
136.绘制正多边形
22 0
SwiftUI—如何给图像视图添加遮罩以突出主题
SwiftUI—如何给图像视图添加遮罩以突出主题
268 0
SwiftUI—如何对图像视图进行缩放和旋转
SwiftUI—如何对图像视图进行缩放和旋转
460 0
Blender视图渲染知识
Blender视图渲染知识
771 0
【QT】图形视图、动画框架
【QT】图形视图、动画框架
160 0
canvas绘制折线路径动画
canvas绘制折线路径动画
236 0
GDI+——使用Graphics类绘制基本图形
GDI+——使用Graphics类绘制基本图形
229 0
openlayers5之view缩放定位
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/gisdoer/article/details/81902386 openlayer...
1329 0
3.3 自定义控件基础 之 View的绘制
当测量好了一个View之后,我们就可以简单地重写onDraw()方法,并在Canvas对象上来绘制所需要的图形。首先我们来了解一下利用系统2D绘图API所必须要使用到的Canvas对象。
622 0
View的绘制过程
View的绘制过程从Activity.setContentView开始经过如下方法: Activity.setContentView—>PhoneWindow.
914 0
+关注
jamesjxiao
游戏领域耕耘者~
文章
问答
视频
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载