Unity——父子关系

一个场景中可以有很多物体,而这些物并不是随意散布在场景里的,而是有"父子关系"的。

父子关系让多个物体形成嵌套的、树形的结构。很多游戏开发技术,如骨骼动画、指定旋转的锚点、同一物体生命周期等问题都可以用"父子关系"表示或解决。下文将指出,只要用好"父子关系"这一特性,就能很好地解决很多实际问题,而不需要引入其他概念


一、使用"父子关系"复用零件

在某些游戏引擎中,可以重复使用的零件也被称为"组件"。例如,制作出的一个灯泡肌可以用在吊灯上,也可以用在台灯上。这样会带来一个概念上的小问题,因为一旦组件可以单独存在,那么概念就变得复杂了——又多出来一种可以单独存在的"组件",甚至它还可以有自身的位置,如灯泡在吊灯里的位置是可以调整的。

而Unity严格规定了物体和组件分别能干什么、不能干什么。例如,组件必须挂在与物体之上,不能单独存在;组件本身不具有位置参数;由于组件和物体是一体的,因此脚本中引用组件实际上是引用了物体。这样的规定让组件无法单独存在,从表面上看限制了实现时的灵活性。

可以重复使用的灯泡显然是必要的,在很多游戏中都可以找到重复使用物体的例子。对复用零件的问题,Unity的解决方案是使用子物体。简单来说,只要把灯泡做成一个单独的物体,然后把它作为吊灯或提灯的子物体,这样灯泡就成了吊灯或台灯的一部分,问题就解决了。由于物体可以任意移动位置,因此仍可以把它放在吊灯的任意位置。

二、"父子关系"与局部坐标系

每个场景整体都有一个大的坐标系,成为世界坐标系。世界坐标系也有x,y,z轴,在Unity中分别规定为右、上、前方。

但在很多情况下,只有世界坐标系是不够的。例如,在移动台灯的时候,希望灯泡能一起移动;旋转台灯的时候,希望灯泡能一起旋转;放大台灯的时候,希望灯泡能一起放大。在这里,台灯就构成了一个局部坐标系,它内部物体的位移、旋转、缩放都要受到局部坐标系的影响。

简单来说,局部坐标系就是父物体自身的坐标系,父物体的位置就是局部坐标系的原点,父物体的右、上、前分别对应xyz。一旦父物体缩放,所有的子物体也会跟着缩放

举个例子,局部坐标系中有一个非常经典的应用——实现房门的转动

先用三个Cube构成一个门框,在用一个Cube来当作门。如果直接旋转这个门,一般门会沿着其自身的中线旋转。而我们想要的是让门沿着门框旋转。可以给门做一个空的父物体,将父物体定位在门的转轴位置。这是旋转父物体,门就会绕父物体转动了。

三、使用"父子关系"表示角色的骨骼

骨骼动画师现代3D游戏不氪互殴饿的功能。简单来说,3D角色不仅有一个模型外观,该模型内部还有一个虚拟的骨骼,这个骨骼的运动会拉扯模型的表面材质跟着运动,这样一来只需要移动骨骼,就可以让模型做出各种动作了。

如果将人的骨骼结构看作一种链接结构,每一个可旋转的部分都有对应的关节链接。肩膀的旋转会带动整条胳膊的旋转,肘部的旋转会带动小臂和手的旋转,再结合前文提到的"局部坐标系"思考,这些骨骼关系正好可以用"父子关系"表示

事实也确实如此,Unity直接用"父子关系"表示模型骨骼,再在模型表面蒙上一层可伸缩的网格,就像皮肤一样(皮肤一样的网格组件叫做Skinned Mesh),这样就用"父子关系"解决了骨骼动画的问题

Skinned Mesh Renderer组件:在Unity中看不到单独的Skinned Mesh组件。带骨骼的三维模型使用Skinned Mesh Renderer统一管理网格和材质,而不像一般的模型用Mesh Filter和Mesh Renderer分别表示

四、利用父物体统一管理大量的物体

某些游戏会大量产生同类物体,如射击游戏中的子弹物体、塔防游戏中的大量敌人等。很多时候需要统一管理这些子弹,如一起隐藏、一起销毁等。如果它们散布在整个场景中,要同时对它们进行操作就会很麻烦。这是可以创建一个空物体作为父物体,让这些大量的痛了对象都称为父物体的子物体。那么只要隐藏父物体,它们就会一起隐藏,也可以一起销毁。因此,结合父物体可以轻松设计出有效的物体管理器

Unity官方文档指出:如果在父物体上使用了非等比缩放,那么在某些特殊情况下可能导致子物体的位置、朝向计算错误,因此建议在父物体上尽可能避免非等比缩放

猜你喜欢

转载自blog.csdn.net/m0_63024355/article/details/130500360