18uec++多人游戏【服务器为两个角色发枪,并能在线开枪】

news2025/7/10 12:29:12

打开主角类,生成枪的代码逻辑在游戏开始函数里

所以在生成之前,我们需要判断该对象是否在服务器端(服务器端视角)

void ASCharacter::BeginPlay()
{
	Super::BeginPlay();
	DefaultsFOV = CameraComp->FieldOfView;
	//判断是否在服务器端
	if (Role == ROLE_Authority)
	{
		//设置生成参数,当生成的actor碰到了其他物体,也要生成
		FActorSpawnParameters Parameters;
		Parameters.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
		//生成武器actor(类型、位置、方向、参数),并且其地址赋予到指针上
		CurrentWeapen1 = GetWorld()->SpawnActor<ASWeapen>(StartWeapen, FVector::ZeroVector, FRotator::ZeroRotator, Parameters);
		//设置武器的位置与骨骼的插槽中,并设置主人
		if (CurrentWeapen1)
		{
			CurrentWeapen1->SetOwner(this);
			CurrentWeapen1->AttachToComponent(GetMesh(), FAttachmentTransformRules::SnapToTargetNotIncludingScale, WeaponAttachSoketName);
		}
	}
	
	//受伤自定义事件绑定
	HealthComp->OnHealthChanged.AddDynamic(this, &ASCharacter::OnHealthChanged);

}

编译一下,看看是什么效果

我们发现,左边的有武器,右边的没有武器

 所以我们要让武器可以进行网络复制

打开武器类,在构造函数中进行设置

	//设置可以进行网络复制
	SetReplicates(true);

编译,然后打开枪的蓝图,打上勾

这一次他们都有枪了

 

 现在枪虽然是有了,左边的玩家可以开枪,但是右边的角色不可以开枪

这是因为右边角色,指向武器的指针是空的

 所以我们要让武器指针可以同步,这样就可以同步了

	//目前玩家手中的武器
	UPROPERTY(Replicated)
	class ASWeapen * CurrentWeapen1;

 要实现网络同步,必须还要有一个函数,这个函数定义在actor类里面

 我们将其复制到玩家类里面

	//用于网络同步的函数
	void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;

导入头文件

#include "Net/UnrealNetwork.h"

 定义这个函数

void ASCharacter::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
	Super::GetLifetimeReplicatedProps(OutLifetimeProps);
	//同步给所有的客户端和服务器
	DOREPLIFETIME(ASCharacter, CurrentWeapen1);
}

测试,两个角色都可以打枪了,但是互相看不见。

下面解决这个问题。

==========================================

给武器类添加成员函数serverfire()

	UFUNCTION(Server, Reliable, WithValidation)
		void ServerFire();

然后实现该函数的方式比较特殊

void ASWeapen::ServerFire_Implementation()
{
    Fire();
}

bool ASWeapen::ServerFire_Validate()
{
	return true;
}

 然后我们修改一下Fire()函数

