Unity数据持久化之XML
目录
- 数据持久化XML概述
- XML文件格式
- XML基本语法
- XML属性
- C#读取存储XML
- XML文件存放位置
- C#读取XML文件
- C#存储XML文件
- 实践小项目
- 必备知识点
- XML序列化(不支持字典)
- XML反序列化
- IXmlSerializable接口
- 让Dictionary支持序列化反序列化
数据持久化XML概述
什么是数据持久化
数据持久化就是将内存中的数据模型转换为存储模型,以及
将存储模型转换为内存中的数据模型的统称
说人话:将游戏数据存储到硬盘,硬盘中数据读取到游戏
中,也就是传统意义上的存盘
XML是什么?
全称:可拓展标记语言(EXtensible Markup Language)
XML是国际通用的
它是被设计来用于传输和存储数据的一种文本特殊格式
文件后缀一般为.xml
如何理解不同后缀的文件
文件后缀名决定了文件的格式
不同的软件可以根据后缀名用来判断文件的类型
并且在打开文件时以特定的读取规则去解析它
文件后缀名是人为定的规则
可以有无数种,可以自定义
我们一般使用XML文件来记录和传输数据
XML文档就是使用XML格式配置填写的文档
后缀一般为.xml
我们在游戏中可以把游戏数据按照XML的格式标准
存储在XML文档中,再将XML文档存储在硬盘上或者传输给远端
达到数据持久化的目的
XML文件格式
XML基本语法
推荐xml文本编辑器
只要能打开文档的软件都能打开XML文件
常用的一些打开XML文件的方式
1.系统自带 – 记事本、写字板
2.专用XML文本编辑器 – XMLSpear、STDU XML Editor等等
3.通用文本编辑器 – Sublime Text等等
创建XML文件
直接右键创建文本,后缀改为xml
选择自己喜欢的用于编辑xml的软件
进行文本编辑
注释
<!---->
<!--在其中写明注释内容-->
固定内容
固定内容代表xml的版本 使用的编码
<?xml version="1.0" encoding="UTF-8"?>
基本语法
<!-- xm1的基本语法 就是<元素标签></元素标签>配对出现 -- >
<PlayerInfo><name>唐老狮</name><age>18</age><sex>true</sex><ItemList><Item><id>1</id><num>10</num></Item><Item><id>2</id><num>10</num></Item></ItemList>
</PlayerInfo>
基本规则
1.每个元素都必须有关闭标签
2.元素命名规则基本遵照C#中变量名命名规则
3.XML标签对大小写敏感
4.XML文档必须有根元素
5.特殊的符号应该用实体引用
< —— <小于
> —— >大于
&——&和号
&apos——'单引号
"——“引号
XML属性
<!-- 属性就是在元素标签后面空格 添加的内容 -- >
<!-- 注意:属性必须用引号包裹 单引号双引号都可以 -- >
<Friend name="小明”age='8'>我的朋友</Friend>
<!-- 如果使用属性记录信息 不想使用元素记录 可以如下这样写 -- >
<Fater name ="爸爸”age ="50"/>
如何查语法错误
1.元素标签必须配对
2.属性必须有引号
3.注意命名
或者直接复制到https://www.runoob.com/xml/xml-validator.html
网页上进行验证
注意:一般专门编辑xml的软件都会有判错功能
C#读取存储XML
XML文件存放位置
1.只读不写的XML文件可以放在Resources或者StreamingAssets 文件夹下
2.动态存储的XML文件放在Application.persistentDataPath 路径下
C#读取XML文件
C#读取XML的方法有几种
1.XmlDocument:把数据加载到内存中,方便读取
2.XmlTextReader:以流形式加载,内存占用更少,但是是单向只读,使用不是特别方便,除非有特殊需求,否则不会使用
3.Linq:以后专门讲Ling的时候讲
使用XmlDocument类读取是较方便最容易理解和操作的方法
读取xml文件信息
XmlDocument xml = new XmlDocument();
通过XmlDocument读取xml文件 有两个API
1.直接根据xm1字符串内容 来加载xml文件
存放在Resorces文件夹下的xml文件加载处理
TextAsset asset = Resources.Load<TextAsset>("TestXml");
print(asset.text);
//通过这个方法 就能够翻译字符串为xml对象
xml.LoadXml(asset.trxt));
2.是通过xml文件的路径去进行加载
xml. Load(Application.streamingAssetsPath + "/TestXml.xml");
读取元素和属性信息
节点信息类
XmlNode 单个节点信息类
节点列表信息
XmlNodeList 多个节点信息类
获取xml中的根节点
xmlNode root = xml.SelectSingleNode("Root");
再通过根节点获取下面的子节点
XmlNode nodeName = root.SelectSingleNode("name");
获取节点包裹的元素信息
print(nodeName.InnerText);
获取属性
//两种方式
XmlNode nodeItem = root.SelectSingleNode("Item");
print(nodeItem.Attributes["id"].Value);
print(nodeItem.Attributes.GetNameItem("id").Value);
获取一个节点下的同名节点
XmlNodeList friendList = root.SelectNodes("Friend");
//迭代器遍历
foreach(XmlNode item in friendList)
{}
//for循环遍历
for(int i = 0;i < friendList.Count;i++)
{print(friendList[i].SelectSingleNode("name").InnerText);
}
总结
1.读取XML文件
XmlDocument xml = new XmlDocument();
读取文本方式1-xml.LoadXml(传入xml文本字符串)
读取文本方式2-xml.Load(传入路径)
2.读取元素和属性
获取单个节点:XmlNode node=xml.SelectSingleNode(节点名)
获取多个节点:XmlNodeList nodeList = xml.SelectNodes(节点名)
获取节点元素内容:node.InnerText
获取节点元素属性:
1.item.Attributes[“属性名”].Value
2.item.Attributes.GetNamedItem(“属性名”).Value
通过迭代器遍历或者循环遍历XmlNodeList对象 可以获取到各单个元素节点
C#存储XML文件
决定存储在哪个文件夹下
注意:存储xml文件 在Unity中一定是使用各平台都可读可写可找到的路径
1,Resources 可读 不可写 打包后找不到 ×
2.Application.streamingAssetsPath 可读 PC端可写 找得到 ×
3.Application.dataPath 打包后找不到 ×
4.Application.persistentDataPath 可读可写找得到 √
string path = Application.persistentDataPath + "/PlayerInfo2.xml";
print(Application.persistentDataPath);
存储xml文件
关键类 XmlDocument 用于创建节点 存储文件
关键类 XmlDeclaration 用于添加版本信息
关键类 XmlElement 节点类
存储有5步
1.创建文本对象
XmlDocument xml = new XmlDocument();
2.添加固定版本信息
XmlDeclaration xmlDec = xml.CreateXmlDeclaration("1.0","UTF-8","");
xml.AppendChild(xmlDec);
3.添加根节点
XmlElement root = xml.CreateElement("Root");
xml.AppendChild(root);
4.为根节点添加子节点
XmlElement name = xml.CreateElement("name");
name.InnerText = "chx";
root.AppendChild(name);
XmlElement itemList = xml.CreateElement("itemList");
itemList.SetAttribute("id",i.ToString());//添加属性
root.AppendChild(itemList);
5.保存
xml.Save(path);
修改xml文件
1.先判断是否存在文件
if(File.Exists(path))
{
}
2.加载后 直接添加节点 移除节点即可
XmlDocument newXml = new XmlDocument();
newXml.Load(path);
XmlNode node = newXml.SelectSingleNode("Root").SelectSingleNode("atk");
//或者
XmlNode node = newXml.SelectSingleNode("Root/atk");
//得到自己的父节点
XmlNode root2 = newXml.SelectSingleNode("Root");
//移除子节点方法
root2. RemoveChild(node);
//添加节点
XmlElement speed = newXml.CreateElement("moveSpeed");
speed.InnerText = "20";
root2.AppendChild(speed);
//保存
newXml.Save(path);
实践小项目
必备知识点
XML序列化(不支持字典)
什么是序列化和反序列化
序列化:把对象转化为可传输的字节序列过程称为序列化
反序列化:把字节序列还原为对象的过程称为反序列化
说人话:
序列化就是把想要存储的内容转换为字节序列用于存储或传递
反序列化就是把存储或收到的字节序列信息解析读取出来使用
xml序列化
public class Lesson1Test
{public int testPublic = 10;private int testPrivate = 11;protected int testProtected = 12;internal int testInternal = 13;public string testPUblicStr = "123";public int testPro { get; set; }public Lesson1Test2 testClass = new Lesson1Test2();
}
public class Lesson1Test2
{public int test1 = 1;public float test2 = 1.1f;public bool test3 = true;
}
1.第一步准备一个数据结构类
Lesson1Test lt = new Lesson1Test();
2.进行序列化
关键知识点
XmlSerializer 用于序列化对象为xml的关键类
Streamwriter 用于存储文件
using 用于方便流对象释放和销毁
第一步:确定存储路径
string path = Application.persistentDataPath + "/Lesson1Test.xml";
第二步:结合 using知识点 和 Streamwriter这个流对象 来写入文件
括号内的代码:写入一个文件流 如果有该文件 直接打开并修改 如果没有该文件 直接新建一个文件
using 的新用法 括号当中包裹的声明的对象 会在 大括号语句块结束后 自动释放掉。当语句块结束,会自动帮助我们调用对象的Dispose方法,让其进行销毁。using一般都是配合内存占用比较大或者有读写操作时进行使用的。
using(StreamWriter stream = new StreamWriter(path))
{//第三步:进行xml文件序列化XmlSerializer s = new XmlSerializer(typeof(Lesson1Test));//这句代码的含义 就是通过序列化对象 对我们类对象进行翻译 将其翻译成 我们的xml文件 写入到对应的文件中//第一个参数:文件流对象//第二个参数:想要备翻译 的对象//注意:翻译机器的类型 一定要和传入的对象是一致的 不然会报错s.Serialize(stream, lt);
}
存储效果:
自定义节点名或设置属性
可以通过特性设置节点或者设置属性并且修改名字
[XmlAttribute("Test1")]
public int test1 = 1;
[XmlElement("testPublic123123")]
public int testPublic = 10;
XML反序列化
判断文件是否存在
string path = Application.persistentDataPath + "/Lesson1Test.xml";
if(File.Exists(path))
{
}
反序列化
关键知识
1.using 和 StreamReader
2.XmlSerializer的Deserialize反序列化方法
using(StreamReader reader = new StreamReader(path))
{XmlSerializer s = new XmlSerializer(typeof(Lesson1Test));Lesson1Test lt = s.Deserialize(reader) as Lesson1Test;
}
List对象如果有默认值,反序列化时,不会清空,会往后面添加。
IXmlSerializable接口
IXmlSerializable是什么
c#的XmlSerializer 提供了可拓展内容
可以让一些不能被序列化和反序列化的特殊类能被处理
让特殊类继承 IXmlSerializable 接口 实现其中的方法即可
自定义类实践
//继承接口
public class TestLesson3 : IXmlSerializable
{public int test1;public string test2;//返回结构public XmlSchema GetSchema(){return null;} //反序列化自动调用public void ReadXml(XmlReader reader){//在里面可以自定义反序列化 的规则//1.读属性this.test1 = int.Parse(reader["test1"]);this.test2 = reader["test2"];//2.读节点reader.Read();//这时是读到的test1节点reader.Read();//这时是读到的test1节点包裹的内容this.test1 = int.Parse(reader.Value);//3.读包裹元素节点XmlSerializer s = new XmlSerializer(typeof(int));//跳过根节点reader.Read();reader.ReadStartElement("test1");test1 = (int)s.Deserialize(reader);reader.ReadEndElement();//方式二:while(reader.Read()){if( reader.NodeType == XmlNodeType.Element ){switch (reader.Name){case "test1":reader.Read();this.test1 = int.Parse(reader.Value);break;case "test2":reader.Read();this.test2 = reader.Value;break;}}}}//序列化时自动调用public void WriteXml(XmlWriter writer){//在里面可以自定义序列化 的规则//如果要自定义 序列化的规则 一定会用到 Xmlwriter中的一些方法 来进行序列化//1.写属性writer.WriteAttributeString("test1", this.test1.ToString());writer.WriteAttributeString("test2", this.test2);//2.写节点writer.WriteElementString("test1", this.test1.ToString());writer.WriteElementString("test2", this.test2);//3.写包裹节点XmlSerializer s = new XmlSerializer(typeof(int));writer.WriteStartElement("test1");s.Serialize(writer, test1);writer.WriteEndElement();}
}
//序列化
TestLesson3 t = new TestLesson3();
string path = Application.persistentDataPath + "/TestLesson3.xml";
using(StreamWriter writer = new StreamWriter(path))
{XmlSerializer s = new XmlSerializer(typeof(TestLesson3));s.Serialize(writer,t);
}
//反序列化
using (StreamReader reader = new StreamReader(path))
{//序列化“翻译机器”XmlSerializer s= new XmlSerializer(typeof(TestLesson3));TestLesson3 t2 = s.Deserialize(reader) as TestLesson3;
}
让Dictionary支持序列化反序列化
思考如何让Dictionary支持xml序列和反序列化
1.我们没办法修改C#自带的类
2.那我们可以重写一个类 继承Dictionary 然后让这个类继承序列化拓展接口IXmlSerializable
3.实现里面的序列化和反序列化方法即可
SerizlizerDictionary.cs
using System.Collections;
using System.Collections.Generic;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;
using UnityEngine;public class SerizlizerDictionary<TKey, TValue> : Dictionary<TKey, TValue>, IXmlSerializable
{public XmlSchema GetSchema(){return null;}//自定义字典的 反序列化 规则public void ReadXml(XmlReader reader){XmlSerializer keySer = new XmlSerializer(typeof(TKey));XmlSerializer valueSer = new XmlSerializer(typeof(TValue));//要跳过根节点reader.Read();//判断 当前不是元素节点 结束 就进行 反序列化while (reader.NodeType != XmlNodeType.EndElement){//反序列化键TKey key = (TKey)keySer.Deserialize(reader);//反序列化值TValue value = (TValue)valueSer.Deserialize(reader);//存储到字典中this.Add(key, value);}reader.Read();}//自定义 字典的 序列化 规则public void WriteXml(XmlWriter writer){XmlSerializer keySer = new XmlSerializer(typeof(TKey));XmlSerializer valueSer = new XmlSerializer(typeof(TValue));foreach (KeyValuePair<TKey, TValue> kv in this){//键值对 的序列化keySer.Serialize(writer, kv.Key);valueSer.Serialize(writer, kv.Value);}}
}
Test.cs
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Xml.Serialization;
using UnityEngine;public class TestLesson4
{public int test1;public SerizlizerDictionary<int, string> dic;
}public class Lesson4 : MonoBehaviour
{// Start is called before the first frame updatevoid Start(){#region 知识点二 让Dictionary支持序列化和反序列化TestLesson4 tl4 = new TestLesson4();//tl4.dic = new SerizlizerDictionary<int, string>();//tl4.dic.Add(1, "123");//tl4.dic.Add(2, "234");//tl4.dic.Add(3, "345");string path = Application.persistentDataPath + "/TestLesson4.xml";//using(StreamWriter writer = new StreamWriter(path))//{// XmlSerializer s = new XmlSerializer(typeof(TestLesson4));// s.Serialize(writer, tl4);//}using (StreamReader reader = new StreamReader(path)){XmlSerializer s = new XmlSerializer(typeof(TestLesson4));tl4 = s.Deserialize(reader) as TestLesson4;}}// Update is called once per framevoid Update(){}
}
相关文章:

