1.
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);
- }
- }
- }