游戏对象
阅读本文大概需要 10 分钟。
在编辑器资源库中,提供了美术对象用来搭建游戏场景、游戏功能对象用来实现常见游戏逻辑。它们都是游戏对象的一种,本章节我们就来学习游戏对象,以及常见用法。
1. 三维坐标系
在学习游戏对象之前,我们先来了解一下口袋方舟中的坐标系。在中学的几何学中,大家应该已经了解 2D 坐标系,也就是大家熟知的二维笛卡尔坐标系,该坐标系从原点(0,0)开始,向右伸出一条横轴,为 x 轴的正方向;向上伸出一条纵轴,为 y 轴的正方向,如图:
在游戏开发中,编辑 3D 场景时,只有两个坐标就无法定位到某个物体的具体位置了,所以引入 3D 坐标系来完成场景中每个物体的定位。
那么 3D 坐标系是如何定位一个物体,除了原来的 x、y 轴以外,还会新增一个轴向为 z 轴(可以理解为,把上面的 2D 坐标系倒下来放桌子上,然后在(0, 0)点位置再加一个垂直的轴-Z 轴。
在我们编辑器中,3D 坐标系如下图所示:
左右方向是 X 轴(红色),前后方向是 Y 轴(绿色 ),上下方向是 Z 轴(蓝色)
- 基于坐标(0, 0, 0)点,如图所示,X 轴向右是正方向是变大,Y 轴向后是正方向是变大,Z 轴向上是正方向是变大。
- 所以,我们想让一个物体向正前方移动应该是减少Y 的值;向右移动是增加X 的值;向下移动是减少Z 的值。
在编辑器中,视角是会随时变化的,视角变化后当前世界的坐标轴是什么方向就不确定了,这个时候可以通过主视口的左下角这里,查看当前的坐标系信息,这里是会随着你视角转动而实时变化的,如图所示:
除了主视口-左下角的信息以外,选中物体时,展示的拖拽箭头,其实也是一样的能体现坐标信息:
这两个位置都符合默认设置:红色是 X 轴,绿色是 Y 轴,蓝色是 Z 轴,箭头方向为正方向!
2. 游戏对象及常用属性
游戏对象包含了游戏功能对象和美术对象两大块:
- 美术对象:提供了搭建场景所必须的物体,如静态模型、特效、音效等,使用它们可以快速搭建游戏场景。
- 游戏功能对象:封装了常见游戏功能逻辑,比如触发器、运动器等,用来快速实现常见游戏功能。
接下来我们从从编辑器的资源库中,拖拽一个静态模型到场景中,这里拖拽了一个正方体到场景中,如图:
然后我们可以看到,属性面板中会显示出该游戏物体的相关属性,并且可以很方便的进行修改设置,这里我们把常用的属性列出来,如图:
基础属性:
Name:示例为 “正方体” ,我们可以在这里修改物体的名称,修改名称后,回车确定修改。
GameObjectId:在场景中的每个物体,都有一个唯一的 Id,我们可以通过 GameObjectId 来查找对应的物体。
网络状态:网络运行环境,具体运行环境的区别可以查看 网络同步原理和结构 | 产品手册
Tag:标签,默认为空,这里可以填写字符串生成标签,一般标签用来标识或区分游戏物体。
变换:
变换:在这里可以修改物体三个轴向的位置、旋转和缩放,但是这里可以看到显示的都是相对坐标,什么是相对坐标呢?具体可以查看下一章节。
场景设置:
可见性:是否显示。包含三个选项,从父对象获取、开启、关闭
碰撞:是否碰撞。包含四个选项,开启碰撞、关闭碰撞、仅开启检测、仅开查询碰撞
- 属性面板的每个节点位置我们都能通过右键点击弹出菜单,进行复制粘贴操作
3. 什么是父子级关系
首先,我们在游戏编辑器的“资源库”中选两个游戏物体并拖拽到游戏场景中,这里将一个正方体和圆锥拖拽到场景中,如图:
在编辑器“对象管理器”窗口中,鼠标单击选中圆锥,然后将圆锥拖拽到正方体上,如视频:
这时候,正方体与圆锥便形成了一个父子关系,之后锥体便会跟随正方体进行移动等操作,如视频:
3.1. 相对位置
选中圆锥,我们在“属性面板”中可以看到,目前显示的位置为“相对位置”,那么这里的相对指的是什么呢?我们在这里点击小三角,发现除了“相对位置”,我们还可以设置“绝对位置”,并且切换显示方式后, X、Y、Z 三个轴的坐标也发生了变化,如图:
那么这里的“相对位置”就是指当前物体相对于父物体的偏移位置,类似于现实世界中,你这样描述你的位置:我在你东边 10 米远,然后南边 5 米远,这就是我对于你的相对位置。
而“绝对位置”指的就是当前物体在游戏场景中的所在位置,类似于现实世界中的经纬度,无论你怎样跟其他人描述你的相对位置,但你的绝对位置经纬度是不会变的。
除了位置以外,旋转和缩放同样也有相对与绝对两种显示方式。
4. 使用脚本获取游戏对象
刚刚我们已经学会了如何拖动一个游戏物体到场景上,现在我们来学习如何使用脚本来获取这个物体,要使用脚本获取物体需要分两种情况:
- 获取脚本自身挂载到的物体。
- 获取场景上其它物体。
4.1 获取脚本挂载的物体
对于脚本自身挂载到的物体,在代码中可以直接使用 this.gameObject
获取,并且可以使用 getChildren
方法来获取该物体下的子物体。
typescript
@Component
export default class Test extends Script {
protected onStart(): void {
// 使用 this.gameObject 获取自身挂载的物体
console.log(this.gameObject.name);
// 获取子物体列表
const children = this.gameObject.getChildren();
console.log("拥有子物体个数:", children.length);
}
}
@Component
export default class Test extends Script {
protected onStart(): void {
// 使用 this.gameObject 获取自身挂载的物体
console.log(this.gameObject.name);
// 获取子物体列表
const children = this.gameObject.getChildren();
console.log("拥有子物体个数:", children.length);
}
}
4.2 获取场景上其它物体
获取场景上的其它物体,我们可以使用 findGameObjectById
函数,通过物体的 GameObjectId
来动态查找。在现实世界中,我们要找到一个置顶的人可以通过它的身份证号来查找,类似的我们在游戏中查找一个游戏对象也可以通过游戏对象的 GameObjectId
来找到它。
GameObjectId
与现实世界中身份证 ID 一样,我们的游戏对象在同个游戏中拥有唯一的 ID,这个 ID 在游戏对象创建时会自动生成,无论怎么修改游戏对象的属性(如修改大小、修改名字)它都不会变。
GameObjectId 相关
每个项目中,物体的 GameObjectId 都不一样,查找时需要注意将下列代码中的 Id 修改为自己本项目物体的的 ID
typescript
@Component
export default class Test extends Script {
/** 当脚本被实例后,会在第一帧更新前调用此函数 */
protected onStart() {
if (SystemUtil.isServer()) {
// 通过立方体的 GameObjectId 找到立方体
const object = GameObject.findGameObjectById("1EB0BD86D97D7EAD");
// 获取立方体有几个子物体(当前只有一个圆锥体)
console.log("子物体个数:" + object.getChildren().length);
}
}
}
@Component
export default class Test extends Script {
/** 当脚本被实例后,会在第一帧更新前调用此函数 */
protected onStart() {
if (SystemUtil.isServer()) {
// 通过立方体的 GameObjectId 找到立方体
const object = GameObject.findGameObjectById("1EB0BD86D97D7EAD");
// 获取立方体有几个子物体(当前只有一个圆锥体)
console.log("子物体个数:" + object.getChildren().length);
}
}
}