Unity官方教程:Roll A Ball(PM版)

这篇文章默认大家已经对Unity3D和PlayMaker有一定的了解,所以没有把所有操作步骤都写的非常详细,不太看得明白的同学可以先行阅读:

视频教程已经上传YouTube:[教程]使用PlayMaker重制Unity官方“滚动小球”教程
视频文件及素材资源下载地址在:百度网盘


Unity3D官方教程是非常非常优秀的新手入门学习资源,将其PlayMaker化是一个挺有趣的体验。

本教程是Unity官方教程第一篇,原教程地址:Roll-a-ball tutorial


准备场景

scene_setup_01.png

Roll-a-ball的场景很简单,一块2×1×2的蓝色Plane做地面(命名为Ground),四个0.5×1×20.5的Cube做墙壁(放在Walls空物体之中),墙壁物体距离坐标原点10单位长度,一个1×1×1的Sphere作为玩家操控的小球(命名为Player)。

scene_setup_camera_01.png
scene_setup_light_01.png

设置Main Camera的位置和旋转,修改Directional Light的位置与旋转,得到合适的摄影机位置以及光照效果。

scene_setup_02.png

添加小球运动

给Player添加一个Rigidbody组件。

player_01.png

Rigidbody将游戏物体变成一个“主动刚体”,使其可以受到力的作用而改变其位置和旋转,并且会根据其碰撞体(Collider)组件的设置而与其他物体相互作用。

Unity中的刚体动力学是这样划分的:

  • 没有添加Collider组件的游戏物体不参与动力学计算;
  • 只有Collider组件且没有勾选Is Trigger选项的游戏物体被认为是“被动刚体”,不会被动力学改变其运动状态,也就是说不会被撞开;
  • 勾选了Is Trigger选项的Collider不会起到阻挡其他Collider的作用,也就是不会发生碰撞现象,但依然能够感知到其与其他Collider之间发生的交互作用,比如有其他Collider进入、停留或离开该Collider范围时,该Collider是能够感知到的;
  • 有Collider组件也有Rigidbody组件的游戏物体被认为是“主动刚体”,主动刚体会受到动力学作用而改变运动状态,我们可以给主动刚体施加作用力或设置运动速度,也可以用其他刚体去撞击主动刚体;
  • 勾选了Use Gravity(使用重力)选项的Rigidbody会持续受到重力作用而向-Y方向运动,除非被其他刚体阻挡;
  • 勾选了Is Kinematic(运动学)选项的Rigidbody将忽略外力作用,也就是说重力和刚体撞击都不会使其产生运动,但我们直接设置其速度(velocity)来让其运动起来,算是一种特殊的“主动刚体”吧。

为Player添加Fsm,在State 1中添加Get Axis Vector以获得输入向量,添加Add Force为Player施加作用力。

player_fsm_01.png

与控制角色运动不同,控制小球运动我们不仅希望改变其位置,还希望小球能够“滚动”起来,这时候使用“施加作用力”的方式就比“设定运动速度”的方式要合适一些。并且,通过“施加作用力”来控制物体(尤其是球形物体)并不能非常精确的控制对象的运动(因为有惯性作用),所以用在这里反而能给游戏添加一些难度和乐趣。

这里我指定了两个变量,一个speed变量用来设置小球的运动速度,一个input axis变量用来储存输入向量值。speed变量勾选了Inspector选项,使其可以在Inspector中可见。

player_fsm_02.png

添加可拾取的小方块(Pickup)

在场景中新建一个Cube(改名为Pickup),修改其位移属性为<<0, 1, 0>>,修改其旋转属性为<<45, 45, 45>>,修改其缩放属性为<<0.5, 0.5, 0.5>>,添加一个黄色材质给Pickup。

为Pickup添加一个Fsm,在State 1添加一个Rotate:

pickup_fsm_01.png

勾选了Every Frame选项之后,Rotate行为可以按照Vector参数中所设定的旋转速度,持续旋转指定游戏物体。为了获得平滑的旋转效果,可以勾选Per Second选项和Fixed Update选项,让其按照“每秒多少度”的方式来进行旋转。

这里我没有直接输入旋转速度,而是通过新建一个名称为rotate speed的变量来控制,rotate speed变量的初始值设置为<<15, 30, 45>>,并在Inspector中可见。

将设置好的Pickup物体转换成prefab,然后在场景中复制摆放。新建一个名为Pickups的空物体来放置所有的Pickup物体,以保持场景整洁。

place_pickups_01.png

小球“拾取”黄色方块

Roll A Ball小游戏的基本交互逻辑是:玩家控制小球在场景中“拾取”所有的黄色小方块。为了达成这个目的,我们需要进行“碰撞”判定:当小球的碰撞体与黄色方块的碰撞体相交时,黄色方块消失。

由于小球和黄色方块上都具有Collider组件,所以这个判定工作可以被放在小球上,也可以被放在黄色小方块上。在这个范例中我们选择将判定工作放在小球上,是因为这个判定是每帧执行的,如果放在小方块上,则所有的小方块都会每帧执行判定操作,显然执行效率不如将判定放在小球这一个物体上。

为Player添加一个Trigger Event,设定其当有其他Trigger进入小球的碰撞体范围时,将这个Trigger物体储存在一个叫做pickup object的变量中,并触发hit a pickup事件。

为了避免别的trigger物体的干扰,我们设定这个Trigger Event行为仅针对那些被Tag为Pickup的Trigger物体起效果。因此,我们需要添加一个名为Pickup的Tag,并将所有的Trigger物体标记上这个Tag。

当hit a pickup事件被触发时,Player的Fsm状态从State 1跳转为State 2。

payer_fsm_02.png

