Unreal-Engine-C-Programming - Components and Collision -part-6/10

Create Components;

  1. Make a Pawn Class 
  2. Name it what you want
  3. We make a components move and collide with solid objects;

Creating Properties

  • Colide_Pawn.h 
UParticleSystemComponent* OurParticalSystem;
  • Colide_Pawn.cpp in Constructor we create :
  • Sphere Component 
  • Static Mesh Component
  • Spring Arm Component 
  • Camera Component  
We need Import Files first :
#include "Classes/Components/SphereComponent.h"
#include "Classes/Components/StaticMeshComponent.h"
#include "ConstructorHelpers.h"
#include "Classes/Particles/ParticleSystemComponent.h"
#include "GameFramework/SpringArmComponent.h"
#include "Camera/CameraComponent.h"                          

we will define first Root Component :

   Physical Presence that interact and collide with our game world.
USphereComponent* SphereComponent = CreateDefaultSubobject<USphereComponent>
(TEXT("SPEHERE"));
    RootComponent = SphereComponent;
    SphereComponent->InitSphereRadius(40.0f);
    SphereComponent->SetCollisionProfileName(TEXT("Pawn"));

Next we create Static Mesh asset :

UStaticMeshComponent* SphereVisual = CreateDefaultSubobject<UStaticMeshComponent>
(TEXT("Mesh"));
    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.0f, 0.0f, -40.0f));
        SphereVisual->SetWorldScale3D(FVector(0.8f));
    }

Next Create our particle System Component :

    Attach with Static Mesh Component, not the root;
// Create paritcal system;
    OurParticalSystem = CreateDefaultSubobject<UParticleSystemComponent>
(TEXT("Paritcal"));
    OurParticalSystem->SetupAttachment(SphereVisual);
    OurParticalSystem->bAutoActivate = false;
    OurParticalSystem->SetRelativeLocation(FVector(-20.0f, 0.0f, 20.0f));

    static ConstructorHelpers::FObjectFinder<UParticleSystem> ParticleAsset
(TEXT("/Game/StarterContent/Particles/P_Fire.P_Fire"));
    if (ParticleAsset.Succeeded())
    {
        OurParticalSystem->SetTemplate(ParticleAsset.Object);
    }

Next we Will want to Spring Arm Component for camera smooth : 
  Attach with camera;
  Camera speed accelerate and decelerate more slowly;
// Use a spring arm to give the camera smooth, natural-feeling motion;
    USpringArmComponent* SpringArm = CreateDefaultSubobject<USpringArmComponent>
(TEXT("Spring ARM"));
    SpringArm->SetupAttachment(RootComponent);
    SpringArm->RelativeRotation = FRotator(-45.0f, 0.0f, 0.0f);
    SpringArm->TargetArmLength = 400.0f;
    SpringArm->bEnableCameraLag = true;
    SpringArm->CameraLagSpeed = 3.0f;

Camera Component  :

    UCameraComponent* Camera = CreateDefaultSubobject<UCameraComponent>
(TEXT("Camera"));
    Camera->SetupAttachment(SpringArm, USpringArmComponent::SocketName);

Set the default pawn player;
// Take control of the defalut palyer;
    AutoPossessPlayer = EAutoReceiveInput::Player0;
now we create basics components:
the code is here;
// Sets default values
AColli_Pawn::AColli_Pawn()
{
   // 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;

    // Our Root component will be a sphere that reacts to physics;
    USphereComponent* SphereComponent = CreateDefaultSubobject<USphereComponent>
(TEXT("SPEHERE"));
    RootComponent = SphereComponent;
    SphereComponent->InitSphereRadius(40.0f);
    SphereComponent->SetCollisionProfileName(TEXT("Pawn"));

    UStaticMeshComponent* SphereVisual = CreateDefaultSubobject<UStaticMeshComponent>
(TEXT("Mesh"));
    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.0f, 0.0f, -40.0f));
        SphereVisual->SetWorldScale3D(FVector(0.8f));
    }

    // Create paritcal system;
    OurParticalSystem = CreateDefaultSubobject<UParticleSystemComponent>
