Unity实战 RTS3D即时战略游戏开发(九) 行为管理器 Action的使用

    大家好,我是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  或者关注我的公众号:







  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值