Unity3D研究院之游戏开发中的人工智能AI

2023-11-17

人工智能这个东西在游戏中是非常重要的,人工智能说简单了就是根据随机的数字让敌人执行一些动作或逻辑,说难了TA需要一个非常复杂的算法,本文我主要说说Unity3D中人工智能的脚本如何来编写。

        首先你应该搞清楚的一点AI脚本属于一个工具类脚本,工具类脚本的含义就是他应当是由策划人员来绑定游戏对象使用的。也就是说AI脚本程序员应当写的非常的灵活,策划人员可以通过修改脚本对外的变量数值接口就能控制其中的敌人AI。接着创建一个c#脚本AI.CS ,如下图所示,目前脚本对外留出枚举接口变量,策划人员在使用这条脚本时选择对应敌人类型即可。(注:这里仅仅是示例,细致的话还可以将很多敌人详细的信息写入,如:攻击速度、技能类型、移动速度、命中率、攻击百分比、等等,但是一定要让你的脚本写的比较灵活,策划人员在外面选择即可完成)因为目前是一个示例,所以我在这里只简单的区分的敌人类型。

 

Unity3D研究院之游戏开发中的人工智能AI(三十八) - 雨松MOMO程序研究院 - 1

 

下面时这段简单AI的脚本

AI.CS

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
using UnityEngine ;
using System . Collections ;
 
//这里是枚举选择敌人类型
public enum EnemyType
{
Enemy0 ,
Enemy1
}
 
public class AI : MonoBehaviour {
 
//敌人类型枚举 有策划人员选择
public EnemyType enemyType = EnemyType . Enemy0 ;
 
//主角游戏对象
public GameObject player ;
 
//敌人状态 普通状态 旋转状态 奔跑状态 追击主角状态 攻击主角状态
private const int EMEMY_NORMAL = 0 ;
private const int EMEMY_ROTATION = 1 ;
private const int EMEMY_RUN = 2 ;
private const int EMEMY_CHASE = 3 ;
private const int EMEMY_ATTACK = 4 ;
 
//记录当前敌人状态 根据不同类型 敌人播放不同动画
private int state ;
//旋转状态,敌人自身旋转
private int rotation_state ;
//记录敌人上一次思考时间
private float aiThankLastTime ;
 
void Start ( )
{
//初始话标志敌人状态 以及动画为循环播放
state = EMEMY_NORMAL ;
this . animation . wrapMode = WrapMode . Loop ;
}
 
void Update ( )
{
//根据策划选择的敌人类型 这里面会进行不同的敌人AI
switch ( enemyType )
{
case EnemyType . Enemy0 :
updateEnemyType0 ( ) ;
break ;
case EnemyType . Enemy1 :
updateEnemyType1 ( ) ;
break ;
}
}
 
//更新第一种敌人的AI
void updateEnemyType0 ( )
{
//这个AI比较简单, 当主角与他的距离小于10米时,他将始终朝向这主角
if ( Vector3 . Distance ( player . transform . position , this . transform . position ) <= 10 )
{
this . transform . LookAt ( player . transform ) ;
}
}
 
//更新第二种敌人的AI
void updateEnemyType1 ( )
{
 
//判断敌人是否开始思考
if ( isAIthank ( ) )
{
//敌人开始思考
AIthankEnemyState ( 3 ) ;
} else
{
//更新敌人状态
UpdateEmenyState ( ) ;
}
}
 
int getRandom ( int count )
{
 
return new System . Random ( ) . Next ( count ) ;
 
}
 
bool isAIthank ( )
{
//这里表示敌人每3秒进行一次思考
if ( Time . time - aiThankLastTime >= 3.0f )
{
aiThankLastTime = Time . time ;
return true ;
 
}
return false ;
}
 
//敌人在这里进行思考
void AIthankEnemyState ( int count )
{
//开始随机数字。
int d = getRandom ( count ) ;
 
switch ( d )
{
case 0 :
//设置敌人为站立状态
setEmemyState ( EMEMY_NORMAL ) ;
break ;
case 1 :
//设置敌人为旋转状态
setEmemyState ( EMEMY_ROTATION ) ;
break ;
case 2 :
//设置敌人为奔跑状态
setEmemyState ( EMEMY_RUN ) ;
break ;
}
 
}
 
void setEmemyState ( int newState )
{
if ( state == newState )
return ;
state = newState ;
 
string animName = "Idle" ;
switch ( state )
{
case EMEMY_NORMAL :
animName    =    "Idle" ;
break ;
case EMEMY_RUN :
animName    =    "Run" ;
break ;
case EMEMY_ROTATION :
animName    =    "Run" ;
//当敌人为旋转时, 开始随机旋转的角度系数
rotation_state = getRandom ( 4 ) ;
break ;
case EMEMY_CHASE :
animName    =    "Run" ;
//当敌人进入追击状态时,将面朝主角方向奔跑
this . transform . LookAt ( player . transform ) ;
break ;
case EMEMY_ATTACK :
animName    =    "Attack" ;
//当敌人进入攻击状态时,继续朝向主角开始攻击砍人动画
this . transform . LookAt ( player . transform ) ;
break ;
}
 
//避免重复播放动画,这里进行判断
if ( ! this . animation . IsPlaying ( animName ) )
{
//播放动画
this . animation . Play ( animName ) ;
}
 
}
 
//在这里更新敌人状态
void UpdateEmenyState ( )
{
//判断敌人与主角之间的距离
float distance = Vector3 . Distance ( player . transform . position , this . transform . position ) ;
//当敌人与主角的距离小于10 敌人将开始面朝主角追击
if ( distance <= 10 )
{
//当敌人与主角的距离小与3 敌人将开始面朝主角攻击
if ( distance <= 3 )
{
setEmemyState ( EMEMY_ATTACK ) ;
} else
{
     //否则敌人将开始面朝主角追击
setEmemyState ( EMEMY_CHASE ) ;
}
 
} else
{
//敌人攻击主角时 主角迅速奔跑 当它们之间的距离再次大于10的时候 敌人将再次进入正常状态 开始思考
if ( state == EMEMY_CHASE || state == EMEMY_ATTACK )
{
setEmemyState ( EMEMY_NORMAL ) ;
}
 
}
 
switch ( state )
{
case EMEMY_ROTATION :
//旋转状态时 敌人开始旋转, 旋转时间为1秒 这样更加具有惯性
transform . rotation = Quaternion . Lerp ( transform . rotation , Quaternion . Euler ( 0 , rotation_state * 90 , 0 ) ,    Time . deltaTime * 1 ) ;
break ;
case EMEMY_RUN :
//奔跑状态,敌人向前奔跑
transform . Translate ( Vector3 . forward * 0.02f ) ;
break ;
case EMEMY_CHASE :
//追击状态 敌人向前开始追击
transform . Translate ( Vector3 . forward * 0.02f ) ;
break ;
case EMEMY_ATTACK :
 
break ;
}
 
}
}

 

 

