刚开始敲代码就在制作小地图,现在还在制作小地图,不过区别在于以前看不懂,现在能看懂了。不说了,说多了都是泪。今天就记录一下制作小地图的过程。
一、场景位置
根据我的理解,场景要放在坐标系的区域内,不要放在坐标轴上,否则计算会很容易把自己搞蒙。
二、放置参照物
就如我们一中那张图,我们把模型放在左上角的区域,本来我们应该用模型的地面的坐标来计算,但是因为有时候建模的不规范,地面的坐标中心不一定是规规矩矩的,所以一劳永逸,我们就放置一个参照物。上图中的小圆圈就是我们的参照物。而玩家是在方框内移动。
三、计算玩家在场景中的位置
我们把玩家叫做player,参照物叫做minimapOrigin,地面叫做realMap。我们先获取地面的长宽,然后用玩家的坐标减去参照物的坐标,再除以地面的宽高,就能够分别得到玩家在地面上的位置。
widthRate = (player.position.z - minimapOrigin.position.z) / realMapWidth;
heightRate = (player.position.x - minimapOrigin.position.x) / realMapHeight;
四、摆放小地图
我们在UI上创建一个小地图的UI,然后在创建一个子节点当作玩家。因为我们的参照物在地面的右下角,所以我们把玩家的锚点也设置在右下角,方便计算。
五、映射玩家位置
我们把刚才得到的玩家在地面的位置比率乘以小地图的长宽,然后赋值给小地图上玩家节点,就能在小地图上看到玩家当前所在的位置了。
playerIcon.anchoredPosition = new Vector2 (-minimap.rect.width * widthRate, minimap.rect.height * heightRate);
六、设置小地图玩家的方向
在静止时,计算3D场景中玩家Y轴和小地图上玩家图标Z轴的角度差,通过换算,就能设置小地图上玩家图标的方向了。
playerIcon.rotation = Quaternion.Euler (0, 0, 180 - player.localEulerAngles.y);
七、详细代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MiniMapController : MonoBehaviour {
[SerializeField, Tooltip ("小地图的实物原点参照物")]
private Transform minimapOrigin = null;
[SerializeField]
private Transform realMap = null;
[SerializeField]
private Transform player = null;
[SerializeField]
private RectTransform minimap = null;
[SerializeField]
private RectTransform playerIcon = null;
private float realMapWidth = 0;
private float realMapHeight = 0;
private float widthRate = 0;
private float heightRate = 0;
// Start is called before the first frame update
void Start () {
realMapWidth = realMap.GetComponent<MeshRenderer> ().bounds.size.z;
realMapHeight = realMap.GetComponent<MeshRenderer> ().bounds.size.x;
}
// Update is called once per frame
void Update () {
UpdateMinimapMod ();
}
private void UpdateMinimapMod () {
widthRate = (player.position.z - minimapOrigin.position.z) / realMapWidth;
heightRate = (player.position.x - minimapOrigin.position.x) / realMapHeight;
playerIcon.anchoredPosition = new Vector2 (-minimap.rect.width * widthRate, minimap.rect.height * heightRate);
playerIcon.rotation = Quaternion.Euler (0, 0, 180 - player.localEulerAngles.y);
}
}