小地图的制作,游戏中的导航仪,minimap制作(继续我们的仙剑demo)

37 篇文章 1 订阅
我们继续白天的话题,白天列出了还有哪些东西需要后续的讲解,今晚我们就来讨论下小地图,说实话,小地图这个概念在u3d里面因为有透视相机的出现,制作起来简单的不能再简单了,看看代码
/// <summary>
/// Minimap sign.
/// This script use for setup minimap sign
/// </summary>

using UnityEngine;
using System.Collections;

public class MinimapSign : MonoBehaviour {
	
	public static MinimapSign Instance;
	
	public Texture player,enemy,boss,npc,shopWeapon,shopPotion,savePoint,quest;
	
	[HideInInspector]
	public Material[] minimapSignMat = new Material[8];
	
	private Shader unlitShader;	
	
	// Use this for initialization
	void Awake () {
		
		//Crate new material to assign minimap sign
		
		minimapSignMat = new Material[8];
		
		Instance = this;
		
		unlitShader = Shader.Find("Unlit/Transparent");	
		
		for(int i=0;i < minimapSignMat.Length;i++)
		{
			minimapSignMat[i] = new Material(unlitShader);	
		}
		
		minimapSignMat[0].mainTexture = player;
		minimapSignMat[1].mainTexture = enemy;
		minimapSignMat[2].mainTexture = boss;
		minimapSignMat[3].mainTexture = npc;
		minimapSignMat[4].mainTexture = shopWeapon;
		minimapSignMat[5].mainTexture = shopPotion;
		minimapSignMat[6].mainTexture = savePoint;
		minimapSignMat[7].mainTexture = quest;
	
	}
}
/// <summary>
/// Minimap.
/// This script use to call minimap on top-right screen
/// </summary>

using UnityEngine;
using System.Collections;

public class Minimap : MonoBehaviour {
	
	private Vector2 defaultScreenRes; //Screen Resolution
	
	[System.Serializable]
	public class GUISetting
	{
		public Vector2 position;
		public Vector2 size;
		public Texture2D[] texture;
	}
	
	[System.Serializable]
	public class LabelSetting
	{
		public Vector2 position;
		public GUIStyle labelStyle;
		
	}
	
	[System.Serializable]
	public class MinimapSetting
	{
		public Vector2 position;
		public Vector2 size;
		public Texture texture;
		public Material renderMaterial;
	}
	
	[System.Serializable]
	public class ButtonSetting
	{
		public Vector2 position;
		public Vector2 size;
		public GUIStyle buttonStlye;
	}
	
	public GUISetting frameMap,mapNameBar; //GUI setting
	public MinimapSetting minimap; //Minimap setting
	public LabelSetting mapName; //Map name setting
	public ButtonSetting zoomInBt,zoomOutBt; //button setting
	
	// Use this for initialization
	void Start () {
		
		defaultScreenRes.x = 1920; //declare max screen ratio
		defaultScreenRes.y = 1080; //declare max screen ratio
	
	}
	
	void OnGUI ()
	{
		
		if(!GameSetting.Instance.hideMinimap)
		{
				// Resize GUI Matrix according to screen size
	        ResizeGUIMatrix();
			
			//Draw Minimap
			Graphics.DrawTexture(new Rect(minimap.position.x,minimap.position.y,minimap.size.x ,minimap.size.y),minimap.texture,minimap.renderMaterial);
			
			//Draw MinimapFrame
			GUI.DrawTexture(new Rect(frameMap.position.x,frameMap.position.y,frameMap.size.x,frameMap.size.y),frameMap.texture[0]);
			
			//Draw Map name bar
			GUI.DrawTexture(new Rect(mapNameBar.position.x,mapNameBar.position.y,mapNameBar.size.x,mapNameBar.size.y),mapNameBar.texture[0]);
			
			TextFilter.DrawOutline(new Rect(mapName.position.x ,mapName.position.y, 1000 , 1000)
				,Application.loadedLevelName,mapName.labelStyle,Color.black,Color.white,2f);
			
			
			//Draw zoom in button
			if(GUI.Button(new Rect(zoomInBt.position.x,zoomInBt.position.y,zoomInBt.size.x,zoomInBt.size.y),"",zoomInBt.buttonStlye))
			{
				MinimapCamera.zoomLevel++;
				MinimapCamera.Instance.ZoomUpdate();
			}
			
			//Draw zoom out button
			if(GUI.Button(new Rect(zoomOutBt.position.x,zoomOutBt.position.y,zoomOutBt.size.x,zoomOutBt.size.y),"",zoomOutBt.buttonStlye))
			{
				MinimapCamera.zoomLevel--;
				MinimapCamera.Instance.ZoomUpdate();
			}
			
			
			// Reset matrix after finish
		        GUI.matrix = Matrix4x4.identity;
		}else
		{
			this.enabled = false;
		}
		
		
	}
	
	void ResizeGUIMatrix()
    {
       // Set matrix
       Vector2 ratio = new Vector2(Screen.width/defaultScreenRes.x , Screen.height/defaultScreenRes.y );
       Matrix4x4 guiMatrix = Matrix4x4.identity;
       guiMatrix.SetTRS(new Vector3(1, 1, 1), Quaternion.identity, new Vector3(ratio.x, ratio.y, 1));
       GUI.matrix = guiMatrix;
    }
}

只有很简单的两个类,这两个类都干了写什么呢

我们看下预制件怎么做的

