unity 通过摄像机模拟实现小地图
2014-04-30 16:11
1526 查看
unity中小地图的应用很广泛,目前多采用两种方式。
1、在unity俯视角下通过截图截取小地图背景图片,如图所示;
优点就是简单便捷,缺点是小地图高、宽需要确定不能通随意改变、不能做一些镜头特效例如缩放地图等。
![](https://oscdn.geek-share.com/Uploads/Images/Content/202010/15/086b97498f175a2f3dd22dbb0336d2f4)
2,、通过摄像机投影到texture上,通过GUI直接绘制出来。
缺点是操作步骤相对繁琐、优点是小地图是实时投影绘制可以通过脚本控制各种视角特效。
![](https://oscdn.geek-share.com/Uploads/Images/Content/202010/15/10ae1488458dbdc5db475efb86b70924)
下面就对第二种方式做一个简单的实例,并详细列出操作步骤及相关程序代码。
小地图功能描述:
1、通过摄像机动态投影地图俯视图作为小地图背景。
2、小地图上可标注游戏对象(通过设置“Tag”标签来自动检索所有待标注游戏对象)
3、小地图上显示当前视角对象位置、旋转角度
4、小地图上单击鼠标左键,移动视角位置
5、动态设置小地图屏幕布局(仅实现右上角布局、左下角布局)
实际运行效果图如下
![](https://oscdn.geek-share.com/Uploads/Images/Content/202010/15/9a35484550363dc641499ac9c1c85a2a)
通过摄像机动态投影地图俯视图作为小地图背景
步骤一:在Hierarchy中添加第二个摄像机,名称为"TopCamera"
![](https://oscdn.geek-share.com/Uploads/Images/Content/202010/15/459342c1089df423c8514a4ab1594a2c)
![](https://oscdn.geek-share.com/Uploads/Images/Content/202010/15/a05c2fb32c0c1f05baff8f9fadb49aa5)
步骤二:在资源面板中新建“Render Texture”,命名“miniMap”
![](https://oscdn.geek-share.com/Uploads/Images/Content/202010/15/c92acbe852e6f798ffc352e0cee47e5f)
![](https://oscdn.geek-share.com/Uploads/Images/Content/202010/15/7d9011d9c72928b62e9ce2ea7f938736)
步骤三:在Hierarchy选中“TopCamera”,设置Target Texture为刚才新建的”miniMap“
![](https://oscdn.geek-share.com/Uploads/Images/Content/202010/15/dcd3927e37da6f455430143667884226)
步骤四:设置”TopCamera“,Transform--》Position--x坐标、y坐标、z坐标均为0
![](https://oscdn.geek-share.com/Uploads/Images/Content/202010/15/a23fef3d7cbff06523ef1a982b3aff6f)
其它算法实现思路:
TopCamera通过程序自动投影全幅地图,设置TopCamera位于地图中央,调整摄像机属性”Field of view“,如图
![](https://oscdn.geek-share.com/Uploads/Images/Content/202010/15/7c3e26b260801ce42023660e94e38975)
待标注物体世界坐标如何换算到小地图中坐标
通过WorldToScreenPoint把世界坐标换算为屏幕坐标,计算该点屏幕坐标X、Y占全屏宽、高比例;
通过宽、高比例计算该点在小地图绘制点。
下面完整代码:
完整的工程项目下载地址:http://download.csdn.net/detail/dulgao/7276927 有分数你懂的。
如果没分数可以给我留言,我邮件发送给你。
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(); } /// <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; } } }
完整的工程项目下载地址:http://download.csdn.net/detail/dulgao/7276927 有分数你懂的。
如果没分数可以给我留言,我邮件发送给你。
相关文章推荐
- Unity 通过摄像机移动实现连续滚动的背景
- unity 通过点击游戏小地图,来移动主相机功能实现
- 通过代码动态实现和模拟Android手机上的back键
- 在 Android 上通过模拟 HTTP multipart/form-data 请求协议信息实现图片上传
- 介绍如何通过代码实现模拟按键的函数
- unity3D MiniMap等比例映射的实现(一) 通过Image做小地图背景,Player实时更新位置在小地图上
- 通过百度API,搜索地名,实现地图和经纬度的查询
- php中通过curl模拟登陆discuz论坛的实现代码
- Tiled结合Unity实现瓦片地图——Tiled2Unity篇
- 通过Surface实现相机功能 摄像机功能
- Unity Shaders and Effects Cookbook (2-1) 修改 UV 坐标实现纹理贴图的滚动 模拟水流效果
- unity 通过使用 photon networking Pun 实现 HTC Vive VR的多人联网。进阶版 《一》
- 常见js实现功能单选框、复选框、通过div模拟下拉列表框...
- Unity中玩家通过点击行走 或 滑动屏幕行走的实现
- Android通过adb命令实现模拟滑动
- Unity滚轮调整摄像机的远近 点击小地图切换摄像机的位置
- Unity 3D UV实现小地图
- 通过重载类的成员操作符来实现对string 类的模拟
- geoserver 通过代码实现发布地图服务
- 模拟实现MyBites中通过SQL反射实体类对象功能