Unity数据持久化之XML
目录 数据持久化XML概述XML文件格式XML基本语法XML属性 C#读取存储XMLXML文件存放位置C#读取XML文件C#存储XML文件 实践小项目必备知识点XML序列化(不支持字典)XML反序列化IXmlSerializable接口让Dictionary支持序列化反序列化 数据持久化XML概述 什么是…...
Leetcode 226:翻转二叉树
给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。 思路:使用递归 //使用前序遍历翻转树public static TreeNode invertTree(TreeNode root){if(rootnull) return root;swap(root);invertTree(root.left);invertTree(root.rig…...
柯里化与无参装饰器
柯里化 柯里化的概念:柯里化(Currying)在Python中是一种编程技术,它将原本接受多个参数的函数转换为一系列接受单个参数的函数。这种方法以逻辑学家Haskell Curry的名字命名。 简而言之就是将一次函数调用变成先放入一个参数得到…...
Spring事务失效的场景
1. 事务方法执行期间出现了异常,但是并未指定rollbackFor: Spring默认只会在遇到error和RunTimeException时才会回滚。 public boolean rollbackon ( Throwable ex){return (ex instanceof RuntimeException || ex instanceof Error); } 2. 事务方法执行期间出现了…...
Python基础学习之datetime模块
在Python编程中,处理日期和时间是一个常见的需求。Python的datetime模块提供了丰富的类和方法,用于表示和操作日期、时间、时间间隔等。本文将详细介绍Python的datetime模块,并给出一些实用的示例。 1. datetime模块概览 datetime模块是Pyt…...
在AI大模型中全精度和半精度参数是什么意思?
环境: 大模型中 问题描述: 在AI大模型中全精度和半精度参数是什么意思? 解决方案: 在深度学习和高性能计算领域,"全精度"和"半精度"通常指的是模型中使用的数值表示的精度,具体涉…...
刷题记录2
文章目录 刷题记录21047.删除字符串中的所有相邻重复项150.逆波兰表达式求值239.滑动窗口最大值347.前k个高频元素144.二叉树前序遍历(145、94后序、中序)102.二叉树的层序遍历226.翻转二叉树101.对称二叉树104.二叉树的最大深度111.二叉树的最小深度222.完全二叉树的节点个数 …...

【配置】Docker搭建JSON在线解析网站
一个python朋友需要,顺便做一下笔记 正常用菜鸟的就够了,点下面 JSON在线解析 云服务器打开端口8787 连接上docker运行 docker run -id --name jsonhero -p 8787:8787 -e SESSION_SECRETabc123 henryclw/jsonhero-webhttp://ip:8787访问 Github&…...
2024.5.2 —— LeetCode 高频题复盘
目录 151. 反转字符串中的单词129. 求根节点到叶节点数字之和104. 二叉树的最大深度101. 对称二叉树110. 平衡二叉树144. 二叉树的前序遍历543. 二叉树的直径48. 旋转图像98. 验证二叉搜索树39. 组合总和 151. 反转字符串中的单词 题目链接 class Solution:def reverseWords(s…...

ThreeJS:光线投射与3D场景交互
光线投射Raycaster 光线投射详细介绍可参考:https://en.wikipedia.org/wiki/Ray_casting, ThreeJS中,提供了Raycaster类,用于进行鼠标拾取,即:当三维场景中鼠标移动时,利用光线投射,…...

docker挂载数据卷-以nginx为例
目录 一、什么是数据卷 二、数据卷的作用 三、如何挂载数据卷 1、创建nginx容器挂载数据卷 2、查看数据卷 3、查看数据卷详情 4、尝试在宿主机修改数据卷 5、查看容器内对应的数据卷目录 6、 访问nginx查看效果 一、什么是数据卷 挂载数据卷本质上就是实…...
Docker-compose部署Fastapi项目
Docker-compose部署Fastapi、postgres、Redis、Nginx) 之前有写过使用容器部署的方式,这次尝试使用Docker-compose试一次大胆的尝试 使用容器的方式部署只是掌握这项技能的基础,在使用Docker-compose的过程中会有些稍许的不同。毕竟踩过的坑才算是跨过去…...

