##Unityゲーム開発者ギルド Advent Calendar 2020
この記事はUnityゲーム開発者ギルド Advent Calendar 2020の25日目です。
##はじめに
タイトルはTrailRendererに当たり判定を与えるための手法です。
以前に別のアプローチとして、
TrailRendererの頂点座標に当たり判定用のオブジェクトを生成する
という記事を書きました。
【参考リンク】:【Unity(C#)】TrailRendererの頂点座標を取得する方法
しかし、数が多いと処理がカクつく原因になるので今回の手法もメモしておきます。
##コード
using UnityEngine;
/// <summary>
/// お絵描き機能 適当なオブジェクトにアタッチ
/// </summary>
public class TrailMeshCreateTest : MonoBehaviour
{
[SerializeField] private Transform _paintObjParent;
[SerializeField] private GameObject _paintObjPrefab;
private GameObject _tmpPaintObj;
private void Update()
{
Vector3 worldClickPos = Camera.main.ScreenToWorldPoint(Input.mousePosition + Camera.main.transform.forward);
//マウス押した瞬間
if (Input.GetMouseButtonDown(0))
{
_tmpPaintObj = Instantiate(_paintObjPrefab, worldClickPos, Quaternion.identity,_paintObjParent);
}
//マウス押し続けている間
if (Input.GetMouseButton(0))
{
_tmpPaintObj.transform.position = worldClickPos;
}
//マウス離した瞬間
if (Input.GetMouseButtonUp(0))
{
MeshCrate();
_tmpPaintObj = null;
}
}
/// <summary>
/// Mesh生成
/// </summary>
private void MeshCrate()
{
//TrailRendererの頂点情報からメッシュを生成する
TrailRenderer paintObjectTrailRenderer = _tmpPaintObj.GetComponent<TrailRenderer>();
//子にコライダーだけ持つオブジェクトを作成する
GameObject colliderContainer = new GameObject("Collider Container");
colliderContainer.transform.SetParent(_tmpPaintObj.transform);
MeshCollider meshCollider = colliderContainer.AddComponent<MeshCollider>();
Mesh mesh = new Mesh();
paintObjectTrailRenderer.BakeMesh(mesh);
meshCollider.sharedMesh = mesh;
}
}
ロジックとしてはまずTrailRendererを持つオブジェクトの子に
MeshColliderのみを持つオブジェクトを生成します。
次に、TrailRendererのBakeMeshメソッドを使用し、
描画したTrailRendererと同じ形状のメッシュを生成します。
最後に、MeshColliderに先ほど生成したメッシュを適用すれば完了です。
ちなみに、子にコライダーだけ持つオブジェクトを作成している理由は
オフセット(座標)が0でないとコライダーの生成位置がずれるからです。
下記GIFがわかりやすいです。
TrailRendererを持つオブジェクトにMeshColliderを直接付与すると、
生成したTrailRendererの座標分だけMeshColliderの位置がずれてしまいます。
##デモ
以上を踏まえてのデモです。
今回は2Dで平面的にTrailRendererを動かしているのでコライダーがいびつですが、
三次元な動きならさらにきれいなMeshColliderが生成されます。
##参考リンク
TrailRenderer.BakeMesh