您的位置:首页 > 娱乐 > 八卦 > 忻州市忻府区_游戏推广赚佣金_百度网址ip_桂林网站优化

忻州市忻府区_游戏推广赚佣金_百度网址ip_桂林网站优化

2024/10/6 12:20:44 来源:https://blog.csdn.net/m0_53219246/article/details/142662780  浏览:    关键词:忻州市忻府区_游戏推广赚佣金_百度网址ip_桂林网站优化
忻州市忻府区_游戏推广赚佣金_百度网址ip_桂林网站优化

零、一些游戏框架知识

        1.UE5中包含游戏模式类(Game Mode)、游戏状态类(Game State)、玩家状态类(Player State)、玩家控制器类(Player Controller)、所有的可以被控制的实体或角色类(Pawn)、窗口类(HUD/Widget)

        Game Mode:存在在服务器上,当我们在客户端访问该类时获得的指针回事一个空指针

        Game State:存在在服务器上和所有的客户端上,可以将服务器上的数据复制到游戏状态类的客户端中

        Player State:存在在服务器上和所有客户端上

        Player Controller:存在在服务器上和自己的客户端上

        Pawn:存在在服务器上和所有客户端上

        HUD/Widget:存在在自己的客户端上

        2.Player Controller类可以访问HUD类

        3.服务器上存在Game Mode、Game State、所有的Player State、所有的Player Controller、所有的Pawn、

        4.Player Controller 可以访问当前客户端的Player State

        5.玩家状态的网络更新比角色更新速度慢

一、创建血条界面

        1.创建界面蓝图

        2.选择UserWidget

        3.界面中的控件如图

        4.创建UserWidget的C++类

        5.将之前创建的窗口的蓝图类的父类设置成在4中创建的C++类的类名(如图左下角父类设置)

        6.C++类中的代码如下

        头文件(注意不要写错变量名字和界面中的名字一定要相同)

// Fill out your copyright notice in the Description page of Project Settings.#pragma once#include "CoreMinimal.h"
#include "Blueprint/UserWidget.h"
#include "CharacterOverLay.generated.h"/*** */
UCLASS()
class BLASTER_API UCharacterOverLay : public UUserWidget
{GENERATED_BODY()public:UPROPERTY(meta = (Bindwidget))class UProgressBar* HealthBar;UPROPERTY(meta = (Bindwidget))class UTextBlock* HealthText;UPROPERTY(meta = (Bindwidget))UTextBlock* ScoreAmount;UPROPERTY(meta = (Bindwidget))UTextBlock* DefeatsAmount;
};

         源文件

创建之后不用管它源文件中没有写代码

        7.添加在界面显示的功能,我在之前绘制界面准心的类中重写了BeginPlay函数

        头文件(不要忘记在界面中设置变量CharacterOverlayClass的值)

public:UPROPERTY(EditAnywhere, Category = "Play States")TSubclassOf<class UUserWidget> CharacterOverlayClass;class UCharacterOverLay* CharacterOverlay;protected:virtual void BeginPlay() override;void AddCharacterOverlay();

        源文件

void AABasterHUD::BeginPlay()
{Super::BeginPlay();AddCharacterOverlay();
}void AABasterHUD::AddCharacterOverlay()
{APlayerController* PlayController = GetOwningPlayerController();if (PlayController && CharacterOverlayClass){CharacterOverlay = CreateWidget<UCharacterOverLay>(PlayController, CharacterOverlayClass);CharacterOverlay->AddToViewport();}
}

 二、更新血条状态跟新得分分数

        1.通过PlayerController可以访问HUD控件类,所以在PlayerController类中代码如下

        头文件

// Fill out your copyright notice in the Description page of Project Settings.#pragma once#include "CoreMinimal.h"
#include "GameFramework/PlayerController.h"
#include "BlasterPlayerController.generated.h"/*** */
UCLASS()
class BLASTER_API ABlasterPlayerController : public APlayerController
{GENERATED_BODY()
public:void SetHUDHealth(float Health , float MaxHealth);void SetHUDScore(float Score);void SetHUDDefeats(int32 Defeats);void OnPossess(APawn* IaPawn) override;protected:virtual void BeginPlay() override;private:UPROPERTY()class AABasterHUD* BlasterHUD;
};

        源文件

