跳到主要内容

场景2—节点变换

概述

这个案例实现了通过键盘控制一个小球移动的效果,主要使用到了Input方法和刚体的相关内容,完整的项目介绍请见应用教程

场景准备

  1. 创建一个3D场景,拖入“迷宫”文件夹下的模型文件到场景中,为模型添加静态刚体

  2. 新建空相机替换默认的飞行相机,调整到合适的位置,启用正交并设置大小为30,让画面具有2.5D效果

  3. 从模型库中拖入一个球体,点击该球体节点,使用工具栏左上角的“一键转换为刚体”

  4. 结构图如下:

脚本实现

为小球的刚体节点添加脚本,脚本的类型会自动继承刚体的节点类型,在脚本中可以使用刚体类型相关的方法,本案例重载了刚体的_integrate_forces方法,这个方法可以自定义刚体的物理行为。

自定义变量

设置速度大小和速度方向的变量,速度的变量添加了一个export关键字,这样可以在属性栏中快速修改速度的值,而不用每次都在脚本中修改。

export var speed = 5 #速度大小
var direction = Vector3.ZERO #速度方向

方向键计算小球运动朝向

使用_input函数获取键盘按键的输入,判断输入事件的类型,如果为键盘按下事件,则进一步使用按键的scancode判断按下了哪一个按键,如果按下的是方向键,则进行对应方向上速度的设置,如果是组合键Control则重置小球的位置

tip

在按下一个按键并松开后,会受到按下时和松开时得到的两个InputEventKey事件,需要用is_pressed()方法进行区分,这和上一章使用Input单例进行移动有所不同。通常_input方法只适用于单个按键的处理,对于更复杂的按键行为推荐使用Input单例,参考上一节的相机控制。

func _input(event):
direction = Vector3.ZERO #方向的初始值
if event is InputEventKey and event.is_pressed():
#按下方向键是调整方向
if event.scancode == KEY_UP:
direction.z += 1
if event.scancode == KEY_DOWN:
direction.z -= 1
if event.scancode == KEY_LEFT:
direction.x += 1
if event.scancode == KEY_RIGHT:
direction.x -= 1

#按下Control+R重置小球位置
if event.scancode == KEY_R and event.control:
transform.origin = Vector3(-1.2, 0.5, -10)

将移动速度应用到小球刚体

刚体类中有一个_integrate_forces方法,可以通过这个方法自定义刚体的运动,但由于IdeaXR的物理系统会自动模拟刚体的运动,可能会与脚本中定义的运动产生冲突,因此需要在_ready函数中将custom_integrator的值设为true

设置刚体的linear_velocity属性可以让刚体按给定速度做匀速直线运动。将linear_velocity设为速度大小和速度方向的积:

func _ready():
custom_integrator = true #启用自定义积分器

func _integrate_forces(state):
linear_velocity = speed*direction

运行场景,按下键盘上的方向键,小球即可移动,遇到碰撞体时会自动停止。调整小球位置,即可开始一个小球在迷宫中移动的小游戏。