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

91 lines
2.4 KiB
C#

// (c) Copyright HutongGames, LLC 2010-2013. All rights reserved.
using UnityEngine;
namespace HutongGames.PlayMaker.Actions
{
[ActionCategory(ActionCategory.Physics)]
[Tooltip("Applies an explosion Force to all Game Objects with a Rigid Body inside a Radius.")]
public class Explosion : FsmStateAction
{
[RequiredField]
[Tooltip("The world position of the center of the explosion.")]
public FsmVector3 center;
[RequiredField]
[Tooltip("The strength of the explosion.")]
public FsmFloat force;
[RequiredField]
[Tooltip("The radius of the explosion. Force falls of linearly with distance.")]
public FsmFloat radius;
[Tooltip("Applies the force as if it was applied from beneath the object. This is useful since explosions that throw things up instead of pushing things to the side look cooler. A value of 2 will apply a force as if it is applied from 2 meters below while not changing the actual explosion position.")]
public FsmFloat upwardsModifier;
[Tooltip("The type of force to apply.")]
public ForceMode forceMode;
[UIHint(UIHint.Layer)]
public FsmInt layer;
[UIHint(UIHint.Layer)]
[Tooltip("Layers to effect.")]
public FsmInt[] layerMask;
[Tooltip("Invert the mask, so you effect all layers except those defined above.")]
public FsmBool invertMask;
[Tooltip("Repeat every frame while the state is active.")]
public bool everyFrame;
public override void Reset()
{
center = null;
upwardsModifier = 0f;
forceMode = ForceMode.Force;
everyFrame = false;
}
public override void OnPreprocess()
{
Fsm.HandleFixedUpdate = true;
}
public override void OnEnter()
{
DoExplosion();
if (!everyFrame)
{
Finish();
}
}
public override void OnFixedUpdate()
{
DoExplosion();
}
void DoExplosion()
{
var colliders = Physics.OverlapSphere(center.Value, radius.Value);
foreach (var hit in colliders)
{
var rigidBody = hit.gameObject.GetComponent<Rigidbody>();
if (rigidBody != null && ShouldApplyForce(hit.gameObject))
{
rigidBody.AddExplosionForce(force.Value, center.Value, radius.Value, upwardsModifier.Value, forceMode);
}
}
}
bool ShouldApplyForce(GameObject go)
{
var mask = ActionHelpers.LayerArrayToLayerMask(layerMask, invertMask.Value);
return ((1 << go.layer) & mask) > 0;
}
}
}