Skip to content

Instantly share code, notes, and snippets.

@SH42913
Last active January 16, 2024 16:29
Show Gist options
  • Save SH42913/586955ad7d103090a1d7c06d6736a941 to your computer and use it in GitHub Desktop.
Save SH42913/586955ad7d103090a1d7c06d6736a941 to your computer and use it in GitHub Desktop.
Collision Listener for Morpeh-ECS
using System;
using System.Diagnostics;
using Morpeh;
using UnityEngine;
using Utils;
[AddComponentMenu("")]
public sealed class CollisionListener : MonoBehaviour {
public IEntity ownerEntity;
public Collider[] colliders;
public bool isTrigger;
public bool handleExits;
private World world;
public CollisionListener Init(World world, IEntity ownerEntity, bool isTrigger, bool handleExits) {
this.world = world;
this.ownerEntity = ownerEntity;
this.isTrigger = isTrigger;
this.handleExits = handleExits;
return this;
}
private void OnEnable() {
this.colliders = this.GetComponentsInChildren<Collider>();
#if DEBUG
if (this.colliders.Length <= 0) {
throw new Exception($"There are no any {nameof(Collider)} to handle collisions on {this.name}");
}
#endif
}
private void OnCollisionEnter(Collision other) {
if (this.isTrigger) return;
this.ThrowIfOwnerNotCompatible();
ref var evt = ref this.world.CreateEntity().AddComponent<CollisionEnterEvent>();
evt.ownerEntity = this.ownerEntity;
evt.ownerGameObject = this.gameObject;
if (other.rigidbody != null) {
evt.otherGameObject = other.rigidbody.gameObject;
evt.otherEntity = evt.otherGameObject.GetComponent<CollisionListener>()?.ownerEntity;
}
else {
evt.otherGameObject = other.gameObject;
}
}
private void OnCollisionExit(Collision other) {
if (this.isTrigger || !this.handleExits) return;
this.ThrowIfOwnerNotCompatible();
ref var evt = ref this.world.CreateEntity().AddComponent<CollisionExitEvent>();
evt.ownerEntity = this.ownerEntity;
evt.ownerGameObject = this.gameObject;
if (other.rigidbody != null) {
evt.otherGameObject = other.rigidbody.gameObject;
evt.otherEntity = evt.otherGameObject.GetComponent<CollisionListener>()?.ownerEntity;
}
else {
evt.otherGameObject = other.gameObject;
}
}
private void OnTriggerEnter(Collider other) {
if (!this.isTrigger) return;
this.ThrowIfOwnerNotCompatible();
ref var evt = ref this.world.CreateEntity().AddComponent<TriggerEnterEvent>();
evt.ownerEntity = this.ownerEntity;
evt.ownerGameObject = this.gameObject;
if (other.attachedRigidbody != null) {
evt.otherGameObject = other.attachedRigidbody.gameObject;
evt.otherEntity = evt.otherGameObject.GetComponent<CollisionListener>()?.ownerEntity;
}
else {
evt.otherGameObject = other.gameObject;
}
}
private void OnTriggerExit(Collider other) {
if (!this.isTrigger || !this.handleExits) return;
this.ThrowIfOwnerNotCompatible();
ref var evt = ref this.world.CreateEntity().AddComponent<TriggerExitEvent>();
evt.ownerEntity = this.ownerEntity;
evt.ownerGameObject = this.gameObject;
if (other.attachedRigidbody != null) {
evt.otherGameObject = other.attachedRigidbody.gameObject;
evt.otherEntity = evt.otherGameObject.GetComponent<CollisionListener>()?.ownerEntity;
}
else {
evt.otherGameObject = other.gameObject;
}
}
[Conditional("DEBUG")]
private void ThrowIfOwnerNotCompatible() {
if (!this.ownerEntity.Exists()) {
throw new Exception($"{nameof(this.ownerEntity)} not exists!");
}
if (!this.isTrigger && !this.ownerEntity.Has<ReadyToCollision>()) {
throw new Exception($"{nameof(this.ownerEntity)} should have {nameof(ReadyToCollision)}");
}
if (this.isTrigger && !this.ownerEntity.Has<ReadyToTrigger>()) {
throw new Exception($"{nameof(this.ownerEntity)} should have {nameof(ReadyToTrigger)}");
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment