// Fill out your copyright notice in the Description page of Project Settings.#pragmaonce#include"CoreMinimal.h"#include"GameFramework/Character.h"#include"MainPlayer.generated.h"UCLASS()classUEGAME_API AMainPlayer :public ACharacter
{GENERATED_BODY()public:// Sets default values for this character's propertiesAMainPlayer();//新建一个SpringArmUPROPERTY(visibleAnywhere,BlueprintReadOnly)classUSpringArmComponent* SpringArm;//新建一个CameraUPROPERTY(visibleAnywhere, BlueprintReadOnly)classUCameraComponent* FollowCamera;float BaseTurnRate;//使用键盘X转向的速率float BaseLookUpRate;//使用键盘Y转向的速率//主角状态UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category ="Playe State")float Health;UPROPERTY(EditAnywhere, BlueprintReadOnly, Category ="Playe State")float MaxHealth;UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category ="Playe State")float Stamina;UPROPERTY(EditAnywhere, BlueprintReadOnly, Category ="Playe State")float MaxStamina;UPROPERTY(EditAnywhere, BlueprintReadOnly, Category ="Playe State")int Coins;protected:// Called when the game starts or when spawnedvirtualvoidBeginPlay()override;public:// Called every framevirtualvoidTick(float DeltaTime)override;// Called to bind functionality to inputvirtualvoidSetupPlayerInputComponent(classUInputComponent* PlayerInputComponent)override;//重新Character类中的Jump方法voidJump()override;voidMoveForward(float value);voidMoveRight(float value);voidTurn(float Value);voidLookUp(float Value);voidTurnRate(float Rate);voidLookUpRate(float Rate);//改变状态voidAddHealth(float value);voidAddStamina(float value);voidAddCoin(float value);};
MainPlayer.cpp
// Fill out your copyright notice in the Description page of Project Settings.#include"MainPlayer.h"#include"GameFramework/SpringArmComponent.h"#include"Camera/CameraComponent.h"#include"Components/CapsuleComponent.h"#include"Components/InputComponent.h"#include"GameFramework/PlayerController.h"#include"GameFramework/CharacterMovementComponent.h"// Sets default valuesAMainPlayer::AMainPlayer(){// 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;SpringArm =CreateDefaultSubobject<USpringArmComponent>(TEXT("SpringArm"));SpringArm->SetupAttachment(GetRootComponent());//设置SPringArm无碰撞臂长SpringArm->TargetArmLength =600.f;SpringArm->bUsePawnControlRotation =true;//硬编码SpringArm继承controlller旋转为真FollowCamera =CreateDefaultSubobject<UCameraComponent>(TEXT("FollowCamera"));FollowCamera->SetupAttachment(SpringArm, NAME_None);FollowCamera->bUsePawnControlRotation =false;//硬编码FollowCamera继承controlller旋转为假//设置胶囊体的默认宽高GetCapsuleComponent()->SetCapsuleSize(35.f,100.f);//对Character的Pawn进行硬编码bUseControllerRotationPitch =false;bUseControllerRotationYaw =false;bUseControllerRotationRoll =false;//硬编码orient Rotation to Movement,给个默认转向速率GetCharacterMovement()->bOrientRotationToMovement =true;GetCharacterMovement()->RotationRate =FRotator(0.f,500.f,0.f);//设置跳跃初始值与在空中的坠落时横向运动控制量GetCharacterMovement()->JumpZVelocity =600.f;GetCharacterMovement()->AirControl =0.15f;//给键盘控制转向的速率变量赋初值BaseTurnRate =21.f;BaseLookUpRate =21.f;//初始化角色状态MaxHealth =100.f;Health = MaxHealth;MaxStamina =200.f;Stamina = MaxStamina;Coins =0;}// Called when the game starts or when spawnedvoidAMainPlayer::BeginPlay(){Super::BeginPlay();}// Called every framevoidAMainPlayer::Tick(float DeltaTime){Super::Tick(DeltaTime);}// Called to bind functionality to inputvoidAMainPlayer::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent){Super::SetupPlayerInputComponent(PlayerInputComponent);//检查PlayerInputComponent指针,check函数只能在这使用check(PlayerInputComponent);//绑定跳跃轴映射事件PlayerInputComponent->BindAction("Jump", IE_Pressed,this,&AMainPlayer::Jump);//按下空格PlayerInputComponent->BindAction("Jump", IE_Released,this,&ACharacter::StopJumping);//抬起空格//绑定移动轴映射事件PlayerInputComponent->BindAxis("MoveForward",this,&AMainPlayer::MoveForward);PlayerInputComponent->BindAxis("MoveRight",this,&AMainPlayer::MoveRight);//绑定Controller控制器去管理视角旋转PlayerInputComponent->BindAxis("Turn",this,&AMainPlayer::Turn);PlayerInputComponent->BindAxis("LookUp",this,&AMainPlayer::LookUp);//绑定键盘鼠标轴映射事件PlayerInputComponent->BindAxis("TurnRate",this,&AMainPlayer::TurnRate);PlayerInputComponent->BindAxis("LookUpRate",this,&AMainPlayer::LookUpRate);}voidAMainPlayer::Jump(){//继承父类的方法Super::Jump();}voidAMainPlayer::MoveForward(float value){if(Controller !=nullptr&& value !=0.f){//获取到Control旋转FRotator Rotation = Controller->GetControlRotation();//转向只关注水平Yaw方向,因此置0防止影响FRotator YowRotation =FRotator(0.0f, Rotation.Yaw,0.0f);//获取相机(鼠标控制器的朝向),并且朝这个轴的方向移动FVector Direction =FRotationMatrix(YowRotation).GetUnitAxis(EAxis::X);AddMovementInput(Direction, value);}}voidAMainPlayer::MoveRight(float value){if(Controller !=nullptr&& value !=0.f){//获取到Controller旋转FRotator Rotation = Controller->GetControlRotation();//转向只关注水平Yaw方向,因此置0防止影响FRotator YowRotation =FRotator(0.0f, Rotation.Yaw,0.0f);//获取相机(鼠标控制器的朝向),并且朝这个轴的方向移动FVector Direction =FRotationMatrix(YowRotation).GetUnitAxis(EAxis::Y);AddMovementInput(Direction, value);}}voidAMainPlayer::Turn(float Value){if(Value !=0.f){AddControllerYawInput(Value);}}voidAMainPlayer::LookUp(float Value){//UE_LOG(LogTemp, Warning, TEXT("%f"), GetControlRotation().Pitch);// //控制视角if(GetControlRotation().Pitch <270.f&&GetControlRotation().Pitch >180.f&& Value >0.f){return;}elseif(GetControlRotation().Pitch <180.f&&GetControlRotation().Pitch >45.f&& Value <0.f){return;}AddControllerPitchInput(Value);}voidAMainPlayer::TurnRate(float Rate){//要乘以一个DeltaTime这样就可以避免高帧底帧差值问题float Value = Rate * BaseTurnRate *GetWorld()->GetDeltaSeconds();if(Value !=0.f){AddControllerYawInput(Value);}}voidAMainPlayer::LookUpRate(float Rate){//要乘以一个DeltaTime这样就可以避免高帧底帧差值问题float Value = Rate * BaseLookUpRate *GetWorld()->GetDeltaSeconds();//控制视角if(GetControlRotation().Pitch <270.f&&GetControlRotation().Pitch >180.f&& Value >0.f){return;}elseif(GetControlRotation().Pitch <180.f&&GetControlRotation().Pitch >45.f&& Value <0.f){return;}AddControllerPitchInput(Value);}voidAMainPlayer::AddHealth(float value){Health =FMath::Clamp(Health + value,0.f, MaxHealth);}voidAMainPlayer::AddStamina(float value){Stamina =FMath::Clamp(Stamina + value,0.f, MaxStamina);}voidAMainPlayer::AddCoin(float value){Coins += value;}
// Fill out your copyright notice in the Description page of Project Settings.#pragmaonce#include"CoreMinimal.h"#include"GameFramework/Actor.h"#include"InteroperableItem.generated.h"UCLASS()classUEGAME_API AInteroperableItem :public AActor
{GENERATED_BODY()public:// Sets default values for this actor's propertiesAInteroperableItem();//球形触发器UPROPERTY(VisibleAnywhere, BlueprintReadWrite)classUSphereComponent* TriggerVolume;UPROPERTY(VisibleAnywhere, BlueprintReadWrite)classUStaticMeshComponent* DisplayMesh;//粒子组件UPROPERTY(VisibleAnywhere, BlueprintReadWrite)classUParticleSystemComponent* ParticleEffectsComponent;//粒子资源UPROPERTY(EditAnywhere, BlueprintReadWrite, Category ="Interoperable Item|Particles")classUParticleSystem* Particle;UPROPERTY(EditAnywhere, BlueprintReadWrite, Category ="Interoperable Item|Sounds")classUSoundCue* Sound;UPROPERTY(EditAnywhere, BlueprintReadWrite, Category ="Interoperable Item|Properties")bool bRotate;UPROPERTY(EditAnywhere, BlueprintReadWrite, Category ="Interoperable Item|Properties")float RotationRate;protected:// Called when the game starts or when spawnedvirtualvoidBeginPlay()override;public:// Called every framevirtualvoidTick(float DeltaTime)override;//自定义AddDynamic绑定的触发器函数UFUNCTION()virtualvoidOnOverlapBegin(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex,bool bFromSweep,const FHitResult& SweepResult);UFUNCTION()virtualvoidOnOverlapEnd(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex);};
InteroperableItem.cpp
// Fill out your copyright notice in the Description page of Project Settings.#include"InteroperableItem.h"#include"Components/SphereComponent.h"#include"Components/StaticMeshComponent.h"#include"Particles/ParticleSystemComponent.h"// Sets default valuesAInteroperableItem::AInteroperableItem(){// 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;TriggerVolume =CreateDefaultSubobject<USphereComponent>(TEXT("TriggerVolume"));RootComponent = TriggerVolume;//设置TriggerVolume碰撞的硬编码TriggerVolume->SetCollisionEnabled(ECollisionEnabled::QueryOnly);//设置碰撞类型TriggerVolume->SetCollisionObjectType(ECollisionChannel::ECC_WorldStatic);//设置对象移动时其应视为某种物体TriggerVolume->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Ignore);//设置所有的碰撞响应为忽略TriggerVolume->SetCollisionResponseToChannel(ECollisionChannel::ECC_Pawn, ECollisionResponse::ECR_Overlap);//设置Pawn碰撞响应为重叠DisplayMesh =CreateDefaultSubobject<UStaticMeshComponent>(TEXT("DisplayMesh"));DisplayMesh->SetupAttachment(GetRootComponent());ParticleEffectsComponent =CreateDefaultSubobject<UParticleSystemComponent>(TEXT("ParticleEffects"));ParticleEffectsComponent->SetupAttachment(GetRootComponent());bRotate =true;RotationRate =45.f;}// Called when the game starts or when spawnedvoidAInteroperableItem::BeginPlay(){Super::BeginPlay();TriggerVolume->OnComponentBeginOverlap.AddDynamic(this,&AInteroperableItem::OnOverlapBegin);TriggerVolume->OnComponentEndOverlap.AddDynamic(this,&AInteroperableItem::OnOverlapEnd);}// Called every framevoidAInteroperableItem::Tick(float DeltaTime){Super::Tick(DeltaTime);if(bRotate){FRotator rotator =GetActorRotation();rotator.Yaw += RotationRate * DeltaTime;SetActorRotation(rotator);}}voidAInteroperableItem::OnOverlapBegin(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex,bool bFromSweep,const FHitResult& SweepResult){}voidAInteroperableItem::OnOverlapEnd(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex){}
// Fill out your copyright notice in the Description page of Project Settings.#pragmaonce#include"CoreMinimal.h"#include"GamePlay/InteroperableItem.h"#include"PickItem.generated.h"/*** */UCLASS()classUEGAME_API APickItem :public AInteroperableItem
{GENERATED_BODY()public:APickItem();public:voidOnOverlapBegin(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex,bool bFromSweep,const FHitResult& SweepResult)override;voidOnOverlapEnd(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex)override;UFUNCTION(BlueprintImplementEvent, Category ="Pick")voidOnPick(classAMainPlayer* Palyer);};
PickItem.cpp
// Fill out your copyright notice in the Description page of Project Settings.#include"PickItem.h"#include"Kismet/GamePlayStatics.h"#include"Characters/Player/MainPlayer.h"#include"Sound/SoundCue.h"APickItem::APickItem(){}voidAPickItem::OnOverlapBegin(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex,bool bFromSweep,const FHitResult& SweepResult){if(OtherActor){AMainPlayer* Player =Cast<AMainPlayer>(OtherActor);if(Player){UGameplayStatics::SpawnEmitterAtLocation(this, Particle,GetActorLocation(),FRotator(0.f),true);}if(Sound){UGameplayStatics::PlaySound2D(this, Sound);}OnPick(Player);//交给蓝图可视化去处理Destroy();}}voidAPickItem::OnOverlapEnd(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex){}