本文主要是介绍Processing Flocking移植unity,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
本文的代码基于Processing官网示例Flocking修改而来(processing flocking),由于参数设置有所不同,所以效果和官网的效果有不小的差距。原先想用C++和easyx来修改的,虽然C++还比较熟悉,但是easyx了解的不多,也没有学过图形学,做的效果不是很好,果断放弃了。使用Unity就比较简单了,但是C#又不是很熟悉,所以不保证完全争取。
下列是运行的部分结果:
通过更改预制体,就能使用自己喜欢的形状来模拟这一群体行为了。
using System.Collections.Generic;
using UnityEngine;class Boid
{Vector3 position;Vector3 velocity;Vector3 acceleration;Transform transform;float maxforce; float maxspeed; public Boid(float x, float y,Transform _transform){this.transform= _transform;acceleration = new Vector3(0, 0);float angle = UnityEngine.Random.Range(0f, Mathf.PI * 2.0f);velocity = new Vector3(Mathf.Cos(angle), Mathf.Sin(angle));position = new Vector3(x, y);maxspeed = 0.02f;maxforce = 0.003f;}public void run(List<Boid> boids){flock(boids);update();borders();}void applyForce(Vector3 force){acceleration += force;}void flock(List<Boid> boids){Vector3 sep = separate(boids);Vector3 ali = align(boids); Vector3 coh = cohesion(boids);sep *= 0.15f;ali *= 0.1f;coh *= 0.1f;applyForce(sep);applyForce(ali);applyForce(coh);}void update(){velocity += acceleration;velocity = velocity.normalized * maxspeed;float angle = Vector3.SignedAngle(Vector3.up, velocity, Vector3.forward);position += velocity;acceleration *= 0;transform.position = position;transform.eulerAngles = Vector3.Lerp(transform.eulerAngles, new Vector3(0, 0, angle), 1f);}Vector3 seek(Vector3 target){Vector3 desired = target - position;desired = desired.normalized;desired *= maxspeed;Vector3 steer = desired - velocity;steer = steer.normalized * maxforce;return steer;}void borders(){if (position.x < -10f) position.x = 10f;if (position.y < -5f) position.y = 5f;if (position.x > 10f) position.x = -10f;if (position.y > 5f) position.y = -5f;}Vector3 separate(List<Boid> boids){float desiredseparation = 0.75f;Vector3 steer = new Vector3(0, 0, 0);int count = 0;for (int i=0;i<boids.Count;++i){float d = Vector3.Distance(position, boids[i].position);if ((d > 0) && (d < desiredseparation)){Vector3 diff = position- boids[i].position;diff = diff.normalized;diff /= d;steer += diff;count++; }}if (count > 0){steer /= (float)count;}if (steer.magnitude > 0){steer = steer.normalized;steer*=maxspeed;steer-=velocity;steer = steer.normalized * maxforce;}return steer;}Vector3 align(List<Boid> boids){float neighbordist = 1.1f;Vector3 sum = new Vector3(0, 0);int count = 0;for (int i = 0; i < boids.Count; ++i){float d = Vector3.Distance(position, boids[i].position);if ((d > 0) && (d < neighbordist)){sum += boids[i].velocity;count++;}}if (count > 0){sum/=(float)count;sum=sum.normalized;sum *= maxspeed;Vector3 steer = sum - velocity;steer = steer.normalized * maxforce;return steer;}else{return new Vector3(0, 0);}}Vector3 cohesion(List<Boid> boids){float neighbordist = 1.1f;Vector3 sum = new Vector3(0, 0); int count = 0;for (int i = 0; i < boids.Count; ++i){float d = Vector3.Distance(position, boids[i].position);if ((d > 0) && (d < neighbordist)){sum+=boids[i].position;count++;}}if (count > 0){sum /= (float)count;return seek(sum);}else{return new Vector3(0, 0);}}
}class Flock
{List<Boid> boids;public Flock(){boids = new List<Boid>();}public void run(){for (int i=0;i<boids.Count;++i){boids[i].run(boids);}}public void add(Boid b){if(boids.Count<200) boids.Add(b);}}public class FlockController : MonoBehaviour
{private Flock flock;public Transform prefab;void Start(){flock = new Flock();for (int i = 0; i < 50; ++i){float x = UnityEngine.Random.Range(-9.5f, 9.5f);float y = UnityEngine.Random.Range(-4.5f, 4.5f);Transform transform = Instantiate(prefab, new Vector3(x, y, 0), Quaternion.identity);flock.add(new Boid(x, y, transform));}}void Update(){flock.run();if (Input.GetMouseButtonDown(0)){Vector3 pos = Input.mousePosition;Vector3 wpos = Camera.main.ScreenToWorldPoint(pos);Transform transform = Instantiate(prefab, wpos, Quaternion.identity);flock.add(new Boid(wpos.x, wpos.y, transform));}}
}
简单修改以下,将三个行为合并,减少运行的耗时
using System.Collections.Generic;
using UnityEngine;class Boid
{Vector3 position;Vector3 velocity;Vector3 acceleration;Transform transform;float maxforce;float maxspeed;public Boid(float x, float y, Transform _transform){this.transform = _transform;acceleration = new Vector3(0, 0);float angle = UnityEngine.Random.Range(0f, Mathf.PI * 2.0f);velocity = new Vector3(Mathf.Cos(angle), Mathf.Sin(angle));position = new Vector3(x, y);maxspeed = 0.02f;maxforce = 0.001f;}public void run(List<Boid> boids){flock(boids);update();borders();}void applyForce(Vector3 force){acceleration += force;}void flock(List<Boid> boids){List<Vector3> res = action(boids);Vector3 sep = res[0];Vector3 ali = res[1];Vector3 coh = res[2];sep *= 1.5f;applyForce(sep);applyForce(ali);applyForce(coh);}void update(){velocity += acceleration;velocity = velocity.normalized * maxspeed;position += velocity;acceleration *= 0;float angle = Vector3.SignedAngle(Vector3.up, velocity, Vector3.forward);transform.position = position;transform.eulerAngles = Vector3.Lerp(transform.eulerAngles, new Vector3(0, 0, angle), 100f);}Vector3 seek(Vector3 target){Vector3 desired = target - position;desired = desired.normalized;desired *= maxspeed;Vector3 steer = desired - velocity;steer = steer.normalized * maxforce;return steer;}void borders(){if (position.x < -10f) position.x = 10f;if (position.y < -5f) position.y = 5f;if (position.x > 10f) position.x = -10f;if (position.y > 5f) position.y = -5f;}List<Vector3> action(List<Boid> boids){List<Vector3> res = new List<Vector3>();float desiredseparation = 0.4f;Vector3 steer = new Vector3(0, 0, 0);int s_count = 0;float neighbordist = 0.8f;Vector3 a_sum = new Vector3(0, 0, 0);int count = 0;Vector3 c_sum = new Vector3(0, 0, 0);for (int i = 0; i < boids.Count; ++i){float d = Vector3.Distance(position, boids[i].position);if ((d > 0) && (d < desiredseparation)){Vector3 diff = position - boids[i].position;diff = diff.normalized;diff /= d;steer += diff;s_count++;}if ((d > 0) && (d < neighbordist)){a_sum += boids[i].velocity;c_sum += boids[i].position;count++;}}if (s_count > 0){steer /= (float)s_count;}if (steer.magnitude > 0){steer = steer.normalized * maxspeed;steer -= velocity;steer = steer.normalized * maxforce;}res.Add(steer);if (count > 0){a_sum /= (float)count;a_sum = a_sum.normalized;a_sum *= maxspeed;Vector3 steer2 = a_sum - velocity;steer2 = steer2.normalized * maxforce;res.Add(steer2);c_sum /= (float)count;res.Add(seek(c_sum));}else{res.Add(new Vector3(0, 0,0));res.Add(new Vector3(0, 0,0));}return res;}
}class Flock
{List<Boid> boids;public Flock(){boids = new List<Boid>();}public void run(){for (int i=0;i<boids.Count;++i){boids[i].run(boids);}}public void add(Boid b){if(boids.Count<600) boids.Add(b);}}public class FlockController : MonoBehaviour
{private Flock flock;public Transform prefab;void Start(){flock = new Flock();for (int i = 0; i < 150; ++i){float x = 0;float y = 0;Transform transform = Instantiate(prefab, new Vector3(x, y, 0), Quaternion.identity);flock.add(new Boid(x, y, transform));}}void Update(){flock.run();if (Input.GetMouseButtonDown(0)){Vector3 pos = Input.mousePosition;Vector3 wpos = Camera.main.ScreenToWorldPoint(pos);Transform transform = Instantiate(prefab, wpos, Quaternion.identity);flock.add(new Boid(wpos.x, wpos.y, transform));}}
}
这篇关于Processing Flocking移植unity的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!