UE5学习笔记21-武器的射击功能

news2024/9/17 8:31:05

一、创建C++类

        创建武器子弹的类,创建生产武器子弹的类,创建弹壳的类,生产武器子弹的类的父类是武器的类

        创建后如图,ProjectileMyWeapon类(产生子弹的类)继承自weapon类,Projectile(子弹的类),Casing(弹壳声音的类)

         在子弹的类中添加如下代码

//头文件中添加
private:
	UPROPERTY(EditAnywhere)
	class UBoxComponent* CollisionBox;// 碰撞盒的类

//构造中添加
CollisionBox = CreateDefaultSubobject<UBoxComponent>(TEXT("CollisionBox"));
SetRootComponent(CollisionBox);
CollisionBox->SetCollisionObjectType(ECollisionChannel::ECC_WorldStatic); //设置自身的碰撞类型
CollisionBox->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics); //启动碰撞,启动触发器
CollisionBox->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Ignore); //设置对其他类型的碰撞
/* 第一个参数对角色 第二个参数是对角色是哪种碰撞 */
CollisionBox->SetCollisionResponseToChannel(ECollisionChannel::ECC_Visibility, ECollisionResponse::ECR_Block);
CollisionBox->SetCollisionResponseToChannel(ECollisionChannel::ECC_WorldStatic, ECollisionResponse::ECR_Block);

 二、武器蒙太奇(开火动画),添加开火功能

        1.将动画设置为加性的(让动作连贯),将瞄准和不瞄准的动画找到设置如图

        2.创建武器蒙太奇动画,在对应动画右键->创建->创建动画蒙太奇 (我将创建好的蒙太奇动画放到了其他文件夹中)

        3.新建蒙太奇片段,添加插槽,将瞄准的动画拖拽到蒙太奇中

 将之前的default片段名删除

 

添加另一端动画

将之前默认跳转的动画清空变成单独的动画 

 

选择插槽

最后样子

 三、绑定开火按键

        1.编辑->项目设置->输入->操作映射->添加fire鼠标左键

        2.在角色类中添加绑定

//角色类头文件
/* 发射子弹函数 */
void FireButtonPressed();
void FireButtonRelease();
/* 发射子弹函数 */

//角色类源文件
void ABlasterCharacter::FireButtonPressed()
{
	if (Combat)
	{
		Combat->FireButtonPressed(true);
	}
}

void ABlasterCharacter::FireButtonRelease()
{
	if (Combat)
	{
		Combat->FireButtonPressed(false);
	}
}

//函数SetupPlayerInputComponent中
PlayerInputComponent->BindAction("Fire", IE_Pressed, this, &ABlasterCharacter::FireButtonPressed);
PlayerInputComponent->BindAction("Fire", IE_Released, this, &ABlasterCharacter::FireButtonRelease);

         3.声明一个蒙太奇动画类指针

//角色头文件	
// 当前类指针在界面中赋值 EditAnywhere可编辑 Combat在细节中找到对应设置
UPROPERTY(EditAnywhere , Category = Combat)
class UAnimMontage* FireWeaponMontage; // 动画蒙太奇类

        4.编译后在角色蓝图中设置对应的蒙太奇动画

        5.定义播放动画的函数,FName中的名字是蒙太奇动画中的名字

//角色类头文件
void PlayFireMontage(bool bAiming);

//角色类源文件
void ABlasterCharacter::PlayFireMontage(bool bAiming)
{
	if (Combat == nullptr || Combat->EquippedWeapon == nullptr) return;

	UAnimInstance* AnimInstance = GetMesh()->GetAnimInstance();
	if (AnimInstance && FireWeaponMontage)
	{
		AnimInstance->Montage_Play(FireWeaponMontage);
		/* 找到播放哪段动画 名字是动画中新建蒙太奇片段的名字 */
		FName SectionName;
		SectionName = bAiming ? FName("RifleAim") : FName("RifleHip");
		/* 找到播放哪段动画 */
		AnimInstance->Montage_JumpToSection(SectionName);
	}
}

         6.动画蓝图中的改变,武器开火实在装备武器后才可以所以如图,动画蓝图类中添加

slot中右侧细节可以选择槽

 new一个姿势

         7.在aimoffset中使用6中的姿势(在动作偏移中使用对应姿势)

        8. 在战斗组件类中添加代码(class ABlasterCharacter* Character指针我在角色类中的PostInitializeComponents函数赋值),使用了RPC函数多播功能让动画在每个客户端都能看见

