UE4 手动创建一个第一人称游戏

根据UE4官方文档,自己动手创建一个第一人称射击游戏。文档详细地址:UE4官方文档第一人称射击游戏

  1. 定义角色
    FPSCharacter.h
// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "FPSCharacter.generated.h"

UCLASS()
class FPSPROJECT_API AFPSCharacter : public ACharacter {
    
    
	GENERATED_BODY()

public:
	// Sets default values for this character's properties
	AFPSCharacter();

	//枪口的偏移位置
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "AAA")
	FVector MuzzleOffset;

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

public:
	// Called every frame
	virtual void Tick(float DeltaTime) override;

	// Called to bind functionality to input
	virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;


private:
	//向前或者向后移动
	UFUNCTION()
	void MoveForward(float Value);

	//向左或者向右移动
	UFUNCTION()
	void MoveRight(float Value);

	UFUNCTION()
	void StartJump();

	UFUNCTION()
	void StopJump();

	UFUNCTION()
	void Fire();

	//摄像机组件
	/**
	* 如果不添加摄像机组件的话,会有一个默认的摄像机组件,并且在模型脖子的位置
	*/
	UPROPERTY(VisibleAnywhere, Category = "AAA")
	class UCameraComponent* FPSCameraComponent;

	//设置第一人称的网格体组件
	UPROPERTY(VisibleAnywhere, Category = "AAA")
	class USkeletalMeshComponent* FPSMesh;

	

	//生产发射物类
	/**
	* TSubclassOf 是提供的UClass类型安全模板类
	*/
	UPROPERTY(EditDefaultsOnly, Category = "AAA")
	TSubclassOf<class AFPSProjectile> ProjectileClass;

};

FPSCharacter.cpp

// Fill out your copyright notice in the Description page of Project Settings.


#include "FPSCharacter.h"
#include "Engine/Engine.h"
#include "Camera/CameraComponent.h"
#include "Components/CapsuleComponent.h"
#include "Components/SkeletalMeshComponent.h"
#include "FPSProjectile.h"

// Sets default values
AFPSCharacter::AFPSCharacter() {
    
    
	// 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;
	FPSCameraComponent = CreateDefaultSubobject<UCameraComponent>(TEXT("FPSCameraComponent"));

	//将摄像机组件放到胶囊体下面
#if 0
	FPSCameraComponent->SetupAttachment(GetRootComponent());
#else
	FPSCameraComponent->SetupAttachment(Cast<UCapsuleComponent>(GetCapsuleComponent()));
#endif
	//将摄像机放到眼睛上方不远处
	FPSCameraComponent->SetRelativeLocation(FVector(0.0, 0.0, 50.0 + BaseEyeHeight));

	//使用Pawn来控制摄像机旋转
	FPSCameraComponent->bUsePawnControlRotation = true;

	//设置第一人称骨骼模型
	FPSMesh = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("FirstPersonMesh"));

	//设置该模型仅对玩家可见
	FPSMesh->SetOnlyOwnerSee(true);

	//设置根组件
	FPSMesh->SetupAttachment(FPSCameraComponent);

	//禁用部分环境阴影,保留单一模型存在的假象
	FPSMesh->bCastDynamicShadow = false;//动态阴影
	FPSMesh->CastShadow = false;//投影

	//拥有玩家无法看到普通(第三人称)身体模型
	GetMesh()->SetOwnerNoSee(true);
}

// Called when the game starts or when spawned
void AFPSCharacter::BeginPlay() {
    
    
	Super::BeginPlay();
	GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Red, TEXT("We are using FPSCharacter."));
}

// Called every frame
void AFPSCharacter::Tick(float DeltaTime) {
    
    
	Super::Tick(DeltaTime);

}

