网站公告 | 泰斗网校全新上线了,可以和论坛用户登录同步,如果遇到登录问题联系管理员解决
查看: 8064|回复: 11
收起左侧

[开发经验] unity 通过摄像机模拟实现小地图

[复制链接]

[开发经验] unity 通过摄像机模拟实现小地图[复制链接]

maxcs2012 发表于 2018-1-3 09:48:06 [显示全部楼层] |只看大图 回帖奖励 |倒序浏览 |阅读模式 回复:  11 浏览:  8064
  unity中小地图的应用很广泛,目前多采用两种方式。
  1、在unity俯视角下通过截图截取小地图背景图片,如图所示;
  优点就是简单便捷,缺点是小地图高、宽需要确定不能通随意改变、不能做一些镜头特效例如缩放地图等。

unity 通过摄像机模拟实现小地图

unity 通过摄像机模拟实现小地图

  2,、通过摄像机投影到texture上,通过GUI直接绘制出来。
  缺点是操作步骤相对繁琐、优点是小地图是实时投影绘制可以通过脚本控制各种视角特效。

unity 通过摄像机模拟实现小地图

unity 通过摄像机模拟实现小地图

  下面就对第二种方式做一个简单的实例,并详细列出操作步骤及相关程序代码。
  小地图功能描述:
  1、通过摄像机动态投影地图俯视图作为小地图背景。
  2、小地图上可标注游戏对象(通过设置“Tag”标签来自动检索所有待标注游戏对象)
  3、小地图上显示当前视角对象位置、旋转角度
  4、小地图上单击鼠标左键,移动视角位置
  5、动态设置小地图屏幕布局(仅实现右上角布局、左下角布局)
  实际运行效果图如下

unity 通过摄像机模拟实现小地图

unity 通过摄像机模拟实现小地图

  通过摄像机动态投影地图俯视图作为小地图背景

  步骤一:在Hierarchy中添加第二个摄像机,名称为"TopCamera"

unity 通过摄像机模拟实现小地图

unity 通过摄像机模拟实现小地图

unity 通过摄像机模拟实现小地图

unity 通过摄像机模拟实现小地图

  步骤二:在资源面板中新建“Render Texture”,命名“miniMap”

unity 通过摄像机模拟实现小地图

unity 通过摄像机模拟实现小地图

unity 通过摄像机模拟实现小地图

unity 通过摄像机模拟实现小地图

  步骤三:在Hierarchy选中“TopCamera”,设置Target Texture为刚才新建的”miniMap“

unity 通过摄像机模拟实现小地图

unity 通过摄像机模拟实现小地图

  步骤四:设置”TopCamera“,Transform--》Position--x坐标、y坐标、z坐标均为0

unity 通过摄像机模拟实现小地图

unity 通过摄像机模拟实现小地图

  其它算法实现思路:
  TopCamera通过程序自动投影全幅地图,设置TopCamera位于地图中央,调整摄像机属性”Field of view“,如图

unity 通过摄像机模拟实现小地图

unity 通过摄像机模拟实现小地图


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占全屏宽、高比例;
通过宽、高比例计算该点在小地图绘制点。

下面完整代码:
[C#] 纯文本查看 复制代码
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();

}
/// <summary>
/// Minis the map move.
/// 换算小地图位置点到世界坐标,设置主视角位置
/// </summary>
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<miniMapX && mp.y <miniMapY  )
{
float rx = mp.x ;
float ry = mp.y ;
float wl = rx /miniMapW;
float hl = ry /miniMapH;
cameraMain.transform.position = new Vector3(wl*terrionWidth,cameraMain.transform.position.y,hl*terrionHeight);
}
}
break;
}
}
}

完整的工程项目下载地址:
游客,如果您要查看本帖隐藏内容请回复

评分

参与人数 1泰斗币 +10 收起 理由
泰课_robin + 10 为您的才华点赞

查看全部评分

+1
8067°C
11
  • anmie7723
  • 泰课_robin
  • swordlegend
  • langtusaupt
  • 2569506800@qq.c
过: 他们
因分享而快乐,学习以自强!
anmie7723 发表于 2018-1-3 10:32:24 显示全部楼层
路过看看 感谢分享
因分享而快乐,学习以自强!
泰课_robin 发表于 2018-1-3 10:44:35 显示全部楼层
anmie7723 发表于 2018-1-3 10:32
路过看看 感谢分享

对你路过也回帖的精神表示肯定
来自苹果客户端来自苹果客户端
因分享而快乐,学习以自强!
swordlegend 发表于 2018-1-3 14:29:39 显示全部楼层
学习下,谢谢分享
因分享而快乐,学习以自强!
langtusaupt 发表于 2018-1-3 16:38:12 显示全部楼层
初学者表示大爱
因分享而快乐,学习以自强!
2569506800@qq.c 发表于 2018-1-3 20:06:36 显示全部楼层
ugui的几个函数挺有用的
因分享而快乐,学习以自强!
协行士 发表于 2018-1-3 22:25:21 显示全部楼层
感谢分享,谢谢楼主
因分享而快乐,学习以自强!
得力固体胶 发表于 2018-1-4 15:13:55 显示全部楼层
unity 通过摄像机模拟实现小地图
因分享而快乐,学习以自强!
星陨尘心_clw 发表于 2018-1-4 17:48:03 显示全部楼层
路过看看 感谢分享
因分享而快乐,学习以自强!
XAN 发表于 2018-1-12 21:26:55 显示全部楼层
看看看看看扩扩扩扩扩扩
因分享而快乐,学习以自强!
ktgirltt 发表于 2018-1-17 14:35:54 显示全部楼层
很使用
因分享而快乐,学习以自强!
kuanyidairen 发表于 2018-2-21 09:17:01 显示全部楼层
挺好的 很不错!!!谢谢分享!!
因分享而快乐,学习以自强!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

VR/AR版块|Unity3d|Unreal4|新手报道|小黑屋|站点地图|沪ICP备14023207号-9|【泰斗社区】-专注互联网游戏和应用的开发者平台 ( 浙ICP 备 13006852号-15 )|网站地图

© 2001-2013 Comsenz Inc.  Powered by Discuz! X3.4

1
QQ