思考并回答以下问题:
本章涵盖:
- 兵营系统
- 兵营系统的组成
- 初始兵营系统
- 兵营信息的显示流程
兵营系统
在Unity3D的界面设计-组合模式中介绍Unity3D用户界面(User Interface)的设计方式时,提到一个“兵营界面”,兵营界面在《P级阵地》中是用来显示玩家当前用鼠标单击而选中的兵营信息,如图1所示。
图1 兵营界面
界面上显示出当前用鼠标单击而选中的兵营基本信息,包含名称、等级、武器等级等,另外还有4个功能按钮,提供给玩家作为对兵营下达命令的界面。而这些从界面下达的命令将会使用命令模式(Command),让玩家的操作与游戏的功能产生连接并执行。这一部分将在兵营训练单位-命令模式中详细说明,在此之前,我们先来说明《P级阵地》中“兵营系统”的运行方式。
兵营系统的组成
比起“角色系统”,《P级阵地》中的“兵营系统”的设计较为简单,它主要是由兵营系统(CampSystem)、兵营(ICamp)和兵营界面(CampInfoUI)组成,如图2所示。
图2 兵营系统的组成
- ICamp(兵营接口):定义兵营的操作接口和信息的提供。
- SoliderCamp(兵营):实现兵营接口,并记录当前等级、武器等级等信息。
- CampSystem(兵营系统):初始化和管理游戏中玩家的所有兵营,并成为PBaseDefenseGame的游戏子系统之一,方便与其他系统进行沟通和获取信息。
- CampInfoUI(兵营界面):负责显示玩家用鼠标单击而选中到的兵营之相关信息。
“兵营”负责作战单位的训练,而按照游戏的需求设置,每个兵营只能训练一种玩家角色,而且各兵营所需要的训练时间及费用都不相同。不同兵营间的差异设置,可以区别出其中的不同,并且利用相关属性来调整游戏平衡。
在兵营(ICamp)类中,除了基本的3D模型成像和2D图像显示外,也包含了其他差异属性:
Listing1 兵营接口(ICamp.cs)
1 | public abstract class ICamp |
兵营(ICamp)当前只有一个子类SoldierCamp:
Listing2 Soldier兵营(SoldierCamp.cs)
1 | public class SoldierCamp : ICamp |
初始兵营系统
游戏画面中的兵营,是在Unity3D编辑模式下的战斗场景(Battle Scene),如图3所示。
图3 编辑模式下的战斗场景
在Unity3D这类“所见即所得”的游戏开发编辑器中,通过“场景设置”或所谓的“关卡设置”方式,让企划人员能方便地设计出想要呈现的游戏效果和关卡难度。因此,在游戏制作的分工上,程序人员可以提供方便的“属性系统工具/企划工具”,让企划人员设置属性、视觉呈现、关卡布置安排及画面设置等,程序人员也可以让企划人员直接使用Unity3D等工具来进行设置。
《P级阵地》兵营的3D视觉呈现,是在Unity3D编辑模式下,将设计好的兵营模型由企划人员放在场景上。等到游戏实际执行时,在程序代码中以“实时”的方式获取所需要的游戏对象(GameObject),并根据需求建立系统功能。所以,《P级阵地》中“兵营系统(CampSystem)”的设计方式,是在战斗场景(Battle Scene)加载完成后,实时找出场景上的兵营游戏对象,并用它们和程序代码中的兵营类(ICamp)进行连接。
在兵营系统(CampSystem)中包含了一个容器类,用来管理游戏运行时,产生的兵营类(ICamp)对象:
Listing3 兵营系统(CampSystem.cs)
1 | public class CampSystem : IGameSystem |
在兵营系统中,使用泛型容器Dictionary作为管理兵营的地方,并在初始化方法Initialize中,将3个玩家阵营的兵营产生出来。在产生兵营方法(SoldierCampFactory)中,会直接在当前的场景中找出对应的兵营游戏对象和集合点的位置,然后利用这两个信息来产生SoldierCamp类对象:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17// 获取对象
GameObject theGameObject = UnityTool.FindGameObject( GameObjectName );
// 获取集合点
Vector3 TrainPoint = GetTrainPoint( GameObjectName );
// 产生兵营
SoldierCamp NewCamp = new SoldierCamp(theGameObject,
emSoldier,
CampName,
IconSprite,
CoolDown,
TrainPoint);
NewCamp.SetPBaseDefenseGame( m_PBDGame );
// 设置兵营使用的Script
AddCampScript( theGameObject, NewCamp);
在这一段程序代码的最后,会调用AddCampScript方法:1
2
3
4
5
6
7// 设置兵营使用的Script
private void AddCampScript(GameObject theGameObject, ICamp Camp)
{
// 加入Script
CampOnClick CampScript = theGameObject.AddComponent<CampOnClick>();
CampScript.theCamp = Camp;
}
这段类的私有成员方法,主要是将脚本类CampOnClick.cs加入到兵营的游戏对象中。该脚本类是用来侦测玩家的“鼠标单击屏幕画面”的操作,并通知PBaseDefenseGame显示被鼠标单击的兵营:
Listing4 兵营单击成功后通知显示(CampOnClick.cs)
1 | public class CampOnClick : MonoBehaviour |
脚本中的OnClick方法,会在PBaseDefenseGame的InputProcess方法中被调用,而InputProcess就是在Game Loop中扮演“判断用户输入”的角色,它会在Update方法中不断地被调用:
Listing5 判断兵营是否被鼠标单击(PBaseDefenseGame.cs)
1 | public class PBaseDefenseGame |
在每一次的输入判断中,确认玩家是否单击鼠标左键之后,就利用Unity3D的碰撞侦测方式,获取场景中被鼠标单击的游戏对象。如果该游戏对象包含了脚本组件CampOnClick类,那么被鼠标单击的对象就是兵营,即可调用下列的OnClick方法:1
2
3
4
5public void OnClick()
{
// 显示兵营信息
PBaseDefenseGame.Instance.ShowCampInfo( theCamp );
}
在CampOnClick类的OnClick中,会利用PBaseDefenseGame的外观界面方法ShowCampInfo:1
2
3
4
5
6
7
8
9
10
11public class PBaseDefenseGame
{
...
// 显示兵营信息
public void ShowCampInfo( ICamp Camp )
{
m_CampInfoUI.ShowInfo( Camp );
m_SoldierInfoUI.Hide();
}
...
}
在ShowCampInfo中,会再去调用兵营界面(CampInfoUI)显示当前鼠标单击的兵营。
回顾Unity3D的界面设计-组合模式提到的兵营界面(CampInfoUI)的显示信息(ShowInfo)方法,在该方法中,会将传入的兵营对象显示到界面上,如此就完成了兵营信息的显示功能:
Listing6 兵营界面(CampInfoUI.cs)
1 | public class CampInfoUI : IUserInterface |
兵营信息的显示流程
图4显示了兵营系统的建立流程,以及判断玩家用鼠标单击兵营对象之后,将信息显示到兵营界面的整个流程。
图4 兵营信息的显示流程