Unity4.6 兴许版本号都已经内置了寻路AI了。之前的文章有介绍

Unity3d 寻路功能 介绍及项目演示

然而两年来项目中一直使用的是 A* Pathfinding 这个插件的。所以抽时间来写下这个插件的简单使用。

依据游戏的类型。使用到的插件功能可能会不一样,我这里仅仅介绍最简单的,也是使用的最多的简单寻路。复杂的如尾随、动态。都有相应的样例来学习。

我也一直都没有去看……

转自http://blog.csdn.net/huutu http://www.thisisgame.com.cn

以下是动态图,借助 A* 插件,编写非常少的代码就能够做到寻路。

1、创建场景

在场景中加入一些Cube 作为障碍物 Obstacles,加入一个 Capsule 作为Player,然后加入一个Plane 作为地面。再加入一个Plane。作为斜坡測试。

在创建一个GameObject,改名为 A* 。加入A Star Path (Path finder) 组件。

2、编辑场景,指定障碍物

A* 插件中,是依据 Layer 来推断障碍物的,所以我们要把 作为障碍物的 Cubes 都设置到 Obstacle 这一个Layer。

然后给我们的地板,设置Layer 为 Ground ,两块地板都是

转自http://blog.csdn.net/huutu http://www.thisisgame.com.cn

3、生成寻路网格

选中 A* ,在Inspector 中,展开 。

查看以下的面板。

如图中,

黑色箭头所指是宽高。这里的宽高。是指格子的数量。

这里用到的就是 A* 的格子寻路。

调整宽高,覆盖整个Plane。

红色箭头所指,是左上、右上、左下、右下、中心 四个点,选中当中一个点,就能够调整这个点的位置。

选中中心。点击蓝色箭头所指的 Snap Size,会依据中心的位置来自己主动对齐。

继续设置。

红框中的Collision Testing。是生成 禁止通过 格子的。

由于我们的 Cubes 是障碍物,所以在 Mask 中选择 Cubes 所在的Layer - Obstacles。

黄色框中的Height Testing 是用来 让寻路节点 与 Ground 进行检測的。比方要爬坡的时候就须要检測高度。

设置完毕后,点击Scan,就会生成寻路网格。

转自http://blog.csdn.net/huutu http://www.thisisgame.com.cn

4、编写寻路 AI 代码

生成寻路网格之后,我们在代码中就能够使用 A* 来进行寻路了。

首先在 Player 这个 Capsule 上加入Seeker 组件。

然后新建脚本 AStarPlayer.cs 作为測试代码。

在代码中,首先我们从 屏幕发射射线。来定位目标位置。

然后使用 Seeker 来開始生成最短路径。

Seeker生成路径成功后。会把每个节点的位置保存在 List中。

我们依照顺序读取 List 中的位置,位移Player 到相应的位置,就完毕了寻路。

以下是完整代码:

using UnityEngine;
using System.Collections;
using Pathfinding; public class AStarPlayer : MonoBehaviour
{
//目标位置;
Vector3 targetPosition; Seeker seeker;
CharacterController characterController; //计算出来的路线;
Path path; //移动速度;
float playerMoveSpeed = 10f; //当前点
int currentWayPoint = 0; bool stopMove = true; //Player中心点;
float playerCenterY = 1.0f; // Use this for initialization
void Start ()
{
seeker = GetComponent<Seeker>(); playerCenterY = transform.localPosition.y;
} //寻路结束;
public void OnPathComplete(Path p)
{
Debug.Log("OnPathComplete error = "+p.error); if (!p.error)
{
currentWayPoint = 0;
path = p;
stopMove = false;
} for (int index = 0; index < path.vectorPath.Count; index++)
{
Debug.Log("path.vectorPath["+index+"]="+path.vectorPath[index]);
}
} // Update is called once per frame
void Update ()
{
if (Input.GetMouseButtonDown(0))
{
RaycastHit hit;
if (!Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hit, 100))
{
return;
}
if (!hit.transform)
{
return;
}
targetPosition = hit.point;// new Vector3(hit.point.x, transform.localPosition.y, hit.point.z); Debug.Log("targetPosition=" + targetPosition); seeker.StartPath(transform.position, targetPosition,OnPathComplete);
}
} void FixedUpdate()
{
if (path == null || stopMove)
{
return;
} //依据Player当前位置和 下一个寻路点的位置,计算方向;
Vector3 currentWayPointV = new Vector3(path.vectorPath[currentWayPoint].x, path.vectorPath[currentWayPoint].y + playerCenterY, path.vectorPath[currentWayPoint].z);
Vector3 dir = (currentWayPointV - transform.position).normalized; //计算这一帧要朝着 dir方向 移动多少距离;
dir *= playerMoveSpeed * Time.fixedDeltaTime; //计算加上这一帧的位移,是不是会超过下一个节点;
float offset = Vector3.Distance(transform.localPosition, currentWayPointV); if (offset < 0.1f)
{
transform.localPosition = currentWayPointV; currentWayPoint++; if (currentWayPoint == path.vectorPath.Count)
{
stopMove = true; currentWayPoint = 0;
path = null;
}
}
else
{
if (dir.magnitude > offset)
{
Vector3 tmpV3 = dir * (offset / dir.magnitude);
dir = tmpV3; currentWayPoint++; if (currentWayPoint == path.vectorPath.Count)
{
stopMove = true; currentWayPoint = 0;
path = null;
}
}
transform.localPosition += dir;
}
}
}