void ASWeapen::Fire()
{
	//如果不是服务器,就执行ServerFire()
	if (Role < ROLE_Authority)
	{
		ServerFire();
		return;
	}
	//创建一个撞击句柄,用来获取弹道相关信息
	FHitResult Hit;
	//弹道的起点,我们设置为角色眼睛的位置
	AActor * MyOwner = GetOwner();
	if (MyOwner)
	{	//位置
		FVector EyeLocation;
		//方向
		FRotator EyeRotator;
		//得到眼睛的位置和角度
		MyOwner->GetActorEyesViewPoint(EyeLocation, EyeRotator);
		//弹道的终点就是起点+方向*10000
		FVector TraceEnd = EyeLocation + (EyeRotator.Vector() * 1000);
		//弹道特效的结束点
		FVector TraceEndPoint = TraceEnd;
		//设置碰撞通道为可见性通道
		FCollisionQueryParams  QueryParams;
		//让射线忽略玩家和枪
		QueryParams.AddIgnoredActor(MyOwner);
		QueryParams.AddIgnoredActor(this);
		//符合追踪设为true,可以让射击更加精准
		QueryParams.bTraceComplex = true;
		//返回命中目标的表面材质
		QueryParams.bReturnPhysicalMaterial = true;


		//在创建一个单轨迹线来计算弹道
		//LineTraceSingleByChannel击中物体返回true
		if (GetWorld()->LineTraceSingleByChannel(Hit, EyeLocation, TraceEnd, COLLISION_WEAPON, QueryParams))
		{
			//命中对象
			AActor * HitActor = Hit.GetActor();
			//实际的伤害
			float ActualDamage = BaseDamage;
			//得到命中物体表面材质
			EPhysicalSurface SurfaceType = UPhysicalMaterial::DetermineSurfaceType(Hit.PhysMaterial.Get());
			//如果命中的是头部表面材质,伤害变成四倍
			if (SurfaceType == SURFACE_FLESHVULNERABLE)
			{
				ActualDamage *= 4;
			}

			//造成点伤害ApplyPointDamage
			//参数分别为命中对象、基础伤害、射击方向、命中信息(命中句柄)、MyOwner->GetInstigatorController(暂时不了解)
			//this(射击者) 和伤害类型 
			UGameplayStatics::ApplyPointDamage(HitActor, ActualDamage, EyeRotator.Vector(), Hit, MyOwner->GetInstigatorController(), this, DamageType);

			//根据材质的不同,进行不同的处理
			UParticleSystem * SelectedEffect = nullptr;
			switch (SurfaceType)
			{
				//这两种情况是一个效果
			case SURFACE_FLESHDEFAULT:
			case SURFACE_FLESHVULNERABLE:
				SelectedEffect = FleshImpactEffect;
				break;
			default:
				SelectedEffect = DefaultImpactEffect;
				break;

			}

			//生成特效在命中点
			//ImpactEffect:特效 ImpactPoint:打击点 Rotation():打击方向
			if (SelectedEffect)
			{
				UGameplayStatics::SpawnEmitterAtLocation(GetWorld(), SelectedEffect, Hit.ImpactPoint, Hit.ImpactNormal.Rotation());
			}
			//命中的时候,修改弹道特效的终点
			TraceEndPoint = Hit.ImpactPoint;



		}
		//方便debug
		//DrawDebugLine(GetWorld(), EyeLocation, TraceEnd, FColor::Red, false, 1, 0, 1);
		//射击特效
		PlayFireEffects(TraceEndPoint);
		//最后开火的时间
		FireLastTime = GetWorld()->TimeSeconds;
	}

}

编译,测试,服务器端开火,客户端看不到(不管控制哪个角色,都是在服务器端看到开火)

 

 修改一下代码,我们把return去掉

 编译测试

服务器端开火,客户端看不到;客户端开火,同时可以看到

 

 给角色蓝图添加两个节点

===========================================

目前

操作客户端,两端都能看到特效

 操作服务器端,客户端看不到特效

在武器类的头文件中,创建结构体

USTRUCT()
struct FHitScanTrace
{
	GENERATED_BODY()
public:
	//弹道的目的坐标
	UPROPERTY()
	FVector_NetQuantize TraceTo;
	//子弹数目:为了让该结构体内容发生变化,结构体才被不断得被网络复制
	UPROPERTY()
	uint8 BrustCounter;

};

创建该类中的结构体成员变量,和对应的网络复制函数

	//网络射击信息
	UPROPERTY(ReplicatedUsing = OnRep_HitScanTrace)
	FHitScanTrace HitScanTrace;

	//网络复制函数
	UFUNCTION()
	void OnRep_HitScanTrace();

当结构体内容发生改变的时候,就会自动调用网络复制函数

在fire函数里面,更新网络射击信息

		//更新网络射击信息
		if (Role == ROLE_Authority)
		{
			//子弹数量++
			HitScanTrace.BrustCounter++;
			//更新弹道目的坐标
			HitScanTrace.TraceTo = TraceEndPoint;

		}
