// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Pawn.h"
#include "CollidingPawn.generated.h"
//CollidingPawn.h
UCLASS()
class HOWTO_COMPONENTS_API ACollidingPawn : public APawn
{
GENERATED_BODY()
public:
// Sets default values for this pawn's properties
ACollidingPawn();
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;
UPROPERTY()
class UParticleSystemComponent* OurParticleSystem;//粒子系统
UPROPERTY()
class UCollidingPawnMovementComponent* OurMovementComponent;//移动系统
virtual UPawnMovementComponent* GetMovementComponent() const override;//重写函数以便导入我们自己设置的input
//移动函数
void MoveForward(float AxisValue);
void MoveRight(float AxisValue);
void Turn(float AxisValue);
void ParticleToggle();
};
//CollidingPawn.cpp
#include "CollidingPawn.h"
#include "CollidingPawnMovementComponent.h"
#include "Camera/CameraComponent.h"
#include "Components/SphereComponent.h"
#include "GameFramework/SpringArmComponent.h"
#include "Particles/ParticleSystemComponent.h"
// Sets default values
ACollidingPawn::ACollidingPawn()
{
// Set this pawn to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
USphereComponent* SphereComponent=CreateDefaultSubobject<USphereComponent>(TEXT("RootComponent"));//创建球体
RootComponent=SphereComponent;//设置为根物体
SphereComponent->InitSphereRadius(40.0);//设置半径
//SphereComponent->SetCollisionProfileName(TEXT("Pawn"));
UStaticMeshComponent* SphereVisual =CreateDefaultSubobject<UStaticMeshComponent>(TEXT("VisualRepresentation"));
SphereVisual->SetupAttachment(RootComponent);
static ConstructorHelpers::FObjectFinder<UStaticMesh> SphereVisualAsset(TEXT("/Game/StarterContent/Shapes/Shape_Sphere.Shape_Sphere"));
if(SphereVisualAsset.Succeeded())//找到球体,如果找到的话,设置其为静态网格体,设置位置以及缩放
{
SphereVisual->SetStaticMesh(SphereVisualAsset.Object);
SphereVisual->SetRelativeLocation(FVector(0,0,-40));
SphereVisual->SetWorldScale3D(FVector(0.8));
}
OurParticleSystem = CreateDefaultSubobject<UParticleSystemComponent>(TEXT("MovementParticles"));
OurParticleSystem->SetupAttachment(SphereVisual);
OurParticleSystem->bAutoActivate=false;
OurParticleSystem->SetRelativeLocation(FVector(-20,0,-20));
static ConstructorHelpers::FObjectFinder<UParticleSystem> ParticleAsset(TEXT("/Game/StarterContent/Particles/P_Fire.P_Fire"));
if(ParticleAsset.Succeeded())
{
OurParticleSystem->SetTemplate(ParticleAsset.Object);
}
USpringArmComponent* SpringArm=CreateDefaultSubobject<USpringArmComponent>(TEXT("CameraAttachmentArm"));
SpringArm->SetupAttachment(RootComponent);
SpringArm->SetRelativeLocation(FVector(-40,0,0));
SpringArm->TargetArmLength=400;//弹簧臂长度
SpringArm->bEnableCameraLag=true;//是否平滑
SpringArm->CameraLagSpeed=3;//平滑速度
UCameraComponent* Camera=CreateDefaultSubobject<UCameraComponent>(TEXT("ActualCamera"));
Camera->SetupAttachment(SpringArm,USpringArmComponent::SocketName);//将新创建的摄像机设置在弹簧臂的插槽上
AutoPossessPlayer=EAutoReceiveInput::Player0;//设置默认控制玩家
OurMovementComponent=CreateDefaultSubobject<UCollidingPawnMovementComponent>(TEXT("CustomMovementComponent"));
OurMovementComponent->UpdatedComponent=RootComponent;//更新根组件
}
UPawnMovementComponent* ACollidingPawn::GetMovementComponent() const//重写方法
{
return OurMovementComponent;
}
// Called when the game starts or when spawned
void ACollidingPawn::BeginPlay()
{
Super::BeginPlay();
}
// Called every frame
void ACollidingPawn::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
// Called to bind functionality to input
void ACollidingPawn::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
//绑定按键
InputComponent->BindAction("ParticleToggle",IE_Pressed,this,&ACollidingPawn::ParticleToggle);
InputComponent->BindAxis("MoveForward",this,&ACollidingPawn::MoveForward);
InputComponent->BindAxis("MoveRight",this,&ACollidingPawn::MoveRight);
InputComponent->BindAxis("Turn",this,&ACollidingPawn::Turn);
}
void ACollidingPawn::MoveForward(float AxisValue)
{
if(OurMovementComponent&&(OurMovementComponent->UpdatedComponent==RootComponent))
{
OurMovementComponent->AddInputVector(GetActorForwardVector()*AxisValue);
}
}
void ACollidingPawn::MoveRight(float AxisValue)
{
if(OurMovementComponent&&(OurMovementComponent->UpdatedComponent==RootComponent))
{
OurMovementComponent->AddInputVector(GetActorRightVector()*AxisValue);
}
}
void ACollidingPawn::Turn(float AxisValue)
{
FRotator ro=GetActorRotation();
ro.Yaw+=AxisValue;
SetActorRotation(ro);
}
void ACollidingPawn::ParticleToggle()
{
if(OurParticleSystem&&OurParticleSystem->Template)
{
OurParticleSystem->ToggleActive();
}
}
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/PawnMovementComponent.h"
#include "CollidingPawnMovementComponent.generated.h"
/**
* CollidingPawnMoment.h
*/
UCLASS()
class HOWTO_COMPONENTS_API UCollidingPawnMovementComponent : public UPawnMovementComponent
{
GENERATED_BODY()
public:
//重写tickcomponent方法
virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
};
//CollidingPawnMovement.cpp
#include "CollidingPawnMovementComponent.h"
void UCollidingPawnMovementComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
if(!PawnOwner||!UpdatedComponent||ShouldSkipUpdate(DeltaTime))//如果不是玩家,不是更新组件,如果不能移动等
{
return;
}
FVector DesiredMovementThisFrame =ConsumeInputVector().GetClampedToMaxSize(1.0)*DeltaTime*150;
if(!DesiredMovementThisFrame.IsNearlyZero())//如果不接近0
{
FHitResult hit;
//更新移动组件
SafeMoveUpdatedComponent(DesiredMovementThisFrame,UpdatedComponent->GetComponentRotation(),true,hit);
if(hit.IsValidBlockingHit())//如果碰撞了
{
//划过去
SlideAlongSurface(DesiredMovementThisFrame,1-hit.Time,hit.Normal,hit);
}
}
}