// Called to bind functionality to input
void AFPSCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent) {
    
    
	Super::SetupPlayerInputComponent(PlayerInputComponent);

	PlayerInputComponent->BindAxis(TEXT("MoveForward"), this, &AFPSCharacter::MoveForward);
	PlayerInputComponent->BindAxis(TEXT("MoveRight"), this, &AFPSCharacter::MoveRight);

	PlayerInputComponent->BindAxis("Turn", this, &AFPSCharacter::AddControllerYawInput);
	PlayerInputComponent->BindAxis("LookUp", this, &AFPSCharacter::AddControllerPitchInput);

	PlayerInputComponent->BindAction("Jump", IE_Pressed, this, &AFPSCharacter::StartJump);
	PlayerInputComponent->BindAction("Jump", IE_Released, this, &AFPSCharacter::StopJump);

	PlayerInputComponent->BindAction("Fire", IE_Pressed, this, &AFPSCharacter::Fire);
}

void AFPSCharacter::MoveForward(float Value) {
    
    
	FVector direction = FRotationMatrix(Controller->GetControlRotation()).GetScaledAxis(EAxis::X);
	AddMovementInput(direction, Value);
}

void AFPSCharacter::MoveRight(float Value) {
    
    
	FVector direction = FRotationMatrix(Controller->GetControlRotation()).GetScaledAxis(EAxis::Y);
	AddMovementInput(direction, Value);
}

void AFPSCharacter::StartJump() {
    
    
	bPressedJump = true;
}

void AFPSCharacter::StopJump() {
    
    
	bPressedJump = false;
}

void AFPSCharacter::Fire() {
    
    
	if (ProjectileClass){
    
    
		//获取摄像机的视点变换的位置
		FVector CameraLocation;
		FRotator CameraRotation;
		GetActorEyesViewPoint(CameraLocation, CameraRotation);

		//枪口的本地坐标装换成世界坐标
		FVector MuzzleLoacation = CameraLocation + FTransform(CameraRotation).TransformVector(MuzzleOffset);
		FRotator MuzzleRotator = CameraRotation;

		//枪口向上抬起10.0度
		MuzzleRotator.Pitch += 10.0;

		UWorld* world = GetWorld();
		if (world){
    
    
			//生成物参数,也就是生产子弹的参数
			FActorSpawnParameters SpawnParameters;
			SpawnParameters.Owner = this;
			SpawnParameters.Instigator = GetInstigator();

			//在枪口出生产发射物
			AFPSProjectile* FPSProjectile = world->SpawnActor<AFPSProjectile>(ProjectileClass, MuzzleLoacation, MuzzleRotator, SpawnParameters);
			
			//设置发射物的初始轨道
			FVector LaunchDirection = MuzzleRotator.Vector();
			FPSProjectile->FireInDirection(LaunchDirection);
		}
	}
}
  1. HUD
// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/HUD.h"
#include "FPSHUD.generated.h"

/**
 *
 */
UCLASS()
class FPSPROJECT_API AFPSHUD : public AHUD {
    
    
	GENERATED_BODY()

public:
	virtual void DrawHUD()override;

	UPROPERTY(EditAnywhere)
	UTexture2D* CrosshairTexture;
};

// Fill out your copyright notice in the Description page of Project Settings.


#include "FPSHUD.h"
#include "Engine/Canvas.h"

void AFPSHUD::DrawHUD() {
    
    
	Super::DrawHUD();
	if (CrosshairTexture){
    
    
		//找到画布的中心
		FVector2D Center(Canvas->ClipX * 0.5f, Canvas->ClipY * 0.5f);
		FVector2D CrossHairDrawPosition(Center.X - (CrosshairTexture->GetSurfaceWidth() * 0.5), Center.Y - (CrosshairTexture->GetSurfaceHeight() * 0.5));
	
		FCanvasTileItem TileItem(CrossHairDrawPosition,CrosshairTexture->Resource, FLinearColor::White);
		Canvas->DrawItem(TileItem);
	}
}

  1. 子弹类
// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "FPSProjectile.generated.h"

/**
* 子弹类
*/

UCLASS()
class FPSPROJECT_API AFPSProjectile : public AActor {
    
    
	GENERATED_BODY()

public:
	// Sets default values for this actor's properties
	AFPSProjectile();

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

public:
	// Called every frame
	virtual void Tick(float DeltaTime) override;

public:
	//球体碰撞组件
	UPROPERTY(VisibleDefaultsOnly, Category = "AAA")
	class USphereComponent* CollisionComponment;

