Processing Flocking移植unity

2023-10-19 11:59

本文主要是介绍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的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/239633

相关文章

FreeRTOS-基本介绍和移植STM32

FreeRTOS-基本介绍和STM32移植 一、裸机开发和操作系统开发介绍二、任务调度和任务状态介绍2.1 任务调度2.1.1 抢占式调度2.1.2 时间片调度 2.2 任务状态 三、FreeRTOS源码和移植STM323.1 FreeRTOS源码3.2 FreeRTOS移植STM323.2.1 代码移植3.2.2 时钟中断配置 一、裸机开发和操作系统开发介绍 裸机:前后台系

Unity Post Process Unity后处理学习日志

Unity Post Process Unity后处理学习日志 在现代游戏开发中,后处理(Post Processing)技术已经成为提升游戏画面质量的关键工具。Unity的后处理栈(Post Processing Stack)是一个强大的插件,它允许开发者为游戏场景添加各种视觉效果,如景深、色彩校正、辉光、模糊等。这些效果不仅能够增强游戏的视觉吸引力,还能帮助传达特定的情感和氛围。 文档

Unity协程搭配队列开发Tips弹窗模块

概述 在Unity游戏开发过程中,提示系统是提升用户体验的重要组成部分。一个设计良好的提示窗口不仅能及时传达信息给玩家,还应当做到不干扰游戏流程。本文将探讨如何使用Unity的协程(Coroutine)配合队列(Queue)数据结构来构建一个高效且可扩展的Tips弹窗模块。 技术模块介绍 1. Unity协程(Coroutines) 协程是Unity中的一种特殊函数类型,允许异步操作的实现

Unity 资源 之 Super Confetti FX:点亮项目的璀璨粒子之光

Unity 资源 之 Super Confetti FX:点亮项目的璀璨粒子之光 一,前言二,资源包内容三,免费获取资源包 一,前言 在创意的世界里,每一个细节都能决定一个项目的独特魅力。今天,要向大家介绍一款令人惊艳的粒子效果包 ——Super Confetti FX。 二,资源包内容 💥充满活力与动态,是 Super Confetti FX 最显著的标签。它宛如一位

Unity数据持久化 之 一个通过2进制读取Excel并存储的轮子(4)

本文仅作笔记学习和分享,不用做任何商业用途 本文包括但不限于unity官方手册,unity唐老狮等教程知识,如有不足还请斧正​​ Unity数据持久化 之 一个通过2进制读取Excel并存储的轮子(3)-CSDN博客  这节就是真正的存储数据了   理清一下思路: 1.存储路径并检查 //2进制文件类存储private static string Data_Binary_Pa

Unity Adressables 使用说明(一)概述

使用 Adressables 组织管理 Asset Addressables 包基于 Unity 的 AssetBundles 系统,并提供了一个用户界面来管理您的 AssetBundles。当您使一个资源可寻址(Addressable)时,您可以使用该资源的地址从任何地方加载它。无论资源是在本地应用程序中可用还是存储在远程内容分发网络上,Addressable 系统都会定位并返回该资源。 您

RT-Thread(Nano版本)的快速移植(基于NUCLEO-F446RE)

目录 概述 1 RT-Thread 1.1 RT-Thread的版本  1.2 认识Nano版本 2 STM32F446U上移植RT-Thread  2.1 STM32Cube创建工程 2.2 移植RT-Thread 2.2.1 安装RT-Thread Packet  2.2.2 加载RT-Thread 2.2.3 匹配相关接口 2.2.3.1 初次编译代码  2.2.3.

2024年 Biomedical Signal Processing and Control 期刊投稿经验最新分享

期刊介绍 《Biomedical Signal Processing and Control 》期刊旨在为临床医学和生物科学中信号和图像的测量和分析研究提供一个跨学科的国际论坛。重点放在处理在临床诊断,患者监测和管理中使用的方法和设备的实际,应用为主导的研究的贡献。 生物医学信号处理和控制反映了这些方法在工程和临床科学的界面上被使用和发展的主要领域。期刊的范围包括相关的评论论文(review p

Unity Adressables 使用说明(六)加载(Load) Addressable Assets

【概述】Load Addressable Assets Addressables类提供了加载 Addressable assets 的方法。你可以一次加载一个资源或批量加载资源。为了识别要加载的资源,你需要向加载方法传递一个键或键列表。键可以是以下对象之一: Address:包含你分配给资源的地址的字符串。Label:包含分配给一个或多个资源的标签的字符串。AssetReference Obj

在Unity环境中使用UTF-8编码

为什么要讨论这个问题         为了避免乱码和更好的跨平台         我刚开始开发时是使用VS开发,Unity自身默认使用UTF-8 without BOM格式,但是在Unity中创建一个脚本,使用VS打开,VS自身默认使用GB2312(它应该是对应了你电脑的window版本默认选取了国标编码,或者是因为一些其他的原因)读取脚本,默认是看不到在VS中的编码格式,下面我介绍一种简单快