Unity基础学习(十二)Unity 物理系统之范围检测

article/2025/7/25 22:25:26

        

目录

一、关于范围检测的主要API:

1. 盒状范围检测 Physics.OverlapBox

2. 球形范围检测 Physics.OverlapSphere

3. 胶囊范围检测 Physics.OverlapCapsule

4. 盒状检测 NonAlloc 版

5. 球形检测 NonAlloc 版

6. 胶囊检测 NonAlloc 版

二、关于API中的两个重点参数

QueryTriggerInteraction 参数详解 

1. QueryTriggerInteraction.UseGlobal

2. QueryTriggerInteraction.Collide

3. QueryTriggerInteraction.Ignore

LayerMask 在范围检测中的深度解析

1. 层级系统基础

2. LayerMask 本质

层级选择:精准定位目标层

基础选择方法

高级选择方式

 层级合并:组合检测

基本合并技巧

层级排除:精准过滤 

常见错误:

1. 层名拼写错误(静默失败)

2. 位运算优先级错误

3. 掩码值为0(不检测任何层)

4. 混淆层索引和掩码值 这个最常见

三、总结

 基本范围检测函数

高效 NonAlloc 版本

 关键参数详解表

通用参数(所有检测函数)

盒状检测特有参数

球形检测特有参数

胶囊检测特有参数

NonAlloc 版本特有参数

 LayerMask 操作指南

 高频错误及解决方案


        在前面的内容中,我们学习了关于碰撞的检测相关,今天我们来看看指定范围的检测,这个检测是什么呢?就是瞬时检测指定空间内的碰撞器对象(无实体碰撞效果),适用于技能攻击、区域触发等场景。

        那么被检测的对象需要具备些什么条件呢?被检测对象 必须挂载碰撞器(Collider)(无需 Rigidbody)。

一、关于范围检测的主要API:

1. 盒状范围检测 Physics.OverlapBox

参数相关:

Collider[] Physics.OverlapBox(Vector3 center,                 // 盒子中心点(世界坐标)Vector3 halfExtents,            // 盒子三边尺寸(半长,非全尺寸)Quaternion orientation,         // 盒子旋转角度int layerMask = AllLayers,      // 层级掩码(默认所有层)QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal
)

返回值:检测范围内的所有碰撞器组成的数组(无碰撞时返回空数组)

例如:

void CheckAttackRange()
{// 在玩家前方1米处创建2x2x2的检测盒Vector3 center = transform.position + transform.forward;Vector3 size = new Vector3(2, 2, 2);int enemyLayer = 1 << LayerMask.NameToLayer("Enemy");Collider[] hits = Physics.OverlapBox(center,size / 2,  // 注意:参数是半长尺寸transform.rotation,enemyLayer,QueryTriggerInteraction.Ignore);foreach (Collider col in hits){Enemy enemy = col.GetComponent<Enemy>();if(enemy != null) enemy.TakeDamage(10);}// 调试绘制Debug.DrawLine(transform.position, center, Color.red, 0.5f);
}

实际上你看不到他的检测范围的,你要自己想象。 

 

2. 球形范围检测 Physics.OverlapSphere

参数相关:

Collider[] Physics.OverlapSphere(Vector3 position,               // 球心位置(世界坐标)float radius,                   // 球体半径int layerMask = AllLayers,      // 层级掩码QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal
)

返回值:球体内的所有碰撞器数组 

void DetectNearbyItems()
{// 检测周围5米内的可收集物品int itemLayer = LayerMask.GetMask("Collectibles");float detectRadius = 5f;Collider[] items = Physics.OverlapSphere(transform.position,detectRadius,itemLayer);foreach (Collider item in items){item.GetComponent<Collectible>().Highlight();}// 调试绘制Gizmos.color = Color.cyan;Gizmos.DrawWireSphere(transform.position, detectRadius);
}

这个球形的和上面的一样,就只是参数不同而已,形状不同,效果都是碰撞检测,还有下面的胶囊检测也是如此。 

3. 胶囊范围检测 Physics.OverlapCapsule

参数相关:

Collider[] Physics.OverlapCapsule(Vector3 point0,                 // 胶囊体底部球心Vector3 point1,                 // 胶囊体顶部球心float radius,                   // 胶囊半径int layerMask = AllLayers,      // 层级掩码QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal
)