在State 2中,我们添加一个Activate Game Object,设置pickup object变量中所储存的游戏物体(也就是进入了Player碰撞体的Trigger物体)的Activate属性进行取消操作。

Activate实际上就是游戏物体Inspector面板中名称前面的小勾选框,如果取消勾选,这个游戏物体就“隐藏”了,或者说“失效”了,虽然依然存在于游戏场景中,却不会起到任何作用。

payer_fsm_03.png

同时,我们还需要将Pickup物体(黄色小方块)的碰撞体设置为Trigger类型(勾选Box Collider组件中的Is Trigger选项),并设置其为Kinematic(勾选Rigidbody组件中的Is Kinematic选项)。

将小方块设置为Trigger类型是因为我们不希望小球和方块发生实际碰撞,只希望检测到双方相互触碰而已;将小方块设置为Kinematic是因为我们不希望小球在添加了Rigidbody之后受到重力作用而改变其“浮空自动旋转”的运动状态设置。

注意,如果是在场景中对Pickup物体进行的修改,需要点击Apply按钮将其修改应用到其他所有Pickup物体上,或者直接对prefab物体进行修改。

pickup_inspector_01.png

运行测试,我们现在可以用小球“吃掉”所有的黄色小方块了。


添加UI

我们希望每“吃掉”一个小方块,就能够得到1分,“吃完”所有的小方块,就可以赢得游戏!

在场景中添加两个UI Text物体:Score Text和Win Text:

UI_01.png
UI_02.png

可以看到,系统自动创建了一个Canvas,并将UI Text物体放置在Canvas中。同时,系统还创建了一个EventSystem,这两个自动创建的节点都不要随便删掉。

修改两个UI Text物体的参数,获得如下UI显示:

UI_03.png
UI_04.png
UI_05.png

注意,这时候我们在Inspector中输入的UI文字内容只是一个预设值,我们后面会用PlayMaker控制其中文字内容的。


在Fsm中控制UI显示内容

这时候需要对Player的Fsm进行一些较大的修改了。

payer_fsm_04.png

首先,State 2中需要加入“计分”的功能,并判断是否所有的Pickup物体都被“吃掉”了。如果是,则跳转到State 4(游戏获胜状态),如果否,则跳转回State 1继续游戏。同时,State 2中还需要进行UI文字内容更新操作,使其显示最新的分数。

其次,需要制作游戏获胜状态State 4,这里需要显示Win Text。

最后,需要在State 1之前添加一个State 3,在State 3中做一些必要的预设工作。

State 3

在State 3中:

  1. 用Set Int Value设置一个score变量,并将其数值初始化为0;
  2. 用Set Game Object设置一个score text变量,并指定Score Text物体给score text变量;
  3. 用Set Game Object设置一个win text变量,并指定Win Text物体给win text变量;
  4. 用Convert Int To String将score变量值转换成一个字符串变量score string,以便指定为UI文字的内容;
  5. 用U Gui Text Set Text将score text物体的Text参数值设置为“ ”(也就是无内容,如果什么字都不打PlayMaker会报错,所以打个空格就好了);
  6. 用U Gui Text Set Text将win text物体的Text参数值也设置为“ ”。

注意:U Gui Text Set Text行为需要自行安装uGui行为包。

payer_fsm_05.png

在State 2中:

  1. 添加Int Add让score数值加1,代表得到1分;
  2. 添加Int Compare比较新的score数值和一个total pickups变量(手动设置为12)中的数值谁大谁小,如果score >= total pickups,则触发win事件(跳转到State 4);
  3. 添加Convert Int To String将score变量值转换成一个字符串变量score string,设置Format参数使其显示为“Score: 1”这样的格式;
  4. 添加U Gui Text Set Text将score string指定给score text物体的Text参数值,更新score text的显示内容。

注意,Int Compare放在Convert Int To String前面,当“吃到”最后一个小方块的时候,score text不会更新为Score: 12,因为已经直接跳转到State 4了。如果希望在State 4的时候能看到Score: 12这样的分数显示,则需要将Int Compare放在U Gui Text Set Text的后面。

payer_fsm_07.png

在State 4中:

  1. 添加U Gui Text Set Text将win text的文字直接设置成“You Win!”。

这里其实偷了个巧,懒得去做显示隐藏Win Text物体的操作,就直接用“ ”来假装Win Text未出现。

最终的UI显示效果如下:

final_01.png

到此为止,就完成了Unity官方Roll A Ball教程的PlayMaker化!


一些小改进

发布游戏之前,添加了一些小改进:

  1. 给小球添加了贴图,可以清晰看到小球的旋转;
  2. 添加了一个RESTART按钮让玩家可以重新开始游戏;
  3. 烘焙了光照贴图;
  4. 添加了一点点后期效果:抗锯齿、边缘暗化;
  5. 添加了背景音乐和“吃掉”小方块时的音效。

WebGL版游戏演示:Roll A Ball


其他的设计思路

Roll A Ball小游戏非常简单,但我们可以在这个基础上开开脑洞,设计一些其他玩法,比如:

  • 添加复杂的墙壁,修改小方块布局,以得到不同的关卡设计;
  • 设置墙壁不可触碰,碰到墙壁则重置游戏;
  • 规定时限,时限内没有吃到所有的小方块则任务失败;
  • 添加陷阱,比如地面有个洞;
  • 添加机关、道具,比如传送门;
  • 为小球添加跳跃行为;
  • 添加坡度,将目前的平面关卡设计转换为立体关卡设计;
  • ……

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,230评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,261评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,089评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,542评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,542评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,544评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,922评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,578评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,816评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,576评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,658评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,359评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,937评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,920评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,859评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,381评论 2 342

推荐阅读更多精彩内容