UE4C++学习:组件和碰撞代码注释详解

// 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);
        }
    }
}

 

上一篇:重排、重绘的概念、区别以及前端的优化


下一篇:070_Todo-list案例