例如:

void CheckCharacterHit()
{// 检测玩家角色碰撞(高度2米,半径0.5米)Vector3 feetPos = transform.position;Vector3 headPos = feetPos + Vector3.up * 2;float charRadius = 0.5f;int playerLayer = LayerMask.GetMask("Player");Collider[] hits = Physics.OverlapCapsule(feetPos,headPos,charRadius,playerLayer);if (hits.Length > 0){Debug.Log("Player character hit detected!");}
}

         上面的三个API只是最基本的范围检测,他们还有好兄弟。你不需要将返回值碰撞器数组存下来,可以直接在外部创建一个数组,然后装入这个数组中即可:

4. 盒状检测 NonAlloc 版

int Physics.OverlapBoxNonAlloc(Vector3 center,                 // 盒子中心点Vector3 halfExtents,            // 盒子半尺寸(长/宽/高各一半)Collider[] results,             // 结果存储数组(预分配)Quaternion orientation = Quaternion.identity, // 旋转角度int layerMask = AllLayers,      // 层级掩码QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal
)

返回值:实际检测到的碰撞器数量(非数组长度) 

5. 球形检测 NonAlloc 版

int Physics.OverlapSphereNonAlloc(Vector3 position,               // 球心位置float radius,                   // 球体半径Collider[] results,             // 结果存储数组int layerMask = AllLayers,      // 层级掩码QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal
)

返回值:实际检测到的碰撞器数量 

6. 胶囊检测 NonAlloc 版

int Physics.OverlapCapsuleNonAlloc(Vector3 point0,                 // 胶囊底部球心Vector3 point1,                 // 胶囊顶部球心float radius,                   // 胶囊半径Collider[] results,             // 结果存储数组int layerMask = AllLayers,      // 层级掩码QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal
)

返回值:实际检测到的碰撞器数量

使用手段都是和前三个差不多的

NonAlloc 方法核心优势

特性基础方法 (OverlapX)NonAlloc 方法 (OverlapXNonAlloc)
内存分配每次调用创建新数组使用预分配数组,无GC开销
性能影响高频调用导致GC压力零内存分配,性能稳定
使用场景低频/单次检测高频检测(如Update中)
返回值Collider[] 数组int (实际检测数量)

二、关于API中的两个重点参数

QueryTriggerInteraction 参数详解 

QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal 是 Unity 物理检测 API 中的一个重要参数,用于控制物理检测如何处理触发器(Trigger)。实际上一般默认的就OK

这个参数决定了在物理检测(如范围检测、射线检测等)中是否应该包括触发器碰撞器:

  1. 控制检测行为:指定是否将触发器视为有效的碰撞对象

  2. 避免意外结果:防止触发器干扰正常的物理检测逻辑

  3. 灵活配置:可以覆盖项目的全局设置

1. QueryTriggerInteraction.UseGlobal

行为:使用项目的全局物理设置
说明:检测行为取决于 "Edit > Project Settings > Physics" 中的 "Queries Hit Triggers" 设置

推荐场景:
希望检测行为与项目全局设置保持一致时
不特别关注触发器处理方式时

2. QueryTriggerInteraction.Collide

行为:包含触发器在检测结果中
说明:无论项目全局设置如何,本次检测都会将触发器视为有效碰撞体

推荐场景:
需要检测区域触发器时(如进入安全区、收集区域)
需要响应触发器事件时

3. QueryTriggerInteraction.Ignore

行为:忽略所有触发器
说明:无论项目全局设置如何,本次检测都会跳过所有触发器

推荐场景:
只关心实体碰撞时(如攻击检测、物理碰撞)
避免触发器干扰检测结果时

示例:不同参数的效果

注: :这种写法叫做可选参数。

