【Unity3D】基于AssetBundle实现资源热更新

article/2025/9/29 15:51:16

1 前言

        Unity3D 本地资源一般放在 Resources 目录下,但是 Resouces 文件夹的大小不能超过 2G,使用 AssetBundle 管理资源可以解决 Resources 文件夹受限问题。

        本文代码资源见→基于AssetBundle实现资源热更新。

        AssetBundle 主要用于管理资源,配合 AssetDatabase 和 AssetImporter 可以实现资源重命名,配合 BuildPipeline 可以实现资源压缩,配合 WWW 或 UnityWebRequest 可以实现加载服务器资源。下面简单介绍下相关接口:

        1)AssetBundle 获取资源名,加载、卸载资源

        静态方法: 

// 从文件中加载AssetBundle
public static AssetBundle LoadFromFile(string path)
// 从二进制数组中加载AssetBundle
public static AssetBundle LoadFromMemory(byte[] binary)
// 从流中加载AssetBundle
public static AssetBundle LoadFromStream(Stream stream)
// 卸载所有AssetBundle
public static void UnloadAllAssetBundles(bool unloadAllObjects)
// 销毁对象
public static void Destroy(Object obj)

        实例方法: 

// 获取所有资源名
public string[] GetAllAssetNames()
// 判断是否包含资源
public bool Contains(string name)
// 加载资源
public Object[] LoadAllAssets()
public T[] LoadAllAssets<T>() where T : Object
public Object[] LoadAllAssets(Type type)
public Object LoadAsset(string name)
public T LoadAsset<T>(string name) where T : Object
public Object LoadAsset(string name, Type type)
// 卸载资源, unloadAllLoadedObjects为false时不卸载已从Bundle中加载出的资源
public void Unload(bool unloadAllLoadedObjects)

        说明:入参 name 不区分大小写,建议使用小写,如果使用大写会自动转换为小写。

        2)AssetBundleManifest 获取资源依赖

// 获取所有AssetBundles
public string[] GetAllAssetBundles()
// 获取指定assetBundleName的直接依赖
public string[] GetDirectDependencies(string assetBundleName)
// 获取指定assetBundleName的所有依赖
public string[] GetAllDependencies(string assetBundleName)

        说明:入参 assetBundleName 不区分大小写,建议使用小写,如果使用大写会自动转换为小写。 

        3)AssetDatabase 获取所有资源名、删除资源

// 获取所有AssetBundle资源名
public static string[] GetAllAssetBundleNames()
// 根据assetBundleName删除AssetBundle
public static bool RemoveAssetBundleName(string assetBundleName, bool forceRemove)
// 刷新Project视图目录, 相当于右键手动刷新
public static void Refresh()

        4)AssetImporter 设置资源名

// 获取AssetImporter, 资源文件路径
public static AssetImporter GetAtPath(string path)
// 获取/设置资源文件名
public string assetBundleName { get; set; }

        5)BuildPipeline 压缩资源

// 压缩所有标记为AssetBundle的资源
public static AssetBundleManifest BuildAssetBundles(string outputPath, // 压缩文件输出路径BuildAssetBundleOptions assetBundleOptions, // 压缩算法BuildTarget targetPlatform // 平台
)
// BuildAssetBundleOptions.None: LZMA压缩算法, 压缩比大, 加载慢, 使用前需要整体解压
// BuildAssetBundleOptions.ChunkBasedCompression: LZ4压缩算法, 压缩比中等, 加载快可以加载指定资源而不用解压全部
// BuildAssetBundleOptions.UncompressedAssetBundle: 不压缩, 加载快

        6)WWW 获取网络资源

// 获取WWW
public static WWW LoadFromCacheOrDownload(string url, int version)
// 获取AssetBundle
public AssetBundle assetBundle { get; }

        说明:WWW 被 Unity3D 官方标记为过时了,建议使用 UnityWebRequest。

         7)UnityWebRequest 获取网络资源

UnityWebRequest webRequest = UnityWebRequestAssetBundle.GetAssetBundle(uri)
yield return webRequest.SendWebRequest()
AssetBundle assetBundle = DownloadHandlerAssetBundle.GetContent(webRequest)

2 资源命名

        Asset 资源主要有脚本、图片、网格、模型、预设体等,在 Assets 窗口选中资源,在 Inspector 窗口选择 AssetBundle 下拉列表,选择 New 给资源添加 AssetBundle 名,如下:

        说明:AssetBundle 名不区分大小写,如果输入大写会自动转换为小写。只有添加了 AssetBundle 名的资源才能通过 BuildPipeline.BuildAssetBundles() 打包压缩

