欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

UE4小游戏4

发布时间:2024/5/15 编程问答 22 豆豆
生活随笔 收集整理的这篇文章主要介绍了 UE4小游戏4 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

记录UE4小游戏

创建一个继承与AIController的AIEnemy用于控制Enemy,Enemy类负责做状态的转换。
Enemy.h

// Fill out your copyright notice in the Description page of Project Settings.#pragma once#include "CoreMinimal.h" #include "GameFramework/Character.h" #include "..\Public\PacManCharacter.h" #include "Enemy.generated.h"UCLASS() class MYPACMAN_API AEnemy : public ACharacter {GENERATED_BODY()public:// Sets default values for this character's propertiesAEnemy();protected:// Called when the game starts or when spawnedvirtual void BeginPlay() override;public: // Called every framevirtual void Tick(float DeltaTime) override;// Called to bind functionality to inputvirtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;void SetVulnerable(); //状态转换void SetInVulnerable();//状态转换void SetMove(bool bMoveIt);//移动用AIEnemy类实现void Killed();//void ReArm();//死亡后恢复UPROPERTY(VisibleAnywhere,Category = Body)UStaticMeshComponent* EnemyBody;UFUNCTION()void OnCollision(class UPrimitiveComponent* HitComp, class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);//碰撞函数bool bIsDead; private:class UMaterialInterface* DefaultMaterial;//材质class UMaterialInterface* VulnerableMaterial;FTimerHandle TimeVulnerable; //处于可被吃状态的时间bool bIsVulnerable;};

Enemy.cpp

// Fill out your copyright notice in the Description page of Project Settings.//#include "Enemy.h" #include "..\Public\Enemy.h" #include "UObject/ConstructorHelpers.h" #include "Components/CapsuleComponent.h" //#include "GameFramework/Actor.h" #include "TimerManager.h" #include "..\Public\AIEnemy.h" #include "GameFramework/CharacterMovementComponent.h" // Sets default values AEnemy::AEnemy() {// Set this character to call Tick() every frame. You can turn this off to improve performance if you don't need it.PrimaryActorTick.bCanEverTick = true;//创建bodyEnemyBody = CreateDefaultSubobject<UStaticMeshComponent> (TEXT("Body"));//用圆柱绑定外形static ConstructorHelpers::FObjectFinder<UStaticMesh> CylinderObj(TEXT("'/Game/StarterContent/Shapes/Shape_Cylinder'"));if (CylinderObj.Succeeded()){EnemyBody->SetStaticMesh(CylinderObj.Object);}//设置大小EnemyBody->SetWorldScale3D(FVector(0.7f, 0.7f, 1.0f));EnemyBody->SetRelativeLocation(FVector(0, 0, -50.0f));//为了和碰撞体适配下移动EnemyBody->SetupAttachment(RootComponent);//绑定为默认根组件//设置碰撞体大小GetCapsuleComponent()->SetCapsuleRadius(40.0f);GetCapsuleComponent()->SetCapsuleHalfHeight(50.0f); //绑定材质static ConstructorHelpers::FObjectFinder<UMaterial> VulnerableMat(TEXT("Material'/Game/Materials/M_Enemy_Vulnerable.M_Enemy_Vulnerable'"));if (VulnerableMat.Succeeded()){VulnerableMaterial = Cast<UMaterialInterface>(VulnerableMat.Object);}//BaseCollisionComponent->SetSphereRadius(16); //开启碰撞SetActorEnableCollision(true);AIControllerClass = AAIEnemy::StaticClass(); }// Called when the game starts or when spawned void AEnemy::BeginPlay() {Super::BeginPlay();DefaultMaterial = EnemyBody->GetMaterial(0); //游戏开始获取默认材质GetCapsuleComponent()->OnComponentBeginOverlap.AddDynamic(this, &AEnemy::OnCollision);//绑定碰撞GetCharacterMovement()->MaxWalkSpeed = 150.0f;//VulnerableMaterial//VulnerableMaterial = EnemyBody->GetMaterial(0, VulnerableMat);//SetVulnerable();}// Called every frame void AEnemy::Tick(float DeltaTime) {Super::Tick(DeltaTime);}// Called to bind functionality to input void AEnemy::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent) {Super::SetupPlayerInputComponent(PlayerInputComponent);}void AEnemy::SetVulnerable() {GetWorldTimerManager().SetTimer(TimeVulnerable, this, &AEnemy::SetInVulnerable, 10.0f, false);//每隔TimeVulnerable时间变为SetInVulnerableif (bIsVulnerable)return;bIsVulnerable = true;EnemyBody->SetMaterial(0, VulnerableMaterial);GetCharacterMovement()->MaxWalkSpeed = 50.0f; }void AEnemy::SetInVulnerable() {//清楚TimeVulnerableGetWorldTimerManager().ClearTimer(TimeVulnerable);bIsVulnerable = false;EnemyBody->SetMaterial(0, DefaultMaterial);GetCharacterMovement()->MaxWalkSpeed = 150.0f; }void AEnemy::SetMove(bool bMoveIt) { //用AIEnemy来控制EnemyAAIEnemy* AI = Cast<AAIEnemy>(GetController());if (bMoveIt){AI->SearchNewPoint();}else {AI->StopMove();} }void AEnemy::Killed() {if (bIsDead) {return;}bIsDead = true;GetCharacterMovement()->MaxWalkSpeed = 300.0f;AAIEnemy* AI = Cast<AAIEnemy>(GetController());AI->GoHome(); }void AEnemy::ReArm() {bIsDead = false;GetCharacterMovement()->MaxWalkSpeed = 150.0f;if (bIsVulnerable) {SetInVulnerable();}SetMove(true); } void AEnemy::OnCollision(UPrimitiveComponent * HitComp, AActor * OtherActor, UPrimitiveComponent * OtherComp, int OtherBodyIndex, bool bFromSweep, const FHitResult & SweepResult) {if (OtherActor->IsA(APacManCharacter::StaticClass())){if (bIsVulnerable) {Killed();}else{APacManCharacter* PacMan = Cast<APacManCharacter>(OtherActor);PacMan->Killed();}} }

