1.
2.這里小地圖顯示的范圍為整個空間區域,而不是單獨的相機渲染區域
3.
4.
5.
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; //圖標與對應的物體的映射關系 public class MinimapCell { public Transform icon; //在小地圖上顯示的圖標 public Transform referObj; //圖標對應的物體 public Transform relativeObj;//地圖上標桿物體 public float scaleRealToUI; RectTransform rectTrans; public MinimapCell(Transform _icon,Transform _referObj,Transform _relativeObj,float _scaleRealToUI) { icon = _icon;//小地圖中的圖標 referObj = _referObj;//小地圖表示的在場景中的物體 relativeObj = _relativeObj;//參考物體,設此物體為坐標計算的中心,從而計算出場景中物體的相對位置 scaleRealToUI = _scaleRealToUI;//比例尺 } //同步位置 public void Synchro() { if (icon && referObj&&relativeObj) { rectTrans = icon.GetComponent<RectTransform>(); rectTrans.anchoredPosition3D = -(referObj.position - relativeObj.position)*scaleRealToUI;//根據比例尺設置圖標和地圖中角色的映射位置 }else if (referObj == null || referObj.gameObject.activeInHierarchy == false) {//如果角色為空(即死亡),那么隱藏該圖標,可用於下一個角色,這里起到了對象池的作用 icon.gameObject.SetActive(false); } } } //原理:根據世界的寬高比例設置地圖UI的寬高大小(其中寬度固定,根據比例得出高度)以及計算出比例尺 //建立列表cells,用於存儲當前圖標和對應的物體的信息 //如果場景中有需要顯示在小地圖上的物體,將標桿物體和比例尺賦予圖標單元; //首先查看列表中是否有可用的cell(即該cell為激活狀態,表示正對應世界中某個物體),如果有,則激活圖標,設置對應物體,如果沒有,則生成一個新的cell //在update中實時調用每個cell的同步函數,實時同步位置 //如果某個物體需要在小地圖中表示,那么該物體必須帶有組件MiniMapFit組件,改組件用於訪問地圖,設置同步圖標 public class MiniMap : MonoBehaviour { public static MiniMap instance; public Transform relativeObj;//場景中的標桿物體,標桿物體放在世界區域的右上角,並且相對的,小地圖的中心點在小地圖的右上角,從而對應映射關系 public GameObject cellPrefab;//圖標物體的預制物體 public List<MinimapCell> cells;//圖標單元列表 public Rect worldSize;//世界區域的真實大小(定為在場景區域中玩家可以移動的區域大小) RectTransform rectTrans; float scaleRealToUI;//比例尺 // Start is called before the first frame update void Awake() { rectTrans = GetComponent<RectTransform>(); Debug.Log(rectTrans.position+" "+rectTrans.anchoredPosition3D+" "+rectTrans.rect); scaleRealToUI = rectTrans.rect.x / worldSize.x;//計算出比例尺 rectTrans.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, -worldSize.y* scaleRealToUI);//設置地圖UI的高度 cells = new List<MinimapCell>(); instance = this; } // Update is called once per frame void Update() { //實時同步結點 foreach (MinimapCell miniCell in cells) { miniCell.Synchro(); } } //當增加圖標示意對應的角色 public void AddCell(Transform _referObj) { bool flag = false;//標記是否查找成功 foreach(MinimapCell miniCell in cells)//查看鏈表中是否有可用的單元 { if (miniCell.icon.gameObject.activeInHierarchy == false) { miniCell.referObj = _referObj; miniCell.icon.gameObject.SetActive(true); flag = true; break; } } if (!flag)//如果鏈表中沒有空余的結點,那么新增一個結點,用於顯示角色位置信息 { Transform trans = Instantiate(cellPrefab, transform).transform; MinimapCell cell = new MinimapCell(trans,_referObj,relativeObj,scaleRealToUI); cells.Add(cell); } } private void OnDrawGizmos() { Gizmos.color = Color.green; if(relativeObj)Gizmos.DrawWireCube(relativeObj.position- new Vector3(worldSize.x / 2, worldSize.y / 2), new Vector3(worldSize.x, worldSize.y)); } }
6.
using System.Collections; using System.Collections.Generic; using UnityEngine; //此類綁定在角色身上,在場景中生成角色時,可以在小地圖中生成對應的圖標 public class MiniMapFit : MonoBehaviour { // Start is called before the first frame update void Start() { if (MiniMap.instance)//訪問小地圖,生成圖標 { MiniMap.instance.AddCell(transform); } } }