59、游戏菜单与关卡设置全解析

游戏菜单系统开发详解

游戏菜单与关卡设置全解析

在游戏开发中,菜单系统是玩家与游戏交互的重要界面,它不仅影响着玩家的游戏体验,还涉及到游戏的各种设置和功能的实现。本文将详细介绍游戏菜单系统的开发过程,包括设置菜单、确认对话框、信用界面、菜单模式跟踪以及导航和场景交互的暂停等方面。

1. 设置菜单的构建

设置菜单是主菜单中最复杂的部分,它允许玩家对游戏的视觉和音频展示进行控制。在开始编码之前,我们需要明确所需的设置项,包括导航、文本、音频和光标选项等。

1.1 添加变量到 MenuManager 脚本
//Settings menu variables
internal var walkSpeed : float;               // element 0
internal var turnSpeed : float;               // element 1
internal var useText : boolean;               // element 2
internal var objectDescriptions : boolean;    // element 3
var fXVolume : float = 1;                     // element 4
var ambVolume : float = 1;                    // element 5
var musicVolume : float = 1;                  // element 6
var voiceVolume : float = 1;                  // element 7
internal var colorElement : int;              // element 8

internal var playerSettings  = new String[9]; // player settings array in string format

// cursor color
var colorSwatch : Texture;
var cursorColors = new Color[8];
var moColor : Color;                          // current mouseover color

这里的 playerSettings 变量用于存储玩家的设置,为了便于在移动平台上使用,我们将值转换为字符串格式。

1.2 在 OnGUI 函数中添加设置项代码
  • 导航速度设置
// fpc speeds
GUI.Label (Rect (25, 35, 100, 30), "Walk Speed");
walkSpeed = GUI.HorizontalSlider (Rect (150,40, 100, 20), walkSpeed, 0.0, 20.0);
GUI.Label (Rect (25, 60, 100, 30), "Turn Speed");
turnSpeed = GUI.HorizontalSlider (Rect (150,65, 100, 20), turnSpeed, 0.0, 40.0);
  • 文本显示选项
// text
var textY : int = 90;
useText = GUI.Toggle (Rect (30,textY, 120, 30), useText, "  Use Text");
objectDescriptions = GUI.Toggle (Rect (30,textY + 30, 120, 30), objectDescriptions,  
" Use Descriptions");
  • 音频音量设置
// audio
var audioY : int = 120;
audioY += 30;
GUI.Label (Rect (25, audioY, 100, 30), "FX Volume");
audioY += 10;
fXVolume = GUI.HorizontalSlider (Rect (150,audioY, 100, 20), fXVolume, 0.0, 1.0);
audioY += 14;
GUI.Label (Rect (25, audioY, 100, 30), "Ambient Volume");
audioY += 10;
ambVolume = GUI.HorizontalSlider (Rect (150,audioY, 100, 20), ambVolume, 0.0, 1.0);
audioY += 14;
GUI.Label (Rect (25, audioY, 100, 30), "Music Volume");
audioY += 10;
musicVolume = GUI.HorizontalSlider (Rect (150,audioY, 100, 20), musicVolume, 0.0, 1.0);
audioY += 14;
GUI.Label (Rect (25, audioY, 100, 30), "Dialog Volume");
audioY += 10;
voiceVolume = GUI.HorizontalSlider (Rect (150,audioY, 100, 20), voiceVolume, 0.0, 1.0);
  • 光标选项设置
// cursor
var cursorY = 260;
GUI.Label (Rect (30, cursorY, 140, 30), "Current Mouseover Color");
GUI.contentColor = moColor;
GUI.Box (Rect (180, cursorY, 20, 20),GUIContent (colorSwatch));
GUI.contentColor = Color.white;

cursorY += 25;
GUI.Label (Rect (20, cursorY , 120, 30),  "Mouseover Colors");
cursorY += 20;
var cursorX : int = 160;
// display color swatches
for (var i : int = 0;i < 8;i++) {
   GUI.color = cursorColors[i];
   if (GUI.Button (Rect (cursorX, cursorY - 15, 20, 40),colorSwatch,simpleText)) {
      moColor = cursorColors[i];
      colorElement = i;
   }
   cursorX += 25;
}
GUI.color = Color.white;// clear the color for the remaining GUI elements

