Unity中实现预制体自动巡逻与攻击敌人的完整实现指南
✅作者简介:2022年博客新星 第八。热爱国学的Java后端开发者,修心和技术同步精进。
🍎个人主页:Java Fans的博客
🍊个人信条:不迁怒,不贰过。小知识,大智慧。
💞当前专栏:Java案例分享专栏
✨特色专栏:国学周更-心性养成之路
🥭本文内容:Unity中实现预制体自动巡逻与攻击敌人的完整实现指南
文章目录
- 前言
- 1. 巡逻功能:
- 1.1 引入命名空间
- 1.2 定义 Patrol 类
- 1.3 声明公共变量
- 1.4 声明私有变量
- 1.5 Start 方法
- 1.6 Update 方法
- 1.7 设置随机巡逻点的逻辑
- 1.8 巡逻等待的协程
- 1.9 巡逻功能总结
- 2. 发现敌人:
- 2.1 类声明
- 2.2 声明公共变量
- 2.3 声明私有变量
- 2.4 Update 方法
- 2.5 MoveToEnemy 方法
- 2.6 发现敌人总结
- 3. 攻击敌人:
- 3.1 类声明
- 3.2 声明公共变量
- 3.3. 声明私有变量
- 3.4. Update 方法
- 3.5 Attack 方法
- 3.6 攻击敌人总结
- 4. 整合逻辑:
- 4.1 定义枚举类型
- 4.2 声明当前状态
- 4.3 Update 方法
- 4.3.1 巡逻状态
- 4.3.2 追逐状态
- 4.3.3 攻击状态
- 4.4 整合逻辑总结
- 总结
前言
在当今游戏开发领域,自动化行为技术的应用已经成为游戏开发者们追求的热门话题。无论是为了增加游戏的趣味性、提升游戏体验,还是为了减轻开发者的工作负担,实现预制体自动化行为已经成为许多游戏项目的必备功能之一。本文将深入探讨如何在Unity游戏引擎中实现预制体自动巡逻并攻击敌人的全过程。
在游戏开发中,预制体是一种非常常见的游戏对象,它们可以被重复使用并在场景中多次实例化。然而,让预制体具备自主行为、能够在游戏世界中自主移动、探索并与敌人交互,是一项具有挑战性的任务。本文将引导读者逐步实现预制体的自动化行为,包括目标位置到达后的随机巡逻、敌人发现与追击、攻击等关键步骤。
通过本文的指导,读者将深入了解自动化行为背后的技术原理,学习如何利用Unity强大的功能和工具,为游戏角色赋予更加智能和自主的行为。无论是想要开发一款冒险游戏、射击游戏还是策略游戏,本文都将为您提供宝贵的指导和灵感,帮助您实现游戏中角色的自动化行为,为玩家带来更加丰富和有趣的游戏体验。
1. 巡逻功能:
预制体在到达目标位置后,会在设定的范围内随机选择一个点作为新的目标位置,并移动到该点。
using UnityEngine;
using UnityEngine.AI;public class Patrol : MonoBehaviour
{public Transform centerPoint; // 巡逻的中心点public float patrolRadius = 10f; // 巡逻半径public float patrolWaitTime = 2f; // 巡逻停留时间private NavMeshAgent agent;private Vector3 targetPosition;void Start(){agent = GetComponent<NavMeshAgent>();SetRandomPatrolPoint();}void Update(){if (!agent.pathPending && agent.remainingDistance < 0.5f){StartCoroutine(PatrolWait());}}// 设置随机的巡逻点void SetRandomPatrolPoint(){Vector3 randomDirection = Random.insideUnitSphere * patrolRadius;randomDirection += centerPoint.position;NavMeshHit hit;NavMesh.SamplePosition(randomDirection, out hit, patrolRadius, 1);targetPosition = hit.position;agent.SetDestination(targetPosition);}// 巡逻点到达后的等待IEnumerator PatrolWait(){yield return new WaitForSeconds(patrolWaitTime);SetRandomPatrolPoint();}
}
这段代码是一个 Unity 脚本,主要用于实现一个 AI 角色的巡逻行为。下面是对代码的逐行解释:
1.1 引入命名空间
using UnityEngine;
using UnityEngine.AI;
-
UnityEngine 是 Unity 的核心命名空间,包含大多数常用类。
-
UnityEngine.AI 是用于处理导航和 AI 行为的命名空间,包含 NavMeshAgent 类。
1.2 定义 Patrol 类
public class Patrol : MonoBehaviour
定义一个名为 Patrol 的公共类,继承自 MonoBehaviour。这使得 Patrol 可以被附加到 Unity 的游戏对象上,并具有 Unity 生命周期方法(如 Start 和 Update)。
1.3 声明公共变量
public Transform centerPoint; // 巡逻的中心点
public float patrolRadius = 10f; // 巡逻半径
public float patrolWaitTime = 2f; // 巡逻停留时间
-
centerPoint: 一个 Transform 类型的公共变量,用于定义巡逻的中心点(AI 角色的巡逻范围中心)。
-
patrolRadius: 一个 float 类型的公共变量,定义 AI 角色巡逻的半径,默认为 10。
-
patrolWaitTime: 一个 float 类型的公共变量,定义 AI 角色在每个巡逻点停留的时间,默认为 2 秒。
1.4 声明私有变量
private NavMeshAgent agent;
private Vector3 targetPosition;
-
agent: 一个 NavMeshAgent 类型的私有变量,用于获取和控制 AI 角色的导航行为。
-
targetPosition: 一个 Vector3 类型的私有变量,用于存储 AI 角色当前巡逻的目标位置。
1.5 Start 方法
void Start()
{agent = GetComponent<NavMeshAgent>();SetRandomPatrolPoint();
}
Start 方法在游戏开始时被调用。
-
agent = GetComponent(): 获取附加在该游戏对象上的 NavMeshAgent 组件,并将其赋值给 agent 变量。
-
SetRandomPatrolPoint(): 调用 SetRandomPatrolPoint 方法,初始化 AI 的巡逻目标点。
1.6 Update 方法
void Update()
{if (!agent.pathPending && agent.remainingDistance < 0.5f){StartCoroutine(PatrolWait());}
}
Update 方法在每一帧被调用。
-
if (!agent.pathPending && agent.remainingDistance < 0.5f): 检查 AI 角色是否已经到达目标位置(remainingDistance 小于 0.5 表示接近目标)。pathPending 表示当前是否还有路径计算未完成。
-
StartCoroutine(PatrolWait()): 如果到达目标位置,则启动一个协程,调用 PatrolWait 方法。
1.7 设置随机巡逻点的逻辑
void SetRandomPatrolPoint()
{Vector3 randomDirection = Random.insideUnitSphere * patrolRadius;randomDirection += centerPoint.position;NavMeshHit hit;NavMesh.SamplePosition(randomDirection, out hit, patrolRadius, 1);targetPosition = hit.position;agent.SetDestination(targetPosition);
}
-
Vector3 randomDirection = Random.insideUnitSphere * patrolRadius;: 生成一个在球体内的随机方向,并乘以 patrolRadius,以得到一个随机方向的偏移量。
-
randomDirection += centerPoint.position;: 将随机偏移量添加到巡逻中心点的坐标,确定目标位置。
-
NavMeshHit hit;: 声明一个 NavMeshHit 变量,用于接收导航网格采样结果。
-
NavMesh.SamplePosition(randomDirection, out hit, patrolRadius, 1);: 在 randomDirection 位置附近采样,找到一个有效的导航网格位置,并将结果存储在 hit 中。
-
targetPosition = hit.position;: 将有效的目标位置赋值给 targetPosition。
-
agent.SetDestination(targetPosition);: 将 AI 角色的目标位置设置为新的巡逻点,使其开始移动。
1.8 巡逻等待的协程
IEnumerator PatrolWait()
{yield return new WaitForSeconds(patrolWaitTime);SetRandomPatrolPoint();
}
-
IEnumerator PatrolWait(): 定义一个协程方法,允许使用 yield return。
-
yield return new WaitForSeconds(patrolWaitTime);: 暂停协程执行,等待 patrolWaitTime 秒。
-
SetRandomPatrolPoint();: 等待结束后,调用 SetRandomPatrolPoint 方法,设置新的巡逻目标点。
1.9 巡逻功能总结
这段代码实现了一个 AI 角色在指定中心点周围巡逻的行为。它会在每个目标点停留一定时间后,再随机选择新的目标点,并利用 Unity 的导航系统(NavMesh)来处理移动。这样可以创建一个简单的巡逻行为,适用于 NPC(非玩家角色)在游戏中的导航。
2. 发现敌人:
在巡逻过程中,如果在一定范围内发现敌人(使用 Physics.OverlapSphere 或者 Physics.Raycast),预制体会停止巡逻并向敌人移动。
public class DetectEnemy : MonoBehaviour
{public float detectionRadius = 15f; // 发现敌人的范围public LayerMask enemyLayer; // 敌人的图层private GameObject enemyTarget;void Update(){Collider[] hitColliders = Physics.OverlapSphere(transform.position, detectionRadius, enemyLayer);if (hitColliders.Length > 0){enemyTarget = hitColliders[0].gameObject;MoveToEnemy();}}void MoveToEnemy(){NavMeshAgent agent = GetComponent<NavMeshAgent>();agent.SetDestination(enemyTarget.transform.position);}
}
这段 Unity 脚本代码实现了一个 AI 角色检测敌人并朝向敌人移动的功能。下面是对代码逐行的解释:
2.1 类声明
public class DetectEnemy : MonoBehaviour
定义一个名为 DetectEnemy 的公共类,继承自 MonoBehaviour。这意味着该类可以被附加到 Unity 中的游戏对象,并能够使用 Unity 的生命周期方法。
2.2 声明公共变量
public float detectionRadius = 15f; // 发现敌人的范围
public LayerMask enemyLayer; // 敌人的图层
-
detectionRadius: 一个公共变量,类型为 float,用于定义 AI 角色检测敌人的半径,默认为 15。
-
enemyLayer: 一个公共变量,类型为 LayerMask,用于指定哪些图层被视为敌人。这使得该 AI 角色能够仅检测特定类型的对象。
2.3 声明私有变量
private GameObject enemyTarget;
- enemyTarget: 一个私有变量,类型为 GameObject,用于存储检测到的敌人对象的引用。
2.4 Update 方法
void Update()
{Collider[] hitColliders = Physics.OverlapSphere(transform.position, detectionRadius, enemyLayer);if (hitColliders.Length > 0){enemyTarget = hitColliders[0].gameObject;MoveToEnemy();}
}
Update 方法在每一帧被调用,用于检查和更新 AI 角色的状态。
-
Collider[] hitColliders = Physics.OverlapSphere(transform.position, detectionRadius, enemyLayer);: 使用 Physics.OverlapSphere 方法在 AI 角色的位置(transform.position)周围创建一个球体,以 detectionRadius 为半径,检测所有与 enemyLayer 图层相交的碰撞体(即敌人)。返回的碰撞体存储在 hitColliders 数组中。
-
if (hitColliders.Length > 0): 检查是否检测到了任何敌人(即 hitColliders 数组的长度是否大于 0)。
-
enemyTarget = hitColliders[0].gameObject;: 如果检测到敌人,获取第一个敌人的引用,并将其赋值给 enemyTarget 变量。
-
MoveToEnemy();: 调用 MoveToEnemy 方法,指示 AI 角色朝向敌人移动。
2.5 MoveToEnemy 方法
void MoveToEnemy()
{NavMeshAgent agent = GetComponent<NavMeshAgent>();agent.SetDestination(enemyTarget.transform.position);
}
-
void MoveToEnemy(): 定义一个私有方法,用于处理朝向敌人移动的逻辑。
-
NavMeshAgent agent = GetComponent();: 获取附加在该游戏对象上的 NavMeshAgent 组件,并将其赋值给 agent 变量,以便使用导航功能。
-
agent.SetDestination(enemyTarget.transform.position);: 将 AI 角色的目标位置设置为 enemyTarget(即敌人)的当前位置,使 AI 角色开始向敌人移动。
2.6 发现敌人总结
这段代码实现了一个基本的敌人检测系统,允许 AI 角色在指定半径内检测到敌人,并朝向第一个检测到的敌人移动。它利用 Unity 的物理系统(Physics.OverlapSphere)和导航系统(NavMeshAgent)来实现这一功能。这个脚本可以用于游戏中 AI 角色的敌人追踪行为。
3. 攻击敌人:
当预制体靠近敌人一定距离时,执行攻击动作。
public class AttackEnemy : MonoBehaviour
{public float attackRange = 2f; // 攻击范围public float attackCooldown = 1.5f; // 攻击冷却时间private float lastAttackTime;void Update(){if (enemyTarget != null && Vector3.Distance(transform.position, enemyTarget.transform.position) <= attackRange){if (Time.time >= lastAttackTime + attackCooldown){Attack();lastAttackTime = Time.time;}}}void Attack(){// 攻击行为,例如减去敌人生命值Debug.Log("Attacking the enemy!");}
}
这段 Unity 脚本代码实现了一个 AI 角色攻击敌人的功能。下面是对代码逐行的解释:
3.1 类声明
public class AttackEnemy : MonoBehaviour
定义一个名为 AttackEnemy 的公共类,继承自 MonoBehaviour。这意味着该类可以被附加到 Unity 的游戏对象上,并能够使用 Unity 的生命周期方法。
3.2 声明公共变量
public float attackRange = 2f; // 攻击范围
public float attackCooldown = 1.5f; // 攻击冷却时间
-
attackRange: 一个公共变量,类型为 float,用于定义 AI 角色攻击的有效范围,默认为 2(单位通常为米)。
-
attackCooldown: 一个公共变量,类型为 float,用于定义攻击之间的冷却时间,默认为 1.5 秒。
3.3. 声明私有变量
private float lastAttackTime;
- lastAttackTime: 一个私有变量,类型为 float,用于记录上一次攻击的时间。这有助于管理攻击的冷却时间。
3.4. Update 方法
void Update()
{if (enemyTarget != null && Vector3.Distance(transform.position, enemyTarget.transform.position) <= attackRange){if (Time.time >= lastAttackTime + attackCooldown){Attack();lastAttackTime = Time.time;}}
}
Update 方法在每一帧被调用,用于检查 AI 角色的攻击条件。
- if (enemyTarget != null && Vector3.Distance(transform.position, enemyTarget.transform.position) <= attackRange):
首先检查 enemyTarget 是否为 null,确保 AI 角色已经有目标。
使用 Vector3.Distance 方法计算 AI 角色与敌人之间的距离。如果距离小于或等于 attackRange,则表示敌人在攻击范围内。
-
if (Time.time >= lastAttackTime + attackCooldown): 检查当前时间是否大于等于上一次攻击时间加上冷却时间。如果满足条件,表示可以进行下一次攻击。
-
Attack();: 调用 Attack 方法,执行攻击动作。
-
lastAttackTime = Time.time;: 更新 lastAttackTime 为当前时间,以记录本次攻击的时间。
3.5 Attack 方法
void Attack()
{// 攻击行为,例如减去敌人生命值Debug.Log("Attacking the enemy!");
}
- void Attack(): 定义一个私有方法,用于处理攻击行为。
在方法中,通过 Debug.Log 输出信息,表示正在攻击敌人。这一行代码只是示例,实际游戏中可以替换为减少敌人生命值、播放攻击动画、音效等攻击逻辑。
3.6 攻击敌人总结
这段代码实现了 AI 角色在一定范围内检测敌人并进行攻击的功能。它使用冷却机制来控制攻击的频率,确保 AI 不会在攻击之间过于频繁地进行攻击。这个脚本可以与敌人检测和移动脚本结合使用,以实现完整的 AI 行为模式。
4. 整合逻辑:
将巡逻、发现敌人和攻击的逻辑整合在一个脚本或通过多个脚本管理,使得预制体能在巡逻、发现敌人、追逐敌人和攻击之间进行状态切换。你可以使用状态机来更清晰地管理这些状态的切换。
public enum AIState { Patrol, Chase, Attack }
public AIState currentState = AIState.Patrol;void Update()
{switch (currentState){case AIState.Patrol:Patrol();if (DetectEnemy())currentState = AIState.Chase;break;case AIState.Chase:ChaseEnemy();if (IsInAttackRange())currentState = AIState.Attack;break;case AIState.Attack:AttackEnemy();if (!IsInAttackRange())currentState = AIState.Chase;break;}
}
这段 Unity 脚本代码实现了一个简单的 AI 状态机,用于控制 AI 角色在不同状态下的行为。这种设计模式可以帮助开发者管理复杂的角色行为,使其在不同情境下表现出不同的反应。以下是对代码逐行的解释:
4.1 定义枚举类型
public enum AIState { Patrol, Chase, Attack }
public enum AIState: 定义一个公共枚举类型 AIState,用于表示 AI 角色的不同状态。
-
枚举包含三个状态:
-
Patrol: 巡逻状态。
-
Chase: 追逐状态。
-
Attack: 攻击状态。
4.2 声明当前状态
public AIState currentState = AIState.Patrol;
public AIState currentState: 声明一个公共变量 currentState,用于存储 AI 角色的当前状态。
- = AIState.Patrol: 初始化 currentState 为 Patrol,表示 AI 角色开始时处于巡逻状态。
4.3 Update 方法
void Update()
{switch (currentState){case AIState.Patrol:Patrol();if (DetectEnemy())currentState = AIState.Chase;break;case AIState.Chase:ChaseEnemy();if (IsInAttackRange())currentState = AIState.Attack;break;case AIState.Attack:AttackEnemy();if (!IsInAttackRange())currentState = AIState.Chase;break;}
}
Update 方法在每一帧被调用,用于检查并执行 AI 角色的行为。
- switch (currentState): 根据 currentState 的值,执行不同的代码块。
4.3.1 巡逻状态
case AIState.Patrol:Patrol();if (DetectEnemy())currentState = AIState.Chase;break;
-
Patrol();: 调用 Patrol 方法,执行巡逻行为。
-
if (DetectEnemy()): 检测是否发现敌人,如果发现,切换状态为 Chase(追逐)。
4.3.2 追逐状态
case AIState.Chase:ChaseEnemy();if (IsInAttackRange())currentState = AIState.Attack;break;
-
ChaseEnemy();: 调用 ChaseEnemy 方法,执行追逐敌人的行为。
-
if (IsInAttackRange()): 检查是否在攻击范围内,如果是,切换状态为 Attack(攻击)。
4.3.3 攻击状态
case AIState.Attack:AttackEnemy();if (!IsInAttackRange())currentState = AIState.Chase;break;
-
AttackEnemy();: 调用 AttackEnemy 方法,执行攻击行为。
-
if (!IsInAttackRange()): 检查是否不再处于攻击范围内。如果不在攻击范围内,切换状态为 Chase(追逐),重新开始追逐敌人。
4.4 整合逻辑总结
这段代码实现了一个简单的 AI 状态机,使得 AI 角色能够根据当前的状态执行相应的行为:巡逻、追逐或攻击敌人。通过使用状态机,AI 能够更灵活地管理行为,便于扩展和维护。具体的巡逻、追逐和攻击行为需要在其他方法(如 Patrol、ChaseEnemy 和 AttackEnemy)中实现。
总结
通过使用Unity中的NavMeshAgent实现预制体的随机巡逻,结合Physics.OverlapSphere检测敌人并触发追击状态,以及在距离足够近时执行攻击动作,我们成功地实现了预制体的自动化行为。通过合理的状态切换逻辑管理预制体的行为,我们为游戏角色赋予了智能和自主性,使其能够在游戏世界中自主探索、发现敌人并进行攻击。这种综合应用不仅提升了游戏的交互性和挑战性,也为开发者们提供了实现自动化行为的有效方法,为游戏开发注入了新的活力和可能性。
码文不易,本篇文章就介绍到这里,如果想要学习更多Java系列知识,点击关注博主,博主带你零基础学习Java知识。与此同时,对于日常生活有困扰的朋友,欢迎阅读我的第四栏目:《国学周更—心性养成之路》,学习技术的同时,我们也注重了心性的养成。
相关文章:

