免责声明:请勿用作任何商业用途
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class OptimizedCrowAI : MonoBehaviour {
public float speed = 3; // 移动速度
public Vector3 velocity = Vector3.forward; // 初始速度
private Vector3 startVelocity; // 初始速度备份
public Transform target; // 目标位置
public Vector3 sumForce = Vector3.zero; // 总力
public float mass = 1; // 质量
public float separationDistance = 3; // 分离距离
public List<GameObject> separationNeighbors = new List<GameObject>(); // 分离邻居列表
public float separationWeight = 1; // 分离力权重
public Vector3 separationForce = Vector3.zero; // 分离力
public float alignmentDistance = 6; // 对齐距离
public List<GameObject> alignmentNeighbors = new List<GameObject>(); // 对齐邻居列表
public float alignmentWeight = 1; // 对齐力权重
public Vector3 alignmentForce = Vector3.zero; // 对齐力
public float cohesionWeight = 1; // 凝聚力权重
public Vector3 cohesionForce = Vector3.zero; // 凝聚力
public float maxSpeed = 5; // 最大速度
public float maxForce = 10; // 最大力
public float checkInterval = 0.2f; // 检测间隔
private Animation anim; // 动画组件
private void Start() {
target = GameObject.Find("Target").transform; // 获取目标位置
startVelocity = velocity; // 备份初始速度
InvokeRepeating("CalcForce", 0, checkInterval); // 定期计算力
anim = GetComponentInChildren<Animation>(); // 获取动画组件
Invoke("PlayAnim", Random.Range(0, 2f)); // 随机播放动画
}
void PlayAnim() {
anim.Play(); // 播放动画
}
void CalcForce() {
sumForce = Vector3.zero; // 重置总力
separationForce = Vector3.zero; // 重置分离力
alignmentForce = Vector3.zero; // 重置对齐力
cohesionForce = Vector3.zero; // 重置凝聚力
// 计算分离力
separationNeighbors.Clear();
Collider[] colliders = Physics.OverlapSphere(transform.position, separationDistance);
foreach (Collider c in colliders) {
if (c != null && c.gameObject != this.gameObject) {
separationNeighbors.Add(c.gameObject);
}
}
foreach (GameObject neighbor in separationNeighbors) {
Vector3 dir = transform.position - neighbor.transform.position;
separationForce += dir.normalized / dir.magnitude;
}
if (separationNeighbors.Count > 0) {
separationForce *= separationWeight;
sumForce += separationForce;
}
// 计算对齐力
alignmentNeighbors.Clear();
colliders = Physics.OverlapSphere(transform.position, alignmentDistance);
foreach (Collider c in colliders) {
if (c != null && c.gameObject != this.gameObject) {
alignmentNeighbors.Add(c.gameObject);
}
}
Vector3 avgDir = Vector3.zero;
foreach (GameObject n in alignmentNeighbors) {
avgDir += n.transform.forward;
}
if (alignmentNeighbors.Count > 0) {
avgDir /= alignmentNeighbors.Count;
alignmentForce = avgDir - transform.forward;
alignmentForce *= alignmentWeight;
sumForce += alignmentForce;
}
// 计算凝聚力
if (alignmentNeighbors.Count > 0) {
Vector3 center = Vector3.zero;
foreach (GameObject n in alignmentNeighbors) {
center += n.transform.position;
}
center /= alignmentNeighbors.Count;
Vector3 dirToCenter = center - transform.position;
cohesionForce += dirToCenter.normalized * velocity.magnitude;
cohesionForce *= cohesionWeight;
sumForce += cohesionForce;
}
// 保持恒定飞行速度的力
Vector3 engineForce = velocity.normalized * startVelocity.magnitude;
sumForce += engineForce * 0.1f;
// 追逐目标的力
Vector3 targetDir = target.position - transform.position;
sumForce += (targetDir.normalized - transform.forward) * speed;
// 限制总力的大小
sumForce = Vector3.ClampMagnitude(sumForce, maxForce);
}
void Update() {
// 计算加速度
Vector3 acceleration = sumForce / mass;
// 更新速度
velocity += acceleration * Time.deltaTime;
// 限制速度的大小
velocity = Vector3.ClampMagnitude(velocity, maxSpeed);
// 更新位置
transform.position += velocity * Time.deltaTime;
// 平滑旋转
transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(velocity), Time.deltaTime * 2);
}
}