场景(Scene)间跳转
注册场景
- 打开文件->生成设置
- 将所有的场景拖入
- 可以将场景调序,后续调用时可以用序号跳转
注意下图中的**Tutorial**错误的拼写为 **Turorial**

跳转场景
初步规划主菜单各个按钮的交互
- 开始游戏
- 单人游戏->跳转到Game
- 组队游戏->跳转到TeamLobby
- 教程->跳转到Tutorial
- 实验室->跳转到Laboratory
- 设置->直接在主菜单生成子菜单
- 退出游戏->弹窗询问是否真的要退出->关闭游戏
- 在父组件Canvas上挂个脚本MainMenuUIInterace
- 编写方法:如下图

- 按照下图顺序完成按钮点击设置:按钮->鼠标点击->选择相应函数->你写的脚本名称->你写的函数名称
- 一定记得把Canvas挂在图中蓝色箭头指向的位置

- 以此类推完成所有按钮的点击设置
次级菜单设置
Start Game子菜单
- 在Canvas下创建空对象命名为StartSubmenu,在StartSubmenu下创建空对象命名为ContentPanel,添加Vertical Layout Group组件,准备将单人游戏和组队游戏的按钮放在一个空对象下
- 使用之前创建好的“Button预制体”,同Day3->场景(Scene)间跳转->跳转场景,预先创建好鼠标点击事件
- 取消勾选StartSubmenu,因为一开始StartSubmenu是隐藏的

最终要实现的逻辑
- 点击Start Game->弹出两个子菜单
- 点击非子菜单内容->子菜单隐藏
- 点击Single Player->跳转到Game
- 点击Multiplayer->跳转到TeamLobby
- 在MainMenuUIInterace脚本中新增方法OnSignlePlayerClick与OnMultiplayerClick,与Day3->场景(Scene)间跳转->跳转场景一样添加场景跳转
- 按照下方代码所示方法获取组件(注意注释)
- 修改OnStartClick方法,去掉原本的场景跳转,修改为点击StartGame后显示StartSubmenu
- 为了实现点击非子菜单内容,将子菜单隐藏的功能,可以在StartSubmenu添加一个覆盖全屏的按钮CloseZone,当点击到此按钮时进行隐藏StartSubmenu
- 为覆盖全屏的按钮添加Layout Element组件,选择Ignore Layout,从而不影响剩余按钮的排版,并且为此按钮添加方法
- 为新添加的按钮添加翻译
最终结构如图所示

代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
| using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.SceneManagement;
public class MainMenuUIInteract : MonoBehaviour { private GameObject startSubmenu; private GameObject SettingsSubmenu; private void Awake() { Transform subTrans = transform.Find("StartSubmenu"); { startSubmenu = subTrans.gameObject; } else { Debug.LogError("StartSubmenu 子物体未找到!"); }
Transform settingsTrans = transform.Find("SettingsSubmenu"); if (settingsTrans != null) { SettingsSubmenu = settingsTrans.gameObject; } else { Debug.LogError("SettingsSubmenu 子物体未找到!"); } } public void OnStartGameClicked() { if (startSubmenu != null) { startSubmenu.SetActive(true); } } public void OnSinglePlayerClicked() { SceneManager.LoadScene("Game"); } public void OnMultiplayerClicked() { SceneManager.LoadScene("TeamLobby"); } public void OnTurorialClicked() { SceneManager.LoadScene("Tutorial"); } public void OnLaboratoryClicked() { SceneManager.LoadScene("Laboratory"); } public void OnSettingsClicked() { if (SettingsSubmenu != null) { SettingsSubmenu.SetActive(true); } }
public void OnExitGameClicked() { Debug.Log("执行退出游戏命令!(提示:在 Unity 编辑器中点击只会打印这行字,打包成 exe 后才会真正关闭窗口)"); Application.Quit(); } public void OnCloseZoneClicked() { if (startSubmenu != null) { startSubmenu.SetActive(false); } } }
|
设置面板
26/3/23 Update:意识到设置面板在任何场景都可能使用,所以应当抽离出来作为单独的部分,用单独的Canvas_Settings_Menu作为设置面板的画布
规划
- 需要Barrier用于屏蔽点击非设置内容时的点击事件(尤其是防止打开设置面板后依旧能点开始游戏等问题)
- 设置面板内需要分为两个区域:选项卡(Tab)和选项内容(Content)
- 选项卡:语言、控制、音效、图像
- 选项内容:具体内容
具体层级如下图所示

