Unity 3D官方教程——2D Roguelike学习记录
1.准备工作
新建2D项目命名为2D Roguelike,导入官方资源。保存场景命名为Main。
2.动画制作
分别于Assets文件夹中新建两个文件夹:Animations和AnimatorControl。随后创建一个新的空对象,并将其命名为Player。打开位于Sprites文件夹中的精灵,并将其展开。通过全选前六个小人并拖入到主工作区来实现这一操作。随后系统将自动生成一个动画保存对话框,并将动画序列命名为PlayerIdle存放在Animations文件夹中。

将Animations下的Player动画控制器从当前位置拖至AnimatorController文件夹下。随后导入另外两个角色 animation controllers,并命名为PlayerChop和PlayerHit(具体导入哪些素材请参考官方视频)。每个 game object 支持多个 animations 但仅能配置一个 animation controller。双击 Player animation controller图标并将其 animation speed属性设置为0.5(即调整 animation rate)。
在游戏对象中选择Player角色时,请设置其Tag属性值为'Player'。默认情况下,默认层级设置已经选择了BlockingLayer吗?或者是否需要特别指定?在Sprite Renderer层次下选择Sort Layer并将其属性值设为Units(列表中最末尾的那个),这样它会在游戏图层中显示在最上方。请给角色添加Rigidbody2D组件,并将其Body Type属性值设为Kinematic。然后请配置Box Collider组件的Size参数设为(0.9, 0.9),使其比自身的体积稍小一些。最后,请将此角色拖入到Prefabs文件夹中以使用作预制件

按照流程搭建游戏对象和动画,并将敌方角色的动画控制器导入到AnimatorController中。随后增添 Rigidbody2D 和 BoxCollider组件完成之后将敌方角色导入到Prefab中
随后将敌方角色编号从1改为2,并导入敌方角色2所需的所有 animation. 经过观察发现, 敌方角色 2 和 敌方角色 1 拥有相同的 animation control panel. 因此, 我们决定删除敌方角色 2 的 animation 内容, 因为两者切换动作逻辑相同. 在 AnimatorController 文件夹中创建一个新的 Override Controller, 并将其命名为‘敌人ID 2’; 将其 parent object 设置为主控面板中的‘敌人ID 1’; 并复制其相关 animation 到新创建的角色中.

切换到位于Hierarchy层级中的Enemy2子对象,并将其中位于Animator组件中的Controller替换为专门用于控制Enemy2的动画控制器。随后将游戏对象Enemy2拖入到prefabs层级中,并删除位于Hierarchy层级中的相应对象

3.其他对象预制件(Tile Prefabs)
依次添加地面模型;创建一个新的空物体并命名为Floor1;随后添加一个Sprite渲染器;将所选中的精灵设置为当前对象;将其父层设为地面模型。接着将Floor1拖入到Prefab层级;并将此物体重命名为Floor2;更换所选精灵后继续拖入到Prefab层级。最后完成所有类型的地板预制件制作(共8种类型)。

随后制作出一个出口,并将Floor8命名为Exit的同时也将Tag字段更改为Exit

接着制作食物与汽水这一环节,请确保与上一步骤中的出口设置保持一致。随后将SortingLayer设为Items,并将BoxCollider属性设为勾选Is trigger选项;请特别注意Tag字段应设置为food与Soda两种类型;最后完成所有配置后请保存至Prefab中
随后制作外围墙,并将其命名为OuterWall1。Tag设置为Untagged。将Layer设置为BlockingLayer(其中玩家、敌人以及墙均无法直接通行)。Sorting Layer设为Floor,并取消勾选Is trigger选项。依次制作其余的外围墙(共有三个),请确保每个外围墙导入到Prefab中。
随后是内墙:将OutWall3重命名为Wall1,并将Sorting Layer设置为Items。无需勾选Is Trigger选项。依次制作其余的内墙段落,则总共将制作8堵

4.随机生成地图&储存地图(Board Manager)
新建Scripts文件夹新建BaordManager脚本,并编辑


5.游戏流程控制(Game Manager)
注



注意 :OnLevelWasLoaded已经被淘汰了,官方package里附带的说明pdf里将这一方法修正为:


请将BoardManager脚本导入,并在Inspector中拖放所需的各个prefab(小技巧:通过点击Inspector右上角的小锁图标来锁定该面板从而方便后续操作)
点击Main Camera,将Position设为(3.5,3.5,0),以对准场景,背景设为黑色。
把Hierarchy下的GameManager拖入Prefabs。并deleteHierarchy下的。
请将新的脚本命名为Loader脚本,并确保能够正确加载GameManager。然后,请将其连接至Main Camera。

注意 :在实际运行时会发现level直接是2,4,6...这样一路跳上去。
在官方论坛上提供了详细的说明:https://forum.unity.com/threads/2d-tutorial-roguelike-issues.435126/


在GameManager中进行类似于pdf中的修改操作,在Loader中同样地执行上述操作

