78 lines
2.7 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|