大家好,我是Zander,我们接着来开发Rts3D即时战略游戏开发。游戏中我们需要一个指令系统来处理不同的指令,每个单位都应该有行动指令,移动或者建造等,所以这一节我们来实现一下HUD面板上按钮的功能。
首先,在Scripts文件夹创建一个ActionManager的脚本并编译它。这里我们要用到Action委托,它是一个可以作为变量并传入形参的方法
using UnityEngine;
using UnityEngine.UI;
using System;
using System.Collections.Generic;
public class ActionsManager : MonoBehaviour {
public static ActionsManager Current;
public Button[] Buttons; //面板里的九个按钮
private List<Action> actionCalls = new List<Action>(); //按钮相对应的相应事件
public ActionsManager()
{
Current = this;
}
/// <summary>
/// 清理按钮的方法
/// </summary>
public void ClearButtons()
{
foreach (var b in Buttons)
b.gameObject.SetActive (false);
actionCalls.Clear ();
}
/// <summary>
/// 添加按钮的方法
/// </summary>
/// <param name="pic"></param>
/// <param name="onClick"></param>
public void AddButton(Sprite pic, Action onClick)
{
int index = actionCalls.Count; //index表明是哪个按钮在执行,调用哪个Action
Buttons [index].gameObject.SetActive (true);
Buttons [index].GetComponent<Image> ().sprite = pic;
actionCalls.Add (onClick);
}
/// <summary>
/// 事件响应方法,当点击按钮时就会响应
/// </summary>
/// <param name="index"></param>
public void OnButtonClick (int index)
{
actionCalls [index] ();
}
// Use this for initialization
void Start () {
for (int i = 0; i < Buttons.Length; i++) {
var index = i;
Buttons[index].onClick.AddListener(delegate() {
OnButtonClick (index);
});
}
ClearButtons ();
}
}
然后返回到Unity中,把脚本拖拽到Manager上,然后给Buttons赋值
这样我们可以创建单个脚本作为单位的按钮,但是我们想让这个架构允许策划从Unity设置单位,我将创建一个特别的组件来实现这个功能。这里需要两个脚本,首先在Scripts下的Interaction文件夹中创建一个ActionSelect的脚本,然后再返回Scripts文件中创建一个ActionBehavior的脚本并编辑。
ActionBehavior将使用Action委托,并且这个类将是抽象类。,如下:
using UnityEngine;
using System;
using System.Collections;
public abstract class ActionBehavior : MonoBehaviour {
public abstract Action GetClickAction();
public Sprite ButtonPic;
}
打开ActionSelect,并让他继承Interaction,编辑脚本,如下:
using UnityEngine;
using System.Collections;
public class ActionSelect : Interaction {
public override void Deselect ()
{
ActionsManager.Current.ClearButtons ();
}
public override void Select ()
{
ActionsManager.Current.ClearButtons ();
foreach (var ab in GetComponents<ActionBehavior>()) {
ActionsManager.Current.AddButton(
ab.ButtonPic,
ab.GetClickAction());
}
}
}
然后切换到RtsManager中,修改Start函数,如下
void Start () {
Current = this;
foreach (var p in Players) {
foreach (var u in p.StartingUnits)
{
var go = (GameObject)GameObject.Instantiate(u, p.Location.position, p.Location.rotation);
var player = go.AddComponent<Player>();
player.Info = p;
if (!p.IsAi)
{
if (Player.Default == null) Player.Default = p;
go.AddComponent<RightClickNavigation>();
go.AddComponent<ActionSelect>();
}
}
}
}
这样做仅会让属于玩家操作的那个阵营显示指令菜单,这样我们就有了让设计师可以编辑单位指令的基础架构了,接下来我们就可以制作第一个附加到单位上的指令,建造建筑。现在我们要做的是让它有点击功能,打开下载好的Resources 中的Content5文件夹,找到CommandBaseFace图片,并把它拖动到Texture文件夹中,首先将图片设置成Sprite类型,
创建CreateBuildingAction脚本并编辑,它继承ActionBehavior,这样就可以实现GetClickAction功能,如下:
using UnityEngine;
using System.Collections;
public class CreateBuildingAction : ActionBehavior {
public override System.Action GetClickAction ()
{
return delegate() {
Debug.Log("Create Command Base Attempt");
};
}
}
保存代码并返回 Unity中个,选中DroneUnit预设,点击添加CreateBuildingAction脚本,并为其图片赋值,如下:
保存运行,点击DroneUnit,发现右下角有一个按钮,点击就会相应点击事件:如图:
接下来我们找到之前下载的资源,在Content6中找到BasePrefab.unitypackage,并把它导入Unity中,这里含有一个CommandBase预设,
下面我们来实现建筑描边效果和建筑跟随鼠标的功能,首先在Scripts文件夹创建一个FindBuildingSite脚本,这个脚本旺旺附加在指挥部或其他建筑的透明壳部分,功能就是让自己跟随鼠标,修改其Update函数
void Update () {
var tempTarget = RtsManager.Current.ScreenPointToMapPosition (Input.mousePosition);
if (tempTarget.HasValue == false)
return;
transform.position = tempTarget.Value;
}
保存,返回修改CreateBuildingAction脚本,如下:
using UnityEngine;
using System.Collections;
public class CreateBuildingAction : ActionBehavior {
public GameObject GhostBuildingPrefab;
private GameObject active = null;
public override System.Action GetClickAction ()
{
return delegate() {
var go = GameObject.Instantiate(GhostBuildingPrefab);
go.AddComponent<FindbuildingSite>();
active = go;
};
}
void Update()
{
if (active == null)
return;
if (Input.GetKeyDown (KeyCode.Escape))
GameObject.Destroy (active);
}
void OnDestroy()
{
if (active == null)
return;
Destroy (active);
}
}
保存,打开Material文件夹找到其中的CommandBase材质,复制一份,并改名为CommandBaseGhost,然后把其渲染模式从Opaque改为Transparent,如图
,然后创建一个CommandBaseGhost预设,如图:
然后把此预设拖拽到DroneUnit中CreateBuildingAction中的GhostBuildingPrefab中,赋值,点击运行就可以跟随鼠标移动了
好了,这一章就写到这,欢迎大家加入QQ群:280993838 或者关注我的公众号: