白泽图

  • 文章
    • Unity渲染
    • Unity项目开发
    • 工具
    • 数学
    • 算法
    • 网站搭建
    • 网络&操作系统
蒋程个人博客
互联网技术经验总结&分享
  1. 首页
  2. Unity项目开发
  3. 正文

常用Gizmos图形封装

2023-08-16 3226点热度 1人点赞 0条评论
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace TBC
{
    public class TBCGizmos
    {
        public enum CapsuleDirection
        {
            XAxis,
            YAxis,
            ZAxis,
        }


        /// <summary>
        /// 线框球体
        /// </summary>
        public static void DrawWireSphere(Matrix4x4 matrix, Vector3 center, float radius, Color color, int thickness = 10)
        {
            var oldColor = Gizmos.color;
            Gizmos.color = color;
            Gizmos.matrix = matrix;
            
            for (var i = 1; i < thickness; i++)
            {
                float progress = i / (float)thickness;
                DrawWireCircle(matrix, center, Vector3.Lerp(Vector3.up, Vector3.right, progress), radius, color);
                DrawWireCircle(matrix, center, Vector3.Lerp(Vector3.up, Vector3.left, progress), radius, color);
                DrawWireCircle(matrix, center, Vector3.Lerp(Vector3.up, Vector3.forward, progress), radius, color);
                DrawWireCircle(matrix, center, Vector3.Lerp(Vector3.up, Vector3.back, progress), radius, color);
            }
            Gizmos.color = oldColor;
        }


        /// <summary>
        /// 线框立方体
        /// </summary>
        public static void DrawWireCube(Matrix4x4 matrix, Vector3 center, Vector3 size, Color color)
        {
            var oldColor = Gizmos.color;
            Gizmos.color = color;
            Gizmos.matrix = matrix;
            Gizmos.DrawWireCube(center, size);
            Gizmos.color = oldColor;
        }


        /// <summary>
        /// 圆
        /// </summary>
        public static void DrawWireCircle(Matrix4x4 matrix, Vector3 center, Vector3 up, float radius, Color color)
        {
            var oldColor = Gizmos.color;
            Gizmos.color = color;
            Gizmos.matrix = matrix;
            up = (up == Vector3.zero ? Vector3.up : up).normalized * radius;
            var forward = Vector3.Slerp(up, -up, 0.5f);
            var right = Vector3.Cross(up, forward).normalized * radius;
            for (var i = 1; i < 26; i++)
            {
                Gizmos.DrawLine(center + Vector3.Slerp(forward, right, (i - 1) / 25f), center + Vector3.Slerp(forward, right, i / 25f));
                Gizmos.DrawLine(center + Vector3.Slerp(forward, -right, (i - 1) / 25f), center + Vector3.Slerp(forward, -right, i / 25f));
                Gizmos.DrawLine(center + Vector3.Slerp(right, -forward, (i - 1) / 25f), center + Vector3.Slerp(right, -forward, i / 25f));
                Gizmos.DrawLine(center + Vector3.Slerp(-right, -forward, (i - 1) / 25f), center + Vector3.Slerp(-right, -forward, i / 25f));
            }
            Gizmos.color = oldColor;
        }


        /// <summary>
        /// 线框胶囊体
        /// </summary>
        public static void DrawWireCapsule(Matrix4x4 matrix, Vector3 center, float radius, float height, Color color, CapsuleDirection direction = CapsuleDirection.YAxis)
        {
            if (height < 0f)
                return;
            if (radius < 0f)
                return;

            Vector3 pos = Vector3.zero;
            Vector3 scale = Vector3.one;
            Vector3 up = Vector3.up;

            // 半径缩放值
            float radiusScale = 1f;
            // 高度缩放值
            float heightScale = 1f;

            switch (direction)
            {
                case CapsuleDirection.XAxis:
                    up = Vector3.right;
                    heightScale = Mathf.Abs(scale.x);
                    radiusScale = Mathf.Max(Mathf.Abs(scale.y), Mathf.Abs(scale.z));
                    break;
                case CapsuleDirection.YAxis:
                    up = Vector3.up;
                    heightScale = Mathf.Abs(scale.y);
                    radiusScale = Mathf.Max(Mathf.Abs(scale.x), Mathf.Abs(scale.z));
                    break;
                case CapsuleDirection.ZAxis:
                    up = Vector3.forward;
                    heightScale = Mathf.Abs(scale.z);
                    radiusScale = Mathf.Max(Mathf.Abs(scale.x), Mathf.Abs(scale.y));
                    break;
            }

            float realRadius = radiusScale * radius;
            height = height * heightScale;
            float sideHeight = Mathf.Max(height - 2 * realRadius, 0f);

            center = new Vector3(center.x * scale.x, center.y * scale.y, center.z * scale.z);
            pos = pos - up.normalized * (sideHeight * 0.5f + realRadius) + center;

            Color oldColor = Gizmos.color;
            Gizmos.color = color;
            Gizmos.matrix = matrix;

            up = up.normalized * realRadius;
            Vector3 forward = Vector3.Slerp(up, -up, 0.5f);
            Vector3 right = Vector3.Cross(up, forward).normalized * realRadius;

            Vector3 start = pos + up;
            Vector3 end = pos + up.normalized * (sideHeight + realRadius);

            // 上下圆
            DrawWireCircle(matrix, start, up, realRadius, color);
            DrawWireCircle(matrix, end, up, realRadius, color);

            // 连接线
            Gizmos.DrawLine(start - forward, end - forward);
            Gizmos.DrawLine(start + right, end + right);
            Gizmos.DrawLine(start - right, end - right);
            Gizmos.DrawLine(start + forward, end + forward);
            Gizmos.DrawLine(start - forward, end - forward);

            for (int i = 1; i < 26; i++)
            {
                // 下部
                Gizmos.DrawLine(start + Vector3.Slerp(right, -up, (i - 1) / 25f), start + Vector3.Slerp(right, -up, i / 25f));
                Gizmos.DrawLine(start + Vector3.Slerp(-right, -up, (i - 1) / 25f), start + Vector3.Slerp(-right, -up, i / 25f));
                Gizmos.DrawLine(start + Vector3.Slerp(forward, -up, (i - 1) / 25f), start + Vector3.Slerp(forward, -up, i / 25f));
                Gizmos.DrawLine(start + Vector3.Slerp(-forward, -up, (i - 1) / 25f), start + Vector3.Slerp(-forward, -up, i / 25f));

                // 上部
                Gizmos.DrawLine(end + Vector3.Slerp(forward, up, (i - 1) / 25f), end + Vector3.Slerp(forward, up, i / 25f));
                Gizmos.DrawLine(end + Vector3.Slerp(-forward, up, (i - 1) / 25f), end + Vector3.Slerp(-forward, up, i / 25f));
                Gizmos.DrawLine(end + Vector3.Slerp(right, up, (i - 1) / 25f), end + Vector3.Slerp(right, up, i / 25f));
                Gizmos.DrawLine(end + Vector3.Slerp(-right, up, (i - 1) / 25f), end + Vector3.Slerp(-right, up, i / 25f));
            }

            Gizmos.color = oldColor;
        }


    }
}

