1.导入乌鸦模型,自带动画(素材百度网盘http://pan.baidu.com/s/1o8C5EKq)
2.创建乌鸦模型 ,目标点,以及编写脚本,使所有乌鸦可以向同一方向移动
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CrowAI : MonoBehaviour {
public Transform target;
public float speed=2.0f;
public float animRandom = 2f;
private Animation anim;
IEnumerable Start(){
anim = GetComponentInChildren<Animation> ();
yield return new WaitForSeconds (Random.Range(0,animRandom));
}
void calcForce(){
}
// Update is called once per frame
void Update () {
transform.LookAt (target.transform);
transform.Translate(Vector3.forward*Time.deltaTime*speed);
}
}
//发现会乌鸦在飞行时有重叠并且在目标点处原地煽动翅膀位置,方向不做任何改变。
群组行为的代码实现:
以下分离,队列,聚集的力,需要在u3d中自行调整,已达到效果。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CrowAI : MonoBehaviour {
public Vector3 velocity= Vector3.forward;
public Vector3 startVelocity;
public float m=1f;
//合力
public Vector3 sumForce= Vector3.zero;
//分离::
public Vector3 separtionForce=Vector3.zero;//分离的力
public float seperationDistance=3f;//分离的距离
public List <GameObject> seperationNeighbors=new List<GameObject>(); //有影响的物体
public float seperationWeight=1f;
//队列:
public Vector3 alignmentForce=Vector3.zero; //队列的力
public float alignmentDistance=6.0f;//队列的距离
public List<GameObject> alignmentNeighbors=new List<GameObject>();
public float alignmentWeight=1f;
//聚集:
public Vector3 cohesionForce=Vector3.zero;
public float cohesionWeight=1f;
public float checkInterval=0.2f;
public Transform target;
public float speed=2.0f;
public int animRandomTime = 10;
private Animation anim;
void Start(){
startVelocity = velocity;
InvokeRepeating ("CalcForce", 0, checkInterval);
anim = GetComponentInChildren<Animation> ();
float f=Random.Range(0,animRandomTime);
Invoke ("PlayAnim",f);
}
void PlayAnim(){
anim.Play ();
}
void Init(){
sumForce= Vector3.zero;
separtionForce=Vector3.zero;
alignmentForce=Vector3.zero;
cohesionForce=Vector3.zero;
}
//若放在update里,每帧计算过于耗费性能
void CalcForce(){
Init ();
//计算离当前物体近的物体
seperationNeighbors.Clear ();
Collider[] colliders= Physics.OverlapSphere (transform.position ,seperationDistance);
foreach (Collider c in colliders) {
if (c != null && c.gameObject != this.gameObject) {
seperationNeighbors.Add (c.gameObject);
}
}
//计算分离的力
foreach (GameObject neighbor in seperationNeighbors) {
Vector3 direction = transform.position - neighbor.transform.position;
separtionForce += direction.normalized/direction.magnitude;//近的力大,远的力小
}
if (seperationNeighbors.Count > 0) {
separtionForce *= seperationWeight;//权重
sumForce += separtionForce;
}
//计算队列的力
alignmentNeighbors.Clear();
Vector3 avgDir = Vector3.zero;
colliders =Physics.OverlapSphere(transform.position,alignmentDistance);
foreach (Collider c in colliders) {
if (c != null && c.gameObject != this.gameObject) {
alignmentNeighbors.Add (c.gameObject);
avgDir += c.gameObject.transform.forward;
}
}
if (alignmentNeighbors.Count > 0) {
avgDir /= alignmentNeighbors.Count;
alignmentForce = avgDir - transform.forward;
alignmentForce *= alignmentWeight;
separtionForce *= seperationWeight;//权重
sumForce += separtionForce;
}
//计算聚集的力
Vector3 center=Vector3.zero;
if ( alignmentNeighbors.Count>0) {
// 由于聚集的力与队列的力范围一直,因此如果队列的内容为0 也退出方法
foreach (GameObject c in alignmentNeighbors) {
center += c.transform.position;
}
center /= alignmentNeighbors.Count ;
Vector3 dir = center - transform.position;
cohesionForce = (cohesionForce + dir.normalized*velocity.magnitude) * cohesionWeight;
sumForce += cohesionForce;
}
//保持恒定速度
Vector3 statusForce=startVelocity-velocity;
sumForce += statusForce;
}
// Update is called once per frame
void Update () {
Vector3 a = sumForce / m;
velocity += a * Time.deltaTime;
transform.rotation = Quaternion.LookRotation (velocity);
transform.Translate (velocity * Time.deltaTime, Space.World);
}
}
效果展示:https://github.com/ycb577114589/AI