void ASWeapen::Fire()
{
	//如果不是服务器,就执行ServerFire()
	if (Role < ROLE_Authority)
	{
		ServerFire();
		
	}
	//创建一个撞击句柄,用来获取弹道相关信息
	FHitResult Hit;
	//弹道的起点,我们设置为角色眼睛的位置
	AActor * MyOwner = GetOwner();
	if (MyOwner)
	{	//位置
		FVector EyeLocation;
		//方向
		FRotator EyeRotator;
		//得到眼睛的位置和角度
		MyOwner->GetActorEyesViewPoint(EyeLocation, EyeRotator);
		//弹道的终点就是起点+方向*10000
		FVector TraceEnd = EyeLocation + (EyeRotator.Vector() * 1000);
		//弹道特效的结束点
		FVector TraceEndPoint = TraceEnd;
		//设置碰撞通道为可见性通道
		FCollisionQueryParams  QueryParams;
		//让射线忽略玩家和枪
		QueryParams.AddIgnoredActor(MyOwner);
		QueryParams.AddIgnoredActor(this);
		//符合追踪设为true,可以让射击更加精准
		QueryParams.bTraceComplex = true;
		//返回命中目标的表面材质
		QueryParams.bReturnPhysicalMaterial = true;


		//在创建一个单轨迹线来计算弹道
		//LineTraceSingleByChannel击中物体返回true
		if (GetWorld()->LineTraceSingleByChannel(Hit, EyeLocation, TraceEnd, COLLISION_WEAPON, QueryParams))
		{
			//命中对象
			AActor * HitActor = Hit.GetActor();
			//实际的伤害
			float ActualDamage = BaseDamage;
			//得到命中物体表面材质
			EPhysicalSurface SurfaceType = UPhysicalMaterial::DetermineSurfaceType(Hit.PhysMaterial.Get());
			//如果命中的是头部表面材质,伤害变成四倍
			if (SurfaceType == SURFACE_FLESHVULNERABLE)
			{
				ActualDamage *= 4;
			}

			//造成点伤害ApplyPointDamage
			//参数分别为命中对象、基础伤害、射击方向、命中信息(命中句柄)、MyOwner->GetInstigatorController(暂时不了解)
			//this(射击者) 和伤害类型 
			UGameplayStatics::ApplyPointDamage(HitActor, ActualDamage, EyeRotator.Vector(), Hit, MyOwner->GetInstigatorController(), this, DamageType);

			//根据材质的不同,进行不同的处理
			UParticleSystem * SelectedEffect = nullptr;
			switch (SurfaceType)
			{
				//这两种情况是一个效果
			case SURFACE_FLESHDEFAULT:
			case SURFACE_FLESHVULNERABLE:
				SelectedEffect = FleshImpactEffect;
				break;
			default:
				SelectedEffect = DefaultImpactEffect;
				break;

			}

			//生成特效在命中点
			//ImpactEffect:特效 ImpactPoint:打击点 Rotation():打击方向
			if (SelectedEffect)
			{
				UGameplayStatics::SpawnEmitterAtLocation(GetWorld(), SelectedEffect, Hit.ImpactPoint, Hit.ImpactNormal.Rotation());
			}
			//命中的时候,修改弹道特效的终点
			TraceEndPoint = Hit.ImpactPoint;



		}
		//方便debug
		//DrawDebugLine(GetWorld(), EyeLocation, TraceEnd, FColor::Red, false, 1, 0, 1);
		//射击特效
		PlayFireEffects(TraceEndPoint);
		//更新网络射击信息
		if (Role == ROLE_Authority)
		{
			//子弹数量++
			HitScanTrace.BrustCounter++;
			//更新弹道目的坐标
			HitScanTrace.TraceTo = TraceEndPoint;

		}
		//最后开火的时间
		FireLastTime = GetWorld()->TimeSeconds;
	}

}

定义网络复制函数,让其执行射击特效

void ASWeapen::OnRep_HitScanTrace()
{
	//调用射击特效
	PlayFireEffects(HitScanTrace.TraceTo);
}

此时,网络射击信息结构体变量还没有实现网络的复制共享,我们让其共享。

创建复制成员变量的函数

void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;

