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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM