unity小地图制作___按比例尺图标布局

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);
        }
    }
}
原文地址:https://www.cnblogs.com/xiaoahui/p/10434872.html