// FPSDemoGameModeBase.h
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/GameModeBase.h"
#include "FPSDemoGameModeBase.generated.h"
UCLASS()
class FPSDEMO_API AFPSDemoGameModeBase : public AGameModeBase
{
GENERATED_BODY()
virtual void StartPlay() override;
};
// FPSDemoGameModeBase.cpp
#include "FPSDemoGameModeBase.h"
#include "Engine/Engine.h"
void AFPSDemoGameModeBase::StartPlay() {
Super::StartPlay();
if (GEngine) {
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Yellow, TEXT("Hello World, this is FPSGameMode!"));
}
}
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "Camera/CameraComponent.h"
#include "Components/CapsuleComponent.h"
#include "FPSProjectile.h"
#include "FPSCharacter.generated.h"
UCLASS()
class FPSDEMO_API AFPSCharacter : public ACharacter
{
GENERATED_BODY()
public:
// Sets default values for this character's properties
AFPSCharacter();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
// 要生成的发射物类。
UPROPERTY(EditDefaultsOnly, Category = Projectile)
TSubclassOf<class AFPSProjectile> ProjectileClass;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
// Called to bind functionality to input
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
UFUNCTION()
void MoveForward(float value);
UFUNCTION()
void MoveRight(float value);
UFUNCTION()
void StartJump();
UFUNCTION()
void StopJump();
// 处理发射物射击的函数。
UFUNCTION()
void Fire();
UPROPERTY(VisibleAnywhere)
UCameraComponent* FPSCameraComponent;
//第一人称 手臂
UPROPERTY(VisibleDefaultsOnly, Category = Mesh)
USkeletalMeshComponent* FPSMesh;
// 枪口相对于摄像机位置的偏移。
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Gameplay)
FVector MuzzleOffset;
};
#include "FPSCharacter.h"
#include "Engine/Engine.h"
#include "Components/InputComponent.h"
#include "GameFramework/PlayerController.h"
#include "Components/SkeletalMeshComponent.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("FirstPersonCamera"));
if (FPSCameraComponent) {
FPSCameraComponent->SetupAttachment(CastChecked<USceneComponent, UCapsuleComponent>(GetCapsuleComponent()));
}
FPSCameraComponent->SetRelativeLocation(FVector(0.0f, 0.0f, 50.0f + BaseEyeHeight));
FPSCameraComponent->bUsePawnControlRotation = true;
//手臂
FPSMesh = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("FirstPersonMesh"));
check(FPSMesh != nullptr);
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();
if (GEngine) {
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("MoveForward", this, &AFPSCharacter::MoveForward);
PlayerInputComponent->BindAxis("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);
// 设置MuzzleOffset,在略靠近摄像机前生成发射物。
MuzzleOffset.Set(100.0f, 0.0f, 0.0f);
FVector MuzzleLocation = CameraLocation + FTransform(CameraRotation).TransformVector(MuzzleOffset);
//使目标方向略向上倾斜
FRotator MuzzleRotation = CameraRotation;
MuzzleRotation.Pitch += 10.0f;
UWorld* World = GetWorld();
if (World) {
FActorSpawnParameters SpawnParams;
SpawnParams.Owner = this;
SpawnParams.Instigator = GetInstigator();
//在枪口位置生成发射物
AFPSProjectile* Projectile = World->SpawnActor<AFPSProjectile>(ProjectileClass, MuzzleLocation, MuzzleRotation, SpawnParams);
if (Projectile) {
//设置发射物初始轨迹
FVector LaunchDirection = MuzzleRotation.Vector();
Projectile->FireInDirection(LaunchDirection);
}
}
}
}