Files
TheVVaS-Assets/RPGCore/Runtime/Core/Trigger.cs
T

69 lines
2.2 KiB
C#

using System;
using System.Collections.Generic;
using RPGCore.Core.Objects;
using RPGCore.ObjectModules.EventObjectModule.Events;
using RPGCoreCommon.Settings;
using UnityEngine;
namespace RPGCore.Core
{
/// <summary>
/// This MonoBehaviour allow any <see cref="BaseObject"/> to call <see cref="OnEnter"/> and <see cref="OnExit"/>.<br/>
/// Setting <see cref="Collider"/>'s <see cref="Collider.isTrigger"/> to true is required!<br/>
/// </summary>
public class Trigger : MonoBehaviour
{
private event Action<BaseObject> OnEnterEvent;
private event Action<BaseObject> OnExitEvent;
private readonly Dictionary<BaseObject, int> _collisionCounter = new();
public static Trigger AddToGameObject(GameObject go, Action<BaseObject> onEnter, Action<BaseObject> onExit)
{
go.layer = SettingsManager.Get<CoreSettings>().triggerLayer;
var interactTrigger = go.AddComponent<Trigger>();
interactTrigger.OnEnterEvent += onEnter;
interactTrigger.OnExitEvent += onExit;
return interactTrigger;
}
internal void OnEnter(BaseObject obj)
{
var alreadyTouching = _collisionCounter.ContainsKey(obj);
if (!alreadyTouching) _collisionCounter.Add(obj, 0);
_collisionCounter[obj]++;
if (!alreadyTouching)
{
obj.events.Register<TriggerClearEvent>(OnClear);
OnEnterEvent?.Invoke(obj);
}
}
internal void OnExit(BaseObject obj)
{
if (!_collisionCounter.ContainsKey(obj))
{
Debug.LogError("Object tried to leave trigger, but never entered it!", obj);
return;
}
_collisionCounter[obj]--;
if (_collisionCounter[obj] == 0) Clear(obj);
}
private void OnClear(TriggerClearEvent ev)
{
Clear(ev.obj);
}
private void Clear(BaseObject obj)
{
obj.events.Unregister<TriggerClearEvent>(OnClear);
_collisionCounter.Remove(obj);
OnExitEvent?.Invoke(obj);
}
}
}