playMaker

Author Topic: Making OverlapSphere custom action(additionally finds closest collider)  (Read 2417 times)

Rakusta

  • Playmaker Newbie
  • *
  • Posts: 2
Hello all, i'm currently trying to create a custom action that uses Physics.OverlapSphere, and stores the closest collider in the array in a vector 3 variable. I've got most of the code down, except when i play the action, the stated variable for the vector 3 is reset to no variable no matter what i try.

Here is my code
Code: [Select]
using UnityEngine;

namespace HutongGames.PlayMaker.Actions
{
[ActionCategory(ActionCategory.Physics)]
[Tooltip("Casts a Sphere into the worldspace and returns an array of the hit colliders")]
public class OverlapSphere : FsmStateAction
{
[Tooltip("Start ray at game object position. \nOr use From Position parameter.")]
public FsmOwnerDefault fromGameObject;

[Tooltip("Start ray at a vector3 world position. \nOr use Game Object parameter.")]
public FsmVector3 fromPosition;

[Tooltip("The radius of the sphere")]
public FsmFloat radius;

[Tooltip("Event to send if the sphere hits an object.")]
[UIHint(UIHint.Variable)]
public FsmEvent hitEvent;

[Tooltip("Set a bool variable to true if hit something, otherwise false.")]
[UIHint(UIHint.Variable)]
public FsmBool storeDidHit;

[Tooltip("Store the game object hit in a variable.")]
[UIHint(UIHint.Variable)]
public FsmVector3 storeHitObject;

[Tooltip("Set how often to cast the sphere. 0 = once, don't repeat; 1 = everyFrame; 2 = every other frame... \nSince raycasts can get expensive use the highest repeat interval you can get away with.")]
public FsmInt repeatInterval;

[Tooltip("Pick only from these layers.")]
[UIHint(UIHint.Layer)]
public FsmInt[] layerMask;

[Tooltip("Invert the mask, so you pick from all layers except those defined above.")]
public FsmBool invertMask;

int repeat;


public override void Reset()
{
fromGameObject = null;
fromPosition = new FsmVector3 { UseVariable = true };
radius = 100;
hitEvent = null;
storeDidHit = null;
storeHitObject = null;
repeatInterval = 1;
layerMask = new FsmInt[0];
}

public override void OnEnter()
{
DoOverlapSphere();

if (repeatInterval.Value == 0)
{
Finish();
}
}
public override void OnUpdate()
{
repeat--;

if (repeat == 0)
{
DoOverlapSphere();
}
}

void DoOverlapSphere()
{
repeat = repeatInterval.Value;

if (radius.Value == 0)
{
return;
}

var go = Fsm.GetOwnerDefaultTarget(fromGameObject);

var originPos = go != null ? go.transform.position : fromPosition.Value;

var Radius = radius.Value;

float minDist = Mathf.Infinity;

Transform nearest = null;

Collider[] colliders = Physics.OverlapSphere(originPos, Radius, ActionHelpers.LayerArrayToLayerMask(layerMask, invertMask.Value));

foreach(Collider hit in colliders)
{

                float dist = Vector3.Distance(originPos, hit.transform.position);

                if (dist < minDist)
{

                    minDist = dist;

                    nearest = hit.transform;

            }
}
storeHitObject = nearest.position;

}
}
}

It would be more advantaegous if i can find the closest object, and store it in a gameObject variable.