功能需求:制作鱼群的随机动画,模拟真实鱼群的自由游动,如图
****:(需翻墙)
https://www.youtube.com/watch?v=eMpI1eCsIyM&t=765s
说明:
实现这个功能只需要两个脚本,
第一个是将预设鱼随机克隆出指定数量但不同位置的鱼群;
globalFlock.CS
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class globalFlock : MonoBehaviour {
public GameObject fishPrefab;
public static int tankSize = 5; //这个参数很重要,控制鱼群范围
static int numFish = 10; //控制鱼群数量
public static GameObject[] allFish = new GameObject[numFish];
public static Vector3 goalPos = Vector3.zero;
// Use this for initialization
void Start ()
{
for (int i = 0; i < numFish; i++)
{
Vector3 pos = new Vector3(Random.Range(-tankSize, tankSize), //这个参数很重要,控制不同鱼群不同的初始位置
Random.Range(-tankSize, tankSize),
Random.Range(-tankSize, tankSize));
allFish[i] = (GameObject)Instantiate(fishPrefab, pos, Quaternion.identity);
}
}
// Update is called once per frame
void Update ()
{
if(Random.Range(0,10000)<50)
{
goalPos= new Vector3(Random.Range(-tankSize, tankSize),
Random.Range(-tankSize, tankSize),
Random.Range(-tankSize, tankSize));
}
}
}
第二个脚本是将鱼群随机动起来;
flock.CS
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class flock : MonoBehaviour {
public float speed = 1f;
float rotationSpeed = 2.0f;
Vector3 averageHeading;
Vector3 averagePosition;
float neighbourDistance = 5.0f;
bool turning = false;
// Use this for initialization
void Start ()
{
speed = Random.Range(0.5f, 1);
}
// Update is called once per frame
void Update ()
{
if (Vector3.Distance(transform.position, Vector3.zero) >= globalFlock.tankSize)
{
turning = true;
}
else
turning = false;
if (turning)
{
Vector3 direction = Vector3.zero - transform.position;
transform.rotation = Quaternion.Slerp(transform.rotation,
Quaternion.LookRotation(direction),
rotationSpeed * Time.deltaTime);
speed = Random.Range(0.5f, 1);
}
else
{
if (Random.Range(0, 5) < 3)
ApplyRules();
}
transform.Translate(0, 0, Time.deltaTime * speed);
}
void ApplyRules()
{
GameObject[] gos;
gos = globalFlock.allFish;
Vector3 vcentre = Vector3.zero;
Vector3 vavoid = Vector3.zero;
float gSpeed = 0.1f;
Vector3 goalPos = globalFlock.goalPos;
float dist;
int groupSize = 0;
foreach (GameObject go in gos)
{
if (go != this.gameObject)
{
dist = Vector3.Distance(go.transform.position, this.transform.position);
if (dist <= neighbourDistance)
{
vcentre += go.transform.position;
groupSize++;
if (dist < 1.0f)
{
vavoid = vavoid + (this.transform.position - go.transform.position);
}
flock anotherFlock = go.GetComponent<flock>();
gSpeed = gSpeed + anotherFlock.speed;
}
}
}
if (groupSize > 0)
{
vcentre = vcentre / groupSize + (goalPos - this.transform.position);
speed = gSpeed / groupSize;
Vector3 direction = (vcentre + vavoid) - transform.position;
if (direction != Vector3.zero)
transform.rotation = Quaternion.Slerp(transform.rotation,
Quaternion.LookRotation(direction),
rotationSpeed * Time.deltaTime);
}
}
}
具体步骤如下:
1.将需要创建鱼群的鱼预设准备好;
2.创建一个空物体,命名为:FishManage,将第一个脚本加载上去;
然后运行,一条鱼就变出了很多不同位置的鱼,如图:
3.在鱼的预设上添加第二个脚本,如图:
运行,这群鱼就可以随机运动了。如图:
如果要在同一场景中设置多群鱼的动画就需要改动几个参数,
第一个脚本里的 Vector3 pos;
第二个脚本里需要替换所有Vector3.zero,这个参数是用来指定零点为初始点,如果需要偏移相应的位置,就需要手动去设置这个值。