void ABlasterCharacter::PostInitializeComponents()
{
	Super::PostInitializeComponents();
	if (Combat)
	{
		Combat->Character = this;
	}
}
FVector_NetQuantize是FVector的网络传输的序列化的结构,减少网络带宽
//战斗组件类头文件
// 开火函数 
void FireButtonPressed(bool bPressed);

/* Server RPC函数 */
UFUNCTION(Server, Reliable)
void ServerFire(const FVector_NetQuantize& TraceHitTarget);
/* Server RPC函数 */

/* 多播函数 */
UFUNCTION(NetMulticast , Reliable)
void MulticastFire(const FVector_NetQuantize& TraceHitTarget);
/* 多播函数 */

/* 命中线 */
void TraceUnderCrosshairs(FHitResult& TraceHitResult);
/* 命中线 */

class ABlasterCharacter* Character;
bool bFireButtonPressed;

//战斗组件类源文件
void UCombatComponent::FireButtonPressed(bool bPressed)
{
	bFireButtonPressed = bPressed;

	if (bFireButtonPressed)
	{
		FHitResult HitResult;
		TraceUnderCrosshairs(HitResult);
		ServerFire(HitResult.ImpactPoint);
	}
}

void UCombatComponent::TraceUnderCrosshairs(FHitResult& TraceHitResult)
{
	/* 屏幕中心为瞄准点 */
	/* 获得视口大小 */
	FVector2D ViewportSize;
	if (GEngine && GEngine->GameViewport)
	{
		GEngine->GameViewport->GetViewportSize(ViewportSize);
	}

	/* 获得屏幕中心坐标 */
	FVector2D CrosshaurLocation(ViewportSize.X / 2.f, ViewportSize.Y / 2.f);

	FVector CrosshairWorldPosition; //世界空间中的相应 3D 位置
	FVector CrosshairWorldDirection; //在给定的 2d 点处远离摄像机的世界空间方向矢量
	bool bScreenToWorld = UGameplayStatics::DeprojectScreenToWorld(
		UGameplayStatics::GetPlayerController(this, 0),
		CrosshaurLocation,
		CrosshairWorldPosition,
		CrosshairWorldDirection
	);

	if (bScreenToWorld)
	{
		FVector Start = CrosshairWorldPosition;
        TRACE_LENGTH 我设置为8000 在世界坐标的长度可以理解成武器的射程
		FVector End = Start + CrosshairWorldDirection * TRACE_LENGTH;

		/*
		* bool LineTraceSingleByChannel(
			FHitResult& OutHit,             // 输出的碰撞信息
			const FVector& Start,           // 射线的起点
			const FVector& End,             // 射线的终点
			ECollisionChannel TraceChannel, // 碰撞通道
			const FCollisionQueryParams& Params = FCollisionQueryParams::DefaultQueryParam, // 可选的额外查询参数
			const FCollisionResponseParams& ResponseParam = FCollisionResponseParams::DefaultResponseParam // 可选的碰撞响应参数
			);
		*/
		//检查射线与场景中的物体是否有交点,并返回相关的碰撞信息
		GetWorld()->LineTraceSingleByChannel(
			TraceHitResult,
			Start,
			End,
			ECollisionChannel::ECC_Visibility
		);
#if 0
		if (!TraceHitResult.bBlockingHit)
		{
			TraceHitResult.ImpactPoint = End;
			HitTarget = End;
		}
		else
		{
			HitTarget = TraceHitResult.ImpactPoint;
			/*DrawDebugSphere(
				const UWorld* World,     // 表示你要在哪个世界中绘制球体
				FVector Center,          // 球体的中心位置
				float Radius,            // 球体的半径
				int32 Segments,          // 球体的分段数,影响球体的平滑度
				FColor Color,            // 球体的颜色
				bool bPersistentLines,    // 是否为持久化的调试线条(场景切换后是否还存在)
				float LifeTime,          // 调试球体的生存时间,0 为永久存在
				uint8 DepthPriority,     // 渲染优先级(影响是否被遮挡)
				float Thickness          // 球体线条的厚度
			)*/
			DrawDebugSphere(
				GetWorld(),
				TraceHitResult.ImpactPoint,
				12.f, //半径
				12, //
				FColor::Red
			);
		} 
#endif
	}
}

