[Unity] [유틸] 복수의 Trigger 에서 OnTriggerEnter 여러번 발생해도 한번만 감지되게 하기

에크까망·2022년 5월 26일

들어가며

요즘 unity 로 간단한거 만들어 보다가, 접근감지 기능을 추가중에 OnTriggerEnter 가 여러번 들어와서 귀찮은 일이 생겼다.

Hero - MonA
가 각각 trigger 를 여러개 가지고 있는데 각 tigger 마다 enter/leave 가 떴든것. gameObject 가 여러 trigger 를 건드려도 처음 건드렸을때 onEnter 이벤트를 발생 시키고, 모든 trigger 를 다 빠져 나가야 onExit 가 발생되게 처리했다.

만약 child-gameObject 에 여러개의 감지 trigger 를 두고 싶다면, 감지하고픈 상대편 본체에만 Tag 를 설정하고, Sensing 쪽에서는 hosting 으로 처리하면 된다.

Sensor.cs

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

public class Sensor : MonoBehaviour
{
		private Dictionary<GameObject, int> detectCounter = new();

		/** host 가 설정되어 있으면 host에도 통보가 간다 [ekflame] */
		public Sensor host;
		public List<string> filterTags;
		public UnityEvent<GameObject> onEnter;
		public UnityEvent<GameObject> onExit;
		
		private void OnDisable()
		{
				detectCounter.Clear();
		}

		private void OnTriggerEnter(Collider other)
		{
				GameObject obj = other.gameObject;

				if ((filterTags?.Count ?? 0) > 0 && !filterTags.Contains(obj.tag))
				{
						return;
				}

				if (host)
				{
						host.OnTriggerEnter(other);
				}

				if (detectCounter.TryGetValue(obj, out var cnt))
				{
						detectCounter[obj] = ++cnt;
				}
				else
				{
						detectCounter[obj] = 1;
						onEnter.Invoke(obj);
				}
		}
		
		private void OnTriggerExit(Collider other)
		{
				GameObject obj = other.gameObject;
				
				if (host)
				{
						host.OnTriggerExit(other);
				}

				if (detectCounter.TryGetValue(obj, out var cnt))
				{
						--cnt;
						if (cnt <= 0)
						{
								onExit.Invoke(obj);
								detectCounter.Remove(obj);
						}
						else
						{
								detectCounter[obj] = cnt;
						}
				}
		}
}

마무리

bug 보시고 알려주시면 감사감사~

profile
Game Client Programmer

0개의 댓글