// Fill out your copyright notice in the Description page of Project Settings.#include "BlasterPlayerController.h"
#include "Blaster/HUD/ABasterHUD.h"
#include "Blaster/HUD/CharacterOverLay.h"
#include "Components/ProgressBar.h"
#include "Components/TextBlock.h"
#include "Blaster/Character/BlasterCharacter.h"void ABlasterPlayerController::BeginPlay()
{Super::BeginPlay();BlasterHUD = Cast<AABasterHUD>(GetHUD());
}void ABlasterPlayerController::OnPossess(APawn* IaPawn)
{Super::OnPossess(IaPawn);ABlasterCharacter* BlasterCharacter = Cast<ABlasterCharacter>(IaPawn);if (BlasterCharacter){SetHUDHealth(BlasterCharacter->GetHealth(), BlasterCharacter->GetMaxHealth());}
}void ABlasterPlayerController::SetHUDHealth(float Health, float MaxHealth)
{BlasterHUD = BlasterHUD == nullptr ? Cast<AABasterHUD>(GetHUD()) : BlasterHUD;bool bHUDValid = BlasterHUD &&BlasterHUD->CharacterOverlay &&BlasterHUD->CharacterOverlay->HealthBar &&BlasterHUD->CharacterOverlay->HealthText;if (bHUDValid){const float HealthPercent = Health / MaxHealth;BlasterHUD->CharacterOverlay->HealthBar->SetPercent(HealthPercent);FString HealthText = FString::Printf(TEXT("%d/%d"), FMath::CeilToInt(Health), FMath::CeilToInt(MaxHealth)); // CeilToInt向上取整BlasterHUD->CharacterOverlay->HealthText->SetText(FText::FromString(HealthText));}
}void ABlasterPlayerController::SetHUDScore(float Score)
{BlasterHUD = BlasterHUD == nullptr ? Cast<AABasterHUD>(GetHUD()) : BlasterHUD;bool bHUDValid = BlasterHUD &&BlasterHUD->CharacterOverlay &&BlasterHUD->CharacterOverlay->ScoreAmount;if (bHUDValid){FString ScoreText = FString::Printf(TEXT("%d"), FMath::FloorToInt(Score)); // FloorToInt 向下取整BlasterHUD->CharacterOverlay->ScoreAmount->SetText(FText::FromString(ScoreText));}
}void ABlasterPlayerController::SetHUDDefeats(int32 Defeats)
{BlasterHUD = BlasterHUD == nullptr ? Cast<AABasterHUD>(GetHUD()) : BlasterHUD;bool bHUDValid = BlasterHUD &&BlasterHUD->CharacterOverlay &&BlasterHUD->CharacterOverlay->DefeatsAmount;if (bHUDValid){FString DefeatsText = FString::Printf(TEXT("%d"), Defeats); // FloorToInt 向下取整BlasterHUD->CharacterOverlay->DefeatsAmount->SetText(FText::FromString(DefeatsText));}
}

        2.我想在角色类中设置血量

        角色类头文件

	/***	玩家健康状态*/UPROPERTY(EditAnywhere, Category = "Platyer Stats")float MaxHealth = 100.f;//玩家的最大血量UPROPERTY(ReplicatedUsing = OnRep_Health, VisibleAnywhere, Category = "Platyer Stats")float Health = 100.f;//玩家当前血量UFUNCTION()void OnRep_Health();//当人物当前血量改变时执行函数class ABlasterPlayerController* BlasterPlayerController;/* 更新界面血量函数 */
void UpdateHUDHealth();
/* 更新界面血量函数 */
/* 等待玩家状态存在后更新界面HUD */
void PollInit();
/* 等待玩家状态存在后更新界面HUD */

        角色类源文件


void ABlasterCharacter::UpdateHUDHealth()
{BlasterPlayerController = BlasterPlayerController == nullptr ? Cast<ABlasterPlayerController>(Controller) : BlasterPlayerController;if (BlasterPlayerController){BlasterPlayerController->SetHUDHealth(Health, MaxHealth);}
}void ABlasterCharacter::PollInit()
{if (BlasterPlayerState == nullptr){BlasterPlayerState = GetPlayerState<ABlasterPlayerState>();if (BlasterPlayerState){BlasterPlayerState->AddToScore(0.f);BlasterPlayerState->AddToDefeats(0);}}
}void ABlasterCharacter::OnRep_Health()
{UpdateHUDHealth();
}void ABlasterCharacter::UpdateHUDHealth()
{BlasterPlayerController = BlasterPlayerController == nullptr ? Cast<ABlasterPlayerController>(Controller) : BlasterPlayerController;if (BlasterPlayerController){BlasterPlayerController->SetHUDHealth(Health, MaxHealth);}
}void ABlasterCharacter::BeginPlay()
{Super::BeginPlay();UpdateHUDHealth();
}

实现PlayerState类

        头文件

// Fill out your copyright notice in the Description page of Project Settings.#pragma once#include "CoreMinimal.h"
#include "GameFramework/PlayerState.h"
#include "BlasterPlayerState.generated.h"/*** */
UCLASS()
class BLASTER_API ABlasterPlayerState : public APlayerState
{GENERATED_BODY()
public:virtual void GetLifetimeReplicatedProps(TArray< FLifetimeProperty >& OutLifetimeProps) const override;/***	复制通知*/virtual void OnRep_Score() override;UFUNCTION()virtual void OnRep_Defeats();void AddToScore(float ScoreAmount);void AddToDefeats(int32 DefeatsAmount);
private:class ABlasterCharacter* Character;class ABlasterPlayerController* Controller;UPROPERTY(ReplicatedUsing = OnRep_Defeats)int32 Defeats;};

        源文件

// Fill out your copyright notice in the Description page of Project Settings.#include "BlasterPlayerState.h"
#include "Blaster/Character/BlasterCharacter.h"
#include "Blaster/PlayerController/BlasterPlayerController.h"
#include "Net/UnrealNetwork.h"void ABlasterPlayerState::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{Super::GetLifetimeReplicatedProps(OutLifetimeProps);DOREPLIFETIME(ABlasterPlayerState, Defeats);
}void ABlasterPlayerState::OnRep_Score()
{Super::OnRep_Score();Character = Character == nullptr ? Cast<ABlasterCharacter>(GetPawn()) : Character;if (Character){ Controller = Controller == nullptr ? Cast<ABlasterPlayerController>(Character->Controller) : Controller;if (Controller){Controller->SetHUDScore(Score);}}
}void ABlasterPlayerState::AddToScore(float ScoreAmount)
{SetScore(GetScore() + ScoreAmount);Character = Character == nullptr ? Cast<ABlasterCharacter>(GetPawn()) : Character;if (Character){Controller = Controller == nullptr ? Cast<ABlasterPlayerController>(Character->Controller) : Controller;if (Controller){Controller->SetHUDScore(Score);}}
}void ABlasterPlayerState::OnRep_Defeats()
{Character = Character == nullptr ? Cast<ABlasterCharacter>(GetPawn()) : Character;if (Character){Controller = Controller == nullptr ? Cast<ABlasterPlayerController>(Character->Controller) : Controller;if (Controller){Controller->SetHUDDefeats(Defeats);}}
}void ABlasterPlayerState::AddToDefeats(int32 DefeatsAmount)
{Defeats += DefeatsAmount;Character = Character == nullptr ? Cast<ABlasterCharacter>(GetPawn()) : Character;if (Character){Controller = Controller == nullptr ? Cast<ABlasterPlayerController>(Character->Controller) : Controller;if (Controller){Controller->SetHUDDefeats(Defeats);}}
}

三、添加角色收到伤害功能

        1.根据子弹类创建新的C++类,命名为ProjectileBullet

        2. 在子弹类中我定义了OnHit()函数去处理当子弹碰到物体时的逻辑,同时OnHit是一个Virtual的函数

        头文件

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

        源文件

void AProjectileBullet::OnHit(UPrimitiveComponent* HitComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit)
{/** * float ApplyDamage(*	AActor* DamagedActor,   // 受伤的对象*	float BaseDamage,       // 施加的基础伤害值*	AController* EventInstigator, // 伤害事件的控制者,通常是攻击者的控制器*	AActor* DamageCauser,   // 造成伤害的对象,例如武器或攻击者*	TSubclassOf<UDamageType> DamageTypeClass // 指定伤害的类型,继承自 UDamageType*	);*/ACharacter* OwnerCharacter = Cast<ACharacter>(GetOwner());if (OwnerCharacter){AController* OwnerController = OwnerCharacter->Controller;if (OwnerController){UGameplayStatics::ApplyDamage(OtherActor, Damage, OwnerController,this,UDamageType::StaticClass());}}Super::OnHit(HitComponent, OtherActor, OtherComp, NormalImpulse, Hit);
}

        3.在子弹类中添加子弹伤害的变量

public:	UPROPERTY(EditAnywhere)float Damage = 20.f;//武器伤害

        4.在角色类中添加收到伤害的功能

        头文件

/* 接收伤害的回调函数 */
UFUNCTION()
void ReceiveDamage(AActor* DamagedActor, float Damage, const UDamageType* DamageType, class AController* InstigatorController, AActor* DamageCauser);
/* 接收伤害的回调函数 */

        源文件 (BeginPlay中绑定受到伤害的代理)

// Called when the game starts or when spawned
void ABlasterCharacter::BeginPlay()
{Super::BeginPlay();if (HasAuthority()){OnTakeAnyDamage.AddDynamic(this,&ABlasterCharacter::ReceiveDamage);}
}void ABlasterCharacter::ReceiveDamage(AActor* DamagedActor, float Damage, const UDamageType* DamageType, AController* InstigatorController, AActor* DamageCauser)
{Health = FMath::Clamp(Health - Damage, 0.f, MaxHealth);UpdateHUDHealth();PlayHitRecatMontage();if (Health == 0.f){ABlasterGameMode* BlasterGameMode = GetWorld()->GetAuthGameMode<ABlasterGameMode>();if(BlasterGameMode){BlasterPlayerController = BlasterPlayerController == nullptr ? Cast<ABlasterPlayerController>(Controller) : BlasterPlayerController;ABlasterPlayerController* AttackerController = Cast<ABlasterPlayerController>(InstigatorController);BlasterGameMode->PlayterEliminated(this,BlasterPlayerController, AttackerController);}}
}

四、给角色添加分数的游戏规则

        1.创建新的C++类

        2.代码实现

        头文件

// Fill out your copyright notice in the Description page of Project Settings.#pragma once#include "CoreMinimal.h"
#include "GameFramework/GameMode.h"
#include "BlasterGameMode.generated.h"/*** */
UCLASS()
class BLASTER_API ABlasterGameMode : public AGameMode
{GENERATED_BODY()
public:virtual void PlayterEliminated(class ABlasterCharacter* ElimmedCharacter, class ABlasterPlayerController* VictimController, ABlasterPlayerController* AttackerController);virtual void RequestRespawn(ACharacter* ElimedCharacter, AController* ElimedController);
};

         源文件

// Fill out your copyright notice in the Description page of Project Settings.#include "BlasterGameMode.h"
#include "Blaster/Character/BlasterCharacter.h"
#include "Blaster/PlayerController/BlasterPlayerController.h"
#include "Kismet/GameplayStatics.h"
#include "GameFramework/PlayerStart.h"
#include "Blaster/PlayerState/BlasterPlayerState.h"void ABlasterGameMode::PlayterEliminated(ABlasterCharacter* ElimmedCharacter, ABlasterPlayerController* VictimController, ABlasterPlayerController* AttackerController)
{ABlasterPlayerState* AttackerPlayerState = AttackerController ? Cast<ABlasterPlayerState>(AttackerController->PlayerState) : nullptr;ABlasterPlayerState* VictimPlayerState = VictimController ? Cast<ABlasterPlayerState>(VictimController->PlayerState) : nullptr;if (AttackerPlayerState && AttackerPlayerState != VictimPlayerState){AttackerPlayerState->AddToScore(1.f);}if (VictimPlayerState){VictimPlayerState->AddToDefeats(1);}if (ElimmedCharacter){ElimmedCharacter->Elim();}
}void ABlasterGameMode::RequestRespawn(ACharacter* ElimedCharacter, AController* ElimedController)
{if (ElimedCharacter){ElimedCharacter->Reset();ElimedCharacter->Destroy();}if (ElimedController){TArray<AActor*> PlayerStart;UGameplayStatics::GetAllActorsOfClass(this, APlayerStart::StaticClass(), PlayerStart);int32 Selection = FMath::RandRange(0, PlayerStart.Num() - 1);RestartPlayerAtPlayerStart(ElimedController, PlayerStart[Selection]);}
}

        3.若角色从新生成失败更改如下配置

        4.代码中的PlayerStart是场景中的玩家出生点,多放几个试试

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com