	//子弹组件
	UPROPERTY(VisibleAnywhere, Category = "AAA")
	class UStaticMeshComponent* ProjectileComponent;

	UPROPERTY(VisibleAnywhere, Category = "AAA")
	class UProjectileMovementComponent* ProjectileMovementComponent;

	//在发射方向上设置在发射物的初始速度
	void FireInDirection(const FVector& ShootDirection);


};

// Fill out your copyright notice in the Description page of Project Settings.


#include "FPSProjectile.h"
#include "Components/SphereComponent.h"
#include "GameFramework/ProjectileMovementComponent.h"

// Sets default values
AFPSProjectile::AFPSProjectile() {
    
    
	// 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;

	//碰撞球体
	CollisionComponment = CreateDefaultSubobject<USphereComponent>(TEXT("SphereComponent"));
	CollisionComponment->SetSphereRadius(15.0);//设置球体半径
	RootComponent = Cast<USceneComponent>(CollisionComponment);

	//静态网格体
	ProjectileComponent = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("ProjectileComponent"));
	ProjectileComponent->SetupAttachment(RootComponent);

	//运动组件
	ProjectileMovementComponent = CreateDefaultSubobject<UProjectileMovementComponent>(TEXT("ProjectileMovementComponent"));
	ProjectileMovementComponent->SetUpdatedComponent(CollisionComponment);//设置更新的组件

	//设置碰撞预设
	CollisionComponment->BodyInstance.SetCollisionProfileName(TEXT("Projectile"));
	ProjectileMovementComponent->InitialSpeed = 3000.0;//设置初始速度
	ProjectileMovementComponent->MaxSpeed = 3000.0;//设置最大速度

	//这个子弹在旋转过程中在每一帧中都要更新,以匹配他的速度方向
	ProjectileMovementComponent->bRotationFollowsVelocity = true;

	//设置反弹
	ProjectileMovementComponent->bShouldBounce = true;
	//设置反弹系数
	ProjectileMovementComponent->Bounciness = 0.3;

	//设置重力系数
	ProjectileMovementComponent->ProjectileGravityScale = 0.0;

	//3秒后消亡
	InitialLifeSpan = 3.0;
}

// Called when the game starts or when spawned
void AFPSProjectile::BeginPlay() {
    
    
	Super::BeginPlay();

}

// Called every frame
void AFPSProjectile::Tick(float DeltaTime) {
    
    
	Super::Tick(DeltaTime);

}

void AFPSProjectile::FireInDirection(const FVector& ShootDirection) {
    
    
	ProjectileMovementComponent->Velocity = ShootDirection * ProjectileMovementComponent->InitialSpeed;
}


  1. 游戏模式类
// Copyright Epic Games, Inc. All Rights Reserved.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/GameModeBase.h"
#include "FPSProjectGameModeBase.generated.h"

/**
 * 
 */
UCLASS()
class FPSPROJECT_API AFPSProjectGameModeBase : public AGameModeBase
{
    
    
	GENERATED_BODY()
private:
	virtual void StartPlay()override;
};

// Copyright Epic Games, Inc. All Rights Reserved.


#include "FPSProjectGameModeBase.h"
#include "Engine/Engine.h"
#include "Kismet/KismetSystemLibrary.h"

void AFPSProjectGameModeBase::StartPlay() {
    
    
	Super::StartPlay();

	if (GEngine) {
    
    
		GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Yellow, TEXT("Hello World, this is FPSGameMode!"));
	}

	UKismetSystemLibrary::DrawDebugCoordinateSystem(GetWorld(), FVector(0.0, 0.0, 50.0), FRotator(0.0, 0.0, 0.0), 10.0, 100,10);

	UKismetSystemLibrary::DrawDebugString(GetWorld(), FVector(100.0, 0.0, 100.0), TEXT("My Name"), NULL, FLinearColor::Red, 50.0);
}
  1. 具体的模型下载可以在官网链接上下载
  2. UEEditor截图
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/wb175208/article/details/128013190