(TEXT("Paritcal"));
    OurParticalSystem->SetupAttachment(SphereVisual);
    OurParticalSystem->bAutoActivate = false;
    OurParticalSystem->SetRelativeLocation(FVector(-20.0f, 0.0f, 20.0f));

    static ConstructorHelpers::FObjectFinder<UParticleSystem> ParticleAsset
(TEXT("/Game/StarterContent/Particles/P_Fire.P_Fire"));
    if (ParticleAsset.Succeeded())
    {
        OurParticalSystem->SetTemplate(ParticleAsset.Object);
    }

    // Use a spring arm to give the camera smooth, natural-feeling motion;
    USpringArmComponent* SpringArm = CreateDefaultSubobject<USpringArmComponent>
(TEXT("Spring ARM"));
    SpringArm->SetupAttachment(RootComponent);
    SpringArm->RelativeRotation = FRotator(-45.0f, 0.0f, 0.0f);
    SpringArm->TargetArmLength = 400.0f;
    SpringArm->bEnableCameraLag = true;
    SpringArm->CameraLagSpeed = 3.0f;

    //Camera and attach to our spring arm;
    UCameraComponent* Camera = CreateDefaultSubobject<UCameraComponent>
(TEXT("Camera"));
    Camera->SetupAttachment(SpringArm, USpringArmComponent::SocketName);

    // Take control of the defalut palyer;
    AutoPossessPlayer = EAutoReceiveInput::Player0;

    // Our Custom Movement Component Class;
    OurMovementComponent = CreateDefaultSubobject<UColidePawnMovementComponent>
(TEXT("MovementCustome"));
    OurMovementComponent->UpdatedComponent = RootComponent;
}


We On now Input Part :

  1. Go to Edit > Project Settings > Input 
  2. We have to options Action Mapping and Axis Mapping
  3. Action Mapping > Particle Toggle : Space Bar
  4. Axis Mapping
    MoveForward
    W
    1.0
    S
    -1.0
    MoveRight
    A
    -1.0
    D
    1.0
    Turn
    Mouse X
    1.0

  1. Now we want create Movement in our Pawn class;
  2. Create Movement Component to mange all movement Input's;
  3. Extend Pawn Movement Component 
  4. check all classes search movement we found Pawn Movement Component;
Pawn movement component have some powerful, built-in features;

help to common physics functionality and more helpful movement code;

Since we call the class name CollidePawnMovement.h or cpp ;

Code Movement And Pawn;

  1. Use our CollidePawnMovement.h make a function;
             TickComponent function how to move each frame.
public:
// this function define in .h file;
    virtual void TickComponent(float DeltaTime,
enum ELevelTick TickType,
FActorComponentTickFunction* ThisTickFunction ) override;
  1. Define in .cpp class of CollidePawnMovement;
if (!PawnOwner || !UpdatedComponent || ShouldSkipUpdate(DeltaTime))
    {
        return;
    }
            This code will move our Pawn smoothly around the world; There is no gravity;

void UColidePawnMovementComponent::TickComponent(float DeltaTime,
enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) {

    Super::TickComponent(DeltaTime, TickType, ThisTickFunction);

    // Make sure that everything is still valid and that we are allowed
    if (!PawnOwner || !UpdatedComponent || ShouldSkipUpdate(DeltaTime))
    {
        return;
    }

    // Get and than clear the movement vector that we set in ACollideingPawn::TIck;
    FVector DesiredMovementThisFrame = ConsumeInputVector().
GetClampedToMaxSize(1.0f)* DeltaTime * 150.0f;
    if (!DesiredMovementThisFrame.IsNearlyZero())
    {
        FHitResult Hit;
        SafeMoveUpdatedComponent(DesiredMovementThisFrame,
UpdatedComponent->GetComponentRotation(), true, Hit);

        //if we bumped into something, try to slide along it;
        if (Hit.IsValidBlockingHit())
        {
            SlideAlongSurface(DesiredMovementThisFrame, 1.0f - Hit.Time,
Hit.Normal, Hit);
        }
    }
}
TickComponent:: 
                        This function makes use of a few of the powerful features;
                         UPawnMovementComponent class ConsumeInputVector  clear the value of built-in
                         variable that use in our movement inputs;
                         SafeMoveUpdatedComponent uses Unreal Engine Physics to move our Pawn                                       Movement Component;
                        SlideAlongSurface handles the calculations and physics involved with sliding                                    smoothly.  

