Unity实战 RTS3D即时战略游戏开发(七): HUD的使用 小地图显示
这是RTS3D即时战略游戏开发系列的第七篇文章,从这开始要介绍的是处理HUD的显示与隐藏这方面的新内容,本篇是其中关于HUD的小地图显示。
首先我们找到在第一章所提供的下载链接中找到Resources—》Content3中找到HUD.Unitypackage包,把它导入到我们的项目包中。这时我们会发现在Prefabs文件夹中多了一个HUD预设。
我们把HUD预设拖到场景中,运行后如下图:
现在拥有了带当前区域的小地图,用边框表示摄像机看到的区域,还有一个信息面板,还有显示我们选中单位Icon的地方,最后面还有一个操作面板.关于UI的制作这里就不介绍了,有兴趣的同学可以自己研究一下。
现在我们来在小地图上显示我们的位置,现在Scripts文件夹中创建一个Hud文件夹,创建Map脚本,并编辑:
using UnityEngine; using UnityEngine.UI; using System.Collections; public class Map : MonoBehaviour { public RectTransform ViewPort; //小地图的视野范围 public Transform Corner1, Corner2; //放置在地形两个对角上标识位置的空物体 ,以便获得地形的尺寸 public GameObject BlipPrefab;//显示玩家位置的预设 public static Map Current; private Vector2 terrainSize; //地形的大小 private RectTransform mapRect; //获取当前地图的位置 public Map() { Current = this; } // Use this for initialization void Start () { terrainSize = new Vector2 ( Corner2.position.x - Corner1.position.x, Corner2.position.z - Corner1.position.z); mapRect = GetComponent (); } /// /// 把世界位置转成地图位置的方法 /// /// /// public Vector2 WorldPositionToMap(Vector3 point) { var pos = point - Corner1.position; //得到当前位置相对于地形起始角的位置 var mapPos = new Vector2 ( point.x / terrainSize.x * mapRect.rect.width, point.z / terrainSize.y * mapRect.rect.height); //缩放到能适配地图尺寸的点 return mapPos; } // Update is called once per frame void Update () { ViewPort.position = WorldPositionToMap (Camera.main.transform.position); } }
,然后再给HUD下的Map添加Map组件,如图:
接下来我们要在地图上显示玩家的位置,首先在HUD文件夹下创建一个MapBlip脚本,如下
using UnityEngine; using UnityEngine.UI; using System.Collections; public class MapBlip : MonoBehaviour { private GameObject blip; public GameObject Blip { get { return blip; } } // Use this for initialization void Start () { blip = GameObject.Instantiate (Map.Current.BlipPrefab); //初始化Blip物体 blip.transform.parent = Map.Current.transform; // var color = GetComponent ().Info.AccentColor; //获取玩家的颜色 blip.GetComponent ().color = color; } // Update is called once per frame void Update () { blip.transform.position = Map.Current.WorldPositionToMap (transform.position); //更新Blip的位置 } void OnDestroy() { GameObject.Destroy (blip); //当玩家死亡后销毁Blip } }
接下来我们要进行单位追踪处理,首先我们找到PlayerSetupDefinition脚本,在其中我们看到有一个StartingUnits的列表,但我们仅想追踪活动的单位,所以我们需要再声明一个activeUnits列表,如下:
private List activeUnits = new List ();//不让外部修改 public List ActiveUnits { get { return activeUnits; } } //方便外部访问
添加Start()和OnDestory()方法
using UnityEngine; using System.Collections.Generic; public class Player : MonoBehaviour { public PlayerSetupDefinition Info; public static PlayerSetupDefinition Default; void Start() { Info.ActiveUnits.Add (this.gameObject); //添加到显示列表中 } void OnDestroy() { Info.ActiveUnits.Remove (this.gameObject); //在显示列表中移除 } }
现在我们的每个玩家都会追踪他们在游戏中所拥有的活动单位,不过现在小地图会显示所有的游戏单位,但我们只想看到一定范围内的单位,而且时刻检测所有敌对单位是否在可见范围比较消耗性能,所有我们要使用比较少耗性能的方式,我们在HUd文件夹下创建一个VisibilityManager脚本,如下:
using UnityEngine; using System.Collections.Generic; public class VisibilityManager : MonoBehaviour { public float TimeBetweenChecks = 1; //检测间隔 public float VisibleRange = 100; //可见距离 private float waited = 10000; // Update is called once per frame void Update () { waited += Time.deltaTime; if (waited <= TimeBetweenChecks) return; waited = 0; List pBlips = new List (); //收集玩家的blips,以便决定是否启用它 List oBlips = new List (); //收集对手的blips,以便决定是否启用它 foreach (var p in RtsManager.Current.Players) { foreach(var u in p.ActiveUnits) { var blip = u.GetComponent(); if (p == Player.Default) pBlips.Add (blip); else oBlips.Add(blip); } } foreach (var o in oBlips) { bool active = false; foreach(var p in pBlips) { var distance = Vector3.Distance(o.transform.position, p.transform.position); //获取和玩家的距离 if (distance <= VisibleRange) { active = true; break; } } o.Blip.SetActive(active); foreach(var r in o.GetComponentsInChildren()) r.enabled = active; } } }
返回到Unity中,把VisibilityManager脚本添加到Manager上,运行Unity,就可以发现在一定距离内可以看到地方单位,超过这个距离,地方单位就会显示不见了。
Unity实战RTS3D即时战略游戏开发系列:
Unity实战 RTS3D即时战略游戏开发(二):玩家状态显示
Unity实战 RTS3D即时战略游戏开发(三):单位选中处理
Unity实战 RTS3D即时战略游戏开发(四):鼠标管理器
Unity实战 RTS3D即时战略游戏开发(五):NavigationMesh自动寻路
Unity实战 RTS3D即时战略游戏开发(八):HUD的使用单位信息显示
Unity实战 RTS3D即时战略游戏开发(九):行为管理器Action的使用
Unity实战 RTS3D即时战略游戏开发(十):可建造地点标示
Unity实战 RTS3D即时战略游戏开发(十一)AiController
Unity实战 RTS3D即时战略游戏开发(十二):建造AI、生产AI