Unity中实现预制体自动巡逻与攻击敌人的完整实现指南
✅作者简介:2022年博客新星 第八。热爱国学的Java后端开发者,修心和技术同步精进。 🍎个人主页:Java Fans的博客 🍊个人信条:不迁怒,不贰过。小知识,大智慧。 💞当前专栏…...
OpenJudge | Shortest Prefixes
总时间限制: 1000ms 内存限制: 65536kB 描述 A prefix of a string is a substring starting at the beginning of the given string. The prefixes of “carbon” are: “c”, “ca”, “car”, “carb”, “carbo”, and “carbon”. Note that the empty string is not co…...
速盾:高防服务器是如何防御CC攻击的?
高防服务器是一种专门用于防御DDoS(分布式拒绝服务)攻击的服务器。其中一种常见的DDoS攻击就是CC(连续性攻击),它通过向目标服务器发送大量的请求来耗尽服务器资源,使网站无法正常运行。高防服务器采用多种…...

Android阶段学习思维导图
前言 记录下自己做的一个对Android原生应用层的思维导图,方便个人记忆扩展;这里只露出二级标题。 后语 虽然有些内容只是初步了解,但还是记录了下来;算是对过去一段学习的告别。...
React生命周期案例详解
React 组件的生命周期是指组件从创建、渲染、更新到卸载的整个过程。在 React 16 及之前的版本中,生命周期方法被分为几个不同的阶段:挂载(Mounting)、更新(Updating)、卸载(Unmounting…...

【ubuntu】ubuntu20.04安装显卡驱动
1.安装 点击右下角Apply Changes。 等安装好之后,重启。 现在的nvidia驱动已经很好安装了,比早期时安装出现黑屏等情况好了很多。 2.验证 nvidia-smi...
Mongo Java Driver使用getCollection做分页查询遇到的一些坑
背景 最近在做Mongo上的表数据的迁移,原本应该是DBA要干的活,但是想着DBA排期比较长,加上我们开发的权限又非常有限,而且数据量又没有多少,就想着自己开发个小小的程序从旧实例上查,写到新实例上去算了。于…...

RK3568笔记六十四:SG90驱动测试
若该文为原创文章,转载请注明原文出处。 前面有测试过PWM驱动,现在使用两种方式来产生PWM驱动SG90,实现舵机旋转任意角度 方法一:使用硬件PWM 方法二:使用高精度定时器,GPIO模拟PWM. 一、PWM子系统框架 二、SG90控制方法 舵机的控制需要MCU产生一个周期为20ms的脉冲信号…...

31 基于51单片机的水位监测系统仿真
目录 一、主要功能 二、硬件资源 三、程序编程 四、实现现象 一、主要功能 基于51单片机,DHT11温湿度检测,水位检测,通过LCD1602显示,超过阈值报警,继电器驱动电机转动。通过矩阵按键切换选择设置各项参数阈值。 …...
Docker 实践与应用举例
一、容器化Web应用: 创建一个Docker容器来运行一个简单的Web应用,例如一个基于Node.js的Express应用。首先,编写Dockerfile来定义容器的构建过程,然后使用Docker命令来构建和运行容器。 使用Docker Compose来定义和管理多个容器组…...

公开数据集网站分享
参考链接:常用的医学组织切片细胞图像数据集_细胞分割数据集-CSDN博客文章浏览阅读1.3w次,点赞32次,收藏133次。乳腺癌细胞图像数据集、血细胞图像数据集、HE染色切片、疟疾细胞图像图像识别、分类、分割_细胞分割数据集https://blog.csdn.ne…...

实验OSPF路由协议(课内实验)
实验1:OSPF路由协议 实验目的及要求: 通过实验,能够理解链路状态型路由协议OSPF协议的工作原理,掌握如何实现单区域 OSPFv2配置指令,能够熟练的应用各种OSPF协议相关的配置指令完善网络设计。掌握验证OSPFv2网络连接…...

GPU Puzzles讲解(一)
GPU-Puzzles项目可以让你学习到GPU编程和cuda核心并行编程的概念,通过一个个小问题让你理解cuda的编程和调用,创建共享显存空间,实现卷积和矩阵乘法等,通过每个小问题之后还会奖励一个狗狗小视频😁 下面是项目的仓库&…...
滚雪球学Oracle[1.3讲]:内存与进程架构
全文目录: 前言一、SGA的深度解析1.1 SGA的作用与构成SGA的大小与调整 1.2 数据库缓冲区缓存(DB Cache)DB Cache的工作原理案例演示:调整DB Cache的大小 1.3 共享池(Shared Pool)的构成与调优共享池的组成部…...

Nginx的正向与反向代理
一、Nginx简介 1. 什么是Nginx Nginx(发音为“engine-x”)是一个高性能的HTTP和反向代理服务器,同时也是一个IMAP/POP3/SMTP代理服务器。Nginx是由俄罗斯的Igor Sysoev(伊戈尔赛索耶夫)为解决C10k问题(即…...

esp8266 at指令链接wifi时一直connect disconnest
那是你的连接wifi的名字密码有误或者热点有问题,看看热点是不是把设备拉入黑名单或者设置为5G或者连了校园网或者设置了最多链接设备...

基于SpringBoot博物馆游客预约系统【附源码】
基于SpringBoot博物馆游客预约系统 效果如下: 主页面 注册界面 展品信息界面 论坛交流界面 后台登陆界面 后台主界面 参观预约界面 留言板界面 研究背景 随着现代社会的快速发展和人们生活水平的提高,文化生活需求也在日益增加。博物馆作为传承文化、…...

【JVM】内存区域划分,类加载的过程,.class文件的格式
一个java写的程序,跑起来就得到了一个java进程,而java进程=JVM上面运行的字节码指令 JVM是「java虚拟机」,负责解释执行java的指令 【JVM内存区域划分】 1.程序计数器(比较小的空间) 作用:保存了下一条…...
esp32-camera入门(基于ESP-IDF)
主要参考资料: ESP32-S2 Kaluga camera lcd 示例入门: https://blog.csdn.net/Marchtwentytwo/article/details/121121028 摄像头应用方案常见问题汇总: https://docs.espressif.com/projects/esp-faq/zh_CN/latest/application-solution/camera-application.html …...
react中类式组件与函数式组件的区别
在React中,类式组件(Class Components)与函数式组件(Functional Components)是两种不同的组件定义方式,它们各有特点,适用于不同的场景。以下是它们之间的主要区别: 一、定义与语法…...

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真
目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销,平衡网络负载,延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...
React hook之useRef
React useRef 详解 useRef 是 React 提供的一个 Hook,用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途,下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...

JavaScript 中的 ES|QL:利用 Apache Arrow 工具
作者:来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗?了解下一期 Elasticsearch Engineer 培训的时间吧! Elasticsearch 拥有众多新功能,助你为自己…...

Day131 | 灵神 | 回溯算法 | 子集型 子集
Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣(LeetCode) 思路: 笔者写过很多次这道题了,不想写题解了,大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...
在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module
1、为什么要修改 CONNECT 报文? 多租户隔离:自动为接入设备追加租户前缀,后端按 ClientID 拆分队列。零代码鉴权:将入站用户名替换为 OAuth Access-Token,后端 Broker 统一校验。灰度发布:根据 IP/地理位写…...

【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力
引言: 在人工智能快速发展的浪潮中,快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型(LLM)。该模型代表着该领域的重大突破,通过独特方式融合思考与非思考…...

ServerTrust 并非唯一
NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...

HDFS分布式存储 zookeeper
hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架,允许使用简单的变成模型跨计算机对大型集群进行分布式处理(1.海量的数据存储 2.海量数据的计算)Hadoop核心组件 hdfs(分布式文件存储系统)&a…...
JS设计模式(4):观察者模式
JS设计模式(4):观察者模式 一、引入 在开发中,我们经常会遇到这样的场景:一个对象的状态变化需要自动通知其他对象,比如: 电商平台中,商品库存变化时需要通知所有订阅该商品的用户;新闻网站中࿰…...

C++:多态机制详解
目录 一. 多态的概念 1.静态多态(编译时多态) 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1).协变 2).析构函数的重写 5.override 和 final关键字 1&#…...