3 资源压缩

        1)创建目录及原资源 

        在 Assets 目录下创建 AssetBundles 目录(存放资源)和 Editor 目录(存放资源压缩脚本),在 AssetBundles 目录下创建 Compress 目录(存放压缩文件)和 Raw 目录(存放原资源文件),再在 Raw 目录下创建 Textures 目录(存放了一张图片 Picture)、Materials 目录(存放了一个材质 Material,并且依赖 Picture)、Prefabs 目录(存放了一个预设体 Quad,并且依赖 Material),目录结构如下:

        2)自动压缩脚本 

        AssetCompressor.cs

using System.IO;
using UnityEditor;
using UnityEngine;public class AssetCompressor : Editor {// G:/Unity3d/AssetBundleDemo/Assets/AssetBundles/Rawprivate static string rawPath = Application.dataPath + "/AssetBundles/Raw";// G:/Unity3d/AssetBundleDemo/Assets/AssetBundles/Compressprivate static string compressPath = Application.dataPath + "/AssetBundles/Compress";[MenuItem("AssetBundle/CompressAssets")]public static void CompressAssets() { // 打包rawPath目录的资源, 生成压缩资源到compressPath目录ClearAllFilesBundleName();SetAssetBundlesName(rawPath);BuildAssetBundles();ClearAllFilesBundleName();AssetDatabase.Refresh(); // 刷新Project视图目录, 相当于右键手动刷新}private static void BuildAssetBundles() { // 压缩资源BuildPipeline.BuildAssetBundles(compressPath, // 压缩包输出包路径BuildAssetBundleOptions.ChunkBasedCompression, // 压缩算法BuildTarget.StandaloneWindows64 // Windows平台);}private static void ClearAllFilesBundleName() { // 删除所有AssetBundle名string[] names = AssetDatabase.GetAllAssetBundleNames();foreach (string name in names) {AssetDatabase.RemoveAssetBundleName(name, true);}}private static void SetAssetBundlesName(string rootPath) { // 设置资源的Bundle名DirectoryInfo rootInfo = new DirectoryInfo(rootPath);FileSystemInfo[] fileInfos = rootInfo.GetFileSystemInfos();foreach (FileSystemInfo fileInfo in fileInfos) {if (fileInfo is DirectoryInfo) {SetAssetBundlesName(fileInfo.FullName); // 递归遍历子文件夹下所有文件} else if (!fileInfo.Name.EndsWith(".meta")) {SetAssetBundleName(fileInfo.FullName);}}}private static void SetAssetBundleName(string filePath) { // 设置资源的Bundle名// 导入的相对路径(G:/Unity3d/AssetBundleDemo/Assets/AssetBundles/Compress/prefabs/quad.prefab)string impoterPath = "Assets/" + filePath.Substring(Application.dataPath.Length + 1);AssetImporter assetImporter = AssetImporter.GetAtPath(impoterPath);if (assetImporter != null) {filePath = filePath.Substring(rawPath.Length + 1); // 去源文件前缀(可选, 建议使用)// filePath = filePath.Substring(filePath.LastIndexOf("\\") + 1); // 去所有前缀(可选, 不建议使用)// 去后缀(可选, 不去后缀刷新目录后会报错, 但不影响资源压缩和后续资源加载)// filePath = filePath.Remove(filePath.LastIndexOf("."));assetImporter.assetBundleName = filePath;}}
}

         说明:AssetCompressor.cs 文件需要放在 Editor 目录下,编译成功后,在菜单栏可以看到 AssetBundle 菜单,如下:

         点击 CompressAssets 选项,会将 Assets/AssetBundles/Raw 目录下的资源打包压缩至 Assets/AssetBundles/Compress 目录,如下:

         注意:运行上述代码后,会报以下错误,这是因为文件已经压缩了,但还是以 “.prefab”、“.jpg”、“.mat” 为后缀,被 Unity3D 识别为损坏文件。该错误不影响压缩文件生成,也不影响后续资源加载,可以忽略。如果不想出现以下报错,可以将去后缀的注释代码打开。

         3)压缩文件

         打开 Compress.manifest 文件如下:

