场景初始化
修改场景加载逻辑我们修改SceneMgr,让它能够抛出场景加载和卸载的事件。
我们每当打开一个新场景,配合当前场景配置文件来动态加载这个场景需要的各种脚本。我们还需要给出加载进度。
进度设置规则:加载场景——设为1,新场景每个需要加载的脚本都设为1,它们的总数为每个需要加载的场景的总进度。加载场景要设为1是因为不设值的话根本不知道场景的加载情况。
修改SceneName修改Enum的SceneName
1234567public enum SceneName{ NULL, StartScene, Game, COUNT//+++}
修改SceneMgr12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788public class SceneMgr : NormalS ...
对象池
文件规制Assets——新建UI文件夹——在其中新建MainUI和GameUI文件夹——把之前的Controller文件夹和View文件夹转移到MainUI文件夹内。
Assets——新建Logic文件夹
GameObjectPoolAssets——Module——新建Pool文件夹,在其中新建GameObjectPool
Module内的代码都是独立的模块,各自的逻辑都是独立的,不能引用LoadMgr等在游戏内使用的逻辑
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120using System;using System.Threadin ...
异步获取Json数组数量(难点)
在上一节,我们动态生成了音量的配置文件,但是它是直接通过LitJson.JsonMapper生成的,由于我们传入的是一个List,所以最后生成的也是一个数组(用中括号括起来的)。
123456789101112131415161718192021222324252627282930[ { "Name": "Game_BG", "Volume": 0.5 }, { "Name": "player_0", "Volume": 0.5 }, { "Name": "player_1", "Volume": 0.5 }, { "Name": "player_2", "Volume": 0.5 }, { ...
音频管理
音频文件处理在音频文件的导入设置中,Default选项卡内,设置Load Type。
比较长的背景音,选择Stream模式。比较短的音效,选择Decompress On Load。一般情况下不选Composed In Memory。
在Decompress On Load模式下,关闭PreLoad Audio Data。
AudioSetting在Editor文件夹中新建AudioSetting
123456789101112131415161718192021using UnityEditor;using UnityEngine;public class AudioSetting : AssetPostprocessor{ private void OnPostprocessAudio(AudioClip clip) { AudioImporter audioImporter = assetImporter as AudioImporter; AudioImporterSampleSettings customSetting ...
关卡加载
补充关卡加载部分的逻辑,在这里的逻辑设计中,每次加载Scene都需要主动打开Loading界面。由Loading界面驱动场景加载逻辑。
Loading界面Loading界面的Prefab包括一个背景和一个Slider和一个Progress(Text)。我们使用Slider作为进度条,因为其中的Fill图片可以使用Sliced模式。这样我们可以使用九宫格切割过(一般是个圆形图片,只切两边)的更好看的图片当作加载进度条了。
Pathes中的Prefab路径
1public const string LOADING_VIEW = PREFAB_FOLDER + "LoadingView";
添加KeyDataKeys里面添加存档中已经通过的关卡部分的Key
1public const string LEVEL_PASSED = "levelPassed";
SceneMgr在Enums中添加Scene名的枚举
123456public enum SceneName{ NULL, StartScene, Game} ...
异步任务队列(难点)
在开发中,我们遇到了需要获取多个异步读取的结果才能继续执行的逻辑。
这时我们设计一个异步读取队列类,它负责收集所有需要异步读取的命令,并且在所有的异步读取命令完成之后,按照指定的顺序返回结果,执行相应的回调。
TaskQueue在Module文件夹内,新建TaskQueue文件夹并新建TaskQueue.cs文件
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556using System;using System.Collections.Generic;using UnityEngine;public class TaskQueue{ private readonly Queue<Action<TaskQueue, int>> _tasks; private int _id; private object[] _values; private int _addValueTim ...
选关界面
PrefabLevelsView
白色的框表示Levels的Rect大小,height为500,width为400.
LevelItem
其中的Enter和Mask都是Button,如果此关卡没有激活,Mask代表的Button会挡住Enter,表示不能选关;反之Mask会关闭,让紫色的Enter按钮露出来,点击Enter就能进入关卡。
LevelItem的锚点对齐方式为top-left,初始的Pos X和Pos Y都为0。
开发准备Pathes在Pathes中添加预制体路径
1234public const string LEVELS_VIEW = PREFAB_FOLDER + "LevelsView";public const string LEVEL_ITEM = PREFAB_FOLDER + "LevelItem";//...public static readonly string LEVEL_CONFIG = CONFIG_FOLDER + "/LevelConfig.json";
SelectedHero ...
英雄选择2
SelectHero和HeroItem还没有分离出View和Controller的逻辑,先分离出来。
SelectHeroController
不要把它和SelectedHeroController搞混了,这里主要分离的是SelectHero的逻辑
123456789101112using UnityEngine;public class SelectHeroController : ControllerBase{ protected override void InitChild() { foreach (Transform trans in transform) { trans.gameObject.AddComponent<HeroItemController>(); } }}
SelectHero修改SelectHero,让它继承ViewBase
123456789101112using UnityEngine;pub ...
公共弹窗
公共弹窗一般即用即生成,不在UIMgr中缓存,生成公共弹窗时正好生成在Canvas的最前面,销毁时也是在Canvas内直接Destroy。
Prefab设计
Content下面挂载Text组件和ContentSizeFitter组件以及Layout Element组件,Horizontal Fit和Vertical Fit都设置成preferred size,Preferred Width设为550。
Content里面显示的文字有多有少,我们需要把它设置成自适应的,挂载ContentSizeFitter组件能够保证文字的Rect数据随着文字的内容动态变化,从而方便计算。注意,我们不能打开Text组件的Best Fit来自适应,那样会消耗很多性能。挂载Layout Element组件能让文本自动换行。文本宽度超过550时自动换行。
Buttons和One、Two都是横向Stretch模式,PosY和Height都可以设置
在自适应计算的过程中,我们以Content的CenterTop锚点为基准点。
挂载Layout Element组件时会强制修改Rect的宽度,我们需要在代码中 ...
强化界面4
接下来,我们完成强化界面的升级部分。
每次升级的花费需要配置好,我们再修改一下游戏的配置。增加升级花费的条目“upgrades”
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152{ "planes": [ { //... "upgrades": { "name": "升级", "coefficient": 2, "max": 4, "0": 100, "1": 200, "2": 300, "3": 400 } }, { //. ...