Eigen求解线性方程组
1、线性方程组的应用 线性方程组可以用来解决各种涉及线性关系的问题。以下是一些通常可以用线性方程组来解决的问题: 在实际工程和科学计算中,求解多项式方程的根有着广泛的应用。 在控制系统的设计中,我们经常需要求解特征方程的根来分析…...

7、Java基本数据类型的使用细节探讨(超详细版本)
Java基本数据类型的使用细节探讨 一、整数类型二、浮点数三、字符型四、布尔型 我觉得基本数据类型大家学计算机的应该都懂,但是韩顺平老师讲的基本类型的使用细节我觉得有必要记录一下,重新学的时候才发现有了新的感悟! 一、整数类型 使用细…...

MFC实现点击列表头进行排序
MFC实现点击列表头排序 1、添加消息处理函数 在列表窗口右键,类向导。选择 IDC_LIST1(我的列表控件的ID),消息选择LVN_COLUMNCLICK。 2、消息映射如下 然后会在 cpp 文件中生成以下函数 void CFLashSearchDlg::OnLvnColumnclic…...

用龙梦迷你电脑福珑2.0做web服务器
用龙梦迷你电脑福珑2.0上做web服务器是可行的。已将一个网站源码放到该电脑,在局域网里可以访问网站网页。另外通过在同一局域网内的一台windows10电脑上安装花生壳软件,也可以在外网访问该内网服务器网站网页。该电脑的操作系统属于LAMP。在该电脑上安装…...
秋招后端开发面试题 - JVM类加载机制
目录 JVM类加载机制前言面试题能说一下类的生命周期吗?类加载的过程知道吗?类加载器有哪些?什么是双亲委派机制?为什么要用双亲委派机制?如何破坏双亲委派机制?如何判断一个类是无用的类? JVM类…...
OceanBase 分布式数据库【信创/国产化】- OceanBase 配置项和系统变量概述
本心、输入输出、结果 文章目录 OceanBase 分布式数据库【信创/国产化】- OceanBase 配置项和系统变量概述前言OceanBase 数据更新架构OceanBase 配置项和系统变量概述配置项配置项分类配置项查询系统变量系统变量分类系统变量查询配置项与系统变量的区分OceanBase 分布式数据库…...

