首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >小地图的制作(非相机版)

小地图的制作(非相机版)

原创
作者头像
张曙光
发布2025-12-18 11:29:35
发布2025-12-18 11:29:35
1440
举报

其实小地图的功能说起来还挺简单的.无非就是通过比例缩放来确定2d sprite的位置而已.

第一步:

 MinimapSystem 这个主要功能就是确定缩放比例,以及以哪个物体为中心计算距离,还有统一管理小地图的图标. 这个脚本可以挂载在场景管理器上.

代码语言:javascript
复制
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;

    public class MinimapSystem : MonoBehaviour
    {

        static MinimapSystem instance;
        public static MinimapSystem Instance
        {
            get
            {
                if (!instance)
                    instance = Object.FindFirstObjectByType<MinimapSystem>();
                return instance;
            }
        }

        List<MinimapIcon> m_iconsPool = new List<MinimapIcon>();

        Dictionary<MinimapObject, MinimapIcon> m_objs_iconsDict = new Dictionary<MinimapObject, MinimapIcon>();

        [SerializeField]
        Transform m_mapFocus;

        [SerializeField]
        RectTransform m_iconsRoot;

        [SerializeField]
        GameObject iconPrefab;

        Vector3 minimapCenter
        {
            get
            {
                return m_iconsRoot.rect.center;
            }
        }

        [SerializeField]
        float m_maxIconDistance = 100f;

        [SerializeField]
        float m_Scale = 1f;

        public void RegisterMMObject(MinimapObject obj)
        {

            var icon = ConstructIcon(obj);
            m_iconsPool.Add(icon);
            m_objs_iconsDict.Add(obj, icon);
        }

        public void UnRegisterMMObject(MinimapObject obj)
        {

            MinimapIcon icon;

            m_objs_iconsDict.TryGetValue(obj, out icon);

            if (!icon)
            {
                return;
            }

            m_iconsPool.Remove(icon);
            Destroy(icon.gameObject);
            m_objs_iconsDict.Remove(obj);
        }

        void FixedUpdate()
        {

            int count = m_iconsPool.Count;

            for (int i = 0; i < count; i++)
            {

                var icon = m_iconsPool[i];

                icon.gameObject.SetActive(CheckVisibility(icon));

                icon.rectTransform.anchoredPosition = ConvertPosition(icon.target.transform.position) * m_Scale;

            }
        }

        MinimapIcon ConstructIcon(MinimapObject mmobj)
        {

            iconPrefab = Resources.Load<GameObject>("Icon");
            if (!iconPrefab)
            {
                return null;
            }

            iconPrefab.SetActive(false);

            var go = Instantiate(iconPrefab, m_iconsRoot, false);

            var icon = go.GetComponent<MinimapIcon>();

            icon.target = mmobj;

            icon.gameObject.SetActive(true);

            iconPrefab.SetActive(true);


            return icon;

        }

        bool CheckVisibility(MinimapIcon icon)
        {
            //只计算在Z平面上的距离        
            return Vector3.Distance(icon.rectTransform.anchoredPosition, Vector3.zero) < m_maxIconDistance;
        }

        Vector3 ConvertPosition(Vector3 position)
        {

            Vector3 transformed = m_mapFocus.transform.InverseTransformPoint(position);
            return new Vector3(transformed.x, transformed.z, 0f);

        }

    }

第二步:

MinimapIcon 这个脚本是小地图的图标脚本,它仅仅是对地图的样式做一个初始化. 而这个初始化是通过MiniMapObj 脚本来的.

代码语言:javascript
复制
public class MinimapIcon : MonoBehaviour
    {

        public MinimapObject target;

        private Image image;

        public RectTransform rectTransform;
        public Animator Ani;

        private void OnEnable()
        {

            image = GetComponent<Image>();

            rectTransform = GetComponent<RectTransform>();

            if (target.Config.icon)
                image.sprite = target.Config.icon;

            image.color = target.Config.color;

            //动画
            if (!target.Config.isNeedAni)
                return;
            else
            {
                Ani.SetTrigger("Show");
            }
        }
    }

第三步:

MiniMapObj 这个是挂载在需要在小地图上显示的场景物体上.

代码语言:javascript
复制
public class MinimapObject : MonoBehaviour
    {


        [SerializeField]
        private MiniMapIconCfg config = new MiniMapIconCfg();

        public MiniMapIconCfg Config
        {
            get { return config; }
        }

        [System.Serializable]
        public class MiniMapIconCfg
        {

            public Sprite icon;
            public Color color = Color.white;
            public bool isNeedAni = false;

        }

        void OnEnable()
        {
            MinimapSystem.Instance.RegisterMMObject(this);
        }

        void OnDisable()
        {
            MinimapSystem.Instance.UnRegisterMMObject(this);
        }
    }

测试

代码语言:javascript
复制
public class RandomCreatObj : MonoBehaviour
{


    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            //随机生成物体
            GameObject obj = Resources.Load<GameObject>("Cube"); //替换为你的预制体路径
            obj.transform.position = new Vector3(Random.Range(-10f, 10f), 0, Random.Range(-10f, 10f));
            GameObject minimapObj = Instantiate(obj, obj.transform.position, Quaternion.identity);
            minimapObj.name = "MinimapObject"; //设置物体名称
            minimapObj.GetComponent<MinimapObject>().Config.color = Color.white; //设置颜色 
            if (obj.transform.position.x > 3)
            {
                minimapObj.GetComponent<MinimapObject>().Config.isNeedAni = true; //如果有动画可以设置
            }
            else
            {
                minimapObj.GetComponent<MinimapObject>().Config.isNeedAni = false; //如果没有动画可以设置
            }
        }
    }
}

再次说明脚本挂载:

MinimapSystem:

图片
图片

MinimapObject: 

图片
图片

这个是需要在小地图上显示的物体.注意这里就将小地图的图标与颜色遮罩设置好.因为这样可以少设置一些小地图的图标预制.

MinimapIcon:

图片
图片

这个是小地图图标的预制体.不需要在此预制体赋值.

已知问题:如果数量过多,UI无法合批,导致drawcall增大.帧率下降.测试中数量上升到500+ 会明显卡顿.

因为过于简单,所以并没有过多的解释.希望各位能用得上.

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档