void UCombatComponent::ServerFire_Implementation(const FVector_NetQuantize& TraceHitTarget)
{
	MulticastFire(TraceHitTarget);
}

void UCombatComponent::MulticastFire_Implementation(const FVector_NetQuantize& TraceHitTarget)
{
	if (EquippedWeapon == nullptr) return;
	if (Character)
	{
		//UE_LOG(LogTemp, Warning, TEXT("FireButtonPressed"));
		Character->PlayFireMontage(bAiming);
		EquippedWeapon->Fire(TraceHitTarget);
	}
}

         9.武器类添加代码

//武器类头文件
/* 开火功能 */
virtual void Fire(const FVector& HitTaget);

UPROPERTY(EditAnywhere , Category = "Weapon Properties")
class UAnimationAsset* FireAnimation; //动画资产类
 
UPROPERTY(EditAnywhere)
TSubclassOf<class ACasing> CasingClass; // 监视类 -- 监视蛋壳弹出

//武器类源文件
void AWeapon::Fire(const FVector& HitTaget)
{
	if (FireAnimation)
	{
		WeapomMesh->PlayAnimation(FireAnimation, false);
	}
	if (CasingClass)
	{
		const USkeletalMeshSocket* AmmoEjectSocket = WeapomMesh->GetSocketByName(FName("AmmoEject"));
		if (AmmoEjectSocket)
		{
			FTransform SocketTransform = AmmoEjectSocket->GetSocketTransform(GetWeaponMesh());

			UWorld* World = GetWorld();
			if (World)
			{
				World->SpawnActor<ACasing>(
					CasingClass,
					SocketTransform.GetLocation(),
					SocketTransform.GetRotation().Rotator()
				);
			}
		}
	}
}

        10.创建子弹蓝图类

        11.设置蓝图

        1.打开蓝图设置对用的武器网格体,WeaponMesh细节中网格体的骨骼网格体资产选择对于你武器资产

         2.设置pickwidget(没有可以不用设置)细节中用户界面的空间选择屏幕空间类选择对饮蓝图类

        3.设置动画(武器开火动画)该蓝图的类是projectileweapon,它的父类是weapon,父类中有

    UPROPERTY(EditAnywhere , Category = "Weapon Properties")
    class UAnimationAsset* FireAnimation; //动画资产类

        所以一在细节中可以找到(C++类的继承)

        4.将11中的创建武器蓝图拖拽到地图中

        12. 摄像机的偏移(可选,若想看见角色前方的可以设置)

         13.生产子弹类中代码(GetSocketName中的名字是对应武器网格体中枪口的插槽的名字)

//子弹类头文件
public:
	virtual void Fire(const FVector& HitTaget) override;

protected:
	UPROPERTY(EditAnywhere)
	TSubclassOf<class AProjectile> ProjectileClass;

//子弹类源文件
void AProjectileMyWeapon::Fire(const FVector& HitTaget)
{
	Super::Fire(HitTaget);

	if (!HasAuthority()) return;
	APawn* InstigatorPawn = Cast<APawn>(GetOwner());
	const USkeletalMeshSocket* MuzzleFlashSocket = GetWeaponMesh()->GetSocketByName(FName("MuzzleFlash"));
	if (MuzzleFlashSocket)
	{
		FTransform SocketTransform = MuzzleFlashSocket->GetSocketTransform(GetWeaponMesh());
		// 从枪口闪光插座到开火位置 获得尖端的位置
		FVector ToTarget = HitTaget - SocketTransform.GetLocation();
		FRotator TargetRotation = ToTarget.Rotation();
		if (ProjectileClass && InstigatorPawn)
		{
			FActorSpawnParameters SpawnParams;
			SpawnParams.Owner = GetOwner();
			SpawnParams.Instigator = InstigatorPawn;
			UWorld* World = GetWorld();
			if (World)
			{
				World->SpawnActor<AProjectile>(
					ProjectileClass,
					SocketTransform.GetLocation(),
					TargetRotation,
					SpawnParams
					);
			}
		}
	}
}

        14.创建子弹类蓝图

        15.打开子弹类蓝图设置(中间黄色的是碰撞盒)

        15.1 设置碰撞盒大小

         16.定义粒子特效类和声音类

