Study Works

YuukiHiraiの勉強したものを上げていきます。

UnityでSkinnedMeshRenderer残像表現

UnityでBakeMeshを使った残像表現を紹介します。

注意:とてもボトルネックになりやすいやり方なので注意してください

youtu.be

1、SkinnedMeshRendererコンポーネントを追加したGameObjectを作成します。

f:id:yuukihirai0331:20190309131205p:plain

そして、これをプレハブ化させます。
これが主に残像のオブジェクトになるため、残像っぽいマテリアル(半透明系)をMaterialsに入れてください。

2、スクリプトを作成

BakeMesh.cs

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

public class BakeMesh : MonoBehaviour
{
    [SerializeField]
    SkinnedMeshRenderer BaseMeshObj;    // ベイクする元のオブジェクト

    [SerializeField]
    GameObject BakeMeshObj;            // ベイクしたメッシュを格納するGameObject

    // BakeMeshObjをインスタンスした際のSkinnedMeshRendererリスト
    List<SkinnedMeshRenderer> BakeCloneMeshList;

    const int CloneCount = 4;       // 残像数
    const int FlameCountMax = 4;    // 残像を更新する頻度
    int FlameCount = 0;

    void Start()
    {
        BakeCloneMeshList = new List<SkinnedMeshRenderer>();

        // 残像を複製
        for (int i = 0; i < CloneCount;i++)
        {
            var obj = Instantiate(BakeMeshObj);
            BakeCloneMeshList.Add(obj.GetComponent<SkinnedMeshRenderer>());
        }
    }

    void FixedUpdate()
    {
        // 4フレームに一度更新
        FlameCount++;
        if (FlameCount % FlameCountMax != 0)
        {
            return;
        }

        // BakeしたMeshを1つ前にずらしていく
        for (int i = BakeCloneMeshList.Count-1; i >= 1; i--)
        {
            BakeCloneMeshList[i].sharedMesh = BakeCloneMeshList[i - 1].sharedMesh;

            // 位置と回転をコピー
            BakeCloneMeshList[i].transform.position = BakeCloneMeshList[i - 1].transform.position;
            BakeCloneMeshList[i].transform.rotation = BakeCloneMeshList[i - 1].transform.rotation;
        }

        // 今のスキンメッシュをBakeする
        // ボトルネックになりやすいから注意!
        Mesh mesh = new Mesh();
        BaseMeshObj.BakeMesh(mesh);
        BakeCloneMeshList[0].sharedMesh = mesh;

        // 位置と回転をコピー
        BakeCloneMeshList[0].transform.position = transform.position;
        BakeCloneMeshList[0].transform.rotation = transform.rotation;
    }
}

 

3、スクリプトをアタッチ

BakeMeshを追加します。
次にBaseMeshObjに複製したいオリジナルのSkinnedMeshRendererを設定します。
その次に1でプレハブ化させたGameObjectをアタッチします。

f:id:yuukihirai0331:20190309133340p:plain


完了です。

f:id:yuukihirai0331:20190309134520p:plain

 

まとめ
これは更新処理でMeshを動的に生成し続けているので、一部のアクションを行うときに演出としてみせるのはとてもありだと思います。BakeMeshはベイクするメッシュの頂点数等によって処理負荷が変わる可能性があるため使用する際はしっかりと処理負荷を調べたうえで使うことを推奨します。