CPPNotes
CPPNotes
DRAFT
CS193U Project 1
CS193U Project 2
Base Systems 10
Camera System
Movement System
Interaction System 45
>barrel
>chest
project 2
PART A)
change : Line Trace from Camera to World and find desired impact location
PART B)
add : new child class black hole ->
new(2): extra spherecompompent and VFX compoent
PART C)
add : new child class black hole ->
new(): If magic component collides with world static or time runs out THEN
teleport
Tags
Magic Projectile
Interactive Barrel
CS193U Project 1 1
Lecture 0 : Setup GameWorld
Lecture 1: Setup Movement
Lecture 2: Setup Magic Projectile
Lecture 3: Setup Interactive Barrel
Project 1 :: Have a gameworld where you can cast magic projectile and interact
with BARREL
CS193U Project 1 2
Set Up World N Camera
Component
Owner L LOMZO GAMING
Tags
Getting the world set up and assigning the base player pawn that that the
character controller will posses during gameplay
WTF is ‘UPROPERTY’
It is everywhere and it’s macros like these which handle automatic garbage
collection. We basically will tag everything with UPROPERTY or some form of that.
In blueprints we would simply drag and drop the spring arm component and the
camera arm components to our character class. We are doing the same thing here
but in CPP we declare component in the .H and then initialize and customize them
in the constructor.
We will add to the : the Hero’s Header Section and the Hero’s CPP Constructor
Section
>Hero’s .H Section
> Hero’s CPP Constructor Section
>Hero’s .H Section
IN THE HEADER : For the following two components we have two steps in the
header :The Spring Arm and The Camera Component each are set aside an empty
pointer. In the constructor we will have a choice for Raw or Smart Pointers ( use
smart ptrs for less memory leak bugs)
1) Forward Declare Declare Classes (imports in CPP not H)
2) Create empty pointers
---------------------------
//raw ptr
SpringArmComponent* CameraComp
UCameracompent* CameraComp
//smart ptr
TObjectPtr<USpringArmComponent> SpringArmComp;
TObjectPtr<UCameraCompent> UCameraComp;
//**RAW VS SMART POINTERS**
//Raw Ptr
//UCameracompent* CameraComp
//Smart Ptr
//TObjectPtr<USpringArmComponent> SpringArmComp;
In the CPP we follow the three steps listed below, these steps all happen in the
constructor. The customization of components can be done in the menu or bp
GUI’s as well as right here baby.
1) Create default sub objects
2) Customize properties of each sub object
3) Attach components to appropriate component
//All done in the constructor of this Hero class and all Compone
//Innit Of Components
SpringArmComp = CreateDefaultSubobject<USpringArmComponent>(
CameraComp = CreateDefaultSubobject<UCameraComponent>("Camer
//Customing Components
SpringArmComp->bUsePawnControlRotation = true;
SpringArmComp->SetUsingAbsoluteRotation(true);
//Attaching Components
SpringArmComp->SetupAttachment(RootComponent);
CameraComp->SetupAttachment(SpringArmComp);
Tags
The player input component allows us to bind these together for total immersion
The PIC will recognize a input function and fire the gameplay function
corresponding to it
While PIC is deprecated in favor of enhanced input system {5.1}, PIC is still popular
//.h{PIC}
virtual void SetupPlayerInputComponent(class UInputComponent* Pl
//.cpp{PIC}
void AHero::SetupPlayerInputComponent(UInputComponent* PlayerInp
{
Super::SetupPlayerInputComponent(PlayerInputComponent); //in
}
And now for setting up some inputs to interact with our character!
Camera Movement
&APawn:: Means this function is defined and declared within the pawn class
In the PIC we have bounded our look around inputs to actually look around with
the built in pawn class and controller class!
We don't have to write anymore code and are free to LOOK but not move around
the game world!
Character Movement
Again make sure previous steps were followed especially that this is included in
the HERO’S CONSTRUCTOR bUseControllerRotationYaw = false;
This is because we want our characters yaw or front direction to not be the literal
front of the mesh but where the camera is facing in terms of camera. AKA Front is
where the camera is facing
While in CAMERA we used &APawn:: here for CHARACTER we will use &AHERO::
because above we declared our functions and then we’re gonna bind and define
em
PlayerInputComponent->BindAxis("MoveForward",this,&AHero::MoveFo
PlayerInputComponent->BindAxis("MoveRight",this,&AHero::MoveRigh
//On right vector of the character add the value of this mov
AddMovementInput(RightVector, Value);
}
A) Add engine action input named ‘jumpmove’ and bind it to space bar
B) In the constructor bind action ‘jumpmove’ to &Character::Jump
sections
Setting Up The Magic Projectile
To Cast A Magic Projectile pt1
To Cast A Magic Projectile pt2
The Magic Of Collisions
So things should start to make a little bit more sense, the world is made up of
actors some actors are a bit more specialized than others. —> we then make
children classes of these actors and add our own functionality. The actor class
being the most default of them all.
Magic Projectile 1
Our Magic Projectile is built of these following components we will add on to the
base class
>Sphere
COMPONENT
>Projectile Movement
COMPONENT
>Particle System Component
COMPONENT
First we create them as UPROPERTIES in the .H and then in the .CPP constructor
set up custom features of each component if they have any and then they
attachments of the components And Tada! We have a moving projectile that exists
in the world and something to work with!
SOLUTION <ALSO quickly in your GIDEON SKELETON Add or find the arm socket
for the code below>
.H
Magic Projectile 2
UPROPERTY(VisibleAnywhere)
USphereComponent* SphereComp;
UPROPERTY(VisibleAnywhere)
UProjectileMovementComponent* ProjectileMovementComp;
UPROPERTY(VisibleAnywhere)
UAudioComponent* AudioComp;
UPROPERTY(VisibleAnywhere)
UParticleSystemComponent* ParticleSystemComp;
.CPP
// Set this actor to call Tick() every frame. You can turn
PrimaryActorTick.bCanEverTick = true;
//SPHERE COMP
SphereComp = CreateDefaultSubobject<USphereComponent>("Spher
SphereComp->SetCollisionProfileName("Projectile");
RootComponent = SphereComp;
//PARTICLE SYS
ParticleSystemComp = CreateDefaultSubobject<UParticleSystemC
ParticleSystemComp->SetupAttachment(RootComponent);
//AUDIO FX
Magic Projectile 3
AudioComp = CreateDefaultSubobject<UAudioComponent>("AudioCo
AudioComp->SetupAttachment(RootComponent);
//PROJECTILE MOVMEMENT
ProjectileMovementComp = CreateDefaultSubobject<UProjectileM
ProjectileMovementComp->bRotationFollowsVelocity = true;
ProjectileMovementComp->bInitialVelocityInLocalSpace = true;
ProjectileMovementComp->ProjectileGravityScale = 0.0f;
ProjectileMovementComp->InitialSpeed = 8000;
}
1) PRESS KEYBOARD
Iff you remember PIC then nice IF NOT hgo back and review it’s core for
interacting with the game via input.
Magic Projectile 4
//Action event binding in The PIC (cpp con)
PlayerInputComponent->BindAction("PrimaryAttack",IE_Pressed,
//CPP DECLR
void AHero::PrimaryAttack()
{
BVFE//GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Yellow,
}
This is great all we need to do now is add the functionality of spawning it in the
world, see commented areas for the breakdown of how what is happening
happens !
void AHero::PrimaryAttack()
{
//Lets shoot our simple magic projectile first4 Log It!
UE_LOG(LogTemp, Warning, TEXT("Player performed the Prim
//LOCATION N DIRECTION
//The Transform is the arrow rotation and the hand locat
FVector HandLocation = GetMesh()->GetSocketLocation("han
FTransform SpawnTransform = FTransform(GetControlRotatio
//ALWAYS SPAWN
//setting the spawn parameters to always spawn
FActorSpawnParameters SpawnParams;
Magic Projectile 5
SpawnParams.SpawnCollisionHandlingOverride = ESpawnActor
In project preferences create the following new collision channel in the image,
yeah working with project settings can feel werid and stuff but it really is the norm
Magic Projectile 6
Now lets add the following line to our MAGIC PROJECTILE’s Constructor .CPP
So now our spawned projectile will block against world static items such as blocks
and meshes
Magic Projectile 7
//and then set it to our target projectile visualizes in the edi
Magic Projectile 8
Interactive Barrel
Owner L LOMZO GAMING
Tags
BARREL
2 simple components
>mesh
>force
Innit both these components, In the .CPP constructor there is some write up for
the force, which is viewable in the project solution.
So here in my .H’s protected I defined a UFUNC aswell as stating “hey Ima use
POST INNIT COMP”
Interactive Barrel 1
void ABarrel::PostInitializeComponents()
{
// Don't forget to call parent function
Super::PostInitializeComponents();
Within the POST INNIT COMP func I added a binding that when this component is
hit I want to call whichever function I writeup for my OnActorHit. In this case of the
barrel I am perhaps gonna use the force component as well as some debug
messages
Interactive Barrel 2
Enhancing Magic Projectile
Owner L LOMZO GAMING
Tags
Once the magic projectile collides with a static mesh, leave it be for two seconds
and then destroy it. This code will be added directly to the .cpp of magic projectile
and I believe other thangz aint needed
1)
2)
HERO .CPP <will need some header stuff>
void AHero::PrimaryAttack()
{
PlayAnimMontage(PrimaryAttackAnimMonty);
GetWorldTimerManager().SetTimer(TimerHandle_PrimaryAttack,th
//GetWorldTimerManager().ClearTimer(&AHero::PrimaryAttack);
}
void AHero::PrimaryAttack_TimeElapsed()
{
//LOCATION N DIRECTION
//The Transform is the arrow rotation and the hand location
FVector HandLocation = GetMesh()->GetSocketLocation("hand_lS
FTransform SpawnTransform = FTransform(GetControlRotation(),
//ALWAYS SPAWN
//setting the spawn parameters to always spawn
FActorSpawnParameters SpawnParams;
SpawnParams.SpawnCollisionHandlingOverride = ESpawnActorColl
3)
HERO.CPP <updating above with debounce>,<will need some header stuff>
void AHero::PrimaryAttack()
{
if (!bIsPrimaryAttackOnCooldown)
{
PlayAnimMontage(PrimaryAttackAnimMonty);
GetWorldTimerManager().SetTimer(TimerHandle_PrimaryAttac
bIsPrimaryAttackOnCooldown = true;
GetWorldTimerManager().SetTimer(TimerHandle_PrimaryAttac
}
}
void AHero::ResetPrimaryAttackCooldown()
{
bIsPrimaryAttackOnCooldown = false;
}
void AHero::PrimaryAttack_TimeElapsed()
{
FVector HandLocation = GetMesh()->GetSocketLocation("hand_lS
FTransform SpawnTransform = FTransform(GetControlRotation(),
FActorSpawnParameters SpawnParams;
SpawnParams.SpawnCollisionHandlingOverride = ESpawnActorColl
Tags
https://docs.unrealengine.com/5.0/en-US/interfaces-in-unreal-engine/
Literally Read The Documentation
Interactable_Interface.h
#pragma once
#include "CoreMinimal.h"
#include "UObject/Interface.h"
#include "Interactable_Interface.generated.h"
Interaction Component ! 1
{
GENERATED_BODY()
//INTERFACE FUNCTION
UFUNCTION(BlueprintNativeEvent)
void DoInteraction (APawn* InstigatorPawn);
};
So this interface does not really have a CPP, this is like a shared list of things that
all classes that implement {this} interface will have. That list of thing starting at the
bottom.
This is really cool because the top half we’re creating a UOBJECT and in the
bottom we are working with it in the I-Interfacestuff.
Our interaction component will belong to the player and give them the funconitlity
to interact with the world. How does this happen?
>Interaction comp offloads code off of our character
>Interaction comp has function interact, where it casts a ray from our chars eyes
forward
>If the ray hits any CPP actors that implement our interface have them call their
version of that function
INTERACTION COMPONENT
.H
Interaction Component ! 2
CPP
void UInteractionComponent::PrimaryInteract()
{
//HIT OUTPUT
FHitResult hit;
//SET UP COLLISION
FCollisionObjectQueryParams MyColParam;
MyColParam.AddObjectTypesToQuery(ECC_WorldDynamic);
MyColParam.AddObjectTypesToQuery(ECC_PhysicsBody);
//Do Da Cast
//GetWorld()->LineTraceSingleByObjectType(hit,EyeLocation,En
Interaction Component ! 3
if (ReactingObj)
{
APawn* MyInstigatingPawn = Cast<APawn>(MyOwner);
.CPP
Interaction Component ! 4
ForceComp->FireImpulse();
}
https://docs.unrealengine.com/5.0/en-US/interfaces-in-unreal-engine/
Interaction Component ! 5