faithbook233 / minecraft-ue4-remake Goto Github PK
View Code? Open in Web Editor NEW我的世界UE4重置版
我的世界UE4重置版
目前所面临的问题是,世界中的Block过多,不可能将所有的面全部显示出来,所以仅仅需要渲染(说简单点就是绘制)能看到的三角面。
视频中已经实现了动态加载Chunk
B站视频教程:无限世界
所以下一步就是需要将Chunk与世界的生成联系起来,即世界生成的时候会将Chunk所包含的方块保存在Chunk内。
因为Chunk的存储使用的是映射——Key:Chunk位置(实际位置/1600),value:Chunk对象引用,
假如在玩家游玩时,玩家发射一次射线,碰到了Chunk内Block的三角面,如何从这个HitResult找到保存它的位置???
其实很简单,就是将HitResult中的碰撞位置直接/1600(得确保结果是整数),得到的二维坐标(无需Z轴),然后在存储Chunk的映射中搜索Key(即搜索当前计算的二维坐标)得到的就是碰撞到的Chunk,就可以用CHunk进行序列化相关操作了
关于渲染优化,就是减少三角面,再确认好要渲染哪些顶点以后,就可以使用Greedy Mesh算法(贪婪网格划分算法)解决这个问题,我学的还不是很深入,只是浅浅的了解了一下。
单人游戏时,在本机创建建服务器(IP:127.0.0.1),服务器负责生成世界,负责一些权威操作(主要是Set操作),客户端只负责操作输入、渲染(Get类函数)等
由于当前的顶点是展开的,所以一旦Block比较多,就会造成极大的资源浪费,在CreateFace中,计算出要四个新的顶点,需要在数组中查找是否有这几个点,如果没有,就直接添加,如果有,则不添加,并且在添加三角形时,将顶点的索引给三角形赋值。
世界的最小单位决定了这个世界的外观,MC中视觉上,一个最小单位是1m * 1m * 1m的 Block
然后将16 * 16 * 256块Block作为一个Chunk,人物移动所引起的加载的最小单位是Chunk
渲染距离决定了当前世界中Chunk的数量
先忽略世界的生成和生物群系的生成,其过于复杂我也还在研究中
先讨论一下怎么样用数据结构+算法表示这个复杂的世界
我找到的方法有:
这种在DiscardVersion中已经经过实际测试,性能十分差劲,跳过
由于实例化静态网格体实例化的所有对象与其使用相同的网格和材质,因此如果要建造复杂的地形,会有诸多方块,那么如果一个Chunk中包含了N种方块,那这个Chunk就需要创建N个实例化静态网格体组件,一个组件对应一种方块,比如,我要添加或删除世界中的一个草方块,首先需要找到包含这个草方块的Chunk对象,然后再找到这个Chunk对象中对应的草方块实例化静态网格体组件,再去更新这个组件的内容。
但类已经破坏的方块和可以互动的方块最好还是直接创建成为Actor,它们有共同的父类,保存在对应的Chunk中,且和Chunk同时创建或销毁。
这种有一个好处就是直接将当前的世界用三角面构建出来,至于哪些面需要显示,哪些面需要剔除,就要归结到算法中,而且在人物添加或删除方块时,方块的表面需要用三角面表示,我目前找到的比较好的方法就是Greedy Mesh
也许这种方法中,Chunk并不是作为一个Actor而是继承自UObject,其仅作为一种序列化的对象。
因为GrddyMesh可能需要遍历所有的顶点,而如果像之前那样将Block存储在不同的Chunk对象中,遍历会比较麻烦,万一两个Chunk有一个共同的面,这个面的顶点到底应该存储在谁里面???
所以这种方法,需要一个世界构建对象(可继承),用来保存和显示所有的Block,其拥有一个程序化静态网格体组件,所有的Block和Block信息用来给程序化静态网格体组件或剔除算法提供顶点扫描,而动态加载世界也是基于Chunk的抽象逻辑的,每一个CHunk保存在不同的文件或插槽中,而且文件或插槽名必须与Chunk的位置对应,即根据位置可以在磁盘中查找到Chunk的信息,如果差找不到这说明这个地方没有来过,此时就需要根据世界种子和固定的世界生成算法实时生成世界并将新生成的Chunk保存到插槽中,供下次加载使用。
世界生成器需要一个种子,可能是一串数字,也可能带字母。同样的种子生成的世界必须是一模一样的。
目前了解到的地形生成有噪声算法(如柏林噪声算法),MC的可能比这个更复杂
生物群落由沃罗诺图(Voronol)划分,由此生成不同的方块内容
需要一个固定的地形生成算法。输入参数为:世界种子+位置(x,y,z),所有参数都能够得到一个确定的值,即当前世界,当前位置是一个什么方块
第二部就是延迟加载存档,从当前游戏的存档中读取特定位置的方块,(当然,存档中只存储在初始地形以后改变的方块数据——为了减少存档容量)
需要解决的问题:
由于方块的复杂性,先将静态的方块作为世界生成的基础元素(比如草方块、土方块这些仅用来建筑或挖局的方块,熔炉这些作为单独的Actor),所以先不考虑动物、植物的生成,先考虑初始地形。
MC中互动的最小元素是方块(Block)将MC中的Chunk作为一个最小的独立的区块,包含16x16x256个Block,Block不会单独存储,Block仅作为一个逻辑单位,真正存储的位置在Chunk中,每个Chunk存储的是一个映射,Key:方块的位置(实际上存储的是int32,实际位置/100),value:方块的所有信息。方块的所有信息需要用结构体,由于不同的方块可能有不同的属性,可以考虑结构体的继承。
Chunk是需要实现动态加载与卸载的,大致流程如下(这是我猜测的)
因此我构想,一个Chunk保存一个插槽,为了确保当前的Chunk保存插槽唯一,当前游戏也必须唯一,
先说当前世界,能确保唯一的数据包括:种子+一些必要的设置(如世界大小等等),或者干脆点,直接用一个uuid表示当前世界,因为这个仅用来判断两个世界是不是相同。
插槽名可以是:当前的游戏uuid+ChunkX坐标/1600+ChunkY坐标/1600
然后加载CHunk的时候,如果插槽存在则表示Chunk曾经被生成过,就加载Chunk数据,生成chunk包含的所有Block(当然渲染需要其他方法确保能用最少的面将当前世界渲染出来,可能会有面剔除等算法)
每个生物群系均有一个温度数值来决定该位置是否能够降水。该数值低于0.15即下雪,0.15-0.95即下雨,高于1.0将会使区域保持干旱。这些数值也用于决定不同生物群系中积雪的高度。每从默认海平面(Y=64)向上升高1米,温度将会降低0.0016(1⁄625)。海平面以下不会有温度变化。
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.