I have the code here. but as an exercise to better yourself try and see what you can come up with first before looking at it. It should also help you understand what I’ve done in my code and why I’ve done it.
First as a disclaimer, I wrote this code to use Collisions. however in your specific use case I would have more likely used Triggers, and have trigger volumes over plates where entities would stand. Triggers would have more consistent enter/exit states, plus from the sounds of it you don’t really need all that collision data that comes inside a Collision object. However Triggers vs Collisions doesn’t change the code too much so I continued with Collisions. you can make it a personal exercise to convert it to using triggers.
Code
The code I’ve provided is a stub, so on its own it won’t do much (at all). There are several different ways you can set this up, personally I prefer to write my code so that it exploits the Inspector as much as possible, as you can see with the code I wrote.
public class CollisionEvent: UnityEngine.Events.UnityEvent<GameObject,Collision>{}
public class CollisionDispatcher: MonoBehaviour
{
public CollisionEvent OnCollisionEntered;
public CollisionEvent OnCollisionUpdated;
public CollisionEvent OnCollisionExiteded;
private OnCollisionEnter(Collision col)
{
OnCollisionEntered.Invoke(gameObject,col);
}
private OnCollisionStay(Collision col)
{
OnCollisionUpdated.Invoke(gameObject,col);
}
private OnCollisionExit(Collision col)
{
OnCollisionExited.Invoke(gameObject,col);
}
}
public class CollisionListener: MonoBehaviour
{
[serializeField] private Gameobject m_collidee;
private GameObject m_lastValidatedCollidee;
public GameObject Collidee
{
get{return m_collidee;}
set
{
if(m_collidee == value) return;
RemoveDispatcher(m_collidee);
AddDispatcher(value);
m_collidee = value;
m_lastValidatedCollidee = value;
}
}
}
private void OnEnable()
{
AddDispatcher(m_collidee);
}
private void OnDisable()
{
RemoveDispatcher(m_collidee);
}
private void OnValidate()
{
#if UNITY_EDITOR
if(!UnityEditor.EditorApplication.isPlaying)
return;
#endif
if(m_collidee == m_lastValidatedCollidee)
return;
RemoveDispatcher(m_lastValidatedCollidee);
AddDispatcher(m_collidee);
m_lastValidatedCollidee = m_collidee;
]
private void AddDispatcher(GameObject target)
{
if(!target) return;
var dispatcher = target.GetComponent<CollisionDispatcher>();
if(!dispatcher)
dispatcher = target.AddComponent<CollisionDispatcher>();
dispatcher.OnCollisionEntered.AddListener(WhenCollisionEnters);
dispatcher.OnCollisionUpdated.AddListener(WhenCollisionUpdates);
dispatcher.OnCollisionExiteded.AddListener(WhenCollisionExits);
}
private void RemoveDispatcher(GameObject target)
{
if(!target) return;
var dispatcher = target.GetComponent<CollisionDispatcher>();
if(! dispatcher) return;
dispatcher.OnCollisionEntered.RemoveListener(WhenCollisionEnters);
dispatcher.OnCollisionUpdated.RemoveListener(WhenCollisionUpdates);
dispatcher.OnCollisionExiteded.RemoveListener(WhenCollisionExits);
//don't remove the dispatcher from the target, some other class might be needing it.
// we just don't need to be listening to it.
}
private void WhenCollisionEnters(GameObject target, Collision collision)
{
// stuff to do when target enters a contact
}
private void WhenCollisionUpdates(GameObject target, Collision collision)
{
// stuff to do while target stays in contact
}
private void WhenCollisionExits(GameObject target, Collision collision)
{
// stuff to do when target leaves contact
}
Since you’re a beginner there are likely several things in the code which you may not understand. For me I didn’t hold back to make it easier for a beginner to read, I simply wrote it how I would like to use it.
Luckily this is the internet so information on Unity API, C#, Properties vs fields, Events, and even design patterns can all be easily found. It just takes practice and study. Plus you can always ask directly in the forums, but before you do try and search if your question has already been answered, you’ll typically find a solution faster that way.