Files
2026-02-21 16:45:37 +08:00

78 lines
2.7 KiB
C#

using UnityEngine;
namespace BehaviorDesigner.Runtime.Tasks.Movement
{
[TaskIcon("Assets/Behavior Designer Movement/Editor/Icons/{SkinColor}FlockIcon.png")]
[TaskCategory("Movement")]
[HelpURLAttribute("http://www.opsive.com/assets/BehaviorDesigner/Movement/documentation.php?id=13")]
[TaskDescription("Flock around the scene using the Unity NavMesh.")]
public class Flock : NavMeshGroupMovement
{
[Tooltip("Agents less than this distance apart are neighbors")]
public SharedFloat neighborDistance = 100f;
[Tooltip("How far the agent should look ahead when determine its pathfinding destination")]
public SharedFloat lookAheadDistance = 5f;
[Tooltip("The greater the alignmentWeight is the more likely it is that the agents will be facing the same direction")]
public SharedFloat alignmentWeight = 0.4f;
[Tooltip("The greater the cohesionWeight is the more likely it is that the agents will be moving towards a common position")]
public SharedFloat cohesionWeight = 0.5f;
[Tooltip("The greater the separationWeight is the more likely it is that the agents will be separated")]
public SharedFloat separationWeight = 0.6f;
public override TaskStatus OnUpdate()
{
for (int i = 0; i < agents.Length; i++)
{
Vector3 alignment;
Vector3 cohesion;
Vector3 separation;
DetermineFlockParameters(i, out alignment, out cohesion, out separation);
Vector3 vector = alignment * alignmentWeight.Value + cohesion * cohesionWeight.Value + separation * separationWeight.Value;
if (!SetDestination(i, transforms[i].position + vector * lookAheadDistance.Value))
{
vector *= -1f;
SetDestination(i, transforms[i].position + vector * lookAheadDistance.Value);
}
}
return TaskStatus.Running;
}
private void DetermineFlockParameters(int index, out Vector3 alignment, out Vector3 cohesion, out Vector3 separation)
{
alignment = (cohesion = (separation = Vector3.zero));
int num = 0;
Transform transform = transforms[index];
for (int i = 0; i < agents.Length; i++)
{
if (index != i && Vector3.Magnitude(transforms[i].position - transform.position) < neighborDistance.Value)
{
alignment += Velocity(i);
cohesion += transforms[i].position;
separation += transforms[i].position - transform.position;
num++;
}
}
if (num != 0)
{
alignment = (alignment / num).normalized;
cohesion = (cohesion / num - transform.position).normalized;
separation = (separation / num * -1f).normalized;
}
}
public override void OnReset()
{
base.OnReset();
neighborDistance = 100f;
lookAheadDistance = 5f;
alignmentWeight = 0.4f;
cohesionWeight = 0.5f;
separationWeight = 0.6f;
}
}
}