定义这个函数

void ASWeapen::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
	Super::GetLifetimeReplicatedProps(OutLifetimeProps);
	//同步给所有的客户端和服务器(DOREPLIFETIME_CONDITION不用同步给自己)
	DOREPLIFETIME_CONDITION(ASWeapen, HitScanTrace,COND_SkipOwner);
}

编译,测试

发现服务器端射击的时候,客户端可以看到弹道的特效,但看不到击中特效

 ============================================

现在解决一下这个问题

为网络射击结构体添加表面材质成员变量

	//表面材质
	UPROPERTY()
	TEnumAsByte<EPhysicalSurface> SurfaceType;

在fire函数里面为其赋值

		//更新网络射击信息
		if (Role == ROLE_Authority)
		{
			//子弹数量++
			HitScanTrace.BrustCounter++;
			//更新弹道目的坐标
			HitScanTrace.TraceTo = TraceEndPoint;
			//更新击中物体的材质
			HitScanTrace.SurfaceType = SurfaceType;

		}

我们为击中特效的生成做成一个函数

	//击中特效
	void PlayImpactEffects(EPhysicalSurface SurfaceType , FVector ImpactPoint);

定义这个函数

void ASWeapen::PlayImpactEffects(EPhysicalSurface SurfaceType , FVector ImpactPoint)
{

	//根据材质的不同,进行不同的处理
	UParticleSystem * SelectedEffect = nullptr;
	switch (SurfaceType)
	{
		//这两种情况是一个效果
	case SURFACE_FLESHDEFAULT:
	case SURFACE_FLESHVULNERABLE:
		SelectedEffect = FleshImpactEffect;
		break;
	default:
		SelectedEffect = DefaultImpactEffect;
		break;

	}

	//生成特效在命中点
	//ImpactEffect:特效 ImpactPoint:打击点 Rotation():打击方向
	if (SelectedEffect)
	{
		//计算枪口位置
		FVector MuzzleLocation = MeshComponent->GetSocketLocation("MuzzleSocket");
		//射击方向向量 = 打击点-枪口
		FVector ShotDirection = ImpactPoint - MuzzleLocation;
		UGameplayStatics::SpawnEmitterAtLocation(GetWorld(), SelectedEffect, ImpactPoint, ShotDirection.Rotation());
	}
}

完善一下复制函数内容函数

void ASWeapen::OnRep_HitScanTrace()
{
	//调用射击特效
	PlayFireEffects(HitScanTrace.TraceTo);
	//生成命中特效
	PlayImpactEffects(HitScanTrace.SurfaceType, HitScanTrace.TraceTo);
}

完善fire函数

