小妖精的完美游戏教室——人工智能,A*算法,导航网络篇
//================================================================
//
// Copyright (C) 2017 Team Saluka
// All Rights Reserved
//
// Author:小妖精Balous
//
//================================================================
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Saruka
{
/// <summary>
/// 导航网格
/// </summary>
public class NavGrid : MonoBehaviour
{
/// <summary>
/// 景物层级,用来建立导航网格
/// </summary>
public LayerMask scapeMask;
/// <summary>
/// 导航网格大小
/// </summary>
public Vector2 navGridSize;
/// <summary>
/// 单个网格半径
/// </summary>
public float gridRadius;
/// <summary>
/// 单个网格直径
/// </summary>
float gridDiameter;
/// <summary>
/// 网格结点
/// </summary>
public NavNode[,] grids
{
private set;
get;
}
/// <summary>
/// X轴方向网格数量
/// </summary>
public int gridCountX
{
private set;
get;
}
/// <summary>
/// Y轴方向网格数量
/// </summary>
public int gridCountY
{
private set;
get;
}
/// <summary>
/// 创建导航网格
/// </summary>
void CreateNavGrid()
{
gridDiameter = gridRadius * 2;
gridCountX = Mathf.RoundToInt(navGridSize.x / gridDiameter);
gridCountY = Mathf.RoundToInt(navGridSize.y / gridDiameter);
grids = new NavNode[gridCountX, gridCountY];
//导航网格左下角,平面直角坐标系
Vector3 navGridBottomLeft = transform.position - Vector3.right * navGridSize.x / 2 - Vector3.up * navGridSize.y / 2;
//创建网格
for (int x = 0; x < gridCountX; x++)
for (int y = 0; y < gridCountY; y++)
{
//网格中心坐标
Vector3 gridCenter = navGridBottomLeft + Vector3.right * (x * gridDiameter + gridRadius) + Vector3.up * (y * gridDiameter + gridRadius);
bool isWalkable = !(Physics2D.CircleCast(new Vector2(gridCenter.x, gridCenter.y), gridRadius, Vector2.zero, 0.0f, scapeMask));
grids[x, y] = new NavNode(gridCenter, isWalkable, x, y);
}
}
/// <summary>
/// 获得世界坐标所在的结点
/// </summary>
/// <param name="worldPosition">世界坐标</param>
/// <returns>结点</returns>
public NavNode NavNodeFromWorldPosition(Vector3 worldPosition)
{
worldPosition -= transform.position;
float percentX = Mathf.Clamp01((worldPosition.x + navGridSize.x / 2) / navGridSize.x);
float percentY = Mathf.Clamp01((worldPosition.y + navGridSize.y / 2) / navGridSize.y);
int x = Mathf.RoundToInt((gridCountX - 1) * percentX);
int y = Mathf.RoundToInt((gridCountY - 1) * percentY);
return grids[x, y];
}
public List<NavNode> GetNeighborNodes(NavNode navNode)
{
List<NavNode> neighborNodes = new List<NavNode>();
for (int x = -1; x <= 1; x++)
{
for (int y = -1; y <= 1; y++)
{
if (x == 0 && y == 0) continue;
int checkX = navNode.gridX + x;
int checkY = navNode.gridY + y;
if (checkX >= 0 && checkX < gridCountX && checkY >= 0 && checkY < gridCountY) neighborNodes.Add(grids[checkX, checkY]);
}
}
return neighborNodes;
}
void OnDrawGizmos()
{
//导航网格边框
Gizmos.DrawWireCube(transform.position, new Vector3(navGridSize.x, navGridSize.y, 1));
if(grids != null)
{
foreach(NavNode node in grids)
{
Gizmos.color = (node.isWalkable) ? new Color(1, 1, 1, 0.4f) : new Color(1, 0, 0, 0.4f);
Gizmos.DrawCube(node.worldPosition, Vector3.one * (gridDiameter - 0.03f));
}
}
}
// Use this for initialization
void Start()
{
CreateNavGrid();
}
}
}
小妖精的完美游戏教室——人工智能,A*算法,导航网络篇的更多相关文章
- 小妖精的完美游戏教室——人工智能,A*算法,引言
今天也要直播魔法,求科学的! 欢迎来到小妖精Balous的完美游戏教室! 经过前两周的学习,相信米娜桑已经对状态机有所了解了呢~虽然状态机能够实现几乎所有的人工智能,但是,在实践中,你们有没有发现,自 ...
- 小妖精的完美游戏教室——人工智能,A*算法,启发因子篇
//================================================================//// Copyright (C) 2017 Team Saluk ...
- 小妖精的完美游戏教室——人工智能,A*算法,结点篇
//================================================================//// Copyright (C) 2017 Team Saluk ...
- 小妖精的完美游戏教室——人工智能,A*算法,实现篇
//================================================================//// Copyright (C) 2017 Team Saluk ...
- 小妖精的完美游戏教室——buff系统
作者:小妖精Balous,未经作者允许,任何个人与单位不得将此源代码用于商业化项目 #region buff /// <summary> /// 是否魔法免疫,魔法免疫的生物不会受到除自己 ...
- 小妖精的完美游戏教室——东方PROJECT,同人,墙
//================================================================//// Copyright (C) 东方同人社// All Rig ...
- 小妖精的完美游戏教室——东方PROJECT,同人,符卡系统
//================================================================//// Copyright (C) 东方同人社// All Rig ...
- 小妖精的完美游戏教室——东方PROJECT,同人,th12灵梦A
╮(╯▽╰)╭没办法,小妖精Balous也很讨厌学院化的教育呀,一点意义都没有. 这次就上传东方地灵殿灵梦A逻辑部分的核心代码吧,估计连老师都看不懂.动画部分的代码就不放上来了. //======== ...
- 小妖精的完美游戏教室——东方PROJECT,同人,子机
//================================================================//// Copyright (C)// All Rights Re ...
随机推荐
- Struts中向显示界面传输数据
方法一:action类成员做对象成员,加getter,setter.例如: public class RegAction extends ActionSupport { private Login l ...
- 一、linux概述
1. 学习Linux之前先了解Unix Unix是一个强大的多用户.多任务操作系统.于1969年在AT&T的贝尔实验室开发.UNIX的商标权由国际开放标准组织(The Open Group) ...
- idea的一般使用和初始配置
----- idea的一般使用和配置 1.java的类注释及方法注释 :https://blog.csdn.net/sikefeng/article/details/80557265 类注释模板 /* ...
- github下载项目代码到本地,不能运行 本地改完代码 再上传
首先用git bash here,在指定目录下执行, git clone 将项目拉取下来, 试运行: 发现需要配置idea的SDK/jdk, 还要选择language level, 建立输出目录tar ...
- wc.exe
1 /* 2 * 没能实现的功能:wc.exe -s递归处理目录下符合条件的文件 3 * wc.exe -x 显示图形界面 4 * 5 * 6 * 实现的功能: wc.exe -c显示文件的字符数. ...
- MySQL行转列、列转行
一.行转列 有如图所示的表,现在希望查询的结果将行转成列 建表语句如下: CREATE TABLE `TEST_TB_GRADE` ( `ID` int(10) NOT NULL AUTO_INCRE ...
- 为什么Python是最适合初创公司的编程语言?
为什么Python是最适合初创公司的编程语言? 选自Medium 作者:Gleb Pushkov 京东云开发者社区编译 对于初创公司而言,要在众多编程语言中为公司选择一个正确.合适的语言绝非易事. 如 ...
- admin 显示多对多字段
class BookAdmin(admin.ModelAdmin): def 作者(self, object): return [a.name for a in object.author.all() ...
- LNMP(三)
第二十二次课 LNMP(三) 目录 一.Nginx负载均衡 二.ssl原理 三.生成ssl密钥对 四.Nginx配置ssl 五.php-fpm的pool 六.php-fpm慢执行日志 七.open_b ...
- css之positon与z-index
在网页设计中,position属性的使用是非常重要的.有时如果不能认识清楚这个属性,将会给我们带来很多意想不到的困难. position属性共有四种不同的定位方法,分别是static.fixed.re ...