至此简单的寻路了。

在A* 的Example 中,有非常多个样例。

最简单的寻路脚本写法是 直接继承 AIPath 。

以下新建一个 脚本 PlayerAI.cs 继承 AIPath 来作为測试

using UnityEngine;
using System.Collections;
using Pathfinding.RVO; namespace Pathfinding
{
[RequireComponent(typeof(Seeker))]
[RequireComponent(typeof(CharacterController))]
public class PlayerAI : AIPath
{
/** Minimum velocity for moving */
public float sleepVelocity = 0.4F; /** Speed relative to velocity with which to play animations */
public float animationSpeed = 0.2F; /** Effect which will be instantiated when end of path is reached.
* \see OnTargetReached */
public GameObject endOfPathEffect; public new void Start()
{
//Call Start in base script (AIPath)
base.Start();
} /** Point for the last spawn of #endOfPathEffect */
protected Vector3 lastTarget; public override void OnTargetReached()
{
if (endOfPathEffect != null && Vector3.Distance(tr.position, lastTarget) > 1)
{
GameObject.Instantiate(endOfPathEffect, tr.position, tr.rotation);
lastTarget = tr.position;
}
} public override Vector3 GetFeetPosition()
{
return tr.position;
} protected new void Update()
{ if (Input.GetMouseButtonDown(0))
{
RaycastHit hit;
if (!Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hit, 100))
{
return;
}
if (!hit.transform)
{
return;
}
target.localPosition = hit.point;
} //Get velocity in world-space
Vector3 velocity;
if (canMove)
{
//Calculate desired velocity
Vector3 dir = CalculateVelocity(GetFeetPosition()); //Rotate towards targetDirection (filled in by CalculateVelocity)
RotateTowards(targetDirection); dir.y = 0;
if (dir.sqrMagnitude > sleepVelocity * sleepVelocity)
{
//If the velocity is large enough, move
}
else
{
//Otherwise, just stand still (this ensures gravity is applied)
dir = Vector3.zero;
} if (this.rvoController != null)
{
rvoController.Move(dir);
velocity = rvoController.velocity;
}
else
if (navController != null)
{
#if FALSE
navController.SimpleMove (GetFeetPosition(), dir);
#endif
velocity = Vector3.zero;
}
else if (controller != null)
{
controller.SimpleMove(dir);
velocity = controller.velocity;
}
else
{
Debug.LogWarning("No NavmeshController or CharacterController attached to GameObject");
velocity = Vector3.zero;
}
}
else
{
velocity = Vector3.zero;
}
}
}
}

代码量少,可是不如自己写的直观。

两种不同的脚本都能够实现寻路效果。

演示样例项目打包下载:

http://pan.baidu.com/s/1hsm6YNi