Pawn And Components:

  1. Add the class in Collide_Pawn.h with "OurParticleSystem":
    class UColidePawnMovementComponent* OurMovementComponent;
  1. Now Include the class in .cpp file of Collide_Pawn;
#include "ColidePawnMovementComponent.h"
  1. Create a Pawn Movement Component in .cpp file of Collide_Pawn.cpp ;
OurMovementComponent = CreateDefaultSubobject<UColidePawnMovementComponent>
(TEXT("MovementCustome"));
    OurMovementComponent->UpdatedComponent = RootComponent;
  1. Pawns have a function called GetMovementComponent that enable other classes in the engine;
    virtual UPawnMovementComponent* GetMovementComponent() const override;
  1. In Collide_Pawn.cpp add the GetMovementComponent() funciton;
UPawnMovementComponent* AColli_Pawn::GetMovementComponent() const {
    return OurMovementComponent;
}
  • Create Pawn Movement Component set up;
  • In Collide_Pawn.h 
// Made Input Functionsa
    void MoveForwardw(float AxisValue);
    void MoveRightw(float AxisValue);
    void Turnw(float AxisValue);
    void ParticleTogglew();
  • In Collide_Pawn.cpp;
void AColli_Pawn::MoveRightw(float AxisValue)
{
    if (OurMovementComponent && (OurMovementComponent->UpdatedComponent ==
RootComponent))
    {
        OurMovementComponent->AddInputVector(GetActorRightVector() * AxisValue);

    }
}

void AColli_Pawn::Turnw(float AxisValue)
{
    FRotator NewRotation = GetActorRotation();
    NewRotation.Yaw += AxisValue;
    SetActorRotation(NewRotation);
}

void AColli_Pawn::ParticleTogglew()
{
    if (OurParticalSystem && OurParticalSystem->Template)
    {
        OurParticalSystem->ToggleActive();
    }
}
  • Our inputs events in SetupPlayerInputComponent();
// Called to bind functionality to input
void AColli_Pawn::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
    Super::SetupPlayerInputComponent(PlayerInputComponent);

    PlayerInputComponent->BindAction("ParticleToggle", IE_Pressed, this,
&AColli_Pawn::ParticleTogglew);

    PlayerInputComponent->BindAxis("MoveForward", this, &AColli_Pawn::MoveForwardw);
    PlayerInputComponent->BindAxis("MoveRight", this, &AColli_Pawn::MoveRightw);
    PlayerInputComponent->BindAxis("Turn", this, &AColli_Pawn::Turnw);
}

All Code Files ::
Colli_Pawn.h
// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Pawn.h"
#include "Colli_Pawn.generated.h"

UCLASS()
class CPLUSPROGRAMMING_API AColli_Pawn : public APawn
{
    GENERATED_BODY()

public:
    // Sets default values for this pawn's properties
    AColli_Pawn();

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;

    UParticleSystemComponent* OurParticalSystem;
    virtual UPawnMovementComponent* GetMovementComponent() const override;
    class UColidePawnMovementComponent* OurMovementComponent;

    // Made Input Functionsa
    void MoveForwardw(float AxisValue);
    void MoveRightw(float AxisValue);
    void Turnw(float AxisValue);
    void ParticleTogglew();
};

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

#include "Colli_Pawn.h"
#include "Classes/Components/SphereComponent.h"
#include "Classes/Components/StaticMeshComponent.h"
#include "ConstructorHelpers.h"
#include "Classes/Particles/ParticleSystemComponent.h"
#include "GameFramework/SpringArmComponent.h"
#include "Camera/CameraComponent.h"
#include "ColidePawnMovementComponent.h"
#include "Classes/Components/InputComponent.h"


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

    // Our Root component will be a sphere that reacts to physics;
    USphereComponent* SphereComponent = CreateDefaultSubobject<USphereComponent>
