您的位置:首页 > 移动开发 > Unity3D

Unity3d开发(十三)导出NavMesh可行走区域信息

2016-06-17 12:15 411 查看
文章作者:松阳 本文出自 阿修罗道,禁止用于商业用途,转载请注明出处。   原文链接:http://blog.csdn.net/fansongy/article/details/51699058




有时我们会需要Unity3d的地图信息,比如A*之类的逻辑运算。当这些操作要放到服务器上进行时,就需要地图信息。通常项目中的行走区域是使用Navmesh制作的。这篇文章中,介绍如何将Navmesh的信息导出成bitmap。

脚本效果

整个工具的设置界面放到Inspector中,由于是程序同学用,所以界面就比较糙,对付用吧

可以设置几个数值,导出地图的左顶点坐标、地图精度、宽、高,设置界面如下图所示:



设置好后点击
Export
按钮,即可在场景中计算出可行走区域:



可以看到,与Navmesh的可行走区域相对应位置会画出绿色标尺线,不能行走则标为红色。最终导出的信息内容如下:startpos=(-6.0, 0.0, 6.0)
height=15
wide=15
accuracy=1
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},
{0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,},
{0,0,1,1,1,1,0,0,0,0,1,0,0,0,0,},
{0,0,1,1,1,1,0,0,0,0,1,0,0,0,0,},
{0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,},
{0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,},
{0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,},
{0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,},
{0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,},
{0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},

核心原理

使用一个Unity3d中Navmesh的接口:
NavMesh.SamplePosition

来检测一个点是否在可行走区域中。同时将内容输出到日志中。检测时增加了不同高度的采样,防止由于斜坡引起的遗漏。

代码实现

using UnityEngine;
using System.Collections;
using System.Text;
using UnityEditor;

public class NavExport : MonoBehaviour
{
#region Public Attributes
public Vector3 leftUpStart = Vector3.zero;
public float accuracy = 1;
public int height = 30;
public int wide = 30;
#endregion

#region Unity Messages

void OnGUI()
{
if (GUILayout.Button("Export"))
{
exportPoint(leftUpStart, height, wide, accuracy);
}
}

#endregion

#region Public Methods

public void Exp()
{
exportPoint(leftUpStart, wide, height, accuracy);
}

public void exportPoint(Vector3 startPos, int x, int y, float accuracy)
{
StringBuilder str = new StringBuilder();
int[,] list = new int[x, y];
str.Append("startpos=").Append(startPos).Append("\r\n");
str.Append("height=").Append(y).Append("\r\nwide=").Append(x).Append("\r\naccuracy=").Append(accuracy).Append("\r\n");
for (int i = 0; i < y; ++i)
{
str.Append("{");
for (int j = 0; j < x; ++j)
{
int res = list[j, i];
NavMeshHit hit;
for (int k = -10; k < 30; ++k)
{
if (NavMesh.SamplePosition(startPos + new Vector3(j * accuracy, k, -i * accuracy), out hit, 0.2f, NavMesh.AllAreas))
{
res = 1;
break;
}
}
Debug.DrawRay(startPos + new Vector3(j * accuracy, 0, -i * accuracy), Vector3.up, res == 1 ? Color.green : Color.red, 5);
str.Append(res).Append(",");
}
str.Append("},\n");
}
Debug.Log(str.ToString());
}
#endregion

}

[CustomEditor(typeof(NavExport))]
public class NavExportHelper : Editor
{
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
if (GUILayout.Button("Export"))
{
var exp = target as NavExport;
exp.Exp();
}
}
}
如果你觉得这篇文章对你有帮助,可以顺手点个顶,不但不会喜当爹,还能让更多人能看到它... 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: