1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

N高グループ・N中等部Advent Calendar 2024

Day 12

【Unity基礎】オブジェクトを使わずMeshだけで描画する方法。Graphics.DrawMesh

Last updated at Posted at 2024-12-20

はじめに

こんにちは、かき氷です。
見やすさを考えているといつの間にか結局最初の方が良かったとなるタイプの人いますよね。私です。
今回はMeshだけを描画する方法を紹介します。

UnityEngine.Meshの基礎的な部分の紹介です。基礎を終えた方には復習になる内容となっています。

Meshって何?

Meshというのは、 三角形です。
この三角形を自在に変え、何個も組み合わせることで、立体的な形が作られています。

スクリーンショット 2024-12-20 10.53.03.png

↑これがMesh一つだけの状態

↓Meshを大量に繋げた状態
mesh.jpeg 全部三角形!
引用:wikipedia

Graphics.DrawMesh

Meshの描画には、Graphics.DrawMeshを使います。
必要な要素・省略可能な要素ともに数が多いので紹介します。

drawMeshScript.cs
Graphics.DrawMesh(Mesh,Matrix4x4,Material,layer,Camera,submeshIndex,MaterialPropertyBlock,castShadows,receiveShadows,useLightProbes,Transform probeAnchor);

Graphics.DrawMeshに必要な要素

必須要素

要素  概要    
0 Mesh 描画するMeshの頂点座標
1 Vector3 position 描画をする位置※1
2 Quaternion rotation Meshの向く方向
3 Material Meshに適応するmaterial
4 layer Meshを描画するレイヤー※2

オプション

要素  概要    
5 camera Meshが表示されるカメラ
6 submeshIndex(int型) 特定のサブメッシュ
7 MaterialPropertyBlock マテリアルを動的に変化させる場合に適応する
8 影を落とす(bool型) 説明なし
9 影を受ける(bool型) 説明なし
10 光の効果を受ける(bool型) 光の色や明るさを受ける場合適応する※3

※1 この座標を中心に、Meshの座標が適応される。
(Meshのxが100で、座標xが500の場合、Meshは600の位置に置かれる)
※2 レイヤーにあまりこだわりがないなら、0で良い。
※3 赤色の光を受けると、キャラクターやオブジェクトが赤みがかるなど。

Meshを描画する

ではMeshを描画していきましょう。
Meshは、3つの座標から三角形を描画します

スクリーンショット 2024-12-20 11.27.27.png

今回は上記した三角形を描画するコードです。
最もわかりやすく書ける(多分)Matrix4x4.TRSを使った方法で書いています。

今回のコードのGraphics.DrawMeshは必須要素のみです。

DrawMeshScript.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class DrawMeshScript : MonoBehaviour
{
    private Mesh mesh;
    
    public Material material;
    
    void Start()
    {
        mesh = new Mesh();
        
        mesh.vertices = new Vector3[] {
            new Vector3(0, 0, 0),
            new Vector3(100, 0, 0),
            new Vector3(0, 100, 0),
        };

        mesh.triangles = new int[] { 0, 1, 2};
    }
    private void Update() 
    {
        Matrix4x4 matrix = Matrix4x4.TRS(new Vector3(0,0,-10), Quaternion.Euler(0, 0, 0), Vector3.one);

        Graphics.DrawMesh(mesh, matrix, material, 0);
    }

}

では解説していきます。

DrawMeshScript.cs
mesh = new Mesh();

ここでは、まず「mesh = new Mesh();」でMesh型の変数に頂点座標を書き込める状態にしています。

DrawMeshScript.cs
mesh.vertices = new Vector3[] {
    new Vector3(0, 0, 0),
    new Vector3(100, 0, 0),
    new Vector3(0, 100, 0),
};

次に、設計図となるMeshの頂点座標を入れています。

DrawMeshScript.cs
mesh.triangles = new int[] { 0, 1, 2};

ここで、先ほど入れた頂点座標を使い、一つの三角形として保存しています。


DrawMeshScript.cs
Matrix4x4 matrix = Matrix4x4.TRS(new Vector3(0,0,-10), Quaternion.Euler(0, 180, 0), Vector3.one);

Graphics.DrawMesh(mesh, matrix, material, 0);

描画のコードです。

描画は一度すればそのまま残るわけではないので、毎フレーム必要です。
Updateに入れましょう

では、Matrix4x4.TRSの解説をしていきます。

DrawMeshScript.cs
Matrix4x4 matrix = Matrix4x4.TRS(new Vector3(0,0,-10), Quaternion.Euler(0, 0, 0), Vector3.one);

Matrix4x4.TRSは、
位置(transform)・回転(rotation)・拡大縮小(scale)を同時に管理・保存ができる型
です。

これを使って、Graphics.DrawMeshに必要な情報の半分を一つに抑えています。

DrawMeshScript.cs
Graphics.DrawMesh(mesh, matrix, material, 0);

最後です。今までに設定した情報を入れて、描画します。
左から、Mesh・Matrix4x4の座標情報・マテリアル・レイヤーです。

これで完成!

それでは実行してみましょう!

スクリーンショット 2024-12-20 13.38.45.png
...あれ?

何も映らなかったのではないでしょうか。これは、

Meshは裏側の描画がない

というのが原因です。
Videotogif.gif
このように、裏側を見ると、Meshが消えます。

解決策

この問題の解決方法はいくつかありますが、二つ紹介します。

1.Shaderに直接書き込む

描画の根元にあるShaderというところに、裏側も描写させるコードを書く解決策です。
しかし、難易度が高く、処理が増えてしまうデメリットがあります。

2.回転させる

無難ですが、最も簡単な解決策です。
デメリットは、は逆さになるので座標の計算をする場合ややこしくなることです。


今回は、回転を使って解決させます。

DrawMeshScript.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class DrawMeshScript : MonoBehaviour
{
    private Mesh mesh;
    
    public Material material;
    
    void Start()
    {
        mesh = new Mesh();
        
        mesh.vertices = new Vector3[] {
            new Vector3(0, 0, 0),
            new Vector3(100, 0, 0),
            new Vector3(0, 100, 0),
        };

        mesh.triangles = new int[] { 0, 1, 2};
    }
    private void Update() 
    {
        Matrix4x4 matrix = Matrix4x4.TRS(new Vector3(0,0,-10), Quaternion.Euler(0, 180, 0), Vector3.one);

        Graphics.DrawMesh(mesh, matrix, material, 0);
    }

}

変更点

DrawMeshScript.cs
Matrix4x4 matrix = Matrix4x4.TRS(new Vector3(0,0,-10), Quaternion.Euler(0, 180, 0), Vector3.one);

非常に単純で、Y軸の回転を180に変更しました。

実行

スクリーンショット 2024-12-20 10.53.03.png
無事表示されました!

最後に

初記事に少しワクワクしていました。
今回はGraphics.DrawMeshを使ったMeshだけの描画を紹介しました。
基礎的な部分のみの紹介だったため、Graphics.DrawMeshの大半の部分には触れられていません。是非、Meshを深く触ってみてください。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?