之前所讲到的制作地图方式都是使用在全局大地图中。因为人物永远都在地图的中心。如图:

  

Unity游戏副本地图制作_3D

更多内容关注:unity风雨路

但是有些游戏副本中的主角人物不是一直处在地图中心,而是可以看到副本的整个地图。角色只是处在大地图中的某个坐标位置。这种地图的制作实现也有所不同。

接下来讲如何实现:看到副本的整个地图场景,角色可以移动到与地图相对的任何坐标位置并非一直在地图中心。如下图:

Unity游戏副本地图制作_UI_02

 

举个例子:有一个场景是副本内的场景。副本场景就是下图中的的建筑区(绿色草地只是背景)

Unity游戏副本地图制作_初始化_03

 

因此副本的地图是这样:就是建筑物区域的俯视图,一张图片而已。如下:

Unity游戏副本地图制作_UI_04

 

新建一个Plane和材质球,将该图赋值给材质球,然后材质球给Plane上。并且将Plane的layer设置为Map。

Unity游戏副本地图制作_3D_05

将plane位置放置对齐到该场景。但一定要放置到场景地下,这样就不会干扰场景显示。

Unity游戏副本地图制作_UI_06

 

接着选择MiniMapCamera设置大小和位置恰好看到整个场景。可以从预览里调整位置大小来参考。

Unity游戏副本地图制作_3D_07

注意:一定要调整到可以看到地图的全貌。这是最佳位置。如下:

Unity游戏副本地图制作_UI_08

   

Unity游戏副本地图制作_3D_09

   

Unity游戏副本地图制作_UI_10

 

一定要记住这个时候的相机size。因为这个值就是我们之前讲到的大地图的尺寸。把它拷贝过来。

 

Unity游戏副本地图制作_3D_11

 

这个时候运行测试发现:显示出小地图中的plan位置变了。。。因为我们的代码中小地图相机是时刻跟随主角的。现在主角的位置在场景的边沿,相机当然会跟随的到这个位置。

Unity游戏副本地图制作_3D_12

    

Unity游戏副本地图制作_3D_13

本节我们关心的是大地图,小地图不做处理。但此时点开大地图也是和小地图中显示的相同的。

因此我们要将大地图中相机位置代码删除。删这句 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;
}
}

Unity游戏副本地图制作_初始化_14

注意要给初始位置赋值,赋值就是上面提到的相机最佳位置坐标

Unity游戏副本地图制作_UI_10

 

所以现在打开大地图后会显示最佳位置。

Unity游戏副本地图制作_UI_16

但是此时的大地图中人物标记只能旋转,不能移动。因为我们此刻只有旋转代码 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           

如下图:两个起始点直接的距离。

Unity游戏副本地图制作_UI_17

 

那么角色图标最终位置就是:

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

这样就实现了角色图标在大地图中的移动显示。如图:

 

Unity游戏副本地图制作_UI_02