UE5多人MOBA+GAS 18、用对象池来设置小兵的队伍的生成,为小兵设置一个目标从己方出生点攻打对方出生点,优化小兵的血条UI

文章目录

  • 根据小兵队伍更换小兵的皮肤
  • 管理小兵的生成
    • 使用对象池来管理小兵的生成
  • 为小兵设置一个目标
  • 小兵生成完整代码
  • 调整一下小兵的UI


根据小兵队伍更换小兵的皮肤

懒得开UE了,增加一个Minion类继承基类角色CCharacter
在这里插入图片描述

// 幻雨喜欢小猫咪#pragma once#include "CoreMinimal.h"
#include "Character/CCharacter.h"
#include "Minion.generated.h"/*** 小兵AI角色类,继承自ACCharacter* 负责小兵的队伍分配、激活状态、目标设置、皮肤切换等功能*/
UCLASS()
class CRUNCH_API AMinion : public ACCharacter
{GENERATED_BODY()public:virtual void SetGenericTeamId(const FGenericTeamId& NewTeamId) override;
private:// 根据队伍ID切换小兵皮肤void PickSkinBasedOnTeamID();// 队伍ID同步时回调(用于网络同步后自动切换皮肤等)virtual void OnRep_TeamID() override;// 队伍ID到对应皮肤的映射表UPROPERTY(EditDefaultsOnly, Category = "Visual")TMap<FGenericTeamId, TObjectPtr<USkeletalMesh>> SkinMap;
};
// 幻雨喜欢小猫咪#include "Minion.h"void AMinion::SetGenericTeamId(const FGenericTeamId& NewTeamId)
{Super::SetGenericTeamId(NewTeamId);PickSkinBasedOnTeamID();
}void AMinion::PickSkinBasedOnTeamID()
{TObjectPtr<USkeletalMesh>* Skin = SkinMap.Find(GetGenericTeamId());if (Skin){GetMesh()->SetSkeletalMesh(*Skin);}
}void AMinion::OnRep_TeamID()
{PickSkinBasedOnTeamID();
}

打开小兵角色蓝图,修改父类
在这里插入图片描述
设置一下皮肤
在这里插入图片描述
换一个原始皮肤
在这里插入图片描述

管理小兵的生成

继承Actor,命名为MinionBarrack,用来管理小兵的生成
在这里插入图片描述
在这里插入图片描述