这个minimap预制件上面绑了两个脚本一个是画出小地图的gui,一个是指定小地图中不同gameobject的类型,效果就是这几个点是怎么出现的呢?以人物为例,看到了吧,我们通过这个minimapsign在人物头顶很高的地方画出一个平面,用这个平面来分辨出各种gameobject,那怎么出现在小地图里的呢?这里我们设定一个orthographic摄像机,把它放置在player头上垂直的地方,并且这个摄像机随着人物移动,这样摄像机里面的照射出来的东西,就都出现在小地图窗口了,这个就是我们小地图的一般做法,说道一般做法,不错,因为游戏场景是千变万化的,有时候特殊的场景无法使用这种方法怎么办,我们举个例子,比如说山洞,山洞的天花板本来很矮,我们如果把摄像机放在头上,那头上的plane板子就没地方放了,如果直接放在头上,当然是不行的,所以我们的小地图系统还需要一种传统的平面小地图制作方式,这种方式其实很普遍,比如说市面上的2d webgame几乎全是这种方式制作小地图,怎么实现的,其实很简单,就是主角在游戏世界中行走时,我们用一个比较小的点来标记当前主角的位置,主角行走后,这个点的坐标也相应发生变化,点在一个地图平面图上面行动,我们从y轴向下俯视这个运动,通过小地图的宽,高与真实的地形场景的宽 高计算出缩放比例,最后计算出小地图上“主角”代表的小点的位置,

using UnityEngine;
using System.Collections;

public class map_plane : MonoBehaviour 
{
	
	//大地图地形对象
	GameObject plane;
	//大地图主角对象
	GameObject cube;
	
	//大地图的宽度
	float mapWidth;
	//大地图的高度
	float mapHeight;
	//地图边界的检测数值
	float widthCheck;
	float heightCheck;
	
	//小地图主角的位置
	float mapcube_x =0;
	float mapcube_y = 0;
	
	
	//GUI按钮是否被按下
	bool keyUp;
	bool keyDown;
	bool keyLeft;
	bool keyRight;
	
	//小地图的背景贴图
	public Texture map;
	//小地图的主角贴图
	public Texture map_cube;
	
	void Start()
	{
		//得到大地图对象
		plane = GameObject.Find("Plane");
		//得到大地图主角对象
		cube = GameObject.Find("Cube");
		//得到大地图默认宽度
		float size_x = plane.GetComponent<MeshFilter>().mesh.bounds.size.x;
		//得到大地图宽度的缩放比例
		float scal_x = plane.transform.localScale.x;
		//得到大地图默认高度
		float size_z = plane.GetComponent<MeshFilter>().mesh.bounds.size.z;
		//得到大地图高度缩放地理
		float scal_z = plane.transform.localScale.z;
		
		//原始宽度乘以缩放比例计算出真实宽度
		mapWidth = size_x * scal_x;
		mapHeight = size_z * scal_z;
		
		//越界监测的宽度
		widthCheck = mapWidth / 2;
		heightCheck = mapHeight / 2;
		
		check();
	}
	
	void OnGUI()
	{
		keyUp = GUILayout.RepeatButton("向前移动");

		keyDown = GUILayout.RepeatButton("向后移动");
		
		keyLeft = GUILayout.RepeatButton("向左移动");
		
		keyRight = GUILayout.RepeatButton("向右移动");
		
		//绘制小地图背景
		GUI.DrawTexture(new Rect(Screen.width - map.width,0,map.width,map.height),map);
		//绘制小地图上的“主角”
		GUI.DrawTexture(new Rect(mapcube_x,mapcube_y,map_cube.width,map_cube.height),map_cube);
	}
	
	void FixedUpdate()
	{
		

		if(keyUp)
		{
			//向前移动
			cube.transform.Translate(Vector3.forward * Time.deltaTime *5); 
			check();
	
		}
		
		if(keyDown)
		{
			//向后移动
			cube.transform.Translate(-Vector3.forward * Time.deltaTime *5); 
			check();
		}
		
		if(keyLeft)
		{
			//向左移动
			cube.transform.Translate(-Vector3.right * Time.deltaTime *5);  
			check();
		}
		
		if(keyRight)
		{
			//向右移动
			cube.transform.Translate(Vector3.right * Time.deltaTime *5); 
			check();
		}
	 
		
		
		
	}
	
	//越界检测
	void check()
	{
		//得到当前主角在地图中的坐标
		float x = cube.transform.position.x;
		float z = cube.transform.position.z;
		
		//当控制主角超过地图范围时,重新计算主角坐标
		if(x >= widthCheck)
		{
			x = widthCheck;
		}
		if(x <= -widthCheck)
		{
			x = -widthCheck;
		}
		if(z >= heightCheck)
		{
			z = heightCheck;
		}
		if(z <= -heightCheck)
		{
			z = -heightCheck;
		}
		
		cube.transform.position = new Vector3(x,cube.transform.position.y,z);
		
		//根据比例计算小地图“主角”的坐标
		mapcube_x = (map.width/mapWidth * x) + ((map.width / 2) - (map_cube.width/2)) + (Screen.width - map.width);
		mapcube_y =map.height - ((map.height/mapHeight * z) + (map.height / 2));
	}
}
代码很简单,效果吗,就是这样的, 我们为了方便测试,直接绑在摄像机上,其实我们可以用ngui做一个地图面板,然后需要的时候,点m键调出来,这样就解决了,有些场景不能使用透视相机的问题,而且m缩略地图也可以这么来做。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值