单单单单单の刁队列
在数据结构的学习中,队列是一种常用的线性数据结构,它遵循先进先出(FIFO)的原则。而单调队列是队列的一种变体,它在特定条件下保证了队列中的元素具有某种单调性质,例如单调递增或单调递减。单调队列在处理…...

电脑windows系统压缩解压软件-Bandizip
一、软件功能 Bandizip是一款功能强大的压缩和解压缩软件,具有快速拖放、高速压缩、多核心支持以及广泛的文件格式支持等特点。 Bandizip软件的功能主要包括: 1. 支持多种文件格式 Bandizip可以处理多种压缩文件格式,包括ZIP, 7Z, RAR, A…...
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以? 在 Golang 的面试中,map 类型的使用是一个常见的考点,其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...

iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版分享
平时用 iPhone 的时候,难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵,或者买了二手 iPhone 却被原来的 iCloud 账号锁住,这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...

相机从app启动流程
一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...

微服务商城-商品微服务
数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...

IT供电系统绝缘监测及故障定位解决方案
随着新能源的快速发展,光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域,IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选,但在长期运行中,例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...

如何理解 IP 数据报中的 TTL?
目录 前言理解 前言 面试灵魂一问:说说对 IP 数据报中 TTL 的理解?我们都知道,IP 数据报由首部和数据两部分组成,首部又分为两部分:固定部分和可变部分,共占 20 字节,而即将讨论的 TTL 就位于首…...

