うにてぃブログ

主にUnityとC#に関する記事を書いていきます

【Unity】選択したオブジェクトの持つ法線をScene上に表示する拡張

デバッグ用に法線を見たいことがあったので選択したオブジェクトの法線を表示する拡張を作成

MeshFilter と SkinnedMeshRenderer に対応してみました
が SkinnedMeshRenderer は正しい位置に法線が表示されない場合があるのですが原因は不明

※頂点数が多いと重くなるのですが、それはどうしようもないのでPCのスペックを上げてください

f:id:hacchi_man:20200520235321p:plain:h300f:id:hacchi_man:20200520235332p:plain:h300

f:id:hacchi_man:20200520235358p:plain:h300

using UnityEditor;
using UnityEngine;

public class EditorNormalDrawer
{
    [DrawGizmo(GizmoType.Selected)]
    private static void DrawGizmo(MeshFilter meshFilter, GizmoType type)
    {
        Draw(meshFilter.sharedMesh, meshFilter.transform);
    }

    [DrawGizmo(GizmoType.Selected)]
    private static void DrawGizmo(SkinnedMeshRenderer meshRenderer, GizmoType type)
    {
        Draw(meshRenderer.sharedMesh, meshRenderer.transform);
    }

    private static void Draw(Mesh mesh, Transform transform)
    {
        if (mesh.normals.Length != mesh.vertices.Length)
            return;

        var rotation = transform.rotation;
        var position = transform.position;
        var scale = (transform.localScale.x + transform.localScale.y + transform.localScale.z) / 3;

        Gizmos.color = Color.red;
        for (var i = 0; i < mesh.vertices.Length; i++)
        {
            var rotatePos =rotation * mesh.vertices[i];
            for (var j = 0; j < 3; j++)
                rotatePos[j] *= transform.localScale[j];

            Gizmos.DrawLine(position + rotatePos, position + rotatePos + mesh.normals[i] * 0.1f);
        }
    }
}