void ASWeapen::Fire()
{
	//如果不是服务器,就执行ServerFire(),服务器端就有响应
	if (Role < ROLE_Authority)
	{
		ServerFire();
		
	}
	//创建一个撞击句柄,用来获取弹道相关信息
	FHitResult Hit;
	//弹道的起点,我们设置为角色眼睛的位置
	AActor * MyOwner = GetOwner();
	//击中物体的材质
	EPhysicalSurface SurfaceType = EPhysicalSurface::SurfaceType_Default;

	if (MyOwner)
	{	//位置
		FVector EyeLocation;
		//方向
		FRotator EyeRotator;
		//得到眼睛的位置和角度
		MyOwner->GetActorEyesViewPoint(EyeLocation, EyeRotator);
		//弹道的终点就是起点+方向*10000
		FVector TraceEnd = EyeLocation + (EyeRotator.Vector() * 1000);
		//弹道特效的结束点
		FVector TraceEndPoint = TraceEnd;
		//设置碰撞通道为可见性通道
		FCollisionQueryParams  QueryParams;
		//让射线忽略玩家和枪
		QueryParams.AddIgnoredActor(MyOwner);
		QueryParams.AddIgnoredActor(this);
		//符合追踪设为true,可以让射击更加精准
		QueryParams.bTraceComplex = true;
		//返回命中目标的表面材质
		QueryParams.bReturnPhysicalMaterial = true;


		//在创建一个单轨迹线来计算弹道
		//LineTraceSingleByChannel击中物体返回true
		if (GetWorld()->LineTraceSingleByChannel(Hit, EyeLocation, TraceEnd, COLLISION_WEAPON, QueryParams))
		{
			//命中对象
			AActor * HitActor = Hit.GetActor();
			//实际的伤害
			float ActualDamage = BaseDamage;
			//得到命中物体表面材质
			EPhysicalSurface SurfaceType = UPhysicalMaterial::DetermineSurfaceType(Hit.PhysMaterial.Get());
			//如果命中的是头部表面材质,伤害变成四倍
			if (SurfaceType == SURFACE_FLESHVULNERABLE)
			{
				ActualDamage *= 4;
			}

			//造成点伤害ApplyPointDamage
			//参数分别为命中对象、基础伤害、射击方向、命中信息(命中句柄)、MyOwner->GetInstigatorController(暂时不了解)
			//this(射击者) 和伤害类型 
			UGameplayStatics::ApplyPointDamage(HitActor, ActualDamage, EyeRotator.Vector(), Hit, MyOwner->GetInstigatorController(), this, DamageType);
			//生成命中特效
			PlayImpactEffects(SurfaceType, Hit.ImpactPoint);

			//命中的时候,修改弹道特效的终点
			TraceEndPoint = Hit.ImpactPoint;

		}
		//方便debug
		//DrawDebugLine(GetWorld(), EyeLocation, TraceEnd, FColor::Red, false, 1, 0, 1);
		//射击特效
		PlayFireEffects(TraceEndPoint);
		//更新网络射击信息
		if (Role == ROLE_Authority)
		{
			//子弹数量++
			HitScanTrace.BrustCounter++;
			//更新弹道目的坐标
			HitScanTrace.TraceTo = TraceEndPoint;
			//更新击中物体的材质
			HitScanTrace.SurfaceType = SurfaceType;

		}
		//最后开火的时间
		FireLastTime = GetWorld()->TimeSeconds;
	}

}

编译,测试,两边特效同步了 

============================

现在是死亡不同步

打开生命值组件

首先在游戏开始函数里判断当前是否是服务器,如果是服务器,才绑定受伤

// Called when the game starts
void USHealthComponent::BeginPlay()
{
	Super::BeginPlay();
	//这就意味着客户端不会响应受伤事件
	if (GetOwnerRole() == ROLE_Authority)
	{
		AActor * Owner = GetOwner();
		//将该函数绑定在角色的受伤事件上
		if (Owner)
		{
			Owner->OnTakeAnyDamage.AddDynamic(this, &USHealthComponent::HandleTakeAnyDamage);
		}
	}

	Health = DefaultHealth;
	
	
}

在构造函数中设为可网路复制

USHealthComponent::USHealthComponent()
{
	// Set this component to be initialized when the game starts, and to be ticked every frame.  You can turn these features
	// off to improve performance if you don't need them.
	PrimaryComponentTick.bCanEverTick = true;

	DefaultHealth = 100;
	//网络复制
	SetIsReplicated(true);
}

将其中的生命值成员变量声明为网路可复制

	//当前生命值
	UPROPERTY(Replicated, BlueprintReadOnly, Category = "HealthComponent")
	float Health;

并定义和声明相关同步函数

		//用于网络同步的函数
	void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;
#include "Net/UnrealNetwork.h"
void USHealthComponent::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
	Super::GetLifetimeReplicatedProps(OutLifetimeProps);
	//同步给所有的客户端和服务器
	DOREPLIFETIME(USHealthComponent, Health);
}

打开角色类,将该变量设为网络可复制

	//是否死亡
	UPROPERTY(Replicated, BlueprintReadOnly, Category = "Player")
	bool bDied;

网络同步函数中,也进行同步一下

void ASCharacter::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
	Super::GetLifetimeReplicatedProps(OutLifetimeProps);
	//同步给所有的客户端和服务器
	DOREPLIFETIME(ASCharacter, CurrentWeapen1);
	DOREPLIFETIME(ASCharacter, bDied);
}