//子弹类头文件
	virtual void Destroyed() override;

protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

	UFUNCTION()
	virtual void OnHit(UPrimitiveComponent* HitComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit);

public:	

private:
	UPROPERTY(VisibleAnywhere)
	class UProjectileMovementComponent* ProjectileMovementComponent; //子弹运动的类

	UPROPERTY(EditAnywhere)
	class UParticleSystem* Tracer; //粒子系统类

	class UParticleSystemComponent* TracerComponent;	//粒子系统组件类

	UPROPERTY(EditAnywhere)
	class UParticleSystem* ImpactParticals; //粒子系统类

	UPROPERTY(EditAnywhere)
	class USoundCue* ImpactSound;//声音提示类

//子弹类源文件
//构造中添加
ProjectileMovementComponent = CreateDefaultSubobject<UProjectileMovementComponent>(TEXT("ProjectileMovementComponent"));
ProjectileMovementComponent->bRotationFollowsVelocity = true; //如果为 true,则此射弹将在每一帧更新其旋转以匹配其速度方向
// Called when the game starts or when spawned
void AProjectile::BeginPlay()
{
	Super::BeginPlay();
	
	if (Tracer)
	{
		//播放附加到指定组件并跟随指定组件的指定效果。当效果完成时,系统将消失。不复制
		TracerComponent = UGameplayStatics::SpawnEmitterAttached(
			Tracer,//粒子系统创建
			CollisionBox,//要附加到的组件。
			FName(),//AttachComponent 中的可选命名点,用于生成发射器
			GetActorLocation(),// 位置 -- 根据 LocationType 的值,这是与附加组件/点的相对偏移量,或者是将转换为相对偏移量的绝对世界位置(如果 LocationType 为 KeepWorldPosition)。
			GetActorRotation(),//旋转 -- 根据 LocationType 的值,这是与附加组件/点的相对偏移量,或者是将转换为相对偏移量的绝对世界旋转(如果 LocationType 为 KeepWorldPosition)
			EAttachLocation::KeepWorldPosition//根据 LocationType 的值,这是附加组件中的相对缩放,或者是将转换为相对缩放的绝对世界缩放(如果 LocationType 为 KeepWorldPosition)。
			//指定 Location 是相对偏移还是绝对世界位置
			//当粒子系统完成播放时,组件是否会自动销毁,或者是否可以重新激活
			//用于池化此组件的方法。默认为 none。
			//组件是否在创建时自动激活。	
		);
	}
	if (HasAuthority())
	{
		CollisionBox->OnComponentHit.AddDynamic(this,&AProjectile::OnHit);
	}
}

void AProjectile::OnHit(UPrimitiveComponent* HitComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit)
{
	Destroy();
}

void AProjectile::Destroyed()
{
	Super::Destroyed();

	if (ImpactParticals)
	{
		UGameplayStatics::SpawnEmitterAtLocation(GetWorld(), ImpactParticals, GetActorTransform());
	}
	if (ImpactSound)
	{
		UGameplayStatics::PlaySoundAtLocation(this, ImpactSound, GetActorLocation());
	}
}

        17.设置声音和粒子特效设置速度

        18. 若想发射子弹时在其他客户端也可以显示在子弹类的构造中将bReplicates = true;即可

        19.弹壳类

//弹壳头文件
	UFUNCTION()
	virtual void OnHit(UPrimitiveComponent* HitComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit);

#if 0
public:	
	// Called every frame
	virtual void Tick(float DeltaTime) override;
#endif

private:
	UPROPERTY(VisibleAnywhere)
	UStaticMeshComponent* CasingMesh;//静态网格体类 武器开火时弹出的子弹的网格体

	UPROPERTY(EditAnywhere)
	float ShellEjectionImpulse;// 弹壳初速度

	UPROPERTY(EditAnywhere)
	class USoundCue* ShellSound;// 弹壳弹出时的声音

//弹壳源文件
ACasing::ACasing()
{
 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = false;

	CasingMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("CasingMesh"));
	SetRootComponent(CasingMesh);
	CasingMesh->SetCollisionResponseToChannel(ECollisionChannel::ECC_Camera,ECollisionResponse::ECR_Ignore);
	CasingMesh->SetSimulatePhysics(true); // 物理
	CasingMesh->SetEnableGravity(true); // 重力
	CasingMesh->SetNotifyRigidBodyCollision(true); //通知
	ShellEjectionImpulse = 10.f;
}