Barrier设置
子物体不会大于父物体,所以Canvas_Settings_Menu需要占据全屏才可以使Barrier占据全屏
- 创建空物体Canvas_Settings_Menu并创建一个按钮作为子物体,命名为Barrier
- 将Canvas_Settings_Menu拉伸至全屏
- 删除按钮的Text(TMP)子物体,调整Image组件,将透明度调为0。
- 将Barrier拉伸至全屏
SettingsPanel切换
先预览最终结构
- UI->Panel创建画板,重命名为SettingsPanel
- 在SettingsPanel下创建两个空对象,分别重命名为Bar与Settings,在Bar下创建空对象并重命名为Content
- 为Bar添加以下组件
- ToggleGroup组件,勾选当中的Allow Switch Off
- Rect Mask 2D组件,取消勾选Scroll Rect中的Horizontal水平滚动选项
- Scroll Rect组件,调整Scroll Sensitivity改变滚动灵敏度;将Content拖入Scroll Rect组件的Content内容选项
- Content下创建Toggle对象,重命名为Bar_Toggle,准备用它制作预制体,需要进行以下操作
- 在Bar_Toggle下的Toggle组件中,选择合适的配色,并且把Bar拖到下方的Group选项卡中
- 删去Bar_Toggle->Background下的Checkmark子物体
- Bar_Toggle->Background的Ract Transform组件调整颜色覆盖区域
- Bar_Toggle->Label像之前一样添加自动切换字体功能,Text组件对齐方式改为居中,Ract Transform延伸至合适大小
- 保存预制体
- 为Content创建Vertical Layout Group组件和Content Size Fitter组件,将Content Size Fitter组件中的Vertical Fit选项设为Preferred Size
- 使用预制体添加自己需要的选项,例如下图

- 新建SettingsManager脚本挂在在Canvas_Settings_Menu上。参考以下代码实现面板的切换
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
| using UnityEngine; using UnityEngine.UI; using UnityEngine.Localization.Settings; using TMPro;
public class SettingsManager : MonoBehaviour { public static SettingsManager Instance { get; private set; }
[Header("UI 引用")] private GameObject _settingsPanel; private GameObject _languagePanel; private GameObject _controlsPanel; private GameObject _audioPanel; private GameObject _graphicsPanel;
private void Awake() { if (Instance != null && Instance != this) { Destroy(this.gameObject); return; } Instance = this; DontDestroyOnLoad(this.gameObject);
_settingsPanel = transform.Find("SettingsPanel").gameObject;
Transform Settings = _settingsPanel.transform.Find("Settings"); _languagePanel = Settings.Find("LanguagePanel").gameObject; _controlsPanel = Settings.Find("ControlsPanel").gameObject; _audioPanel = Settings.Find("AudioPanel").gameObject; _graphicsPanel = Settings.Find("GraphicsPanel").gameObject;
Transform Bar = _settingsPanel.transform.Find("Bar"); Toggle ToggleLanguage = Bar.Find("Content/Language").GetComponent<Toggle>(); Toggle ToggleControls = Bar.Find("Content/Controls").GetComponent<Toggle>(); Toggle ToggleAudio = Bar.Find("Content/Audio").GetComponent<Toggle>(); Toggle ToggleGraphics = Bar.Find("Content/Graphics").GetComponent<Toggle>();
ToggleLanguage.onValueChanged.AddListener((isOn) => { if (isOn) SwitchSettingsPage(_languagePanel); }); ToggleControls.onValueChanged.AddListener((isOn) => { if (isOn) SwitchSettingsPage(_controlsPanel); }); ToggleAudio.onValueChanged.AddListener((isOn) => { if (isOn) SwitchSettingsPage(_audioPanel); }); ToggleGraphics.onValueChanged.AddListener((isOn) => { if (isOn) SwitchSettingsPage(_graphicsPanel); });
ToggleLanguage.isOn = true; SwitchSettingsPage(_languagePanel);
CloseSettings(); }
public void OpenSettings() { foreach (Transform child in transform) { child.gameObject.SetActive(true); } }
public void CloseSettings() { foreach (Transform child in transform) { child.gameObject.SetActive(false); } }
private void SwitchSettingsPage(GameObject page) { _languagePanel.SetActive(false); _controlsPanel.SetActive(false); _audioPanel.SetActive(false); _graphicsPanel.SetActive(false); page.SetActive(true); } }
|
SettingsPanel内容
因为有许多设置内容,可能无法全部呈现,所以同样要设置为可滑动窗口,步骤与上面的Bar一致,我这里不再详细描述,而是提供两张图片。
注意组件的添加位置以及需要更改的内容

