最新文章
泰课在线 | 微信拼团成功后如何获取课程?
08-09 17:57
Unity教程 | 使用ARKit为iOS开发AR应用
07-31 17:23
Unity Pro专业版7折订阅四选一工具包之VR开发与艺术设计
07-28 11:47
网友使用虚幻UE4实现CAVE 多通道立体渲染的沉浸式环境
07-27 11:57
VR晕动症调查:未来5年内大部分VR晕动症将得到解决
07-27 11:26
AMD CEO:未来3-5年最重要 希望5年达1亿VR用户
07-27 10:44
用虚幻4开发搭积木的VR游戏
虚幻引擎作为国际顶尖水平的3D引擎,一直是众多技术人员所向往的。感谢Epic Games采取免费、开源的政策,让它从“旧时王谢堂前燕”,飞入了“寻常百姓家”。在当前VR开发火热的大环境下,虚幻4在VR技术领域始终保持领先。笔者有幸在虚幻3时代就深入学习过这款引擎,目前也从事虚幻4 VR领域的开发工作,因此希望将自己的经验分享给更多对虚幻4引擎技术感兴趣的同学。
虚幻4 VR开发从何入手
很多人听闻“虚幻引擎比较难学”,但我想说“对未知的恐惧是学习新知的最大障碍”,而且虚幻4在易用性上相较于前一代已有大幅提升。所以,对虚幻4引擎技术心动的同学,不妨放松心情,勇敢尝试,实际上并没有那么难。
无论是VR开发还是游戏开发,我们首先要对引擎中的概念有基础的理解,扎实掌握基础知识。这涵盖基本的编辑器操作、资源管理流程、C++/Blueprint蓝图编程,以及Actor、ActorComponent等基础入门知识。由于大量入门知识不适合用文字表达,我正在泰课在线播出虚幻4入门的系列视频教学课程(https://www.taikr.com/course/417)。对于未接触过虚幻4开发的读者,建议先观看此视频教程,再继续阅读本文。
对引擎有了基本掌握后,VR开发便水到渠成。VR开发在技术层面,主要需对接主流的VR硬件,如头戴式显示(HMD)、手柄等。像Oculus和HTC Vive都为软件开发者提供了可访问其硬件的SDK。而整合这些SDK的工作,虚幻4引擎已完成,我们只需开启指定的插件即可(如图1所示)。虚幻4引擎在上层针对VR硬件提供统一的抽象接口,下面示例中会详细讲解。
虚幻4内置了主流VR硬件支持插件
在Gear VR上开发搭积木的小游戏,下面我们通过这个简单的小游戏,来阐述使用虚幻4开发VR游戏的基本知识。
在这个小游戏中,玩家通过视线瞄准一个积木块,点击Gear VR头盔右侧的Touch Pad即可拿起积木;转动头盔时,拿起的积木块会跟随视线移动;再次点击Touch Pad,积木块放下。之后,使用物理刚体模拟进行状态更新,玩家可以尝试堆积多个积木块。
Gear VR项目创建
首先,我们使用C++ Basic Code工程模板创建新工程,基本设置选择:Mobile/Tablet,以及Scalable 2D/3D。需要注意的是,必须选择C++的工程模板,若使用Blueprint模板,打包到Gear VR后将无法正常运行。
然后,要向引擎中添加一个Oculus签名文件,具体方法如下:
- 手机使用USB线连接电脑。
- 使用“adb devices”命令获取Device ID,例如:0915f92985160b05。
- 打开网址https://developer.oculus.com/osig/,将签名的Device ID粘贴进输入框,点击Download按钮。
- 将获取到的文件(如oculussig_0915f92985160b05)放入:引擎安装目录\引擎版本号\Engine\Build\Android\Java\assets(如图2所示)。
- 最后,在编辑器中打开“Project Settings”->“Android”,修改以下选项:
- Minimum SDK Version:设置为19。
- Target SDK Version:设置为19。
- Configure the AndroidManifest for deployment to GearVR。
这样配置后,UE4项目就可以打包到Gear VR上运行了。
资源准备
尽管虚幻4引擎中默认带有一些基本形状的几何体,但我还是使用3ds Max生成了一套自己的几何体FBX文件。此外,还有几个表情图标作为这些几何体的贴图,我们用不同表情标识对象的不同状态。将这些FBX、TGA文件拖入Content Browser中即可完成导入。
接下来,我们要在引擎中创建一个材质。需注意,贴图的节点“TextureSampleParameter2D”是一个Parameter,这使我们能在运行时改变该节点的内容。
Gear VR开发基础功能
创建VRPlayerBase类
首先,创建一个名为VRPlayerBase的C++类,它从Pawn派生,作为玩家角色。开发Gear VR游戏时,若每次测试都打包到手机运行会很耗时,因此我编写了一段C++代码,用鼠标模拟HMD头盔转动,方便在编辑器中测试视线焦点相关操作。同时,将Gear VR Touch Pad相关操作封装在这个类中,关键代码如下:
void AVRPlayerBase::SetupPlayerInputComponent(class UInputComponent* InputComponent)
{
Super::SetupPlayerInputComponent(InputComponent);
//-- 测试用的鼠标转动操作
// InitializeDefaultPawnInputBindings
UPlayerInput::AddEngineDefinedAxisMapping(FInputAxisKeyMapping("Turn", EKeys::MouseX, 1.f));
UPlayerInput::AddEngineDefinedAxisMapping(FInputAxisKeyMapping("LookUp", EKeys::MouseY, -1.f));
UPlayerInput::AddEngineDefinedActionMapping(FInputActionKeyMapping("MouseLMB", EKeys::LeftMouseButton));
// Action Bind
InputComponent->BindAxis("Turn", this, &AVRPlayerBase::AddControllerYawInput);
InputComponent->BindAxis("LookUp", this, &AVRPlayerBase::AddControllerPitchInput);
InputComponent->BindAction("MouseLMB", IE_Pressed, this, &AVRPlayerBase::OnTouchTap);
//-- Touch
InputComponent->BindTouch(IE_Pressed, this, &AVRPlayerBase::OnTouchBegin);
InputComponent->BindTouch(IE_Released, this, &AVRPlayerBase::OnTouchEnd);
InputComponent->BindTouch(IE_Repeat, this, &AVRPlayerBase::OnFingerMove);
}
在Gear VR真机运行时,要使摄像机跟随头显转动,只需设置VR Player的转动与Controller一致即可(见下图)。
实现视线焦点检测功能
接下来实现视线焦点检测功能,这部分使用Blueprint开发。在蓝图中,我们调用引擎提供的“LineTraceByChannel”进行射线检测。需要指定线段的起点和终点,起点是玩家眼睛所在位置,通过GetActorEyeViewPoint节点获取;终点是沿着玩家面朝向(GetForwardVector)一定距离的点。“LineTraceByChannel”有两个返回值,“Out Hit”是一个结构体,我们用Break节点取出所需项:射线击中的最近的Actor;然后检测它是否实现了“BPI_VRObject”蓝图接口(自定义蓝图接口,后面详述);最后调用自定义事件“OnFocusActorChanged”处理具体逻辑。
现在,可以设置一个新的GameMode,指定这个类作为Player Pawn,并将其设为默认的GameMode。
积木块
创建一个新的蓝图类,从Static Mesh Actor派生,实现积木块的相关功能。首先,为实现动态改变积木块贴图的功能,在Construction Script中创建Dynamic Material Instance。在蓝图脚本中,使用“CreateDynamicMaterialInstance”节点为StaticMeshComponent创建一个动态材质实例,并保存到名为“BlockMaterial”的变量中。
另外,考虑到今后可能添加其他对象类型,创建了一个名为“BPI_VRObject”的Blueprint Interface,用于定义玩家对场景中物体的交互,主要包含以下四项。
实现积木块交互功能
当玩家注视积木块时,让它眨眼(换张贴图)。首先,在积木块的Blueprint的Class Settings中添加上述Blueprint Interface,然后在EventGraph中使用Add Event菜单添加OnFocus和LostFocus事件处理。在蓝图中,实现“BPI_VRObject”的两个接口事件,分别是OnFocus和LostFocus,在焦点获得或失去时,调用“SetTextureParameterValue”节点改变材质中的BaseColor所使用的贴图资源对象。
当积木块坠落时,显示害怕的表情;静止不动时,显示微笑表情。此功能通过刚体(Rigid Body)的Wake、Sleep状态实现。要设置StaticMesh组件的“Generate WakeEvent”才能收到这两个事件。在Blueprint脚本中,通过响应“OnComponentWake”和“OnComponentSleep”变更自定义变量“IsSleeping”,然后调用自定义事件“ChangeTextureByState”变更材质的贴图参数。
当玩家抓起积木时,让它开始哭,实现方法与上述类似,在此不再赘述。
在玩家周围随机生成积木块
既然积木已准备好,可在关卡启动时随机生成一些积木供玩家玩耍。此功能可在Level Blueprint或Game Mode中实现,这里假设是本测试关卡的功能,将其放在Level Blueprint中。蓝图代码在PlayerStart对象周围随机产生10个积木块,响应关卡的BeginPlay事件,通过ForLoop节点调用10次SpawnActor节点,Class参数选择积木块(BP_Block);积木块的出生点通过MakeTransform节点生成,该节点使用3种不同随机方式产生位置、旋转和缩放参数。
拿起和放下积木
继续完善玩家类,添加拿起、放下积木块的功能。玩家先注视某个积木,轻点Touch Pad拿起积木;转动头盔,积木随视线移动;再次轻点TouchPad放下积木。
首先,在Touch Pad的Tap事件中实现上述流程,该Tap事件在VRPlayerBase的C++类中触发。在此,判断如果PickActor是有效值,则调用DropActor,否则调用PickFocusActor。
其中,Pickup Focus Actor和Drop Actor是两个自定义事件。在PickupFocusActor事件中,先通知积木块对象调用其OnPickup接口,然后用TimeLine驱动的动画控制积木块位置,使其从当前位置平滑移动到玩家面前的位置。在DropActor事件中,先通知积木块对象调用其OnDrop接口,然后将PickedActor对象设为空值。
总结
通过上述步骤,一个简单且有趣的积木小游戏就完成了。你可以通过项目打包功能生成APK包,在Gear VR上体验。由于篇幅限制,项目中的一些细节无法详述。
本文演示的项目仅为讲述基本开发方法,未对画面效果进行修饰。实际上,虚幻4在手机上已支持PBR材质效果。各种酷炫效果有待大家发掘。在未来一段时间内,我会持续更新关于虚幻4开发的视频教程,欢迎大家关注“泰斗社区”。