Skip to content

Instantly share code, notes, and snippets.

@restush
Last active June 29, 2023 14:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save restush/f0c386bf6b9f7a87b3d8968da90884cd to your computer and use it in GitHub Desktop.
Save restush/f0c386bf6b9f7a87b3d8968da90884cd to your computer and use it in GitHub Desktop.
Get target position in form of Circular / Circle position. So multiple agents that are following target, will try circling target. This prevent agents colliding with each other because wants to go to the same position.
using System.Collections.Generic;
using UnityEngine;
///<summary> Attach this script on Monobehaviour class </summary>
public interface ICircleTarget
{
/// <summary> Circle radius around target </summary>
float RadiusAroundTarget { get; set; }
/// <summary> Contain objects that following this target </summary>
List<Transform> CircleObjects { get; set; }
Transform ThisTransform => (this as Component).transform;
/// <summary>Get position of target in circular area </summary>
Vector3 GetCirclePosition(Transform other)
{
if (!CircleObjects.Contains(other))
CircleObjects.Add(other);
int length = CircleObjects.Count - 1;
Vector3 pos = GetPosition(0);
for (int i = 0; i < length; i++)
{
pos = GetPosition(i);
if (i < length && CircleObjects[i] == other)
break;
}
return pos;
Vector3 GetPosition(int i)
{
Vector3 pos;
float x = ThisTransform.position.x + RadiusAroundTarget * Mathf.Cos(2 * Mathf.PI * i / CircleObjects.Count);
float y = ThisTransform.position.y;
float z = ThisTransform.position.z + RadiusAroundTarget * Mathf.Sin(2 * Mathf.PI * i / CircleObjects.Count);
pos = new Vector3(x, y, z);
return pos;
}
}
/// <summary>Use this method after agent stop/not following target.</summary>
void RemovePosition(Transform other)
{
if (CircleObjects.Contains(other))
CircleObjects.Remove(other);
}
public class ExampleTargetObject : MonoBehaviour, ICircleTarget
{
[field: SerializeField] float ICircleTarget.RadiusAroundTarget { get; set; } = 4;
List<Transform> ICircleTarget.CircleObjects { get; set; } = new();
}
public class ExampleAgentObject : MonoBehaviour
{
[SerializeField] private Transform _target; // Attach GameObject of ExampleTargetObject.cs to this target
public void MoveToTarget()
{
transform.position = _target.GetComponent<ICircleTarget>().GetCirclePosition(transform);
}
public void StopAgent()
{
_target.GetComponent<ICircleTarget>().RemovePosition(transform);
transform.position = Vector3.zero;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment