Unity C#写的A*寻路
原地址:http://www.unity蛮牛.com/blog-13769-1078.html
首先看了这篇翻译外国人的文章http://www.raywenderlich.com/zh-hans/21503/a%E6%98%9F%E5%AF%BB%E8%B7%AF%E7%AE%97%E6%B3%95%E4%BB%8B%E7%BB%8D
[code]csharpcode:
using UnityEngine;
using System.Collections.Generic; public class Map
{
/// <summary>
/// 初始化地图
/// </summary>
/// <returns></returns>
public static Dictionary<string, MapInfo> GetMap()
{
Dictionary<string, MapInfo> temp = new Dictionary<string, MapInfo>(); for (int i = ; i < ; i++)
{
string s = "";
for (int j = ; j < ; j++)
{
int tt = ;
if (i > && i < && j == )
{
tt = ;
}
MapInfo mi = new MapInfo(i, j, tt);
temp.Add(i + "-" + j, mi);
s += mi.tag + " ";
}
Debug.Log(s);
}
return temp;
}
} /// <summary>
/// 地图节点
/// </summary>
public class MapInfo
{
/// <summary>
/// X
/// </summary>
public int x;
/// <summary>
/// Y
/// </summary>
public int y;
/// <summary>
/// 是否可行走
/// </summary>
public int tag;
/// <summary>
/// G
/// </summary>
public int gValue;
/// <summary>
/// H
/// </summary>
public int hValue;
/// <summary>
/// 父节点
/// </summary>
public MapInfo parent; public MapInfo()
{ } /// <summary>
/// 构造
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <param name="tag"></param>
public MapInfo(int x, int y,int tag)
{
this.x = x;
this.y = y;
this.tag = tag;
this.gValue = ;
this.hValue = ;
this.parent = null;
}
}
2.由起点终点寻路,有注释,知道原理的话,应该很容易懂
[code]csharpcode:
using UnityEngine;
using System.Collections.Generic; public class AStar : MonoBehaviour
{
/// <summary>
/// 地图
/// </summary>
Dictionary<string, MapInfo> map;
/// <summary>
/// open列表
/// </summary>
Dictionary<string, MapInfo> openList = new Dictionary<string, MapInfo>();
/// <summary>
/// close列表
/// </summary>
Dictionary<string, MapInfo> closeList = new Dictionary<string, MapInfo>(); /// <summary>
/// 当前点
/// </summary>
MapInfo currentV;
/// <summary>
/// 当前点的相邻节点列表
/// </summary>
Dictionary<string, MapInfo> adjancentMap; // Use this for initialization
void Start ()
{
map = Map.GetMap();
MapInfo st = map["5-2"];//start
MapInfo end = map["6-8"];//end FindPath(st, end);
} /// <summary>
/// 寻路
/// </summary>
/// <param name="start">起点</param>
/// <param name="end">终点</param>
public void FindPath(MapInfo start,MapInfo end)
{
openList.Add(start.x + "-" + start.y, start); do
{
currentV = GetTheLowestFrom(openList); closeList.Add(currentV.x + "-" + currentV.y, currentV);
openList.Remove(currentV.x + "-" + currentV.y); if (closeList.ContainsKey(end.x + "-" + end.y))
{
Debug.Log("FindPath"); PrintThePath(end);
break;
} adjancentMap = AdjacentList(currentV); foreach (string k in adjancentMap.Keys)
{
if (closeList.ContainsKey(k))
{
continue;
} if (!openList.ContainsKey(k))
{
adjancentMap[k].parent = currentV;
adjancentMap[k].gValue = currentV.gValue + ;
adjancentMap[k].hValue = GetManhattanDistance(adjancentMap[k], end);
openList.Add(k, adjancentMap[k]);
}
else
{
int g = currentV.gValue + ;
if (g < adjancentMap[k].gValue)
{
adjancentMap[k].gValue = g;
adjancentMap[k].parent = currentV;
}
}
} } while (openList.Count > );
} /// <summary>
/// 获取openlist中F最小的节点
/// </summary>
/// <param name="open"></param>
/// <returns></returns>
public MapInfo GetTheLowestFrom(Dictionary<string, MapInfo> open)
{
MapInfo result=null;
int min = ;
foreach (MapInfo m in open.Values)
{
if (m.gValue + m.hValue < min)
{
result = m;
min = m.gValue + m.hValue;
}
}
return result;
} /// <summary>
/// 获取当前节点的相邻节点
/// </summary>
/// <param name="m">当前节点</param>
/// <returns></returns>
public Dictionary<string, MapInfo> AdjacentList(MapInfo m)
{
Dictionary<string, MapInfo> resultDic=new Dictionary<string,MapInfo>(); string left = (m.x - ) + "-" + m.y;
string right = (m.x + ) + "-" + m.y;
string top = m.x + "-" + (m.y - );
string bot = m.x + "-" + (m.y + ); if (map.ContainsKey(left))
{
if(map[left].tag==)
resultDic.Add(left, map[left]);
} if (map.ContainsKey(right))
{
if (map[right].tag == )
resultDic.Add(right, map[right]);
} if (map.ContainsKey(top))
{
if (map[top].tag == )
resultDic.Add(top, map[top]);
} if (map.ContainsKey(bot))
{
if (map[bot].tag == )
resultDic.Add(bot, map[bot]);
}
return resultDic;
} /// <summary>
/// 获得两个点的曼哈顿距离
/// 作为估值函数
/// </summary>
/// <param name="st"></param>
/// <param name="end"></param>
/// <returns></returns>
public int GetManhattanDistance(MapInfo st, MapInfo end)
{
int result = ;
result = Mathf.Abs(st.x - end.x) + Mathf.Abs(st.y - end.y);
return result;
} /// <summary>
/// 输出路径
/// </summary>
/// <param name="end">终点</param>
public void PrintThePath(MapInfo end)
{
string s = "";
MapInfo m = end;
while (m.parent != null)
{
s += "("+m.parent.x + "," + m.parent.y + ")->";
m = m.parent;
}
Debug.Log(s);
}
}
Unity C#写的A*寻路的更多相关文章
- 关于Unity中网格导航与寻路
寻路思路 1.烘焙出地形数据,导航数据,区分哪些是路径,哪些是障碍物 2.给要寻路的角色添加寻路的组件,加好了以后就会有速度和目的地之类的参数设置 3.只要设置好目的地,角色就会根据烘焙好的地图自己走 ...
- unity自带寻路Navmesh入门教程(三)
继续介绍NavMesh寻路的功能,接下来阿赵打算讲一下以下两个例子,先看看完成的效果: 第一个例子对于喜欢DOTA的朋友应该很熟悉了,就是不同小队分不同路线进攻的寻路,红绿蓝三个队伍分别根据三条路 ...
- 【转】unity自带寻路Navmesh入门教程(三)
http://liweizhaolili.blog.163.com/blog/static/16230744201271225812998/ 继续介绍NavMesh寻路的功能,接下来阿赵打算讲一下以下 ...
- unity3d——自带寻路Navmesh (三)(转)
继续介绍NavMesh寻路的功能,接下来阿赵打算讲一下以下两个例子,先看看完成的效果: 第一个例子对于喜欢DOTA的朋友应该很熟悉了,就是不同小队分不同路线进攻的寻路,红绿蓝三个队伍分别根据三条路 ...
- Unity手游之路<八>自动寻路Navmesh之入门
http://blog.csdn.net/janeky/article/details/17457533 在的大部分mmo游戏都有了自动寻路功能.点击场景上的一个位置,角色就会自动寻路过去.中间可能会 ...
- Unity调用Android方法
步骤 废话不多说,直接来步骤吧1.创建工程,弄大概像这样一个界面2.在unity中写好代码,像这样,记得给界面绑定好事件啥的 using UnityEngine; using UnityEngine. ...
- 极简Unity调用Android方法
简介 之前写了篇unity和Android交互的教程,由于代码里面有些公司的代码,导致很多网友看不懂,并且确实有点小复杂,这里弄一个极简的版本 步骤 废话不多说,直接来步骤吧 1.创建工程,弄大概像这 ...
- Unity Shaders Vertex & Fragment Shader入门
http://blog.csdn.net/candycat1992/article/details/40212735 三个月以前,在一篇讲卡通风格的Shader的最后,我们说到在Surface Sha ...
- unity android 集成指南
原地址:http://blog.csdn.net/alking_sun/article/details/36175187 1.安卓层开发并暴露接口. launcher activity(以下称为U ...
随机推荐
- JS学习笔记——标准对象
一.对象 在js中万物皆对象. 二.对象类型 number.string.boolean.undefined.function.object等 用typeof来获取对象的类型 如: alert( ty ...
- c# 远程监控(2) 摄像头调研及模拟
经过N多调研,最终选择了OpenCV(Emgu CV) ** 至于DirectShow, OpenCV等等其他大家可以百度,在这里我就不再赘述 环境:vs2010 vs2012 vs2013均可 Op ...
- MySQL flush privileges 명령어
INSERT나 UPDATE, DELETE문을 이용해서 MySQL의 사용자를 추가,삭제하거나, 사용자 권한 등을 변경하였을 때, MySQL에 변경사항을 적용하기 위해서 사용하는 명령 ...
- List的add方法与addAll方法的区别
add是将传入的参数作为当前List中的一个Item存储,即使你传入一个List也只会另当前的List增加1个元素addAll是传入一个List,将此List中的所有元素加入到当前List中,也就是当 ...
- 【高级JSE技术】线程池
引言 线程池是java并发技术中常用的一种,通过缓存线程资源避免了频繁的创建销毁线程带来的额外开销,从而提高性能.JDK中有相应的Executor框架实现,而Spring中也带有线程池的功能.本文将从 ...
- 提高查询速度:SQL Server数据库优化方案
查询速度慢的原因很多,常见如下几种: 1.没有索引或者没有用到索引(这是查询慢最常见的问题,是程序设计的缺陷) 2.I/O吞吐量小,形成了瓶颈效应. 3.没有创建计算列导致查询不优化. 4.内存不足 ...
- Ext.Net学习笔记15:Ext.Net GridPanel 汇总(Summary)用法
Ext.Net学习笔记15:Ext.Net GridPanel 汇总(Summary)用法 Summary的用法和Group一样简单,分为两步: 启用Summary功能 在Feature标签内,添加如 ...
- 15_会话技术_Cookie
[简述] 会话可理解为:用户打开一个浏览器,点击多个超链接,访问服务器多个Web资源,然后关闭浏览器,整个过程成为一个会话. [会话过程中我们要解决的一些问题] * 每个用户与服务器进行交互的过程中, ...
- makefile--#的不正确使用
/usr/vacpp/bin/makeC++SharedLib -o /cicm/src/dao/testcase/rel/FUNCTEST.ibmcpp -brtl -bnortllib -p100 ...
- Qt-获取主机网络信息之QNetworkAddressEntry
QNetworkAddressEntry类存储了一个网络接口所支持的一个IP地址,同时还有与之相关的子网掩码和广播地址. 每个网络接口可以包含0个或多个IP地址,这些IP地址可以分别关联一个子网掩码和 ...