ManifestFileVersion: 0
CRC: 3680739267
AssetBundleManifest:AssetBundleInfos:Info_0:Name: materials/material.matDependencies:Dependency_0: textures/picture.jpgInfo_1:Name: prefabs/quad.prefabDependencies:Dependency_0: materials/material.matInfo_2:Name: textures/picture.jpgDependencies: {}

         说明:后续要加载资源时,如果不清楚 AssetBundle 名,可以在 Compress.manifest 文件中查看相应 Name 值。可以看到,这里的 Name 值也全都自动转换为小写了,在加载资源时,如果传入大写的也能正常获取到相应资源

4 加载本地资源

        1)加载简单资源

// targetPath="ptextures/picture.jpg"
public static T LoadAsset<T>(string targetPath) { // 加载资源// G:/Unity3d/AssetBundleDemo/Assets/AssetBundles/Compress/ptextures/picture.jpgAssetBundle targetBundle = AssetBundle.LoadFromFile(compressPath + "/" + targetPath);string fileName = targetPath.Substring(targetPath.LastIndexOf("/") + 1); // picture.jpgobject obj = targetBundle.LoadAsset(fileName);if (obj != null) {return (T) obj;}return default(T);
}

        说明:如果没有依赖资源,可以使用该方法;如果有依赖资源,就会出现异常。当 targetPath = "prefabs/quad.prefab" 时,创建的 Quad 显示如下,Quad 显示品红,表示它依赖的材质和图片缺失。

        2)加载有依赖的资源

        LocalAssetLoader.cs 

using UnityEngine;public class LocalAssetLoader {// G:/Unity3d/AssetBundleDemo/Assets/AssetBundles/Compressprivate static string compressPath = Application.dataPath + "/AssetBundles/Compress"; // 压缩文件根路径// G:/Unity3d/AssetBundleDemo/Assets/AssetBundles/Compress/Compressprivate static string rootManifestPath = compressPath + "/Compress"; // 根manifest文件路径(Compress.manifest文件绝对路径)public static T LoadAsset<T>(string targetPath) { // 加载资源LoadDependencies(targetPath);return LoadTarget<T>(targetPath);}private static void LoadDependencies(string targetPath) { // 加载目标资源的依赖AssetBundle manifestBundle = AssetBundle.LoadFromFile(rootManifestPath);// 解压Manifest文件, 传入的参数不区分大小写(如果是大写, 会自动转换为小写)AssetBundleManifest manifest = manifestBundle.LoadAsset<AssetBundleManifest>("AssetBundleManifest");string[] dependencies = manifest.GetAllDependencies(targetPath); // 获取目标文件的所有依赖for (int i = 0; i < dependencies.Length; i++) {string filePath = compressPath + "/" + dependencies[i];AssetBundle.LoadFromFile(filePath);}}private static T LoadTarget<T>(string targetPath) { // 加载目标资源AssetBundle targetBundle = AssetBundle.LoadFromFile(compressPath + "/" + targetPath);string fileName = targetPath.Substring(targetPath.LastIndexOf("/") + 1);object obj = targetBundle.LoadAsset(fileName);if (obj != null) {return (T) obj;}return default(T);}
}

        说明:manifest.GetAllDependencies()、AssetBundle.LoadFromFile()、targetBundle.LoadAsset() 的入参不区分大小写,因此传入的 targetPath 也可以不区分大小写。

        3)调用 LocalAssetLoader 加载资源

        SimpleLoad.cs

