Files
beyond/Assets/ThirdParty/PlayMaker/Actions/Physics/CollisionEvent.cs
2024-11-20 15:21:28 +01:00

290 lines
8.9 KiB
C#

// (c) Copyright HutongGames, LLC 2010-2013. All rights reserved.
using UnityEngine;
namespace HutongGames.PlayMaker.Actions
{
[ActionCategory(ActionCategory.Physics)]
[Tooltip("Detect collisions between Game Objects that have RigidBody/Collider components.")]
public class CollisionEvent : FsmStateAction
{
[Tooltip("The GameObject to detect collisions on.")]
public FsmOwnerDefault gameObject;
[Tooltip("The type of collision to detect.")]
public CollisionType collision;
[UIHint(UIHint.TagMenu)]
[Tooltip("Filter by Tag.")]
public FsmString collideTag;
[Tooltip("Event to send if a collision is detected.")]
public FsmEvent sendEvent;
[UIHint(UIHint.Variable)]
[Tooltip("Store the GameObject that collided with the Owner of this FSM.")]
public FsmGameObject storeCollider;
[UIHint(UIHint.Variable)]
[Tooltip("Store the force of the collision. NOTE: Use Get Collision Info to get more info about the collision.")]
public FsmFloat storeForce;
// cached proxy component for callbacks
private PlayMakerProxyBase cachedProxy;
public override void Reset()
{
gameObject = null;
collision = CollisionType.OnCollisionEnter;
collideTag = "";
sendEvent = null;
storeCollider = null;
storeForce = null;
}
public override void OnPreprocess()
{
if (gameObject == null) gameObject = new FsmOwnerDefault();
if (gameObject.OwnerOption == OwnerDefaultOption.UseOwner)
{
switch (collision)
{
case CollisionType.OnCollisionEnter:
Fsm.HandleCollisionEnter = true;
break;
case CollisionType.OnCollisionStay:
Fsm.HandleCollisionStay = true;
break;
case CollisionType.OnCollisionExit:
Fsm.HandleCollisionExit = true;
break;
case CollisionType.OnControllerColliderHit:
Fsm.HandleControllerColliderHit = true;
break;
case CollisionType.OnParticleCollision:
Fsm.HandleParticleCollision = true;
break;
}
}
else
{
// Add proxy components now if we can
GetProxyComponent();
}
}
public override void OnEnter()
{
if (gameObject.OwnerOption == OwnerDefaultOption.UseOwner)
return;
if (cachedProxy == null)
GetProxyComponent();
AddCallback();
gameObject.GameObject.OnChange += UpdateCallback;
}
public override void OnExit()
{
if (gameObject.OwnerOption == OwnerDefaultOption.UseOwner)
return;
RemoveCallback();
gameObject.GameObject.OnChange -= UpdateCallback;
}
private void UpdateCallback()
{
RemoveCallback();
GetProxyComponent();
AddCallback();
}
private void GetProxyComponent()
{
cachedProxy = null;
var source = gameObject.GameObject.Value;
if (source == null)
return;
switch (collision)
{
case CollisionType.OnCollisionEnter:
cachedProxy = PlayMakerFSM.GetEventHandlerComponent<PlayMakerCollisionEnter>(source);
break;
case CollisionType.OnCollisionStay:
cachedProxy = PlayMakerFSM.GetEventHandlerComponent<PlayMakerCollisionStay>(source);
break;
case CollisionType.OnCollisionExit:
cachedProxy = PlayMakerFSM.GetEventHandlerComponent<PlayMakerCollisionExit>(source);
break;
case CollisionType.OnParticleCollision:
cachedProxy = PlayMakerFSM.GetEventHandlerComponent<PlayMakerParticleCollision>(source);
break;
case CollisionType.OnControllerColliderHit:
cachedProxy = PlayMakerFSM.GetEventHandlerComponent<PlayMakerControllerColliderHit>(source);
break;
}
}
private void AddCallback()
{
if (cachedProxy == null)
return;
switch (collision)
{
case CollisionType.OnCollisionEnter:
cachedProxy.AddCollisionEventCallback(CollisionEnter);
break;
case CollisionType.OnCollisionStay:
cachedProxy.AddCollisionEventCallback(CollisionStay);
break;
case CollisionType.OnCollisionExit:
cachedProxy.AddCollisionEventCallback(CollisionExit);
break;
case CollisionType.OnParticleCollision:
cachedProxy.AddParticleCollisionEventCallback(ParticleCollision);
break;
case CollisionType.OnControllerColliderHit:
cachedProxy.AddControllerCollisionEventCallback(ControllerColliderHit);
break;
}
}
private void RemoveCallback()
{
if (cachedProxy == null)
return;
switch (collision)
{
case CollisionType.OnCollisionEnter:
cachedProxy.RemoveCollisionEventCallback(CollisionEnter);
break;
case CollisionType.OnCollisionStay:
cachedProxy.RemoveCollisionEventCallback(CollisionStay);
break;
case CollisionType.OnCollisionExit:
cachedProxy.RemoveCollisionEventCallback(CollisionExit);
break;
case CollisionType.OnParticleCollision:
cachedProxy.RemoveParticleCollisionEventCallback(ParticleCollision);
break;
case CollisionType.OnControllerColliderHit:
cachedProxy.RemoveControllerCollisionEventCallback(ControllerColliderHit);
break;
}
}
private void StoreCollisionInfo(Collision collisionInfo)
{
storeCollider.Value = collisionInfo.gameObject;
storeForce.Value = collisionInfo.relativeVelocity.magnitude;
}
public override void DoCollisionEnter(Collision collisionInfo)
{
if (gameObject.OwnerOption == OwnerDefaultOption.UseOwner)
CollisionEnter(collisionInfo);
}
public override void DoCollisionStay(Collision collisionInfo)
{
if (gameObject.OwnerOption == OwnerDefaultOption.UseOwner)
CollisionStay(collisionInfo);
}
public override void DoCollisionExit(Collision collisionInfo)
{
if (gameObject.OwnerOption == OwnerDefaultOption.UseOwner)
CollisionExit(collisionInfo);
}
public override void DoControllerColliderHit(ControllerColliderHit collisionInfo)
{
if (gameObject.OwnerOption == OwnerDefaultOption.UseOwner)
ControllerColliderHit(collisionInfo);
}
public override void DoParticleCollision(GameObject other)
{
if (gameObject.OwnerOption == OwnerDefaultOption.UseOwner)
ParticleCollision(other);
}
private void CollisionEnter(Collision collisionInfo)
{
if (collision == CollisionType.OnCollisionEnter)
{
if (TagMatches(collideTag, collisionInfo))
{
StoreCollisionInfo(collisionInfo);
Fsm.Event(sendEvent);
}
}
}
private void CollisionStay(Collision collisionInfo)
{
if (collision == CollisionType.OnCollisionStay)
{
if (TagMatches(collideTag, collisionInfo))
{
StoreCollisionInfo(collisionInfo);
Fsm.Event(sendEvent);
}
}
}
private void CollisionExit(Collision collisionInfo)
{
if (collision == CollisionType.OnCollisionExit)
{
if (TagMatches(collideTag, collisionInfo))
{
StoreCollisionInfo(collisionInfo);
Fsm.Event(sendEvent);
}
}
}
private void ControllerColliderHit(ControllerColliderHit collisionInfo)
{
if (collision == CollisionType.OnControllerColliderHit)
{
if (TagMatches(collideTag, collisionInfo))
{
if (storeCollider != null)
storeCollider.Value = collisionInfo.gameObject;
storeForce.Value = 0f; //TODO: impact force?
Fsm.Event(sendEvent);
}
}
}
private void ParticleCollision(GameObject other)
{
if (collision == CollisionType.OnParticleCollision)
{
if (TagMatches(collideTag, other))
{
if (storeCollider != null)
storeCollider.Value = other;
storeForce.Value = 0f; //TODO: impact force?
Fsm.Event(sendEvent);
}
}
}
public override string ErrorCheck()
{
return ActionHelpers.CheckPhysicsSetup(Fsm.GetOwnerDefaultTarget(gameObject));
}
}
}