在完成上述代码添加后,保存脚本并退出播放模式,然后将白色纹理分配给 Color Swatch 参数,填充 Cursor Colors 数组元素。

1.3 监测设置值的变化

为了监测玩家对设置值的更改,我们使用 GUI.changed 。在 OnGUI 函数的设置组末尾添加以下代码:

// track changes
if (GUI.changed) {
   print (walkSpeed + " * " + turnSpeed);
}

之后将 print 语句替换为调用 UpdateSettings 函数:

function UpdateSettings() {
   playerSettings[0] = walkSpeed.ToString();
   playerSettings[1] = turnSpeed.ToString();
   playerSettings[2] = useText.ToString();
   playerSettings[3] = objectDescriptions.ToString();
   playerSettings[4] = fXVolume.ToString();
   playerSettings[5] = ambVolume.ToString();
   playerSettings[6] = musicVolume.ToString();
   playerSettings[7] = voiceVolume.ToString();
   playerSettings[8] = colorElement.ToString();

   // update the settings in the GameManager
   gameManager.NewSettings(playerSettings);
}

MenuManager 脚本中添加访问 GameManager fPCamera fPController 的变量,并在 Start 函数中分配这些对象。同时,在 Start 函数中初始化 GUI 设置值。

2. 确认对话框的创建

当玩家选择退出游戏时,我们需要创建一个确认对话框,让玩家选择是否退出、是否保存游戏等。

2.1 在 MenuManager 脚本中添加确认对话框代码
// *******   confirmDialog dialog  *******
if (confirmDialog) {
   // Make a group on the center of the screen
   GUI.BeginGroup (Rect (Screen.width / 2 - 100, Screen.height / 2 - 75, 200, 155));

   // make a box so you can see where the group is on-screen.
   GUI.Box (Rect (0,0,200,155), "Do you really want to quit?");

   // reset the  buttnRectTemp.y value
   buttnRectTemp = Rect (25,30,150,buttnRect .height);

   if (GUI.Button (buttnRectTemp, "No, resume game")) {
      // turn off the menu
      confirmDialog = false;
   }

   buttnRectTemp.y += 40;
   if (GUI.Button (buttnRectTemp, " Yes, quit without saving")) {
      // quit the game without saving
      confirmDialog = false;
      print ("closing");
      Application.Quit();
   }

   buttnRectTemp.y += 40;
   if (GUI.Button (buttnRectTemp, " Yes, but Save first")) {
      // turn off the menu, save the game, then quit
      confirmDialog = false;
      //SaveGame(true); // quit after saving
   }
   // End the confirmDialog group
   GUI.EndGroup ();
} // end confirm

保存脚本后,按下 F1 键选择退出选项,即可看到确认对话框。

2.2 添加退出快捷键

Update 函数中添加以下代码,使玩家按下 ESC 键时弹出确认对话框:

// brings up the yes/no menu when the player hits the escape key to quit
if (Input.GetKey ("escape")) {
   if (end) Application.Quit(); // end now
   confirmDialog = true;        // flag to bring up yes/no menu
}

同时,我们需要设置 SaveGame LoadGame 函数的占位符,并在相应位置调用这些函数。

3. 信用界面的实现

信用界面是一个简单的对话框,显示游戏的相关信息。

3.1 在 MenuManager 脚本中添加信用界面代码
// ********  credits screen  *************
if(creditsScreen) {
   // Make a group on the center of the screen
   GUI.BeginGroup (Rect (Screen.width / 2 - 150 , Screen.height  / 2 - 200, 300, 400));

   // make a box so you  can see where the group is on-screen
   GUI.Box (Rect (0,0,300,400), "Credits");

   // add labels here
   GUI.Label( Rect (20,20,250,100), "Your name here in lights!");

   // End the credits menu group
   GUI.EndGroup ();
} // end the credits screen conditional

if (end) return; // block any other GUI during the end sequence

Update 函数中添加代码,使玩家按下任意键时退出信用界面:

if(creditsScreen && Input.anyKeyDown) {
   creditsScreen = false;
   //MenuMode(false);
}
4. 菜单模式的跟踪

为了确保玩家在菜单打开时不能进行场景导航和交互,我们需要跟踪菜单模式。

4.1 在 MenuManager 脚本中添加菜单模式变量和相关代码
internal var menuMode = false; // no menus are open