测试

同时倒地

 

 

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

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

相关文章

支付系统 — 支付路由

本文主要介绍下支付中路由系统的主要流程。 支付路由的作用 降低成本&#xff1a;越便宜越好&#xff1b; 提高用户体验&#xff1a;用户支付的越爽越好&#xff1b;越快越好&#xff1b;成功率越高越好。 确保有可用通道&#xff1a;多个选择&#xff0c;确保能完成支付。 …

【JVM】PC程序计数器和PC寄存器

一、JVM体系结构 本文所讲内容主要是 JVM 体系结构图中 运行时数据区 中的 PC寄存器&#xff0c;如下图所示&#xff1a; 二、PC寄存器是什么&#xff1f; 这里引用别人的一句话&#xff1a; 首先这里的PC寄存器并非广义上所指的物理寄存器&#xff0c;或许将其翻译为PC计数…

antd Carousel 重写dot样式

antd的Carousel走马灯组件的dot也就是下面那个滑动的按钮非常的不起眼。 白色背景的时候完全看不到。 但是我们大部分时候又都是白色背景&#xff0c;于是来自己重写一下样式。 在控制台看了一下&#xff0c;应该是这个属性在控制dot的颜色&#xff0c;重写这个属性就可以了。…

Nginx源码解析 --红黑树

预读知识 红黑树是一种自平衡二叉树&#xff0c;不仅可以使用二分法快速查找&#xff0c;而且插入和删除操作的效率也很高&#xff0c;常用于构造关联数组&#xff08;例如C标准库里的set和 map)。 在Nginx里红黑树主要用在事件机制里的定时器&#xff0c;检查连接超时&#…

Debian11之基于kubeadm安装K8S集群

官方安装教程 硬件要求 每台机器的内存要 2GB、CPU2 核心及以上 集群中的所有机器的网络彼此均能相互连接&#xff08;公网和内网都可以&#xff09; 节点之中不可以有重复的主机名、MAC 地址或 product_uuid 开启机器上的某些端口 为了保证 kubelet 正常工作&#xff0c;必须…

FluentCRM 2.6.0:更多功能、集成改进等等!

FluentCRM 2.6.0最新版发布了&#xff0c;它是一个主要的更新版本&#xff0c;为您带来了更多的功能、改进的集成、升级和错误修复&#xff01;让我们来看看 FluentCRM 2.6.0 提供了什么新功能&#xff01; 目录 FluentCRM 2.6的更高级过滤条件 电子邮件活动条件 基于自动化…

STC32G 单片机EEPROM 操作实例

一 STC32G 单片机EEPROM简介 STC32G系列单片机内部集成了大量的EEPROM&#xff0c;特别是STC32G12K128集成多达128K EEPROM。 STC32G内部EEPROM可擦写10万次&#xff0c;分若干扇区&#xff0c;每个扇区512字节。EEPROM的写操作只能将1写为0。要将0写为1&#xff0c;必须擦除…

Hive之函数

Hive之函数 第九章 函数 9.1 系统内置函数 9.1.1 理论 查看内置函数&#xff1a; show functions; 显示函数的详细信息&#xff1a; desc function abs; 显示函数的扩展信息&#xff1a; desc function extended concat; 一、关系运算&#xff1a; 1. 等值比较: 2. 等值…

VSCode:使用CMakeLists.txt构建C++项目

vscode配置 插件&#xff1a; CMake插件主要功能是CMake语法高亮、自动补全CMake Tools的功能主要是结合VSCode IDE使用CMake这个工具&#xff0c;比如生成CMake项目、构建CMake项目等CMake Tools Helper CMake工具本身还是要下载到本地&#xff0c;并且配置环境变量。 项目…

足球二三事 - 世界杯征文

征文活动链接&#xff1a; https://bbs.csdn.net/topics/609601920 从报纸上时候看 1982 年的世界杯&#xff0c;当时我们家里没有电视&#xff0c;晚上的时候听到马路对面的房子里传来惊呼声&#xff0c;也不知道为啥。 1983 年的春节前&#xff0c;家里要打扫房间&#xff…