A* Pathfinding Project (Unity A*寻路插件) 使用教程的更多相关文章

  1. [Unity] A* pathfinding project integrated with influence map

    简介 最近一阶段重温了一些关于游戏人工智能方面的书籍. 加强了对influence map的认知.想要亲自动手实现一下. 正如文章标题所示,这篇文章讲的是:如何将influence map的机制融入到 ...

  2. unity自带寻路Navmesh入门教程(一)

    说明:从今天开始,我阿赵打算写一些简单的教程,方便自己日后回顾,或者方便刚入门的朋友学习.水平有限请勿见怪.不过请尊重码字截图录屏的劳动,如需转载请先告诉我.谢谢! unity自从3.5版本之后,增加 ...

  3. 【转】unity自带寻路Navmesh入门教程(一)

    http://liweizhaolili.blog.163.com/blog/static/16230744201271161310135/ 说明:从今天开始,我阿赵打算写一些简单的教程,方便自己日后 ...

  4. 使用A* Pathfinding Project的一些心得

    最近在游戏开发中要做寻路.首选果断就是Unity3D自带的寻路啦.方便稳定,基本功能都能满足.我们的需求也不复杂,就是一个英雄在不同的地图中探索.但是介于一个比较恶心的问题,果断放弃了它.所以,说A* ...

  5. Unity的NGUI插件篇——入场效果

    Unity的NGUI插件篇--入场效果 入场效果 入场效果须要借助于NGUI提供的TweenPosition类来完毕.为了说明此类的用法.本节将使会解说两个演示样例.本文选自  大学霸 <NGU ...

  6. Unity时钟定时器插件

    Unity时钟定时器插件 http://dsqiu.iteye.com/blog/2020603https://github.com/joserocha3/KillerCircles/blob/67a ...

  7. 记录一个Unity播放器插件的开发

    背景 公司最近在做VR直播平台,VR开发我们用到了Unity,而在Unity中播放视频就需要一款视频插件,我们调研了几个视频插件,记录两个,如下: Unity视频插件调研 网上搜了搜,最流行的有以下两 ...

  8. Curved UI - VR Ready Solution To Bend Warp Your Canvas 1.7,1.8,2.2,2.3 四种版本压缩包(Unity UGUI曲面插件),可以兼容VRTK

    Curved UI - VR Ready Solution To Bend Warp Your Canvas 1.7,1.8,2.2,2.3 四种版本压缩包(Unity UGUI曲面插件) 可以兼容V ...

  9. unity assetStore 常用插件

    常用插件 20180723============= 教程类 =============<Mecanim Example Scenes > 官方示例场景<Surivial Shoot ...

随机推荐

  1. 计算器Pro应用项目源码

    本计算器实现了一些简单的功能,可能本身还存在一些缺陷,希望大家提建议,能够改进一下. 源码项目我已经上传到源码天堂那里了:http://code.662p.com/list/11_1.html < ...

  2. 无聊的我写了一个代码 。。。P1605 迷宫

    搜索水题 哎 直接不行了 . #include <ctype.h> #include <cstdio> void read(int &x) { x=;char ch=g ...

  3. iOS截取特定的字符串(正则匹配)

    有时候我们会有需求从一个字符串中截取其他的字符串,根据情况的不同,我们来分析几种方法~~ 一. 固定长度字符串中截取固定位置长度的字符串 // 这是比较简单的一种情况:比如截取手机号的后4位 let ...

  4. 用Python控制摄像头拍照并发邮件

    概述前言 工具 思路 安装及导入包 设置参数 实现拍照 构造邮件内容 发送邮件 判断网络连接 开机自启 后记 o1 前言为什么会有写这个程序的想法呢? 最初的想法是写一个可以用电脑前置摄像头拍照的程序 ...

  5. Java基础(十二)--clone()方法

    Clone在Java中就是用来复制对象,通过分配一个和源对象相同大小的内存空间,然后创建一个新的对象,那么他和=的区别在哪? 通过=实现对象拷贝: @Data @NoArgsConstructor @ ...

  6. MySQL操作数据库和表的基本语句(DDL)

    1.创建数据库: CREATE DATABASE 数据库名; eg.CREATE DATABASE test_ddl;2.创建表 CREATE TABLE 表名(列名 数据类型 约束,...); eg ...

  7. JAVA基础——设计模式之单列模式

    一:单例设计模式 Singleton是一种创建型模式,指某个类采用Singleton模式,则在这个类被创建后,只可能产生一个实例供外部访问,并且提供一个全局的访问点. 单例设计模式的特点: 单例类只能 ...

  8. [PyTorch] rnn,lstm,gru中输入输出维度

    本文中的RNN泛指LSTM,GRU等等 CNN中和RNN中batchSize的默认位置是不同的. CNN中:batchsize的位置是position 0. RNN中:batchsize的位置是pos ...

  9. 零基础入门学习Python(24)--递归:汉诺塔

    知识点 这节课主要讲解用递归的方法,实现汉诺塔的解答 对于游戏的玩法,我们可以简单分解为三个步骤: 1) 将前63个盘子从X移动到Y上. 2) 将最底下的第64个盘子从X移动到Z上. 3) 将Y上的6 ...

  10. UART整理

    通用异步收发器简称UART,英文全称"Universal Asynchronous Receiver Transmitter".UART使用标准的TTL/CMOS逻辑电平(0~5V ...