// Called when the game starts or when spawned
void ACasing::BeginPlay()
{
	Super::BeginPlay();
	
	CasingMesh->OnComponentHit.AddDynamic(this, &ACasing::OnHit);
	// 给弹壳添加初始速度
	CasingMesh->AddImpulse(GetActorForwardVector() * ShellEjectionImpulse);
}
void ACasing::OnHit(UPrimitiveComponent* HitComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit)
{
	if (ShellSound)
	{
		UGameplayStatics::PlaySoundAtLocation(this, ShellSound, GetActorLocation());
	}

	Destroy();
}
#if 0
// Called every frame
void ACasing::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

}
#endif

        20.弹壳类蓝图

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

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

相关文章

Claude 3.5:如何高效辅助编程——全面入门指南

在现代编程世界中&#xff0c;AI的角色越来越重要&#xff0c;尤其是在代码生成、调试、文档生成等领域中&#xff0c;AI工具的运用让开发者可以更高效地完成任务。Claude 3.5是一个这样的AI助手&#xff0c;凭借其强大的自然语言处理能力&#xff0c;在编程中提供了大量的支持…

Sui Narwhal and Tusk 共识协议笔记

一、Overwiew [ 整体流程: Client提交transaction到Narwhal Mempool。(Narwhal Mempool由一组worker和一个primary组成) Mempool接收到的Transaction->以Certificate的形式进行广播 由worker将交易打包为Batch,worker将Batch的hash发送给primary primary上运行了mempo…

mysql笔记4(数据类型)

数据库的数据类型应该是数据库架构师(DBA)和产品经理沟通后依据公司的项目、业务而定的&#xff0c;而且会不停地变化。数据类型的选择方面没有一个统一的标准&#xff0c;但是应该符合业务、项目的逻辑标准。 菜鸟教程 Mysql 数据类型 文章目录 1. int类型2. 浮点数3. 定点数4…

C# Dotfuscator加密dll设置流程

按照以下步骤处理后&#xff0c;反编译基本只能看到函数名&#xff0c;看不到源代码 1.Input 2.Setting 3.Rename 4.Rename 5.Control Flow 6.String Encryption 7.Output

【stata】自写命令分享dynamic_est,一键生成dynamic effect

1. 命令简介 dynamic_est 是一个用于可视化动态效应&#xff08;dynamic effect&#xff09;的工具。它特别适用于事件研究&#xff08;event study&#xff09;或双重差分&#xff08;Difference-in-Differences, DID&#xff09;分析。通过一句命令即可展示动态效应&#xf…

EasyPlayer.js网页H5 Web js播放器能力合集

最近遇到一个需求&#xff0c;要求做一款播放器&#xff0c;发现能力上跟EasyPlayer.js基本一致&#xff0c;满足要求&#xff1a; 需求 功性能 分类 需求描述 功能 预览 分屏模式 单分屏&#xff08;单屏/全屏&#xff09; 多分屏&#xff08;2*2&#xff09; 多分屏…

JVM面试(七)G1垃圾收集器剖析

概述 上一章我们说了&#xff0c;G1收集器&#xff0c;它属于里程碑式的发展&#xff0c;开创了面向局部收集垃圾的概念。专门针对多核处理器以及大内存的机器。在JDK9中&#xff0c;更是呗指定为官方的GC收集器。满足高吞吐的通知满足GC的STW停顿时间尽可能的短。 虽然现在我…

恶意代码分析-Lab01-01

实验一 这个实验使用Lab01-01.exe和Lab01-01.d文件,使用本章描述的工具和技术来获取关于这些文件的信息。 问题: 将文件上传至 http:/www.VirusTotal.com/进行分析并查看报告。文件匹配到了已有的反病毒软件特征吗?这些文件是什么时候编译的?这两个文件中是否存在迹象说明它…

如何在docker容器中导入.sql文件

一、准备工作 确保容器运行&#xff1a; 首先确认包含 MySQL 服务的 Docker 容器正在运行。可以通过 docker ps 命令查看正在运行的容器列表。如果容器未运行&#xff0c;使用 docker start [container_id] 命令启动容器。 准备数据库文件&#xff1a; 将需要导入的数据库文件&…

VMware安装Ubuntu虚拟机

Ubuntu镜像下载 https://ubuntu.com/download/desktop 创建虚拟机 1.典型配置 2.稍后安装操作系统 3.选择操作系统&#xff0c;Linux&#xff0c;ubuntu64位 3.设置虚拟机名称和安装位置 4.磁盘大小&#xff0c;存储为单个文件 安装系统 1.选择镜像 2.开启虚拟机 2.安装Ub…

CTFHub技能树-Git泄漏-Log

目录 一、前提知识 1.git泄漏原理 ​编辑 2.git文件泄漏造成后果 3.利用方法 (1) GitHack是一个.git泄露利用脚本&#xff0c;通过泄露的.git文件夹下的文件&#xff0c;还原重建工程源代码。渗透测试人员、攻击者&#xff0c;可以进一步审计代码&#xff0c;挖掘&#x…

【重学 MySQL】十七、比较运算符的使用

【重学 MySQL】十七、比较运算符的使用 **等于&#xff08;&#xff09;**基本用法示例注意事项结论 **安全等于运算符&#xff08;<>&#xff09;****不等于&#xff08;<> 或 !&#xff09;**示例注意事项 **大于&#xff08;>&#xff09;、大于等于&#xf…

傅里叶级数,傅里叶变换

先读文章&#xff1a;傅里叶分析之掐死教程&#xff08;完整版&#xff09;更新于2014.06.06 - 知乎 (zhihu.com) 傅里叶级数 一、内容&#xff1a;每个周期性函数都可以表示为无穷多个不同频率的正弦函数的叠加。 二、公式&#xff1a; 三、从时域到频域所保留的三点信息&…

修改Anaconda中JupterLab的默认文件存储路径

安装好Anaconda后&#xff0c;使用JupterLab创建的文件会默认存储在C盘&#xff0c;每次打开业都是打开C盘&#xff0c;可以按照如下步骤修改默认存储路径 1.点击开始然后打开anconda prompt。 2.打开命令行输入 jupyter notebook --generate-config &#xff0c;点击回车&…

MySQL——表操作

目录 一、创建表 二、查看表 2.1 查看表中某成员的数据 2.2 查看整个表中的表成员 2.3 查看创建表时的句柄 三、修改表 alter 3.1 重命名 rename 3.2 新增一列 add 3.3 更改列属性 modify 3.4 更改列名称 change 3.5 删除某列 上一篇博客介绍了库的操作&#xff0c;…

零基础快速上手HarmonyOS ArkTS开发5---从简单的页面开始2---使用List组件构建列表、Grid组件构建网格布局

接着零基础快速上手HarmonyOS ArkTS开发4---从简单的页面开始继续往下学习页面布局的知识。最近发现之前学习这一章节的内容在官方已经被下了&#xff0c;替换成了另外一个案例了&#xff08;华为开发者学堂&#xff09;&#xff1a; 而且整个视频的风格也不一样了&#xff0c;…

DBeaver 24.0 高阶用法

DBeaver 24.0 高阶用法 文章目录 DBeaver 24.0 高阶用法DBeaver 介绍功能一、元数据搜索功能二、仪表盘显示功能三、ER图功能四、导出数据最后 DBeaver 介绍 DBeaver 确实是一款功能强大的通用数据库管理工具&#xff0c;适合所有需要以专业方式处理数据的用户。它不仅提供了直…

【笔记篇】Davinci Configurator BswM模块

目录 1 简介1.1 架构概览2 功能描述2.1 特性2.2 初始化2.3 状态机2.3.1 BSWM_INIT2.3.2 BSWM_WAIT_IMMEDIATE_REQUEST2.3.3 BSWM_MAIN_FUNCTION2.3.4 BSWM_MODE_ARBITRATION_AND_CONTROL2.3.5 BSWM_EMPTY_QUEUE2.3.6 BSWM_DEINIT2.4 模式管理2.4.1 即时模式处理2.4.2 强制即时模…

计算机毕业设计选题推荐-剧本杀创作与预约管理系统-Java/Python项目实战(亮点:数据可视化分析)

✨作者主页&#xff1a;IT研究室✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Python…

maven配置文件常用模板

注释很详细&#xff0c;直接上代码 项目结构 内容 父项目 pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi…