Unity游戏副本地图制作

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

  

更多内容关注: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;
    }
}

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

 

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值