7080 + 1

ゲームプログラミングの記事を書いてます。

【Unity】GameObjectを配置せずに、オブジェクトを描画する【RenderMesh】

突然ですが、以下の画像を見てください。

シーンに赤い立方体が10個存在しているなんてことないシーンですが、ヒエラルキーには GameObject が3つしかありません。
どういうことでしょうか??

Graphics.RenderMesh

Unity で何かキャラクターなどの3Dモデルを描画しようと思うと、MeshRendererSkinnedMeshRenderer のついた GameObject をシーンに配置しないといけないと思っている方が多いかもしれません。
実は、GameObject を配置しなくてもシーン上に3Dモデルを描画することができます。

実は、 RenderMesh オブジェクトについている、RenderMesh コンポーネントが描画処理をしています。

public class RenderMesh : MonoBehaviour
{
    [SerializeField]
    Mesh _mesh;

    [SerializeField] 
    Material _material;

    [SerializeField, Range(0, 5)]
    float _interval = 3f;

    RenderParams _renderParams;

    void Start()
    {
        _renderParams = new RenderParams(_material);
    }

    void Update()
    {
        var matrix = new Matrix4x4(
            new Vector4(1, 0, 0, 0),
            new Vector4(0, 1, 0, 0),
            new Vector4(0, 0, 1, 0),
            new Vector4(0, 0, 0, 1));

        var row0 = matrix.GetRow(0);
        for (int i = 0; i < 10; i++) {
            matrix.SetRow(0, row0);

            // 描画
            Graphics.RenderMesh(_renderParams, _mesh, 0, matrix);

            // X座標を等間隔にずらして配置
            var c = row0;
            c.w += _interval;
            row0 = c;
        }
    }
}

Graphics.RenderMesh に、描画のパラメータ (RenderParams)とメッシュ、あとは座標を渡すことで、簡単にオブジェクトを描画することができます。

RenderParams

描画時に使うありとあらゆるデータを設定することができます。唯一必要なのはマテリアルくらいかなと思います。ほかにもどのカメラに映すのかなどの設定ができるみたいです。
詳細はリファレンス見たほうが早いかと思います。
docs.unity3d.com

メリット

スクリプトからものを描画できるメリットは、主に以下かと思います。

  • GameObject を Instantiate する必要がないので、パフォーマンス的に早いし、メモリにも優しい
  • GameObject をシーンに配置するわけではないので、シーンに差分が出ない
  • 配置を数学的に制御できる

デメリット

GameObjectを使わないことによるデメリットは結構あります。

  • シーン上で配置をいじることができないし、そもそも選択することができない
  • スキンメッシュアニメーションさせることはできない
  • コンポーネントをつけることができないので、例えば当たり判定などは自前で用意する必要がある

使いどころ

個人的には、あまりゲーム中で使うものではないかもと思いました。どちらかというと、デバッグ用などに使えるかもしれません。
例えば、ゲームを作っていると、デバッグで一部のメッシュだけをハイライトしたくなるということが出てきます。
その時にこれを使えば、シーンにある GameObject を一切いじることなく、またシーンを汚さずにハイライト用のメッシュを描画することができます。
個人的にはシーンに差分が出ないのがメリットとして一番大きいかもと思いました。