LoginSignup
2
3

【Unity】OnTriggerEnter 等で衝突した Collider から GetComponent を使わずに低負荷でコンポーネントを取得する方法

Last updated at Posted at 2024-03-26

背景

私はヴァンサバライクなゲームを作る際、OnTriggerEnter 等で衝突した Collider から目的のコンポーネントを取得するために TryGetComponent(GetComponent)を使っていました。
しかし GetComponent は重めの処理なので、弾幕や無双ゲームといった大量の物体を扱うゲームでは利用頻度を減らしたいと思いました。
そこで私は、シングルトンな Dictionary<GameObject, Component> を用意して目的のコンポーネントを追加しておけば、GameObject をキーとして目的のコンポーネントを簡単かつ低負荷で取得できると考え、それを実現する GetComponentDictionary クラスを作りました。

コード

Enter Play ModeReload Domainを無効にしても利用できます。

UniTask/UniRx がインポートされたプロジェクトで1行目/2行目をコメントアウトすると、Add() で追加されたコンポーネントの GameObject が破壊される際に自動で Remove() が呼ばれます。Component だけ破棄する際は Component の OnDestroy() に Remove() を追加し Add() の第二引数を false にしてください。

使い方

プレイヤーの弾が敵に当たり、敵がダメージを受けるといった具合の実装例です。

Enemy.cs
public class Enemy : MonoBehaviour
{
    [SerializeField] public int Hp;

    private void Start()
    {
        GetComponentDictionary<Enemy>.Add(this);
    }
    public void ReceiveDamage(int damage)
    {
        Hp -= damage;
    }
}
PlayerBullet.cs
using Generic;
using UnityEngine;

public class PlayerBullet : MonoBehaviour
{
    [SerializeField] private int damage;

    private void OnTriggerEnter(Collider other)
    {
        if (GetComponentDictionary<Enemy>.TryGetValue(other.gameObject, out var enemy))
        {
            enemy.ReceiveDamage(damage);
        }
    }
}
2
3
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
2
3