使用Demo

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TBC;

public class GzmosDemo : MonoBehaviour
{
    List<Vector3> m_PosList;
    
    public List<Vector3> posList
    {
        get 
        {
            if (m_PosList == null || m_PosList.Count == 0)
            {
                m_PosList = new List<Vector3>();
                for (int i = 0; i < 10; i++)
                    m_PosList.Add(new Vector3(Random.Range(-7, 7), 0, Random.Range(-7, 7)));
            }
            return m_PosList;
        }
    }

    void OnDrawGizmos()
    {
        TBCGizmos.DrawWireCircle(transform.localToWorldMatrix, posList[0], Vector3.up, 1f, Color.black);

        TBCGizmos.DrawWireCircle(transform.localToWorldMatrix, posList[1], Vector3.left, 0.5f, Color.white);

        TBCGizmos.DrawWireCube(transform.localToWorldMatrix, posList[2], new Vector3(1, 2, 1), Color.red);

        TBCGizmos.DrawWireCapsule(transform.localToWorldMatrix, posList[3], 0.5f, 3f, Color.yellow);

        TBCGizmos.DrawWireCapsule(transform.localToWorldMatrix, posList[4], 1f, 3f, Color.green, TBCGizmos.CapsuleDirection.XAxis);

        TBCGizmos.DrawWireSphere(transform.localToWorldMatrix, posList[5], 1f, Color.blue);
    }


} 

效果图

标签: 暂无
最后更新:2023-08-16

蒋程

这个人很懒,什么都没留下

点赞
< 上一篇
下一篇 >

文章评论

您需要 登录 之后才可以评论

COPYRIGHT © 2023 白泽图. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang

登录
注册|忘记密码?