// 检测所有碰撞体(包括普通碰撞器和触发器)
Collider[] allHits = Physics.OverlapSphere(position: transform.position,radius: 5f,layerMask: LayerMask.GetMask("Enemy", "Trap", "SafeZone"),queryTriggerInteraction: QueryTriggerInteraction.Collide
);
// 结果:包含敌人、陷阱区域、安全区// 只检测实体碰撞体(忽略所有触发器)
Collider[] physicalHits = Physics.OverlapSphere(position: transform.position,radius: 5f,layerMask: LayerMask.GetMask("Enemy", "Trap", "SafeZone"),queryTriggerInteraction: QueryTriggerInteraction.Ignore
);
// 结果:只包含敌人(陷阱区域和安全区是触发器,被忽略)// 使用全局设置检测
Collider[] globalSettingHits = Physics.OverlapSphere(position: transform.position,radius: 5f,layerMask: LayerMask.GetMask("Enemy", "Trap", "SafeZone"),queryTriggerInteraction: QueryTriggerInteraction.UseGlobal
);
// 结果:取决于项目设置中的"Queries Hit Triggers"选项

LayerMask 在范围检测中的深度解析

LayerMask 核心概念

1. 层级系统基础

Unity 提供 32 个层级(0-31)
每个游戏对象分配到一个层级
层级用于逻辑分组(如:玩家、敌人、环境、UI等)

2. LayerMask 本质

32 位位掩码(bitmask)
每个位对应一个层级(1=包含,0=排除)
示例:00000000 00000000 00000000 00000101 表示包含第0层和第2层

可以在这里进行创建层级

通过代码来获取层级:

// 单层级
int enemyLayer = LayerMask.NameToLayer("Enemy");
LayerMask enemyMask = 1 << enemyLayer;// 多层级组合
LayerMask enemyAndObstacleMask = (1 << LayerMask.NameToLayer("Enemy")) | (1 << LayerMask.NameToLayer("Obstacle"));// 排除特定层
LayerMask allExceptUI = ~(1 << LayerMask.NameToLayer("UI"));//或者
// 包含多个层级
LayerMask mask = LayerMask.GetMask("Enemy", "Projectile", "Destructible");// 等效于:
// (1 << LayerMask.NameToLayer("Enemy")) |
// (1 << LayerMask.NameToLayer("Projectile")) |
// (1 << LayerMask.NameToLayer("Destructible"))

接下来咱们讲讲为什么它会这么进行设计,和如何进行层级的选择,合并,排除。

        因为位运算很快,而且非常的适合做状态合并与排除。你只需要将对应位置的数置0即排除,置1就合并了。利用,位与,位或进行操作。 

层级选择:精准定位目标层

基础选择方法

// 选择单个层级
LayerMask enemyMask = 1 << LayerMask.NameToLayer("Enemy");// 选择多个层级
LayerMask combatMask = (1 << LayerMask.NameToLayer("Enemy")) | (1 << LayerMask.NameToLayer("Boss"));

高级选择方式

// 使用 GetMask 更简洁
LayerMask environmentMask = LayerMask.GetMask("Ground", "Water", "Wall");

 层级合并:组合检测

基本合并技巧