(TEXT("SPEHERE"));
    RootComponent = SphereComponent;
    SphereComponent->InitSphereRadius(40.0f);
    SphereComponent->SetCollisionProfileName(TEXT("Pawn"));

    UStaticMeshComponent* SphereVisual = CreateDefaultSubobject<UStaticMeshComponent>
(TEXT("Mesh"));
    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.0f, 0.0f, -40.0f));
        SphereVisual->SetWorldScale3D(FVector(0.8f));
    }

    // Create paritcal system;
    OurParticalSystem = CreateDefaultSubobject<UParticleSystemComponent>
(TEXT("Paritcal"));
    OurParticalSystem->SetupAttachment(SphereVisual);
    OurParticalSystem->bAutoActivate = false;
    OurParticalSystem->SetRelativeLocation(FVector(-20.0f, 0.0f, 20.0f));

    static ConstructorHelpers::FObjectFinder<UParticleSystem> ParticleAsset
(TEXT("/Game/StarterContent/Particles/P_Fire.P_Fire"));
    if (ParticleAsset.Succeeded())
    {
        OurParticalSystem->SetTemplate(ParticleAsset.Object);
    }

    // Use a spring arm to give the camera smooth, natural-feeling motion;
    USpringArmComponent* SpringArm = CreateDefaultSubobject<USpringArmComponent>
(TEXT("Spring ARM"));
    SpringArm->SetupAttachment(RootComponent);
    SpringArm->RelativeRotation = FRotator(-45.0f, 0.0f, 0.0f);
    SpringArm->TargetArmLength = 400.0f;
    SpringArm->bEnableCameraLag = true;
    SpringArm->CameraLagSpeed = 3.0f;

    //Camera and attach to our spring arm;
    UCameraComponent* Camera = CreateDefaultSubobject<UCameraComponent>
(TEXT("Camera"));
    Camera->SetupAttachment(SpringArm, USpringArmComponent::SocketName);

    // Take control of the defalut palyer;
    AutoPossessPlayer = EAutoReceiveInput::Player0;

    // Our Custom Movement Component Class;
    OurMovementComponent = CreateDefaultSubobject<UColidePawnMovementComponent>
(TEXT("MovementCustome"));
    OurMovementComponent->UpdatedComponent = RootComponent;
}

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

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

}

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

    PlayerInputComponent->BindAction("ParticleToggle", IE_Pressed, this,
&AColli_Pawn::ParticleTogglew);

    PlayerInputComponent->BindAxis("MoveForward", this, &AColli_Pawn::MoveForwardw);
    PlayerInputComponent->BindAxis("MoveRight", this, &AColli_Pawn::MoveRightw);
    PlayerInputComponent->BindAxis("Turn", this, &AColli_Pawn::Turnw);
}

// UPawn Movement Component;
UPawnMovementComponent* AColli_Pawn::GetMovementComponent() const {
    return OurMovementComponent;
}

void AColli_Pawn::MoveForwardw(float AxisValue)
{
    if (OurMovementComponent && (OurMovementComponent->UpdatedComponent ==
RootComponent))
    {
        OurMovementComponent->AddInputVector(GetActorForwardVector() * AxisValue);

    }
}

void AColli_Pawn::MoveRightw(float AxisValue)
{
    if (OurMovementComponent && (OurMovementComponent->UpdatedComponent ==
RootComponent))
    {
        OurMovementComponent->AddInputVector(GetActorRightVector() * AxisValue);

    }
}

void AColli_Pawn::Turnw(float AxisValue)
{
    FRotator NewRotation = GetActorRotation();
    NewRotation.Yaw += AxisValue;
    SetActorRotation(NewRotation);
}

void AColli_Pawn::ParticleTogglew()
{
    if (OurParticalSystem && OurParticalSystem->Template)
    {
        OurParticalSystem->ToggleActive();
    }
}

Comments

Popular posts from this blog

Manually Android SDK Setup in Unreal Engine 5

Unreal Engine C++ Interfaces