请将GameManager游戏对象保存为Prefab形式,并确保无需删除位于hierarchy层级中的对象。接着将Loader组件连接至Main Camera,并将相应的Prefab拖入场景中。
第二种修改方案:
参考:https://answers.unity.com/questions/1139046/fix-for-2d-roguelike-no-restart-and-jumping-scenes.html
参考
保持原Loader脚本,然后把GameManager进行如下修改

-----------------------------------------------------------------------------------------------------

6.移动游戏对象(Moving Objects)
在这个游戏中, player与enemy的移动模式具有相似性, 因此可以把这些移动相似性整合到一个抽象类脚本中, 其中包含一系列需要改进的基础类方法.
新建脚本MovingObject并编辑,



7.对内墙的设置
将墙面分为外墙面与内墙面。我们希望Player能够攻击并摧毁内墙。随后创建名为Wall的脚本,并对其进行编辑。

选中八个内墙预制件拖入脚本,并把对应的精灵填入。
8.玩家设置
将Prefab Player拖拽至Hirerchy面板中。(在每次重启场景(nextlevel)的过程中,在Hirerchy中仅保留Main Camera与Player。在运行期间,默认情况下会从Main Camera子节点加载一个空的Object集(ObjectBundle),随后该ObjectBundle将被用来生成多个辅助组件。在此之后,默认情况下会从Main Camera子节点加载一个空的Object集(ObjectBundle),随后该ObjectBundle将被用来生成多个辅助组件。地图上的其他东西会继续创建。
在完成第一个层级之后(Level 1),Prefab Object不再被销毁;同时,在Player所在的层级地图上创建的所有其他组件依然存活。
再次启动Player游戏控制台的操作步骤如下:首先,在放松模式下进行设置;然后切换至攻击模式并执行操作。

请取消勾选Has Exit Time选项,并将Transition Duration字段设为0;同时针对从刺激态到休闲态的箭头设置进行相应调整。

切换到放松模式的流程在触发条件下的动画仅持续一秒,并无需额外设置;请确保选择Has Exit Time选项并将其时间参数设置为1秒。
Idle和hurt状态的也是同样的操作 。


接下来编写player移动攻击等脚本,新建Player脚本拖入Player并编辑。





记得将脚本的BlockLayer选上。

9.敌人设置
新建脚本命名为Enemy,打开并编辑


随后为怪物配置动画控制器。启动Enemy1的动画控制器,并与Player的一致。创建新的转换状态命名为enemyAttack,并确保与脚本中的名称一致。参考Player设定的方式进行操作。无需为Enemy2配置独立的动画控制器;
它们共享转换状态(Animator Override Controller)。将两个怪物拖入脚本,并启用Blocking Layer。
将敌人的伤害值分别设置为10和20.
10.计分板和关卡设置
在层级结构中创建一个名为LevelImage的新图像,在预设窗口勾选'全覆盖'选项并使用快捷键Ctrl+Alt+S打开该窗口。随后设置该图像的背景色并将其居中显示。接着在图像右侧新增一个名为LevelText的文字框,并将文字框的位置居中设置字号32pt并将文字颜色调整为白色。由于文字过长无法完整显示,请选择水平方向和垂直方向的滚动按钮并将显示内容居中。最后从可变宽字符集选项卡中选择PressStart2P-Ragular字体样式并将该文字框拖拽至 LevelImage 区域,并将其作为子对象添加

创建Text并命名为FoodText,在完成所有设置后,请将它拖动至LevelImage的上方,并将其设为较低层次

将FoodText的Anchor-Ymin和max都设为0.05,修改Pos-Y为0,使分数板稍微上移。
将脚本中的所有与UI相关的注释内容进行修复。(可根据视频教程自行添加),注意在GameManager这一段代码中找到游戏对象的名称可用name = GameObject.Find("targetname");

11.音频设置
在层级架构中新增并命名一个名为SoundManager的部分,并引入两个Audio Source组件和一个名为SoundManager的脚本

保存时导入至SoundManager,并在Wall、Player及Enemy脚本中添加相应的指令以导入音频后顺利播放。(参考视频教程)
12.移动端发布
首先需要在Buliding Settings中添加当前场景并设置平台选择为Ios之后关闭Building Settings随后应在Player脚本中加入以下语句

UNITY_EDITOR主要应用于Unity核心开发环境的调试工作; UNITY_STANDLONE则主要用于iOS、Windows以及Linux系统上的独立应用开发; 而UNITY_WEBPLAY则专门用于网页版游戏或应用程序的远程调试工作。
-------------------------------------------------------------
完成了游戏,在实际测试中发现仅支持第一关的游戏内容。这一现象归因于版本更新导致脚本逻辑发生变化。
将GameManager脚本做如下替换

替换为

建议将level变量初始化为0(如果不进行相应的设置,则可能导致游戏流程被跳过)
再把Player脚本的如下语句

改成

意识到我将food值存入到语句中,并将其被加入到Restart中,并删除了Disable方法的原因是因为如果按照原来的方式放置food值不会有任何变化。
在学习过程中遇到的问题请教官方论坛的2D Roguelike: Q&A会非常有帮助
参考:
探索在Unity3d环境下构建二维roguelike游戏的技术路径
