之前所讲到的制作地图方式都是使用在全局大地图中。因为人物永远都在地图的中心。如图:
更多内容关注:unity风雨路
但是有些游戏副本中的主角人物不是一直处在地图中心,而是可以看到副本的整个地图。角色只是处在大地图中的某个坐标位置。这种地图的制作实现也有所不同。
接下来讲如何实现:看到副本的整个地图场景,角色可以移动到与地图相对的任何坐标位置并非一直在地图中心。如下图:
举个例子:有一个场景是副本内的场景。副本场景就是下图中的的建筑区(绿色草地只是背景)
因此副本的地图是这样:就是建筑物区域的俯视图,一张图片而已。如下:
新建一个Plane和材质球,将该图赋值给材质球,然后材质球给Plane上。并且将Plane的layer设置为Map。
将plane位置放置对齐到该场景。但一定要放置到场景地下,这样就不会干扰场景显示。
接着选择MiniMapCamera设置大小和位置恰好看到整个场景。可以从预览里调整位置大小来参考。
注意:一定要调整到可以看到地图的全貌。这是最佳位置。如下:
一定要记住这个时候的相机size。因为这个值就是我们之前讲到的大地图的尺寸。把它拷贝过来。
这个时候运行测试发现:显示出小地图中的plan位置变了。。。因为我们的代码中小地图相机是时刻跟随主角的。现在主角的位置在场景的边沿,相机当然会跟随的到这个位置。
本节我们关心的是大地图,小地图不做处理。但此时点开大地图也是和小地图中显示的相同的。
因此我们要将大地图中相机位置代码删除。删这句 minicamera.transform.position = new Vector3(player.position.x, minicamera.transform.position.y, player.position.z);。
并且给大地图初始化赋值。
所以我们需要在每一次打开大地图的时候对相机位置进行初始化。定义变量public Vector3 startPos = Vector3.zero;//相机初始位置
然后初始化的时候赋值。 startPos = minicamera.transform.position;//初始化小地图位置。
全部代码如下:
-
using UnityEngine;
-
using System.Collections;
-
-
public
class
testmin :
MonoBehaviour {
-
public Camera minicamera;
-
public Transform player;
-
public Transform miniplayerIcon;
//小地图人物图标
-
public Transform maxplayerIcon;
-
private
float mapSize;
//小地图的orthographicSize大小
-
public
float Maxmapsize;
//大地图的orthographicSize大小
-
public
float minSize;
//小地图的orthographicSize最小值
-
public
float maxSize;
//小地图的orthographicSize最大值
-
public GameObject maxmap;
//大地图
-
public GameObject minimap;
//小地图
-
-
public Vector3 startPos = Vector3.zero;
//小地图初始位置
-
-
-
public
bool isMaxmap =
false;
//是否打开大地图
-
-
void Awake()
-
{
-
mapSize = minicamera.orthographicSize;
-
-
}
-
// Use this for initialization
-
void Start () {
-
-
}
-
-
// Update is called once per frame
-
void Update () {
-
-
if (isMaxmap)
-
{
-
minicamera.transform.position = startPos;初始化大地图位置
-
-
-
-
-
maxplayerIcon.eulerAngles =
new Vector3(
0,
0, -player.eulerAngles.y);
//地图中的人物图标会根据3D物体的人物转动而转动
-
-
}
-
else
-
{
-
-
minicamera.transform.position =
new Vector3(player.position.x, minicamera.transform.position.y, player.position.z);
-
miniplayerIcon.eulerAngles =
new Vector3(
0,
0, -player.eulerAngles.y);
-
}
-
-
-
-
-
-
}
-
-
//打开大地图
-
public void OpenMaxmap()
-
{
-
maxmap.gameObject.SetActive(
true);
-
minimap.gameObject.SetActive(
false);
-
minicamera.orthographicSize = Maxmapsize;
-
isMaxmap =
true;
-
-
}
-
-
//打开小地图
-
public void OpenMinimap()
-
{
-
maxmap.gameObject.SetActive(
false);
-
minimap.gameObject.SetActive(
true);
-
minicamera.orthographicSize = mapSize;
-
isMaxmap =
false;
-
}
-
//缩放地图方法
-
public void ChangeMapSize(float value)
-
{
-
mapSize +=
value;
-
mapSize = Mathf.Clamp(mapSize, minSize, maxSize);
-
minicamera.orthographicSize = mapSize;
-
}
-
}
注意要给初始位置赋值,赋值就是上面提到的相机最佳位置坐标。
所以现在打开大地图后会显示最佳位置。
但是此时的大地图中人物标记只能旋转,不能移动。因为我们此刻只有旋转代码 maxplayerIcon.eulerAngles = new Vector3(0, 0, -player.eulerAngles.y);//地图中的人物图标会根据3D物体的人物转动而转动。
接下来就是让图标跟着3D场景人物移动而移动。
要知道,现在我们能够看到的界面是2D的,是一个窗口UI界面。而相机看到的主角是在3D的场景中。。。要让相机中主角的位置从3D的位置转化到2D的相对位置需要用到一个方法WorldToViewportPoint(player.position)。
关键语句:minicamera.WorldToViewportPoint(player.position);//从世界坐标变成viewport坐标
所以定义一个变量ptScreen ,一个3D场景转化为窗口视图坐标: private Vector3 ptScreen = Vector3.zero;//转化为窗口视图坐标
而3D场景中转化到界面上的坐标就是:
ptScreen = minicamera.WorldToViewportPoint(player.position);//从世界坐标变成viewport坐标
注意:2D窗口指的是整个UI窗口。它是从左下角为起点(0,0),右上角为(1,1)。
因此ptScreen的坐标最大就是(1,1),也就是UI的右上角。
现在要做的是让角色图标显示在大地图中的位置,而不是整个UI中的位置。所以我们要通过大地图的尺寸与整个UI坐标的比例来算出角色图标显示在大地图中的比例位置。
注意是比例位置。
用X轴来做例子
整个UI的位置是从0到1,也就是大小是1*1,而大地图的尺寸是700*700。也就是说按比例算大地图是转化过来的坐标长度的700倍。
但是大地图是处在整个UI的分辨率中的,而且大地图现在是在整个UI的中心,假如整个UI的分辨率是1366*768。
拿UI起止点(0,0)做例子
因为大地图在UI中心,所以大地图的起始点是从整个UI界面起始点加上这个:(1366-700)/2;Y是(768-700)/2
如下图:两个起始点直接的距离。
那么角色图标最终位置就是:
maxplayerIcon.position = new Vector3(ptScreen.x * 700 + (1366-700)/2, ptScreen.y * 700 +(768-700)/2);
上面只是一个具体的例子用1366*768的分辨率做例子方便理解。
通用的代码是
maxplayerIcon.position = new Vector3((ptScreen.x * maxmap.GetComponent<RectTransform>().sizeDelta.x)+(Screen.width - maxmap.GetComponent<RectTransform>().sizeDelta.x)/2,
(ptScreen.y * maxmap.GetComponent<RectTransform>().sizeDelta.y+(Screen.height - maxmap.GetComponent<RectTransform>().sizeDelta.y)/2), 0);//大地图人物图标的位置
解释就是在转化过来的坐标点乘以大地图的尺寸,然后加上大地图与整个UI起始点的差值。
所以最终代码是:
-
using UnityEngine;
-
using System.Collections;
-
-
public
class
testmin :
MonoBehaviour {
-
public Camera minicamera;
-
public Transform player;
-
public Transform miniplayerIcon;
//小地图人物图标
-
public Transform maxplayerIcon;
-
private
float mapSize;
//小地图的orthographicSize大小
-
public
float Maxmapsize;
//大地图的orthographicSize大小
-
public
float minSize;
//小地图的orthographicSize最小值
-
public
float maxSize;
//小地图的orthographicSize最大值
-
public GameObject maxmap;
//大地图
-
public GameObject minimap;
//小地图
-
-
public Vector3 startPos = Vector3.zero;
//小地图初始位置
-
-
private Vector3 ptScreen = Vector3.zero;
//转化为窗口视图坐标
-
public
bool isMaxmap =
false;
//是否打开大地图
-
-
void Awake()
-
{
-
mapSize = minicamera.orthographicSize;
-
-
}
-
// Use this for initialization
-
void Start () {
-
-
}
-
-
// Update is called once per frame
-
void Update () {
-
-
if (isMaxmap)
-
{
-
minicamera.transform.position = startPos;初始化大地图位置
-
-
ptScreen = minicamera.WorldToViewportPoint(player.position);
//从世界坐标变成viewport坐标
-
-
//大地图在中心,所以大地图的起始点的x是从整个界面起始点加上这个:(1366-700)/2;Y是(768-700)/2
-
Debug.Log(
"屏幕大小" + Screen.width + Screen.height);
-
-
-
-
// maxplayerIcon.position = new Vector3(ptScreen.x * 700 + (1366-700)/2, ptScreen.y * 700 + (768-700)/2);//1366*768的例子
-
-
-
//通用分辩率
-
maxplayerIcon.position =
new Vector3((ptScreen.x * maxmap.GetComponent<RectTransform>().sizeDelta.x) + (Screen.width - maxmap.GetComponent<RectTransform>().sizeDelta.x) /
2,
-
(ptScreen.y * maxmap.GetComponent<RectTransform>().sizeDelta.y + (Screen.height - maxmap.GetComponent<RectTransform>().sizeDelta.y) /
2),
0);
//大地图人物图标的位置
-
-
Debug.Log(
"地图大小" + maxmap.GetComponent<RectTransform>().sizeDelta.x);
-
maxplayerIcon.eulerAngles =
new Vector3(
0,
0, -player.eulerAngles.y);
//地图中的人物图标会根据3D物体的人物转动而转动
-
-
}
-
else
-
{
-
-
minicamera.transform.position =
new Vector3(player.position.x, minicamera.transform.position.y, player.position.z);
-
miniplayerIcon.eulerAngles =
new Vector3(
0,
0, -player.eulerAngles.y);
-
}
-
-
-
-
-
-
}
-
-
//打开大地图
-
public void OpenMaxmap()
-
{
-
maxmap.gameObject.SetActive(
true);
-
minimap.gameObject.SetActive(
false);
-
minicamera.orthographicSize = Maxmapsize;
-
isMaxmap =
true;
-
-
}
-
-
//打开小地图
-
public void OpenMinimap()
-
{
-
maxmap.gameObject.SetActive(
false);
-
minimap.gameObject.SetActive(
true);
-
minicamera.orthographicSize = mapSize;
-
isMaxmap =
false;
-
}
-
//缩放地图方法
-
public void ChangeMapSize(float value)
-
{
-
mapSize +=
value;
-
mapSize = Mathf.Clamp(mapSize, minSize, maxSize);
-
minicamera.orthographicSize = mapSize;
-
}
-
}
这样就实现了角色图标在大地图中的移动显示。如图:
转载:https://blog.csdn.net/alayeshi/article/details/116063841