// 幻雨喜欢小猫咪#pragma once#include "CoreMinimal.h"
#include "GenericTeamAgentInterface.h"
#include "Minion.h"
#include "GameFramework/Actor.h"
#include "MinionBarrack.generated.h"/*** 小兵兵营类,负责批量生成和管理小兵* 支持队伍分配、目标设置、定时批量生成等功能*/
UCLASS()
class AMinionBarrack : public AActor
{GENERATED_BODY()public:	AMinionBarrack();protected:virtual void BeginPlay() override;public:	virtual void Tick(float DeltaTime) override;private:// 兵营所属队伍IDUPROPERTY(EditAnywhere, Category = "Spawn", meta = (DisplayName = "队伍ID"))FGenericTeamId BarrackTeamId;// 每组小兵生成的数量UPROPERTY(EditAnywhere, Category = "Spawn", meta = (DisplayName = "每组小兵生成的数量"))int32 MinionPerGroup = 3;// 兵营的生成间隔UPROPERTY(EditAnywhere, Category = "Spawn", meta = (DisplayName = "小兵生成间隔"))float GroupSpawnInterval = 5.f;// 小兵对象池UPROPERTY()TArray<TObjectPtr<AMinion>> MinionPool;// 小兵的目标点(如推进目标)UPROPERTY(EditAnywhere, Category = "Spawn", meta = (DisplayName = "小兵的目标点"))TObjectPtr<AActor> Goal;// 小兵的类(用于生成小兵实例)UPROPERTY(EditAnywhere, Category = "Spawn", meta = (DisplayName = "小兵的类"))TSubclassOf<AMinion> MinionClass;// 生成小兵的出生点列表UPROPERTY(EditAnywhere, Category = "Spawn", meta = (DisplayName = "生成小兵的出生点列表"))TArray<APlayerStart*> SpawnSpots;// 下一个出生点索引int32 NextSpawnSpotIndex = -1;// 获取下一个出生点(轮流分配)const APlayerStart* GetNextSpawnSpot();// 生成指定数量新小兵void SpawnNewMinions(int Amt);};

void AMinionBarrack::BeginPlay()
{Super::BeginPlay();// 测试用SpawnNewMinions(5);
}const APlayerStart* AMinionBarrack::GetNextSpawnSpot()
{if (SpawnSpots.Num() == 0) return nullptr;++NextSpawnSpotIndex;if (NextSpawnSpotIndex >= SpawnSpots.Num()){NextSpawnSpotIndex = 0;}// 返回出生点return SpawnSpots[NextSpawnSpotIndex];
}void AMinionBarrack::SpawnNewMinions(int Amt)
{if (Amt <= 0) return;for (int32 i = 0; i < Amt; ++i){// 获取出生点变换FTransform SpawnTransform = GetActorTransform();// 获取下一个出生点if (const APlayerStart* NextSpawnSpot = GetNextSpawnSpot()){SpawnTransform = NextSpawnSpot->GetActorTransform();}// 生成小兵AMinion* NewMinion = GetWorld()->SpawnActorDeferred<AMinion>(MinionClass, SpawnTransform, this, nullptr, ESpawnActorCollisionHandlingMethod::AdjustIfPossibleButAlwaysSpawn);// 设置小兵的队伍IDNewMinion->SetGenericTeamId(BarrackTeamId);// 完成小兵的生成NewMinion->FinishSpawning(SpawnTransform);// NewMinion->SetGoal(Goal);// 添加小兵到小兵池中MinionPool.Add(NewMinion);}
}

在这里插入图片描述

放到场景中点击吸管再点击这个场景的出生点,来出生
在这里插入图片描述
然后你会发现怪叠了两层,应该是服务器和客户端都生成了,在生成处加个权威
在这里插入图片描述

使用对象池来管理小兵的生成

在角色基类CCharacter中添加判断死亡函数和移除死亡标签函数

#pragma region 死亡和复活 (Death and Respawn)
public:bool IsDead() const;void RespawnImmediately();
private:
#pragma endregion
bool ACCharacter::IsDead() const
{return GetAbilitySystemComponent()->HasMatchingGameplayTag(TGameplayTags::Stats_Dead);
}void ACCharacter::RespawnImmediately()
{// 仅在服务器上执行:移除所有带有“死亡”标签的激活效果,实现立即复活if (HasAuthority()){GetAbilitySystemComponent()->RemoveActiveEffectsWithGrantedTags(FGameplayTagContainer(TGameplayTags::Stats_Dead));}
}void ACCharacter::DeathMontageFinished()
{if (IsDead()){SetRagdollEnabled(true);}
}

到小兵角色类中添加判断小兵是否激活的函数

public:// 判断小兵是否处于激活状态bool IsActive() const;// 激活小兵(如复活、生成时调用)void Activate();
bool AMinion::IsActive() const
{return !IsDead();
}void AMinion::Activate()
{// 移除死亡标签,复活RespawnImmediately();
}
UCLASS()
class AMinionBarrack : public AActor
{GENERATED_BODY()
private:// 生成一组小兵(优先用对象池)void SpawnNewGroup();// 从池中获取可用小兵AMinion* GetNextAvailableMinion() const;// 生成组的定时器句柄FTimerHandle SpawnIntervalTimerHandle;
};
void AMinionBarrack::BeginPlay()
{Super::BeginPlay();// 仅在服务器上定时生成小兵if (HasAuthority()){// 设置定时器,定时批量生成小兵GetWorldTimerManager().SetTimer(SpawnIntervalTimerHandle, this, &AMinionBarrack::SpawnNewGroup, GroupSpawnInterval, true);}
}void AMinionBarrack::SpawnNewGroup()
{// 需要生成的小兵数量int32 i = MinionPerGroup;while (i > 0){// 获取出生点变换FTransform SpawnTransform = GetActorTransform();// 获取下一个出生点if (const APlayerStart* NextSpawnSpot = GetNextSpawnSpot()){SpawnTransform = NextSpawnSpot->GetActorTransform();}// 优先复用对象池中的非激活小兵AMinion* NextAvailableMinion = GetNextAvailableMinion();// 对象池内没有可以用的小兵了就退出循环,生成一个新的小兵if (!NextAvailableMinion) break;NextAvailableMinion->SetActorTransform(SpawnTransform);NextAvailableMinion->Activate();--i;}// 如果对象池不够,则新建剩余数量的小兵SpawnNewMinions(i);
}AMinion* AMinionBarrack::GetNextAvailableMinion() const
{for (AMinion* Minion : MinionPool){if (!Minion->IsActive()){return Minion;}}return nullptr;
}

想必以及发现了AI小兵的颜色跟自己设置的队伍颜色有点不对劲了吧,在AI控制器那里,已经强行设置了一个队伍ID.

void ACAIController::OnPossess(APawn* InPawn)
{Super::OnPossess(InPawn);IGenericTeamAgentInterface* PawnTeamInterface = Cast<IGenericTeamAgentInterface>(InPawn);if (PawnTeamInterface){SetGenericTeamId(PawnTeamInterface->GetGenericTeamId());ClearAndDisableAllSenses();EnableAllSenses();}UAbilitySystemComponent* PawnASC = UAbilitySystemBlueprintLibrary::GetAbilitySystemComponent(InPawn);if (PawnASC){PawnASC->RegisterGameplayTagEvent(TGameplayTags::Stats_Dead, EGameplayTagEventType::NewOrRemoved).AddUObject(this, &ACAIController::PawnDeadTagUpdated);}
}

创建一个持续时间为无限的死亡GE
在这里插入图片描述
把他给小兵用上
在这里插入图片描述
打死小兵之后的尸体消失,就是在对象池中复活了。

为小兵设置一个目标

public:// 设置小兵的目标(如推进目标、攻击目标等)void SetGoal(AActor* Goal);
private:// 黑板中用于存储目标的Key名UPROPERTY(EditDefaultsOnly, Category = "AI")FName GoalBlackboardKeyName = "Goal";
void AMinion::SetGoal(AActor* Goal)
{if (AAIController* AIController = GetController<AAIController>()){if (UBlackboardComponent* BlackboardComponent = AIController->GetBlackboardComponent()){// 修改黑板组件中对应键目标的值BlackboardComponent->SetValueAsObject(GoalBlackboardKeyName, Goal);}}
}

创建小兵的时候为其设置该键的值

void AMinionBarrack::SpawnNewMinions(int Amt)
{if (Amt <= 0) return;for (int32 i = 0; i < Amt; ++i){// 获取出生点变换FTransform SpawnTransform = GetActorTransform();// 获取下一个出生点if (const APlayerStart* NextSpawnSpot = GetNextSpawnSpot()){SpawnTransform = NextSpawnSpot->GetActorTransform();}// 生成小兵AMinion* NewMinion = GetWorld()->SpawnActorDeferred<AMinion>(MinionClass, SpawnTransform, this, nullptr, ESpawnActorCollisionHandlingMethod::AdjustIfPossibleButAlwaysSpawn);// 设置小兵的队伍IDNewMinion->SetGenericTeamId(BarrackTeamId);// 完成小兵的生成NewMinion->FinishSpawning(SpawnTransform);// 设置小兵的目标NewMinion->SetGoal(Goal);// 添加小兵到小兵池中MinionPool.Add(NewMinion);}
}

到黑板中创建该健
在这里插入图片描述
可以让AI走向设定的目标
在这里插入图片描述
添加黑板装饰器
在这里插入图片描述
在值改变的时候就会重启行为树,不去追击设定的目标,转来打发现的敌人
在这里插入图片描述

目标跟小兵出生点一点,通过吸管吸取场景的物品
在这里插入图片描述
小兵发现你后就会来打你了
在这里插入图片描述

小兵生成完整代码

// 幻雨喜欢小猫咪#pragma once#include "CoreMinimal.h"
#include "GenericTeamAgentInterface.h"
#include "Minion.h"
#include "GameFramework/Actor.h"
#include "MinionBarrack.generated.h"/*** 小兵兵营类,负责批量生成和管理小兵* 支持队伍分配、目标设置、定时批量生成等功能*/
UCLASS()
class AMinionBarrack : public AActor
{GENERATED_BODY()public:	// Sets default values for this actor's propertiesAMinionBarrack();protected:// Called when the game starts or when spawnedvirtual void BeginPlay() override;public:	// Called every framevirtual void Tick(float DeltaTime) override;private:// 兵营所属队伍IDUPROPERTY(EditAnywhere, Category = "Spawn", meta = (DisplayName = "队伍ID"))FGenericTeamId BarrackTeamId;// 每组小兵生成的数量UPROPERTY(EditAnywhere, Category = "Spawn", meta = (DisplayName = "每组小兵生成的数量"))int32 MinionPerGroup = 5;// 兵营的生成间隔UPROPERTY(EditAnywhere, Category = "Spawn", meta = (DisplayName = "小兵生成间隔"))float GroupSpawnInterval = 15.f;// 小兵对象池UPROPERTY()TArray<TObjectPtr<AMinion>> MinionPool;// 小兵的目标点(如推进目标)UPROPERTY(EditAnywhere, Category = "Spawn", meta = (DisplayName = "小兵的目标点"))TObjectPtr<AActor> Goal;// 小兵的类(用于生成小兵实例)UPROPERTY(EditAnywhere, Category = "Spawn", meta = (DisplayName = "小兵的类"))TSubclassOf<AMinion> MinionClass;// 生成小兵的出生点列表UPROPERTY(EditAnywhere, Category = "Spawn", meta = (DisplayName = "生成小兵的出生点列表"))TArray<APlayerStart*> SpawnSpots;// 下一个出生点索引int32 NextSpawnSpotIndex = -1;// 获取下一个出生点(轮流分配)const APlayerStart* GetNextSpawnSpot();// 生成一组小兵(优先用对象池)void SpawnNewGroup();// 生成指定数量新小兵void SpawnNewMinions(int Amt);// 从池中获取可用小兵AMinion* GetNextAvailableMinion() const;// 生成组的定时器句柄FTimerHandle SpawnIntervalTimerHandle;
};
// 幻雨喜欢小猫咪#include "AI/MinionBarrack.h"#include "GameFramework/PlayerStart.h"// Sets default values
AMinionBarrack::AMinionBarrack()
{// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.PrimaryActorTick.bCanEverTick = true;}// Called when the game starts or when spawned
void AMinionBarrack::BeginPlay()
{Super::BeginPlay();// 仅在服务器上定时生成小兵if (HasAuthority()){// 设置定时器,定时批量生成小兵GetWorldTimerManager().SetTimer(SpawnIntervalTimerHandle, this, &AMinionBarrack::SpawnNewGroup, GroupSpawnInterval, true);}
}// Called every frame
void AMinionBarrack::Tick(float DeltaTime)
{Super::Tick(DeltaTime);}const APlayerStart* AMinionBarrack::GetNextSpawnSpot()
{if (SpawnSpots.Num() == 0) return nullptr;++NextSpawnSpotIndex;if (NextSpawnSpotIndex >= SpawnSpots.Num()){NextSpawnSpotIndex = 0;}// 返回出生点return SpawnSpots[NextSpawnSpotIndex];
}void AMinionBarrack::SpawnNewGroup()
{// 需要生成的小兵数量int32 i = MinionPerGroup;while (i > 0){// 获取出生点变换FTransform SpawnTransform = GetActorTransform();// 获取下一个出生点if (const APlayerStart* NextSpawnSpot = GetNextSpawnSpot()){SpawnTransform = NextSpawnSpot->GetActorTransform();}// 优先复用对象池中的非激活小兵AMinion* NextAvailableMinion = GetNextAvailableMinion();// 对象池内没有可以用的小兵了就退出循环,生成一个新的小兵if (!NextAvailableMinion) break;NextAvailableMinion->SetActorTransform(SpawnTransform);NextAvailableMinion->Activate();--i;}// 如果对象池不够,则新建剩余数量的小兵SpawnNewMinions(i);
}void AMinionBarrack::SpawnNewMinions(int Amt)
{if (Amt <= 0) return;for (int32 i = 0; i < Amt; ++i){// 获取出生点变换FTransform SpawnTransform = GetActorTransform();// 获取下一个出生点if (const APlayerStart* NextSpawnSpot = GetNextSpawnSpot()){SpawnTransform = NextSpawnSpot->GetActorTransform();}// 生成小兵AMinion* NewMinion = GetWorld()->SpawnActorDeferred<AMinion>(MinionClass, SpawnTransform, this, nullptr, ESpawnActorCollisionHandlingMethod::AdjustIfPossibleButAlwaysSpawn);// 设置小兵的队伍IDNewMinion->SetGenericTeamId(BarrackTeamId);// 完成小兵的生成NewMinion->FinishSpawning(SpawnTransform);// 设置小兵的目标NewMinion->SetGoal(Goal);// 添加小兵到小兵池中MinionPool.Add(NewMinion);}
}AMinion* AMinionBarrack::GetNextAvailableMinion() const
{for (AMinion* Minion : MinionPool){if (!Minion->IsActive()){return Minion;}}return nullptr;
}

调整一下小兵的UI

	// 数值文本字体UPROPERTY(EditAnywhere, Category = "Visual")FSlateFontInfo ValueTextFont;// 是否显示数值文本UPROPERTY(EditAnywhere, Category = "Visual")bool bValueTextVisible = true;// 是否显示进度条UPROPERTY(EditAnywhere, Category = "Visual")bool bProgressBarVisible = true;
void UValueGauge::NativePreConstruct()
{Super::NativePreConstruct();// 设置进度条颜色ProgressBar->SetFillColorAndOpacity(BarColor);ValueText->SetFont(ValueTextFont);ValueText->SetVisibility(bValueTextVisible ? ESlateVisibility::Visible : ESlateVisibility::Hidden);ProgressBar->SetVisibility(bProgressBarVisible ? ESlateVisibility::Visible : ESlateVisibility::Hidden);
}

设置字体
在这里插入图片描述
复制原本的头部ui,关闭蓝条的字体和进度条显示
在这里插入图片描述
关于大小的调整
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/88816.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/88816.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Clojure持久化数据结构的底层实现

文章目录一、Clojure的持久化数据结构二、向量(Vector)/Map的底层结构​1. HAMT 哈希数组映射字典树&#xff08;1&#xff09;简介&#xff08;2&#xff09;HAMT 的核心思想&#xff08;3&#xff09;HAMT 的结构​a. 基本组成​b. 树的分支因子​&#xff08;4&#xff09;H…

面试150 二叉树展开为链表

思路 思路:使用列表存储先序遍历的相关节点。然后遍历列表&#xff0c;分别获取前驱节点和当前节点,将前驱节点的左指针指向空&#xff0c;前驱节点的右指针指向当前节点。 # Definition for a binary tree node. # class TreeNode: # def __init__(self, val0, leftNone, …

代码随想录算法训练营第十七天

目录 LeetCode.654 最大二叉树 题目链接 最大二叉树 题解 解题思路 LeetCode.617 合并二叉树 题目链接 合并二叉树 题解 解题思路 LeetCode.700 二叉搜索树中的搜索 题目链接 二叉搜索树中的搜索 题解 解题思路 解题思路 LeetCode.98 验证二叉搜索树 题目链接 验…

pycharm无法识别pip安装的包

在使用conda创建一个新的环境后&#xff0c;有些包通过pip的方式安装更方便有效&#xff0c;若在pip安装后&#xff0c;遇到该环境没有此包&#xff0c;或pycharm监测不到此包&#xff0c;通常是pip的环境指向有问题。 解决措施&#xff1a; # 首先检查当前pip的指向 which pip…

Elasticsearch 的 `modules` 目录

Elasticsearch 的 modules 目录是存放**核心功能模块**的目录&#xff0c;这些模块是 Elasticsearch 运行所必需的基础组件&#xff0c;**随官方发行版一起提供**&#xff0c;但设计上允许通过移除或替换模块来**定制化部署**&#xff08;比如构建一个最小化的 Elasticsearch 实…

https——TCP+TLS

https——TCPTLS主题&#xff1a;基于mbedtls-2.16.0&#xff0c;验证TLS会话复用功能验证环境&#xff1a;1.TLS服务端2.TLS客户端2.1 基于Sesssion ID2.1.1mbedtls-2.16.0库的宏配置2.1.2 初始化配置2.1.3 TCP连接2.1.4 首次TLS连接2.1.4.1 发送加密算法列表2.1.4.2 选择加密…

uni-app uni-push 2.0推送图标不展示问题

问题现象&#xff1a;我在uni-app的配置文件&#xff0c;配置了推送的大图标小图标发现在真机测试无法展示配置的推送图标问题 官网文档&#xff1a;开通 | uni-app官网 解决方法&#xff1a; 在uni-app官网中说的并不是很清楚只给了一个简单的示例&#xff0c;配置并没有告诉我…

scp:上传大型数据集到实验室服务器

我通过百度网盘下载了大概200GB的LUNA-2016的肺结节CT数据。实验是在实验室服务器上进行的&#xff0c;我现在需要将本地的数据集传输到实验室的服务器上。我已经通过remote-ssh连接上了实验室的服务器&#xff0c;但是如果通过这个插件上传数据的话&#xff0c;一方面不支持上…

量子计算突破:8比特扩散模型实现指数级加速

目录 一、量子扩散模型&#xff08;Quantum Diffusion&#xff09; 二、DNA存储生成&#xff08;Biological-GAN&#xff09; 三、光子计算加速 四、神经形态生成 五、引力场渲染 六、分子级生成 七、星际生成网络 八、元生成系统 极限挑战方向 一、量子扩散模型&…

Flask3.1打造极简CMS系统

基于Flask 3.1和Python 3.13的简易CMS以下是一个基于Flask 3.1和Python 3.13的简易CMS管理系统实现方案&#xff0c;包含核心功能和可运行代码示例。环境准备安装Flask和其他依赖库&#xff1a;pip install flask3.1.0 flask-sqlalchemy flask-login配置数据库在config.py中设置…

用 Node.js 构建模块化的 CLI 脚手架工具,从 GitHub 下载远程模板

本文将手把手带你构建一个支持远程模板下载、自定义项目名称&#xff0c;并完成模块化拆分的 CLI 脚手架工具&#xff0c;适用于初创项目、团队内部工具或者开源项目快速初始化。&#x1f9e9; 为什么要自己造一个 CLI 脚手架&#xff1f; 在日常开发中&#xff0c;我们常用脚手…

08.如何正确关闭文件

如何正确关闭文件(File Handling Best Practices) 文件操作是日常开发中非常常见的任务,正确关闭文件对于避免资源泄漏尤为关键。错误的文件关闭方式可能导致文件未保存、锁定或其他异常。 1. 常见的错误方式:手动 close() 许多初学者会手动调用 close() 关闭文件,这在异…

算法入门--动态规划(C++)

深入浅出掌握动态规划核心思想&#xff0c;图文并茂实战代码 什么是动态规划&#xff1f; 动态规划&#xff08;Dynamic Programming, DP&#xff09; 是一种高效解决多阶段决策问题的方法。它通过将复杂问题分解为重叠子问题&#xff0c;并存储子问题的解&#xff08;避免重…

[2025CVPR]GNN-ViTCap:用于病理图像分类与描述模型

论文结构解析​ 本文采用经典学术论文结构: ​引言​:阐述病理图像分析的挑战与现有方法局限性​相关工作​:系统梳理MIL、视觉语言预训练和生物医学语言模型三大领域​方法​:详细阐述GNN-ViTCap四阶段架构​实验​:在BreakHis和PatchGastric数据集验证性能​讨论​:通…

Java SE--图书管理系统模拟实现

一.设计思路首先这个系统可以由俩种用户使用&#xff0c;分别为管理者用户和普通者用户&#xff0c;根据不同的用户有不同的界面&#xff0c;每个界面有不同的功能。二.代码实现创建三个包和一个类book包&#xff1a;包括Book类和Booklist类Book类&#xff1a;package book; pu…

[RPA] 批量数据抓取指定商品名称信息

影刀RPA案例&#xff1a;批量数据抓取指定商品名称信息流程图&#xff1a;操作步骤&#xff1a;涉及的影刀RPA大致指令&#xff1a; 1. 打开影刀商城页面 2. 使用【填写输入框(web)】指令输入用户名和密码&#xff0c;并点击"登录"按钮 3. 切换到"订单管理"…

我的世界Java版1.21.4的Fabric模组开发教程(十四)方块实体

这是适用于Minecraft Java版1.21.4的Fabric模组开发系列教程专栏第十四章——方块实体。想要阅读其他内容&#xff0c;请查看或订阅上面的专栏。 方块实体(Block Entity) 指的是一种用于存储方块额外数据的方法。但这种数据和为了控制方块状态而在自定义方块类中创建的属性不太…

【UE教程/进阶】UE中的指针与引用

目录直接属性引用共享指针 TSharedPtr实现原理共享引用 TSharedRef弱引用指针 TWeakPtrObject弱指针 FWeakPtr实现原理Object软指针 FSoftObjectPtr原理直接属性引用 在c通过UPROPERTY()宏将属性公开&#xff0c;蓝图中属性类型中的Object Reference。 对一个类型及其子类型的…

早期 CNN 的经典模型—卷积神经网络(LeNet)

目录 LeNet 的设计背景与目标 LeNet 的网络结构&#xff08;经典 LeNet-5&#xff09; 局部感受野详解 一、局部感受野和全连接网络的区别 1. 传统全连接网络的问题 2. 局部感受野的解决方案 二、局部感受野的优势 1. 参数大幅减少 2. 提取局部特征 3. 平移不变性 参数…

RabbitMQ 高级特性之延迟队列

1. 简介 在某些场景下&#xff0c;当生产者发送消息后&#xff0c;可能不需要让消费者立即接收到&#xff0c;而是让消息延迟一段时间后再发送给消费者。 2. 实现方式 2.1 TTL 死信队列 给消息设置过期时间后&#xff0c;若消息在这段时间内没有被消费&#xff0c;就会将消…