//toggle the main menu off and on
if (Input.GetKeyDown("f1") && !menuMode) {
   if(mainMenu) {
      mainMenu= false;
      MenuMode(false);
   }
   else if (!menuMode ) { // if no other menus are open, open it
      mainMenu= true;
      MenuMode(true);
   }
}

function MenuMode (state : boolean) {
   if (end) return; // don't process menu mode

   if (state) { // go into menuMode
      menuMode = true;
   }
   else { // return from menuMode
      menuMode = false;
   }
}

OnGUI Update 函数中相应位置添加 MenuMode 函数的调用,确保菜单打开和关闭时正确设置菜单模式。

5. 导航和场景交互的暂停

在菜单打开时,我们需要暂停玩家的导航和场景交互。

5.1 在 MenuManager 脚本的 MenuMode 函数中添加暂停导航代码
function MenuMode (state : boolean) {
   if (end) return; // don't process menu mode

   if (state) { // go into menuMode
      menuMode = true;
      fPController.GetComponent(CharacterMotor).enabled = false;              // turn off navigation
      fPController.GetComponent(FPAdventurerInputController).enabled = false; // turn off navigation
      fPController.GetComponent(MouseLookRestricted).enabled = false;         // turn off navigation
      fPCamera.GetComponent(MouseLookRestricted).enabled = false;
   }
   else { // return from menuMode
      menuMode = false;
      fPController.GetComponent(CharacterMotor).enabled = true;              // turn on navigation
      fPController.GetComponent(FPAdventurerInputController).enabled = true; // turn on navigation
      fPController.GetComponent(MouseLookRestricted).enabled = true;         // turn on navigation
      fPCamera.GetComponent(MouseLookRestricted).enabled = true;
   }
}

Interactor 脚本中添加 menuMode 变量,并在 OnMouseOver OnMouseDown 函数中检查菜单模式,确保鼠标悬停和点击操作在菜单打开时被禁用。

5.2 避免菜单和库存同时打开

InventoryManager 脚本的 ToggleMode 函数中,通知 MenuManager 库存模式的变化,避免菜单和库存同时打开。

graph TD;
    A[开始] --> B[设置菜单构建];
    B --> C[确认对话框创建];
    C --> D[信用界面实现];
    D --> E[菜单模式跟踪];
    E --> F[导航和场景交互暂停];
    F --> G[结束];

通过以上步骤,我们完成了游戏菜单系统的开发,包括设置菜单、确认对话框、信用界面、菜单模式跟踪以及导航和场景交互的暂停等功能。这些功能的实现可以提高玩家的游戏体验,确保游戏在各种情况下都能正常运行。

游戏菜单与关卡设置全解析

6. 菜单与库存模式的交互优化

为了避免菜单和库存同时打开,我们需要在 InventoryManager 脚本的 ToggleMode 函数中进行相应的处理,让 MenuManager 知晓库存模式的变化。

6.1 在 InventoryManager 脚本中修改 ToggleMode 函数

ToggleMode 函数的 if 子句和 else 子句中,分别添加通知 MenuManager 的代码:

// 在 if 子句中
controlCenter.GetComponent(MenuManager).iMode = false;   // 通知菜单管理器库存模式关闭

// 在 else 子句中
controlCenter.GetComponent(MenuManager).iMode = true;    // 通知菜单管理器库存模式开启

这样,菜单系统就能根据库存模式的变化做出相应的调整,避免两者同时打开给玩家带来不好的体验。

7. 菜单系统的测试与验证

完成上述所有功能的开发后,我们需要对菜单系统进行全面的测试,确保其在各种情况下都能正常工作。

7.1 测试设置菜单
  • 速度设置测试 :点击播放按钮,进入游戏后打开设置菜单,调整步行速度和转身速度的滑块。观察控制台输出,确保速度值的变化能正确显示。同时,在游戏中尝试移动,检查角色的移动速度是否与设置值相符。
  • 文本显示选项测试 :切换文本显示和对象描述的复选框,检查游戏中的文本显示是否相应地开启或关闭。
  • 音频音量设置测试 :调整各种音频的音量滑块,在游戏中播放相应的音效、环境音、音乐和语音,检查音量是否按照设置值进行调整。
  • 光标颜色设置测试 :点击不同的光标颜色样本,检查鼠标悬停时光标的颜色是否随之改变。
7.2 测试确认对话框

