unity中小地图的应用很广泛,目前多采用两种方式。
1、在unity俯视角下通过截图截取小地图背景图片,如图所示;
优点就是简单便捷,缺点是小地图高、宽需要确定不能通随意改变、不能做一些镜头特效例如缩放地图等。
2,、通过摄像机投影到texture上,通过GUI直接绘制出来。
缺点是操作步骤相对繁琐、优点是小地图是实时投影绘制可以通过脚本控制各种视角特效。
下面就对第二种方式做一个简单的实例,并详细列出操作步骤及相关程序代码。
小地图功能描述:
1、通过摄像机动态投影地图俯视图作为小地图背景。
2、小地图上可标注游戏对象(通过设置“Tag”标签来自动检索所有待标注游戏对象)
3、小地图上显示当前视角对象位置、旋转角度
4、小地图上单击鼠标左键,移动视角位置
5、动态设置小地图屏幕布局(仅实现右上角布局、左下角布局)
实际运行效果图如下
通过摄像机动态投影地图俯视图作为小地图背景
步骤一:在Hierarchy中添加第二个摄像机,名称为"TopCamera"
步骤二:在资源面板中新建“Render Texture”,命名“miniMap”
步骤三:在Hierarchy选中“TopCamera”,设置Target Texture为刚才新建的”miniMap“
步骤四:设置”TopCamera“,Transform--》Position--x坐标、y坐标、z坐标均为0
其它算法实现思路:
TopCamera通过程序自动投影全幅地图,设置TopCamera位于地图中央,调整摄像机属性”Field of view“,如图
TopCamera.transform.Translate(new Vector3(terrionWidth/2,200,terrionHeight/2),Space.World);// 200设置摄像机Y具备一定高度,
TopCamera.transform.Rotate(new Vector3(90,0,0),Space.Self);// 调整摄像机为俯视角度
通过WorldToScreenPoint把世界坐标换算为屏幕坐标,计算该点屏幕坐标X、Y占全屏宽、高比例;
通过宽、高比例计算该点在小地图绘制点。
下面完整代码:
using UnityEngine;
using System.Collections;
public enum miniMapPosition{
右上角,左下角
}
public class miniMap : MonoBehaviour {
public float terrionHeight=0;// 场景高度
public float terrionWidth=0;// 场景宽度
public Camera cameraMap;// 投影地图摄像机
public Camera cameraMain;// 主摄像机
public Texture image;// 投影地图材质
//public Transform target;// 标注对象位置
public string targetTag;// 标注对象Tag
public Texture point;// 标注图标
public Texture cmTexture;// 主摄像机图标
public float miniMapW = 128;
public float miniMapH = 128;
public miniMapPosition mmPosition;
// Use this for initialization
void Start () {
if (terrionWidth!=0&&terrionHeight!=0)
{
// 设置顶层摄像机位置,投影实景地图
cameraMap.transform.Translate(new Vector3(terrionWidth/2,200,terrionHeight/2),Space.World);
cameraMap.transform.Rotate(new Vector3(90,0,0),Space.Self);
}
}
// Update is called once per frame
void Update () {
if ( Input.GetMouseButton(0) )
{
miniMapMove();
}
}
void OnGUI() {
switch(mmPosition)
{
case miniMapPosition.右上角:
GUI.BeginGroup(new Rect(Screen.width-miniMapW,0,miniMapW,miniMapH));
break;
case miniMapPosition.左下角:
GUI.BeginGroup(new Rect(0,Screen.height-miniMapH,miniMapW,miniMapH));
break;
}
GUI.DrawTexture(new Rect(0,0,miniMapW,miniMapH), image, ScaleMode.ScaleToFit, false, 0);
GUI.EndGroup();
GameObject[] objs = GameObject.FindGameObjectsWithTag(targetTag);
foreach(GameObject obj in objs)
{
drawFlag(obj.transform,point,4,4);
}
drawRotateFlag(cameraMain.transform,cmTexture,10,10);
}
void drawFlag(Transform tf,Texture flag,float flagW,float flagH)
{
Vector3 screenPos = cameraMap.WorldToScreenPoint(tf.position);
float wl = tf.position.x /terrionWidth;
float hl = tf.position.z /terrionHeight;
float mpw = wl * miniMapW;
float mph = miniMapH-hl *miniMapH;
// 等比例缩放
switch(mmPosition)
{
case miniMapPosition.右上角:
GUI.BeginGroup(new Rect(Screen.width-miniMapW,0,miniMapW,miniMapH));
break;
case miniMapPosition.左下角:
GUI.BeginGroup(new Rect(0,Screen.height-miniMapH,miniMapW,miniMapH));
break;
}
GUI.DrawTexture(new Rect(mpw-flagW/2,mph-flagH/2, flagW, flagH), flag);
GUI.EndGroup();
}
void drawRotateFlag(Transform tf,Texture flag,float flagW,float flagH)
{
Vector3 screenPos = cameraMap.WorldToScreenPoint(tf.position);
float wl = tf.position.x /terrionWidth;
float hl = tf.position.z /terrionHeight;
float mpw = wl * miniMapW;
float mph = miniMapH-hl *miniMapH;
// 等比例缩放
switch(mmPosition)
{
case miniMapPosition.右上角:
GUI.BeginGroup(new Rect(Screen.width-miniMapW,0,miniMapW,miniMapH));
break;
case miniMapPosition.左下角:
GUI.BeginGroup(new Rect(0,Screen.height-miniMapH,miniMapW,miniMapH));
break;
}
GUIUtility.RotateAroundPivot(cameraMain.transform.eulerAngles.y+90,new Vector2(mpw+flagW/2,mph));
GUI.DrawTexture(new Rect(mpw-flagW/2,mph-flagH/2, flagW, flagH), flag);
GUI.EndGroup();
}
///
/// Minis the map move.
/// 换算小地图位置点到世界坐标,设置主视角位置
///
void miniMapMove()
{
// 小地图定位场景区域
Vector3 mp = Input.mousePosition;
Debug.Log("mp:"+mp);
switch(mmPosition)
{
case miniMapPosition.右上角:
{
float miniMapX = Screen.width-miniMapW;
float miniMapY = Screen.height-miniMapH;
if ( mp.x>miniMapX && mp.y >miniMapY )
{
float rx = mp.x - miniMapX;
float ry = mp.y - miniMapY;
float wl = rx /miniMapW;
float hl = ry /miniMapH;
cameraMain.transform.position = new Vector3(wl*terrionWidth,cameraMain.transform.position.y,hl*terrionHeight);
}
}
break;
case miniMapPosition.左下角:
{
float miniMapX = miniMapW;
float miniMapY = miniMapH;
if ( mp.x
完整的工程项目下载地址:http://download.csdn.net/detail/dulgao/7276927 有分数你懂的。
如果没分数可以给我留言,我邮件发送给你。