AIEnemy.h

// Fill out your copyright notice in the Description page of Project Settings.#pragma once#include "CoreMinimal.h" #include "AIController.h" #include "..\Public\Enemy.h" #include "..\MypacmanGameModeBase.h" #include "..\Public\PacManCharacter.h" #include "AIEnemy.generated.h"/*** */ UCLASS() class MYPACMAN_API AAIEnemy : public AAIController {GENERATED_BODY()public:void OnPossess(class APawn* InPawn) override; //==beginplayvirtual void OnMoveCompleted(FAIRequestID RequestID, const FPathFollowingResult& Result) override;//移动停止做什么void SearchNewPoint();void GoHome();void ReArm();//void StopMove();private:class AEnemy* Bot;FVector HomeLocation;FTimerHandle DeadTime;AMypacmanGameModeBase* GameMode; };

AIEnemy.cpp

// Fill out your copyright notice in the Description page of Project Settings.//#include "AIEnemy.h" #include "..\Public\AIEnemy.h" #include "NavigationSystem.h" #include "Kismet/GameplayStatics.h" #include "TimerManager.h"void AAIEnemy::OnPossess(class APawn* InPawn) {Super::OnPossess(InPawn);Bot = Cast<AEnemy>(InPawn);HomeLocation = Bot->GetActorLocation();SearchNewPoint();GameMode = Cast<AMypacmanGameModeBase>(UGameplayStatics::GetGameMode(this));}void AAIEnemy::OnMoveCompleted(FAIRequestID RequestID, const FPathFollowingResult & Result) {if (!Bot->bIsDead && GameMode->GetCurrentState()!=EGameState::Epause) {SearchNewPoint();} } //这个函数很重要,最好看下底层源码 void AAIEnemy::SearchNewPoint() {UNavigationSystemV1* NavMesh = FNavigationSystem::GetCurrent<UNavigationSystemV1>(this);if (NavMesh) {const float SearchRadius = 10000.0f;FNavLocation RandomPt;const bool bFound = NavMesh->GetRandomReachablePointInRadius(Bot->GetActorLocation(), SearchRadius, RandomPt);//const bool bFound = NavMesh->GetRandomReachablePointInRadius(myPacMan->GetActorLocation(), SearchRadius, RandomPt);if (bFound){MoveToLocation(RandomPt);}} }void AAIEnemy::GoHome() {MoveToLocation(HomeLocation);GetWorldTimerManager().SetTimer(DeadTime,this,&AAIEnemy::ReArm,5.0f,false); }void AAIEnemy::ReArm() {GetWorldTimerManager().ClearTimer(DeadTime);Bot->ReArm(); }void AAIEnemy::StopMove() {//StopMovement();MoveToLocation(Bot->GetActorLocation()); }

这里还需要改个东西

MypacmanGameModeBase.h

// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.#pragma once#include "CoreMinimal.h" #include "GameFramework/GameModeBase.h" //#include "PacManCharacter.h" #include "MypacmanGameModeBase.generated.h"/*** */ enum class EGameState :short {EMenu,EPlaying,Epause,EGameOver,EWin }; UCLASS() class MYPACMAN_API AMypacmanGameModeBase : public AGameModeBase {GENERATED_BODY()public:virtual void BeginPlay() override;EGameState GetCurrentState() const;void SetCurrentState(EGameState value);void SetEnemyVulnerable();private:EGameState currentState;TArray<class AEnemy*> Enemys; };FORCEINLINE EGameState AMypacmanGameModeBase::GetCurrentState() const { return currentState; };

AMypacmanGameModeBase.cpp

// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.#include "MypacmanGameModeBase.h" #include "Public/Enemy.h" #include "EngineUtils.h"void AMypacmanGameModeBase::SetCurrentState(EGameState value) {currentState = value;switch (value){case EGameState::EPlaying:for (auto Iter(Enemys.CreateIterator()); Iter; ++Iter){(*Iter)->SetMove(true);}break;case EGameState::Epause:for (auto Iter(Enemys.CreateIterator()); Iter; ++Iter){(*Iter)->SetMove(false);}break;case EGameState::EGameOver:for (auto Iter(Enemys.CreateIterator()); Iter; ++Iter){(*Iter)->Destroy();}break;case EGameState::EWin:for (auto Iter(Enemys.CreateIterator()); Iter; ++Iter){(*Iter)->Destroy();}break;default:break;} } void AMypacmanGameModeBase::SetEnemyVulnerable() {for (auto Iter(Enemys.CreateIterator()); Iter; ++Iter){(*Iter)->SetVulnerable();} } void AMypacmanGameModeBase::BeginPlay() {Super::BeginPlay();SetCurrentState(EGameState::EMenu);for (TActorIterator<AEnemy> enemyIter(GetWorld()); enemyIter; ++enemyIter){AEnemy* enemy = Cast<AEnemy>(*enemyIter);if (enemy){Enemys.Add(enemy);}}}

总结

以上是生活随笔为你收集整理的UE4小游戏4的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。