Unity-群组行为AI

来源:互联网 发布:那种下载软件好 编辑:程序博客网 时间:2024/05/17 05:15

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 framevoid 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 ;Vector3dir = center - transform.position;cohesionForce = (cohesionForce + dir.normalized*velocity.magnitude) * cohesionWeight;sumForce += cohesionForce;}//保持恒定速度Vector3 statusForce=startVelocity-velocity;sumForce += statusForce;}// Update is called once per framevoid 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