using UnityEngine;public class SimpleLoad : MonoBehaviour {private void Start() {GameObject obj = LocalAssetLoader.LoadAsset<GameObject>("prefabs/quad.prefab"); // 加载预设体// GameObject obj = LocalAssetLoader.LoadAsset<GameObject>("Prefabs/Quad.prefab"); // 加载预设体Instantiate(obj);}
}

        说明: 由于 LocalAssetLoader.LoadAsset 的入参不区分大小写,因此传入 "prefabs/quad.prefab" 和 "Prefabs/Quad.prefab" 都能正确加载资源。

        运行效果如下:

5 使用 WWW 加载服务器资源

        W3AssetLoader.cs

using System;
using System.Collections;
using UnityEngine;public class W3AssetLoader : MonoBehaviour {private string compressPath; // 压缩文件根路径private string rootManifestPath; // 根manifest文件路径private static W3AssetLoader instance; // 单例private void Awake() {instance = this;// compressPath = GetW3Path(Application.dataPath + "/AssetBundle/Compress");compressPath = "https://gitcode.net/m0_37602827/AssetBundleDemo/-/raw/master/Assets/AssetBundle/Compress";rootManifestPath = compressPath + "/Compress";}public static void LoadAsset<T>(string targetPath, Action<T> action) { // 加载资源instance.StartCoroutine(instance.LoadAssetCorutine<T>(targetPath, action));}private IEnumerator LoadAssetCorutine<T>(string targetPath, Action<T> action) { // 加载资源的协程yield return LoadDependencies(targetPath);yield return LoadTarget(targetPath, action);}private IEnumerator LoadDependencies(string targetPath) { // 加载目标资源的依赖WWW w3 = WWW.LoadFromCacheOrDownload(rootManifestPath, 1);yield return w3;AssetBundle assetBundle = w3.assetBundle;if (assetBundle != null) {AssetBundleManifest manifest = assetBundle.LoadAsset<AssetBundleManifest>("AssetBundleManifest");if (manifest != null) {string[] dependencies = manifest.GetAllDependencies(targetPath); // 获取目标文件的所有依赖for (int i = 0; i < dependencies.Length; i++) {string filePath = compressPath + "/" + dependencies[i];w3 = WWW.LoadFromCacheOrDownload(filePath, 1);yield return w3;assetBundle = w3.assetBundle;}}}}private IEnumerator LoadTarget<T>(string targetPath, Action<T> action) { // 加载目标文件string fullPath = compressPath + "/" + targetPath;WWW w3 = WWW.LoadFromCacheOrDownload(fullPath, 1);yield return w3;AssetBundle assetBundle = w3.assetBundle;if (assetBundle != null) {string fileName = targetPath.Substring(targetPath.LastIndexOf("/") + 1);object obj = assetBundle.LoadAsset(fileName); // 解压文件if (obj != null && action != null) {action.Invoke((T) obj);}}}private string GetW3Path(string path) {#if UNITY_EDITOR_WIN || UNITY_STANDALONE_WINpath = "file:///" + path;#elif UNITY_EDITOR_OSX || UNITY_STANDALONE_OSXpath = "file://" + path;#endifreturn path;}
}

        SimpleLoad.cs 

using UnityEngine;public class SimpleLoad : MonoBehaviour {private void Start() {W3AssetLoader.LoadAsset<GameObject>("prefabs/quad", Callback);// W3AssetLoader.LoadAsset<GameObject>("Prefabs/Quad", Callback);}private void Callback(GameObject obj) {Instantiate(obj);}
}

        注意:W3AssetLoader.LoadAsset() 方法的入参不要加 ".prefab" 后缀,并且入参也不区分大小写。

6 使用 UnityWebRequest 加载服务器资源

        WebAssetLoader.cs

using System;
using System.Collections;
using UnityEngine;
using UnityEngine.Networking;public class WebAssetLoader : MonoBehaviour {private string compressPath; // 压缩文件根路径private string rootManifestPath; // 根manifest文件路径private static WebAssetLoader instance; // 单例private void Awake() {instance = this;// compressPath = GetW3Path(Application.dataPath + "/AssetBundle/Compress");compressPath = "https://gitcode.net/m0_37602827/AssetBundleDemo/-/raw/master/Assets/AssetBundle/Compress";rootManifestPath = compressPath + "/Compress";}public static void LoadAsset<T>(string targetPath, Action<T> action) { // 加载资源instance.StartCoroutine(instance.LoadAssetCorutine<T>(targetPath, action));}private IEnumerator LoadAssetCorutine<T>(string targetPath, Action<T> action) { // 加载资源的协程yield return LoadDependencies(targetPath);yield return LoadTarget(targetPath, action);}private IEnumerator LoadDependencies(string targetPath) { // 加载目标资源的依赖UnityWebRequest webRequest = UnityWebRequestAssetBundle.GetAssetBundle(rootManifestPath);yield return webRequest.SendWebRequest();AssetBundle assetBundle = DownloadHandlerAssetBundle.GetContent(webRequest);if (assetBundle != null) {AssetBundleManifest manifest = assetBundle.LoadAsset<AssetBundleManifest>("AssetBundleManifest");if (manifest != null) {string[] dependencies = manifest.GetAllDependencies(targetPath); // 获取目标文件的所有依赖for (int i = 0; i < dependencies.Length; i++) {string filePath = compressPath + "/" + dependencies[i];webRequest = UnityWebRequestAssetBundle.GetAssetBundle(filePath);yield return webRequest.SendWebRequest();assetBundle = DownloadHandlerAssetBundle.GetContent(webRequest);}}}}private IEnumerator LoadTarget<T>(string targetPath, Action<T> action) { // 加载目标文件string fullPath = compressPath + "/" + targetPath;UnityWebRequest webRequest = UnityWebRequestAssetBundle.GetAssetBundle(fullPath);yield return webRequest.SendWebRequest();AssetBundle assetBundle = DownloadHandlerAssetBundle.GetContent(webRequest);if (assetBundle != null) {string fileName = targetPath.Substring(targetPath.LastIndexOf("/") + 1);object obj = assetBundle.LoadAsset(fileName); // 解压文件if (obj != null && action != null) {action.Invoke((T) obj);}}}private string GetW3Path(string path) {#if UNITY_EDITOR_WIN || UNITY_STANDALONE_WINpath = "file:///" + path; // Windows平台#elif UNITY_EDITOR_OSX || UNITY_STANDALONE_OSXpath = "file://" + path; // Mac平台#endifreturn path;}
}

        SimpleLoad.cs 

using UnityEngine;public class SimpleLoad : MonoBehaviour {private void Start() {WebAssetLoader.LoadAsset<GameObject>("prefabs/quad.prefab", Callback);}private void Callback(GameObject obj) {Instantiate(obj);}
}

        注意:WebAssetLoader.LoadAsset() 的入参需要添加 ".prefab" 后缀,并且入参区分大小写。 


http://chatgpt.dhexx.cn/article/TjKLjZgG.shtml

相关文章

Unity3D资源加密解决方案

https://blog.csdn.net/love_hot_girl 很多VR企业开发的软件有很多文件资源需要保护&#xff0c;而目前行业鲜有好的加密方案可供开发者使用。基于深思云授权平台&#xff0c;有一套Unity3D代码及资源加密保护方案&#xff0c;可通过Virbox Protector加壳工具对代码及资源进行加…

unity3d 挂载脚本_Unity3D加载资源的四种方式

一、准备场景和预设和AB包资源 ①新建一个Cube然后创建一个材质球,然后将其做成预设,如下所示: ②编写打包预设为AB包的脚本(注意:该脚本需要放置在Editor这个特定的目录文件夹下)/*** *Title:"三维可视化" 项目 *主题:打AB包 *Description: *功能:XXX *Date…

Unity3D资源加载Resources

Unity3D资源加载Resources 目录 1、博客介绍 2、内容 3、推送 4、结语 1、博客介绍 本篇博客对资源加载类Resources做一个介绍 2、内容 FindObjectsOfTypeAll返回一个该类型对象的列表Load从Resources文件夹内加载一个路径的资源LoadAll从Resources文件夹内加载一个路径下…

Unity3D学习 ④ Unity导入商店资源,实现基本的奔跑、攻击动作切换与交互

1.导入unity3D商店资源 ① 直接进入unity商店下载 Unity Asset Store - The Best Assets for Game Makinghttps://assetstore.unity.com/② 在3D下面的动画栏&#xff0c;点进去然后找些自己喜欢的模型就好了&#xff0c;可以通过排序“价格由低到高”筛选些免费的模型。 下面…

Unity 3D 资源下载 || Unity 3D 综合案例

Unity 3D 资源下载 你也可以在 Unity 3D 中执行 Window → Asset Store 菜单命令直接访问 Unity 资源商店&#xff08;Asset Store&#xff09;。 Unity 资源商店简介 Unity 资源商店https://www.assetstore.unity3d.com/ 中提供了多种类的游戏媒体资源&#xff08;人物模型…

Unity 3D 导入资源包 || Unity 3D 导出资源包

项目中的一些资源具有复用性&#xff0c;只需要将资源导出&#xff0c;就能够重复使用。 导出资源包 执行 Assets → Select Dependencies 菜单命令&#xff0c;选中与导出资源相关的内容。接着执行 Assets→ Export Package 菜单命令。 弹出的 Exporting Package 导出资源对话…

干货整理 Unity3D资源汇总

Unity3D是目前最流行的游戏开发工具&#xff0c;是一个可以让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具&#xff0c;是一个全面整合的专业游戏引擎。 为了让开发者能够系统全面的学习Unity3D知识&#xff0c;CSDN特…

嵌入式编程之状态机

文章目录 1、什么是状态机&#xff1f;2、状态机编程的优点(1)提高CPU使用效率(2) 逻辑完备性(3)程序结构清晰 3、状态机的三种实现方法switch—case 法表格驱动法函数指针法小节 摘要&#xff1a;不知道大家有没有这样一种感觉&#xff0c;就是感觉自己玩单片机还可以&#xf…

FPGA学习之状态机

1. 理论学习 状态机简写为FSM&#xff0c;也称为同步有限状态机&#xff0c;我们简称为状态机。所以说同步时因为状态机中所有的状态跳转都是在时钟的作用下进行的&#xff0c;而有限则是说状态机的个数有限的。状态机分为两大类&#xff0c;即Moore状态机和Mealy状态机&#…

单片机的状态机介绍

当初是粘贴复制的&#xff0c;格式已经乱了&#xff0c; pdf文档自行下载: 单片机高级编程.pdf_51单片机编程pdf-单片机文档类资源-CSDN下载 第1章 单片机初试牛刀 1.1 一个LED闪烁的故事 用单片机实现1个LED闪烁功能&#xff0c;要求LED亮500ms, 灭300ms。这个问题对于学过单…

状态机的概念与设计

⭐本专栏针对FPGA进行入门学习&#xff0c;从数电中常见的逻辑代数讲起&#xff0c;结合Verilog HDL语言学习与仿真&#xff0c;主要对组合逻辑电路与时序逻辑电路进行分析与设计&#xff0c;对状态机FSM进行剖析与建模。 &#x1f525;文章和代码已归档至【Github仓库&#xf…

c++状态机的使用

什么是状态机 状态机是有限状态自动机的简称&#xff0c;是现实事物运行规则抽象而成的一个数学模型。英文名字叫State Machine &#xff0c;不是指一台实际机器&#xff0c;一般就是指一张状态转换图。全称是有限状态自动机&#xff0c;自动两个字包含重要含义。给定一个状态…

状态机设计举例

⭐本专栏针对FPGA进行入门学习&#xff0c;从数电中常见的逻辑代数讲起&#xff0c;结合Verilog HDL语言学习与仿真&#xff0c;主要对组合逻辑电路与时序逻辑电路进行分析与设计&#xff0c;对状态机FSM进行剖析与建模。 &#x1f525;文章和代码已归档至【Github仓库&#xf…

浅谈状态机

一、状态机原理 &#xff08;一&#xff09;有限状态机 状态机由状态寄存器和组合逻辑电路构成&#xff0c;能够根据控制信号按照预先设定的状态进行状态转移&#xff0c;是协调相关信号动作、完成特定操作的控制中心。有限状态机简写为FSM&#xff08;Finite State Machine&…

状态机与序列机

状态机由状态寄存器和组合逻辑电路构成&#xff0c;能够根据控制信号按照预先设定的状态进行状态转移&#xff0c;是协调相关信号动作、完成特定操作的控制中心。 一、线性序列机 序列机是什么&#xff1a;用计数器对时钟个数计数&#xff0c;根据相应时钟周期下的单个周期时…

状态机总结(简洁)

一、概念 状态机简写为 FSM&#xff08;Finite State Machine&#xff09;&#xff0c;也称为同步有限状态机&#xff0c;我们一般简称为状态机&#xff0c;之所以说“同步”是因为状态机中所有的状态跳转都是在时钟的作用下进行的&#xff0c;而“有限”则是说状态的个数是有…

有限状态机详解(转载)

以前总觉得有限状态机和无限状态机非常的难理解&#xff0c;原来也就是自己一直没有一个直观的认识&#xff0c;今天看到一篇博客&#xff0c;总算对有限状态机入门了。一看就懂。 转载地址&#xff1a;http://blog.csdn.net/zqixiao_09/article/details/50239337 我们知道&a…

状态机

有限状态机&#xff08;Finite State Machine或者Finite State Automata)是软件领域中一种重要的工具&#xff0c;很多东西的模型实际上就是有限状态机。最近看了一些游戏编程AI的材料&#xff0c;感觉游戏中的AI&#xff0c;第一要说的就是有限状态机来实现精灵的AI&#xff0…

状态机的深入理解

目录 1.什么是状态机 2. 生活中的状态机 3. 工程中的应用 4. 发散思考 1.什么是状态机 ■1.1 有向图 有向图是指由定点和边构成的集合&#xff0c;我们常用G&#xff08;E, V&#xff09;来表示一个有向图&#xff0c;其中定点之间由有向边进行连接就构成了有向图。有向图…

有限状态机

文章目录 有限状态机状态机的表示状态转移图二维表 实现穷举法查表法状态模式 总结 有限状态机 有限状态机(Finite State Machine) 缩写为 FSM。以下简称为状态机。 状态机有 3 个组成部分&#xff1a;状态、事件、动作。 状态&#xff1a;所有可能存在的状态。包括当前状态和…