// 创建基础掩码
LayerMask baseMask = LayerMask.GetMask("Player", "Enemy");// 动态添加层级
void AddLayerToMask(ref LayerMask mask, string layerName)
{int layer = LayerMask.NameToLayer(layerName);if (layer != -1) {mask |= (1 << layer);  // 按位或操作}
}// 使用
AddLayerToMask(ref baseMask, "Projectile");

多掩码组合

// 定义不同类别的掩码
LayerMask characterMask = LayerMask.GetMask("Player", "NPC", "Enemy");
LayerMask environmentMask = LayerMask.GetMask("Ground", "Wall", "Water");
LayerMask interactableMask = LayerMask.GetMask("Chest", "Door", "Lever");// 组合掩码
LayerMask fullDetectionMask = characterMask | environmentMask | interactableMask;

层级排除:精准过滤 

// 所有层
LayerMask allLayers = ~0; // 或 Physics.AllLayers// 排除 UI 层
int uiLayer = LayerMask.NameToLayer("UI");
LayerMask noUIMask = allLayers & ~(1 << uiLayer);// 排除多个层
int ignoreLayer1 = LayerMask.NameToLayer("IgnoreRaycast");
int ignoreLayer2 = LayerMask.NameToLayer("Water");
LayerMask filteredMask = allLayers & ~((1 << ignoreLayer1) | (1 << ignoreLayer2));

假设你要排除的层级:00000000 00000000 00000000 00001001

取反后                         11111111   11111111   11111111   11110110

全层级                         11111111   11111111   11111111   11111111

相与后,便排除了指定层级

常见错误:

1. 层名拼写错误(静默失败)

// 错误:层名拼错无提示
LayerMask mask = 1 << LayerMask.NameToLayer("Enemi"); // 返回 -1// 解决方案:验证层名
int GetLayerSafe(string layerName)
{int layer = LayerMask.NameToLayer(layerName);if (layer == -1){Debug.LogError($"Layer '{layerName}' does not exist!");return 0; // 默认层}return layer;
}

2. 位运算优先级错误

// 错误:运算优先级问题
LayerMask wrongMask = 1 << 8 | 1 << 9; // 实际是 (1 << 8) | (9)!// 正确:使用括号明确优先级
LayerMask correctMask = (1 << 8) | (1 << 9);

3. 掩码值为0(不检测任何层)

// 常见于动态构建掩码失败
LayerMask emptyMask = 0; // 不检测任何层// 防护:添加默认层
if (mask == 0)
{mask = 1 << 0; // 至少包含默认层Debug.LogWarning("Empty layer mask, using default layer");
}

4. 混淆层索引和掩码值 这个最常见

// 错误:传入层索引而非掩码
int enemyLayer = LayerMask.NameToLayer("Enemy");
Physics.Raycast(..., enemyLayer); // 应该传入 1 << enemyLayer// 正确:始终使用位掩码
Physics.Raycast(..., 1 << enemyLayer);

三、总结

 基本范围检测函数
函数名返回值核心功能
Physics.OverlapBoxCollider[]检测盒状区域内的碰撞器
Physics.OverlapSphereCollider[]检测球形区域内的碰撞器
Physics.OverlapCapsuleCollider[]检测胶囊区域内的碰撞器
高效 NonAlloc 版本
函数名返回值核心优势
Physics.OverlapBoxNonAllocint零GC分配,适合高频调用
Physics.OverlapSphereNonAllocint预分配数组,性能稳定
Physics.OverlapCapsuleNonAllocint返回实际碰撞数量而非数组

 关键参数详解表

通用参数(所有检测函数)
参数名类型说明
layerMaskint层级掩码(位运算值),决定检测哪些层
queryTriggerInteractionenum触发器处理方式:
UseGlobal-用项目设置
Collide-包含触发器
Ignore-忽略触发器
盒状检测特有参数
参数名类型说明注意事项
centerVector3盒子中心点(世界坐标)
halfExtentsVector3三边尺寸的一半​(非全尺寸)例:2x2x2盒子需传入(1,1,1)
orientationQuaternion盒子的旋转角度默认Quaternion.identity
球形检测特有参数
参数名类型说明
positionVector3球心位置(世界坐标)
radiusfloat球体半径
胶囊检测特有参数
参数名类型说明
point0Vector3胶囊底部球心(世界坐标)
point1Vector3胶囊顶部球心(世界坐标)
radiusfloat胶囊半径
NonAlloc 版本特有参数
参数名类型说明
resultsCollider[]预分配的碰撞器数组(避免GC分配)

 LayerMask 操作指南

操作类型代码示例说明
单层选择1 << LayerMask.NameToLayer("Enemy")位左移构建掩码
多层合并LayerMask.GetMask("Enemy", "Boss")官方推荐的多层获取方式
动态添加层`mask= (1 << LayerMask.NameToLayer("Projectile"))`
排除特定层LayerMask filteredMask = ~0 & ~(1 << LayerMask.NameToLayer("UI"))取反+位与实现层排除
所有层Physics.AllLayers 或 ~032位全1掩码

 高频错误及解决方案

错误类型错误示例正确写法解决方案
层名拼写错误NameToLayer("Enemi")验证层名是否存在添加层名检查逻辑
位运算优先级错误`1 << 81 << 9``(1 << 8)
空掩码LayerMask mask = 0添加默认层兜底mask = mask==0 ? 1<<0 : mask
混淆层索引与掩码Physics.Raycast(..., enemyLayer)Physics.Raycast(..., 1<<enemyLayer)始终使用位掩码格式
盒状尺寸参数错误OverlapBox(center, fullSize, ...)OverlapBox(center, fullSize/2, ...)牢记用半长尺寸

http://www.hkcw.cn/article/ukNkdyrKNA.shtml

相关文章

05.29.2025 CCNA++ 学习完成

05.29.2025 CCNA 学习完成 从哪个遥远的冬天开始的。。。断断续续鸽了几个月(春节&#xff0c;马来西亚旅游), 实际大概学习了3个半月 通过这个学习对网络的底层有了一个更全面的认识&#xff0c;后面还得经常看看才能理解这些东西 课程的资料慢慢补上来 To Be continued…

Vert.x学习笔记-什么是Worker线程池

Vert.x学习笔记 一、Worker线程池的作用二、Worker线程池的特点三、Worker线程池的使用四、Worker线程池的配置与调优五、Worker线程池的工作原理1. 任务分类与线程隔离2. Worker线程池的启动与配置3. 任务提交与执行流程4. 线程安全与上下文切换5. 性能优化与监控6. 关键特性总…

Smith圆图知识学习笔记

Smith圆图知识学习笔记 理论背景 图 1 Smith图表是由菲利普史密斯(Phillip Smith)于1939年发明的,如图1所示,当时他在美国的RCA公司工作。史密斯曾说过,“在我能够使用计算尺的时候,我对以图表方式来表达数学上的关联很有兴趣”。 史密斯图表的基本在于以下的算式: 图 …

MySQL 8.0 OCP 英文题库解析(十一)

Oracle 为庆祝 MySQL 30 周年&#xff0c;截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始&#xff0c;将英文题库免费公布出来&#xff0c;并进行解析&#xff0c;帮助大家在一个月之内轻松通过OCP认证。 本期公布试题91~100 试题91…

RT-Thread Studio学习(十八)ADC+TIM+DMA

RT-Thread Studio学习&#xff08;十八&#xff09;ADCTIMDMA 一、简介二、新建RT-Thread项目并使用外部时钟三、启用ADC四、修改代码五、测试 一、简介 本文将基于STM32F407VET芯片介绍如何在RT-Thread Studio开发环境下使用ADC设备。硬件及开发环境如下&#xff1a; OS WIN…

ES分词搜索

ES的使用 前言作者使用的版本作者需求 简介ES简略介绍ik分词器简介 使用es的直接简单使用es的查询 es在java中使用备注说明 前言 作者使用的版本 es: 7.17.27spring-boot-starter-data-elasticsearch: 7.14.2 作者需求 作者接到一个业务需求&#xff0c;我们系统有份数据被…

Drawio编辑器二次开发

‌ Drawio &#xff08;现更名为 Diagrams.net &#xff09;‌是一款完全免费的在线图表绘制工具&#xff0c;由 JGraph公司 开发。它支持创建多种类型的图表&#xff0c;包括流程图、组织结构图、UML图、网络拓扑图、思维导图等&#xff0c;适用于商务演示、软件设计等多种场景…

破解高原运维难题:分布式光伏智能监控系统的应用研究

安科瑞刘鸿鹏 摘要 高原地区光照资源丰富&#xff0c;具有发展分布式光伏发电的巨大潜力。然而&#xff0c;该地区复杂的气候环境、地形地貌和运维条件对光伏电站的运行与维护带来严峻挑战。本文结合Acrel1000DP分布式光伏监控系统的技术特点和典型应用案例&#xff0c;探讨其…

Golang|分布式搜索引擎中所使用到的设计模式

迭代器模式 定义&#xff1a;在遍历接口时&#xff0c;提供统一的方法函数供调用&#xff0c;保持一致性。核心思想&#xff1a;与大众习惯保持一致&#xff0c;方便第三方实现容器类时保持一致。常见方法&#xff1a;如next()方法&#xff0c;适用于所有集合类&#xff0c;简化…

招工招聘系统开发——适配多元场景,满足企业多样化招聘需求

不同的企业有不同的招聘需求&#xff0c;不同的岗位也有不同的招聘特点。我们的招工招聘系统开发&#xff0c;充分考虑了企业的多样化需求&#xff0c;适配多元场景&#xff0c;为企业提供全方位的招聘解决方案。 对于大型企业来说&#xff0c;招聘规模大、岗位种类多、招聘流…

优化版本,增加3D 视觉 查看前面的记录

上图先 运来的超出发表上限&#xff0c;重新发。。。 #11:06:57Current_POS_is: X:77Y:471Z:0U:-2 C:\Log\V55.txt import time import tkinter as tk from tkinter import messagebox from PIL import Image, ImageTk import socket import threading from date…

《TCP/IP 详解 卷1:协议》第2章:Internet 地址结构

基本的IP地址结构 分类寻址 早期Internet采用分类地址&#xff08;Classful Addressing&#xff09;&#xff0c;将IPv4地址划分为五类&#xff1a; A类和B类网络号通常浪费太多主机号&#xff0c;而C类网络号不能为很多站点提供足够的主机号。 子网寻址 子网&#xff08;Su…

JNI开发流程

一. 引言 最近在做一个自己的项目&#xff0c;就是基于FastDDS封装一套JAVA库&#xff0c;让android和java应用可以使用dds的功能。 由于FastDDS是使用C编写的开源库&#xff0c;因此java的类库想要调用FastDDS的接口&#xff0c;需要额外编写一个JNI层的动态库对FastDDS的接口…

powershell 中 invoke-expression 报错解决

打开powershell就出现这个报错&#xff1a; 网上搜了也没有很好的解决办法&#xff0c;抱着一点点期待&#xff0c;问了豆包 根据豆包的指示&#xff0c;在终端执行以下 几个命令&#xff0c;报错解决了&#xff08;开心万岁&#xff09; # 移除多余的引号和空路径 $pathArra…

交错推理强化学习方法提升医疗大语言模型推理能力的深度分析

核心概念解析 交错推理:灵活多变的思考方式 交错推理(Interleaved Reasoning)是一种在解决复杂问题时,不严格遵循单一、线性推理路径,而是交替、灵活应用多种推理策略的方法。这种思维方式与人类专家在处理复杂医疗问题时的思考模式更为接近,表现为一种动态、适应性强的…

【下载ECharts最简单的方法】

最简单下载ECharts的方法 对于简单项目&#xff0c;我们需要的echarts文件是echarts.min.js&#xff0c;以下是下载ECharts的最简单方法&#xff1a; 方法一&#xff1a;直接下载&#xff08;推荐初学者&#xff09; 访问ECharts官网&#xff1a;https://echarts.apache.org…

西藏建筑安全员 B 证考试中常见的 单选题及解析

西藏建筑安全员 B 证考试中常见单选题及解析&#xff0c;涵盖安全生产管理、法律法规、安全技术等核心考点&#xff0c;结合西藏地区建筑施工特点整理&#xff0c;帮助理解考试重点&#xff1a; 一、安全生产管理基础 1. 安全管理原则与制度 1、建筑施工安全管理的方针是&am…

案例分享--血管支架的径向力分布评估--DIC数字图像相关技术用于生物医学-高置信度DIC测量

医疗设备制造商有责任创造和确保高效且安全的产品&#xff0c;以守护人类的健康。EchoBio LLC公司的Kenneth Perry博士是植入式医疗设备实验验证行业的领导者和专家。Perry博士的一项研究任务是评估用于疏通血管阻塞的编织自膨胀支架的径向力分布。Perry博士特别需要关注径向力…

[Javascript进阶]JSON.stringify与JSON.parse详解

JSON.stringfy JSON.stringify 的核心作用是&#xff1a; &#x1f449; 将 JS 的对象、数组、基本类型转换为合法的 JSON 字符串。 手撕实现时&#xff0c;要考虑以下几个方面&#xff1a; 基本类型处理&#xff1a; string → 加上双引号&#xff0c;注意转义&#xff1b;nu…

VirtualBox给Rock Linux9.x配置网络

写这篇文章之前&#xff0c;先说明一下&#xff0c;我参考的是我之前写的《VirtualBox Linux网络配置》 我从CentOS7转到了Rock9&#xff0c;和配置Centos7一样&#xff0c;主流程没有变化&#xff0c;变化的是Rock9.x中的配置文件和使用的命令。 我再说一次&#xff0c;因为主…