SkinnedMeshなオブジェクトにMeshColliderを生成する

このブログでは紹介できない内容のVRコンテンツを作っていて、動的にSkinnedMeshの当たり判定を生成する必要があったのでメモ

動的にMeshColliderを生成する

SteamVRのインタラクションシステムの実験で、女性キャラクターの体を触っているかのような演出を行いたいと思ってます。
インタラクションシステムを使えば、コライダーが設定されているオブジェクトについては当たり判定を行ってくれるようで、手がめり込んだりすることはありません。
ただ、SkinnedMeshなオブジェクトに対して、単純にMeshColliderをアタッチしても機能しないようでした。

BakeMeshを利用してColliderを生成

SkinnedMeshRenderer.BakeMeshメソッドを利用することで動的にコライダーが生成できるので、以下のスクリプトをキャラクターの洋服にアタッチしてみました

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

public class CreateSkinedMeshCollider : MonoBehaviour
{

    public float interval;

    private MeshCollider meshCollider;
    private SkinnedMeshRenderer skinnedMeshRenderer;
    private float nextTime;

    // Start is called before the first frame update
    void Start()
    {
        meshCollider = GetComponent<MeshCollider>();
        skinnedMeshRenderer = GetComponent<SkinnedMeshRenderer>();
        nextTime = 0.0f;
    }

    // Update is called once per frame
    void Update()
    {
        nextTime -= Time.deltaTime;
        if (nextTime < 0.0f)
        {
            nextTime = interval;

            Mesh bakedMesh = new Mesh();
            skinnedMeshRenderer.BakeMesh(bakedMesh);
            meshCollider.sharedMesh = null;
            meshCollider.sharedMesh = bakedMesh;
        }
    }
}

MeshBakeの処理はコストがかかるとのことだったため、毎フレーム処理するのではなく、時間で制御するようにしました。

これを適用すると、以下のようになります。

こんな感じで、きちんと当たり判定が設定され、キャラクターをなでなですることができるようになります。

今後の展開

まずは当たり判定が設定できました。この後は特定の個所を触った時のリアクションとか、スカートやお胸を触った時のリアクション(布のヒラヒラ感とか、肌の柔らかい感じ)が出せると良いですが、この辺りは要研究になりそうです。