
其实小地图的功能说起来还挺简单的.无非就是通过比例缩放来确定2d sprite的位置而已.
第一步:
MinimapSystem 这个主要功能就是确定缩放比例,以及以哪个物体为中心计算距离,还有统一管理小地图的图标. 这个脚本可以挂载在场景管理器上.
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 脚本来的.
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 这个是挂载在需要在小地图上显示的场景物体上.
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);
}
}测试
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 删除。