Last active
June 29, 2023 14:42
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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