Files
2024-11-20 15:21:28 +01:00

111 lines
2.6 KiB
C#

// (c) Copyright HutongGames, LLC 2010-2013. All rights reserved.
// Added Ignore Owner option. Thanks Nueral Echo: http://hutonggames.com/playmakerforum/index.php?topic=71.0
using UnityEngine;
namespace HutongGames.PlayMaker.Actions
{
[ActionCategory(ActionCategory.GameObject)]
[Tooltip("Finds the closest object to the specified Game Object.\nOptionally filter by Tag and Visibility.")]
public class FindClosest : FsmStateAction
{
[RequiredField]
[Tooltip("The GameObject to measure from.")]
public FsmOwnerDefault gameObject;
[RequiredField]
[UIHint(UIHint.Tag)]
[Tooltip("Only consider objects with this Tag. NOTE: It's generally a lot quicker to find objects with a Tag!")]
public FsmString withTag;
[Tooltip("If checked, ignores the object that owns this FSM.")]
public FsmBool ignoreOwner;
[Tooltip("Only consider objects visible to the camera.")]
public FsmBool mustBeVisible;
[UIHint(UIHint.Variable)]
[Tooltip("Store the closest object.")]
public FsmGameObject storeObject;
[UIHint(UIHint.Variable)]
[Tooltip("Store the distance to the closest object.")]
public FsmFloat storeDistance;
[Tooltip("Repeat every frame")]
public bool everyFrame;
public override void Reset()
{
gameObject = null;
withTag = "Untagged";
ignoreOwner = true;
mustBeVisible = false;
storeObject = null;
storeDistance = null;
everyFrame = false;
}
public override void OnEnter()
{
DoFindClosest();
if (!everyFrame)
{
Finish();
}
}
public override void OnUpdate()
{
DoFindClosest();
}
void DoFindClosest()
{
var go = gameObject.OwnerOption == OwnerDefaultOption.UseOwner ? Owner : gameObject.GameObject.Value;
GameObject[] objects; // objects to consider
if (string.IsNullOrEmpty(withTag.Value) || withTag.Value == "Untagged")
{
objects = (GameObject[])GameObject.FindObjectsOfType(typeof(GameObject));
}
else
{
objects = GameObject.FindGameObjectsWithTag(withTag.Value);
}
GameObject closestObj = null;
var closestDist = Mathf.Infinity;
foreach (var obj in objects)
{
if (ignoreOwner.Value && obj == Owner)
{
continue;
}
if (mustBeVisible.Value && !ActionHelpers.IsVisible(obj))
{
continue;
}
var dist = (go.transform.position - obj.transform.position).sqrMagnitude;
if (dist < closestDist)
{
closestDist = dist;
closestObj = obj;
}
}
storeObject.Value = closestObj;
if (!storeDistance.IsNone)
{
storeDistance.Value = Mathf.Sqrt(closestDist);
}
}
}
}