如下图所示,我们在游戏世界中添加两个敌人,此时给敌人们都绑定上AI的脚本,编辑器中设置不同的敌人类型,敌人执行各自的生命周期,当你控制主角与接近敌人时,敌人开始追击你并且向你展开攻击。

 

Unity3D研究院之游戏开发中的人工智能AI(三十八) - 雨松MOMO程序研究院 - 2

 

         demo仅仅是一个示例,主要希望大家明白一个道理。在编写Unity游戏脚本时,一定要想想这条脚本和对象的生命周期,切记每一条脚本只管和自己有关的东西,和自己无关的东西一概不要管。不然你会发现你的脚本会越写越乱,下一篇文章我会写点我平时在Unity3D开发中时如何搭建架构的,希望大家多多讨论,互相学习。

下载地址:http://vdisk.weibo.com/s/hmJUs

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Unity3D研究院之游戏开发中的人工智能AI 的相关文章

  • 数据库开发考试复习

    文章目录 B树索引结构 B树索引的结构和使用方式 B树索引的使用 什么时候使用B树索引 为什么为外键建立索引是普遍的要求 上面一个问题的例外情况 IOT 大概率不考 B树索引练习 索引 系统生成键 含有索引但未使用的几种情况 位图索引 哈希

随机推荐

  • Unity的C#编程教程_62_语言集成查询 LINQ 详解及应用练习

    文章目录 LINQ Querys 1 Any 2 Contains 3 Distinct 4 Where Challenge Hands on with LINQ LINQ Order by Descending Challenge Fil
  • 代码注释:机器学习实战第8章 预测数值型数据:回归

    写在开头的话 在学习 机器学习实战 的过程中发现书中很多代码并没有注释 这对新入门的同学是一个挑战 特此贴出我对代码做出的注释 仅供参考 欢迎指正 coding gbk from numpy import 作用 从文件中导入数据 输入 文件
  • RocketMQ系列之架构浅谈

    RMQ的架构设计 下面我从GitHub上截取了一张RMQ的源码结构图 图中我框框出来的9大模块 基本就构成了整个RMQ的内部结构 上面9大模块的依赖层次主要如下 依赖越强的越处于底层 下面介绍下最上层的4个模块 这4个模块中工具命令行就不讲
  • 使用cpio命令导致系统几乎崩溃的一次经历

    做嵌入式linux开发 内核编译生成了一个initramfs data cpio文件 发现是一个根文件系统的压缩文件 在windows下可以用IZArc解压 但不能用tar gunzip解压 Windows下使用IZArc解压时 符号链接文
  • CentOS 8 逻辑卷管理LVM详解(扩容、快照等)

    逻辑卷管理LVM 一 概述 二 逻辑卷管理布局 三 LVM1和LVM2 四 使用LVM管理逻辑卷 1 物理卷 1 创建物理卷 2 删除物理卷 2 卷组 1 创建卷组 2 扩展卷组 3 删除卷组 4 减小卷组 3 逻辑卷 1 创建逻辑卷 2
  • 基于TCP的socket通信

    本文转载自http blog csdn net chocolate001 article details 6612201 基于TCP 面向连接 的socket编程 分为客户端和服务器端 客户端的流程如下 1 创建套接字 socket 2 向
  • 修片要点+规则

    一 曝光度 相机的曝光补偿 1 1 快速修改 1 2 细改 二 对比度 白和黑的对比程度 黑的更黑 白的更白 越小越朦胧 越大越清晰 可以让色彩更鲜艳 2 1 設置對比度 三 高光 控制高光部分的曝光度 3 1 設置高光 四 阴影 控制阴影
  • 微服务契约测试框架-Pact

    契约测试 契约测试的思想就是将原本的 Consumer 与 Provider 间同步的集成测试 通过契约进行解耦 变成 Consumer 与 Provider 端两个各自独立的 异步的单元测试 契约测试的优点 契约测试与单元测试以及其它测试
  • PT100所谓的二线制,三线制,四线制如何接线(详解)

    PT100所谓的二线制 三线制 四线制如何接线 铂热电阻是利用铂丝的电阻值随着温度的变化而变化的 那么铂热电阻的三种接线方法以及消除误差的原理是怎么样的呢 二线制 二线制 在热电阻的两端各连接一根导线来引出电阻信号的方式叫二线制 这种引线方
  • PyOpenGL帧缓存

    安装 python m pip install PyOpenGL PyOpenGL accelerate i http mirrors aliyun com pypi simple trusted host mirrors aliyun c
  • java-使用newTaskFor封装任务中非标准取消

    1 使用newTaskFor钩子函数来改进用来封装非标准取消的方法 这是ThreadPoolExecutor的新特性 2 当提交一个callable给ExecutorService时 submit返回一个Future 可以用Future来取
  • 【Python开发】Python中数据分析环境的搭建

    注 无论是任何一门语言 刚开始入门的时候 语言运行环境的搭建都是一件不轻松的事情 Python的运行环境 要运行或写Python代码 就需要Python的运行环境 主要的Python有以下三类 原生态的Python 就是直接从Python的
  • KVM管理平台选型与开源企业级虚拟化平台oVirt详解

    一 KVM管理平台 虚拟化和云计算以在当今IT工业中的用途和优势 成为近年来的技术热点之一 其发展非常迅速 搞KVM虚拟化的时候 面临的一个很重要的问题是 管理平台如何搞定 目前 已经出现了很多与KVM相关的管理工具和云计算平台 比较知名和
  • go memcpy

    来源 https github com jsgilmore shm callback syscall NewCallback func r uintptr size int ret uintptr 定义一个 byte切片 用来存储C返回的字
  • 代码随想录算法训练营第二天

    1 双指针法 leetcode 题977 给你一个按 非递减顺序 排序的整数数组 nums 返回 每个数字的平方 组成的新数组 要求也按 非递减顺序 排序 1 1 暴力解法 先求出数组所有值的平方 然后再排序 1 2 双指针法 i指向初始位
  • MySQL中时间函数(史上最全的时间函数)

    一 MySQL 获得当前日期时间 函数 获得当前日期 时间 date time 函数 now mysql gt select now now 2019 08 19 10 23 46 除了 now 函数能获得当前的日期时间外 MySQL 中还
  • Spring Data Elasticsearch篇(3):ElasticsearchRepository文档操作

    1 ElasticsearchRepository 1 1 ElasticsearchRepository源码 NoRepositoryBean public interface ElasticsearchRepository
  • matplotlib画折线图

    matplotlib画折线图 假设一天中每隔两个小时 range 2 26 2 的气温 分别是 15 13 14 5 17 20 25 26 26 27 22 18 15 代码如下 导入pyplot from matplotlib impo
  • HDU--1861:游船出租

    1 题目源地址 http acm hdu edu cn showproblem php pid 1861 2 源代码 HOJ 1861 游船出租 include
  • Unity3D研究院之游戏开发中的人工智能AI

    人工智能这个东西在游戏中是非常重要的 人工智能说简单了就是根据随机的数字让敌人执行一些动作或逻辑 说难了TA需要一个非常复杂的算法 本文我主要说说Unity3D中人工智能的脚本如何来编写 首先你应该搞清楚的一点AI脚本属于一个工具类脚本 工