UE4,UE5虚幻引擎源码版下载

1、进入Epic的GitHub仓库 https://github.com/EpicGames/Signup GitHub - EpicGames/Signup: Information about signing up for a free Epic Games account, and getting access to UnrealEngine source code. 2、加入EpicTeamAdmin 3、进入UnrealEngine仓库 4、找到需要下…

Linux系统中curl命令用法详解

在Linux系统中curl是一个利用URL规则在命令行下工作的文件传输工具&#xff0c;是一款强大的http命令行工具。它支持文件的上传和下载&#xff0c;是综合传输工具。 curl 是常用的命令行工具&#xff0c;用来请求 Web 服务器。它的名字就是客户端&#xff08;client&#xff09…

(C语言)printf打印的字符串太长了,我想分两行!

本文来自于公众号&#xff1a;C语言编程技术分享 一、提问 有下述C程序&#xff1a; #include <stdio.h> #include <stdlib.h>int main() { printf("123456789012345678901234567890\n");system("pause");return 0; } printf函数要打印的字…

tomcat启动配置java_home,启动网址等,点击startup.bat直接启动

自己开发了一个网址&#xff08;基于angular&#xff09;&#xff0c;想共享给别人&#xff0c;直接点击运行&#xff0c;通过tomcat部署网站方式执行。 1、下载tomcat 从官网上下载tomcat&#xff0c;我下载的是tomcat9.0.36,下载完成后&#xff0c;解压&#xff1a; 双击b…

新知实验室

TUIRoom 是一个包含 UI 的开源音视频组件&#xff0c;通过集成 TUIRoom&#xff0c;可以在业务中快速上线音视频房间&#xff0c;屏幕分享&#xff0c;聊天等功能。 项目是开源的项目&#xff0c;根据自己 的需求设计项目。 创建步骤如下 &#xff1a; 一、 开通腾讯云实时…

被裁后一个offer都没有,测试人的问题出在哪里?

裁员潮涌&#xff0c;经济严冬。最近很多测试人过得并不好&#xff0c;行业缩水对测试岗位影响很直接干脆&#xff0c;究其原因还是测试门槛在IT行业较低&#xff0c;同质化测试人员比较多。但实际上成为一位好测试却有着较高的门槛&#xff0c;一名优秀的测试应当对产品的深层…

代码随想录65——额外题目【二叉树】:129求根节点到叶节点数字之和、1382将二叉搜索树变平衡、100相同的树、116填充每个节点的下一个右侧节点指针

文章目录1.129求根节点到叶节点数字之和1.1.题目1.2.解答2.1382将二叉搜索树变平衡2.1.题目2.2.解答3.100相同的树3.1.题目3.2.解答4.116填充每个节点的下一个右侧节点指针4.1.题目4.2.解答4.2.1.递归解法4.2.2.迭代方法1.129求根节点到叶节点数字之和 参考&#xff1a;代码随…

品优购项目详细分析

能够独立完成品优购首页制作哦 能够独立完成品优购列表页制作 能够独立完成品优购注册页制作 能够把品优购网站部署上线 网站制作流程&#xff1a; 初稿审核&#xff1a;网页美工会制作原型图和psd效果图 品优购项目规划&#xff1a; 1 品优购项目整体介绍 描述&#xff1…

【TS】函数重载--可选参数--默认参数

可选参数–默认参数 在ts中定义的数据类型&#xff0c;某些情况下只需要传入定义数据类型的一部分参数&#xff0c;比如&#xff1a;id 、name、age、address&#xff0c;此时需要修改用户的名称&#xff0c;那么只需要传入id、name就够了&#xff1b;某些情况下需要修改用户的…

.net-----集合和数据结构

集合和数据结构前言集合和数据结构的基本概念命名空间列表类集合列表类集合&#xff1a;数组列表列表类集合&#xff1a;列表List<T>双向链表LinkedList<T>字典类集合字典类集合类型哈希表Hashtable字典类集合&#xff1a;Dictionary<TKey, TValue >排序列表…