看《哪吒之魔童降世》有个印象很深的点,就是太乙真人有个法宝,叫山河社稷图,里面包含了一个完整的世界。
URSINA也是,不比其他大型3D引擎少,该有的都有,可以在里面创建一个完整的世界。(不过好像作者提到没有独立光源。)
它的API文档也是很少,但是基本上都好懂,只要会python,都能看懂。
网页上就一页,一千行左右,作者把它命名为cheat-sheet,意思可能是说看了这个相当于作弊吧,因为并没多少内容。可以在附件查看。
还是从简单的例子开始吧。
1.要有窗口:
跑之前 安装一下ursina就好了。 pip install ursina
from ursina import *
app=Ursina()
app.run
导入ursina库,用Ursina这个函数实例化一个app的对象,调用run的方法,把窗口跑起来。
三行代码就可以显示一个空的“山河社稷图”了。
2.关于坐标系
xyz是我们常用的坐标系,例如(1,2,3)代表一个点高度是3,平面投影是(1,2);
但ursina使用的是类似于相机坐标系,z代表深度,x,y是当前平面。
ursina的坐标系和我们理解的坐标系有点不一样,y和z对调了一下,不过没关系,我们可以写个简单的函数进行转换。
def switch_yz(vects): #for ursina unusual use of coord 7.16 solve the problem
t=[]
for item in vects:
t.append((item[0],item[2],item[1]))
return t
3.画一个基本的地平面
好吧,得说点稍微复杂的东西了。
ursina 核心一个概念就是Entity,他是一个类,英文翻译为实体。这里我按照我的理解和模式来写例子,因为python的语法很灵活,用一个固定的模式来写,可能会让大家更专注于实现本身。
继承这个类。
class world(Entity):
定义类的初始化方法
def __init__(self):
super().__init__()
调用父类的初始化方法,world继承了Entity这个类,如果要初始化它原有的方法,必先来这么一下。如果没来这一下,很多方法就用不了。比如,下节我们会讲到让这个世界的物体动起来,要用一个update的方法,就是从Entity继承来的。super()代表父类,init前面的__代表这个方法是私有的,python真是简洁。
在初始化方法里面,还可以做些初始化的事情,比如,给这个世界加个地平面。
s =100
grid = Entity(model=Grid(s, s), scale=s, color=color.color(0, 0, .8, 1), rotation_x=90,position=(-s / 2, 0, -s / 2))
定义一个100×100的网格,原点放在(-50,-50)的地方(x,y)。请注意ursina 的坐标系是(x,z,y),所以原点是
position=(-s/2,0,-s/2),网格默认是向z方向生成的,所以绕x轴转90度,铺开就是平面了。
看着还有点光突突,再加个xyz 轴,有个参照。直接上一份完整的代码,贴上去就可以跑的。
跑之前 安装一下ursina就好了。 pip install ursina
from ursina import *
class world(Entity):#Entity # 定义构造方法
def __init__(self):
super().__init__()
s =100
grid = Entity(model=Grid(s, s), scale=s, color=color.color(0, 0, .8, 1), rotation_x=90,
position=(-s / 2, 0, -s / 2))
vertsx = ((0, 0, 0), (10, 0, 0))
Entity(model=Mesh(vertices=vertsx, mode='line', thickness=3), color=color.cyan)
vertsyz = [(0, 0, 0), (0, 5, 0), (0, 0, 0), (0, 0, 10)]
self.linesyz =Entity(model=Mesh(vertices=vertsyz, mode='line', thickness=3), color=color.yellow)
if __name__ == '__main__':
app = Ursina()
world()
EditorCamera()
app.run()
4.要有点,线,面,体
Entity(model='quad', color=color.orange, position=(0,0,1), scale=1.5, rotation=(0,0,45))
作为最基础的对象,有一些基本参数是必须了解的,当然它有更多的参数,可以在需要的时候查阅文档
model模型参数,可加载自定义的模型,也可以加载预制带参数模型。
比如要画一堆点:
verts = []
verts_points = Entity(model=Mesh(vertices=verts, mode='point', thickness=15), color=color.green)
for i in range(100):
verts.append(Vec3(2 * math.cos(i +self.counts), i / 5, 2 * math.sin(i +self.counts)))
verts_points.model=Mesh(vertices=verts, mode='point', thickness=15)
这么写是为了后续变化的世界做准备。先准备一个空的列表,生成点,然后修改这个模型。
再画个面。
verts = (Vec3(5, 0.01, 2), Vec3(5, 3, 2), Vec3(5, 3, 3), Vec3(5, 0.01, 3))
obj1 =Entity(model=Quad(vertices=verts),color=color.rgb(0,255,0,255))
最后是体
obj2 = Entity(model='cube', texture = 'brick',position=(3,3,3))
好了,基本的东西差不多都会了,摸索一下,就可以搞出很多有意思的花样出来。
当然前提有一定的python基础,这个现在也比较火,找些B站或者udacity的教程,可以很快入门。
下次以及下下次我们聊,怎么让物体在这个世界运动,碰撞,以及和用户交互的一些内容。