【VLNs篇】07:NavRL—在动态环境中学习安全飞行
项目内容论文标题NavRL: 在动态环境中学习安全飞行 (NavRL: Learning Safe Flight in Dynamic Environments)核心问题解决无人机在包含静态和动态障碍物的复杂环境中进行安全、高效自主导航的挑战,克服传统方法和现有强化学习方法的局限性。核心算法基于近端策略优化…...

MFC 抛体运动模拟:常见问题解决与界面美化
在 MFC 中开发抛体运动模拟程序时,我们常遇到 轨迹残留、无效刷新、视觉单调、物理逻辑瑕疵 等问题。本文将针对这些痛点,详细解析原因并提供解决方案,同时兼顾界面美化,让模拟效果更专业、更高效。 问题一:历史轨迹与小球残影残留 现象 小球运动后,历史位置的 “残影”…...

LLMs 系列实操科普(1)
写在前面: 本期内容我们继续 Andrej Karpathy 的《How I use LLMs》讲座内容,原视频时长 ~130 分钟,以实操演示主流的一些 LLMs 的使用,由于涉及到实操,实际上并不适合以文字整理,但还是决定尽量整理一份笔…...

【无标题】湖北理元理律师事务所:债务优化中的生活保障与法律平衡之道
文/法律实务观察组 在债务重组领域,专业机构的核心价值不仅在于减轻债务数字,更在于帮助债务人在履行义务的同时维持基本生活尊严。湖北理元理律师事务所的服务实践表明,合法债务优化需同步实现三重平衡: 法律刚性(债…...