按下 F1 键,选择退出选项,查看确认对话框是否正确弹出。分别点击“否,继续游戏”、“是,不保存退出”和“是,但先保存”按钮,检查游戏是否按照预期进行操作。同时,按下 ESC 键,验证是否能正确弹出确认对话框。

7.3 测试信用界面

通过主菜单中的按钮打开信用界面,按下任意键,检查是否能正确退出信用界面。

7.4 测试菜单模式

在游戏中按下 F1 键,打开主菜单,尝试在菜单打开时移动角色,检查角色是否无法移动。关闭菜单后,再次尝试移动角色,确保角色可以正常移动。同时,在菜单打开时,将鼠标悬停在动作对象上并点击,检查是否不会触发任何响应。

8. 菜单系统的性能优化

为了提高菜单系统的性能,我们可以采取以下措施。

8.1 减少不必要的检查

OnGUI 函数中,避免在每一帧都进行不必要的检查。例如,对于一些只需要在特定条件下更新的设置项,可以添加条件判断,减少不必要的计算。

8.2 优化资源加载

对于菜单中使用的纹理、音频等资源,确保在需要时才进行加载,避免一次性加载过多资源导致内存占用过高。同时,合理管理资源的释放,避免资源泄漏。

8.3 减少函数调用

在代码中,尽量减少不必要的函数调用,特别是在循环中。可以将一些常用的计算结果缓存起来,避免重复计算。

9. 菜单系统的扩展与维护

随着游戏的不断发展,菜单系统可能需要进行扩展和维护。以下是一些建议。

9.1 功能扩展
  • 添加新的设置项 :如果需要添加新的设置选项,如画面质量、分辨率等,可以在 MenuManager 脚本中添加相应的变量和代码。在 OnGUI 函数中添加新的设置项界面,并在 UpdateSettings 函数中处理新设置项的值。
  • 增加新的菜单界面 :如果需要增加新的菜单界面,如帮助菜单、排行榜等,可以参考现有的菜单界面代码,创建新的菜单组和按钮,并在 OnGUI 函数中添加相应的逻辑。
9.2 代码维护
  • 代码注释 :在代码中添加详细的注释,解释每个函数和变量的作用,方便后续的开发人员理解和维护代码。
  • 模块化设计 :将不同的功能模块封装成独立的函数或类,提高代码的可维护性和可扩展性。例如,将菜单模式的处理逻辑封装在 MenuMode 函数中,将设置项的更新逻辑封装在 UpdateSettings 函数中。
10. 总结

通过本文的介绍,我们详细了解了游戏菜单系统的开发过程,包括设置菜单的构建、确认对话框的创建、信用界面的实现、菜单模式的跟踪以及导航和场景交互的暂停等方面。同时,我们还讨论了菜单系统的测试、优化、扩展和维护等问题。

功能模块 主要实现步骤
设置菜单构建 添加变量、在 OnGUI 中添加设置项代码、监测设置值变化
确认对话框创建 MenuManager 中添加代码、添加退出快捷键
信用界面实现 MenuManager 中添加代码、处理按键退出
菜单模式跟踪 添加菜单模式变量和相关代码、在合适位置调用 MenuMode 函数
导航和场景交互暂停 MenuMode 函数中添加暂停导航代码、在 Interactor 中检查菜单模式
菜单与库存模式交互优化 InventoryManager ToggleMode 函数中通知 MenuManager
graph LR;
    A[菜单系统开发] --> B[功能实现];
    B --> B1[设置菜单];
    B --> B2[确认对话框];
    B --> B3[信用界面];
    B --> B4[菜单模式跟踪];
    B --> B5[导航与交互暂停];
    B --> B6[菜单与库存交互优化];
    A --> C[测试与验证];
    A --> D[性能优化];
    A --> E[扩展与维护];

在实际开发中,我们可以根据游戏的需求对菜单系统进行灵活的调整和扩展,以提高玩家的游戏体验。同时,要注意代码的质量和性能,确保菜单系统在各种设备上都能稳定运行。通过不断地优化和改进,我们可以打造出一个功能强大、用户友好的游戏菜单系统。

最后,保存好场景和项目,以便后续的开发和测试。通过以上一系列的操作,我们为游戏打造了一个完善的菜单系统,能够满足玩家在游戏过程中的各种设置和操作需求,提升游戏的整体品质。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值