Sunday, June 30, 2024

Game update

 I hadnt realized that my last update was almost two months ago. Admittedly I've been VERY busy, but that's not a great excuse. I all say all that to remind myself that it's okay, but I have to get my numbers up. Anyways. that's not why I'm here. Just an update on the progress of the game. (I'd like to get into the habit of posting an update every Sunday)


Currently  The game has the following features

1. Saving Loading

2. Checkpoints 

3. Swithces for traps. 

4. Traps

5. An Ending. 


When you cross a threshold the game presents you with your time, and congratulates you , and asks if you want to start again. 

A solid gameplay loop. 

I'm at the point where I want to do a few things;  

1. Polish what I've got

2. Add some delicious art. 

I have a Miro board of things I need to add. But to sum it up. 


Polish 

1. the movement. 

2. the UX

Considering thats what the game is. Thats all I have to work with. 


As for the art, that's all in the MIro board. (Chief among the items  is  the lighting)

I don't want to add any new code, (unless its for fixing bugs). Because I want this game to be out by October. 

The question is though, how do I keep my programming knowledge up to snuff? 

I'll be doing some game jams while I'm working on this game, to keep expanding my skill set, and reinforcing my coding. 

Monday, March 25, 2024

6 Degrees of aiming. Lets talk about it

Cutting to the chase. In my game I want the character to have the ability to aim forward, Upwards, and mid between those two positions. 

So basically 

0 Degrees, 

45 Degrees

90 Degrees

135 Degrees

180 Degrees. 



I asked my bbuddy DharmaPunk 

youtube.com/@DharmaPunkGames for some assistance, because I for the life of me could NOT figure out hwo to get it to work.


Long story short; I got my results via using Enumerators + the logic that I used for making line traces.

Now at the Time I'm using Blueprints to get this done, but I'll just briefly explain what I did s othaht someone could bring this over to C++ (myself lol)

The first thing I did was set up a basic line trace, going forward from the actor's forward position.




Now for the Aim up, it was also VERY simple. At the time I didnt know this functino existed, BUT LO and behold; 

Get Actor Up Vector...
I simply replaced get the forward Vector With the aforementioned up vector, and it works as I need it to!


Now the Mid aim was a bit "trickier". I referred to Reddit and got a clue to my solution. I needed to rotate my Vector by some degrees. 

So What I did was Rotate my Forward Vector times 45 Degrees on the Pitch (Y). And that solved my issue. Eeyrthing else remained the same!
Magic!



Honestly it was very simple once I "figured it out" . Shout out to my friendly devs help. 

Now the next part. Gettin the Projectiles to follow the direction from the Line trace. 

The first thing was establishing a Trace Start and stop. We're going to use that as the Projectile Direction. 
For this, what you'll need t do; is subtract The Actor Location, from the Out Trace End. This basically draws a direction from your projectile. That lokos like this. 


We have to make sure that stays in a Variable that we will then send into Local Velocity from the spawned Projectile like below. (Make sure to multiply this times a float so the projectile will fly!). 


It's




Go ahead and assign the aiming to the controls to you want, and boom! you're done. Now that I'm typing this, and re reading it. Its much easier to do than I remember. I hope this helps someone! (Myself) in the future!

Wednesday, February 28, 2024

Some more knowoledge on Enhanced input. Specifically bindings, and some gotchas

 So I was following a tutorial this morning. Another Stephen Ulibarri one. 

I got to othe point in his tutorial where I was to bind the functions to the input actions. And I have a pretty good idea of what i'm meant t do, so I went ahead to start, but there were quite a few trip ups I had, that in hindsight make sense. But I wanted to jot some notes down..




1. YOu have to declare your Input Action. I was under the impression All I needed to do was connect the IA like I would in blueprints, but just like mapping context you need to declare it. 

2. With the function that you're going to bind, you need to make sure it is a a ActionInput value. Or more specifically 

void Function ( const FInputActionValue& Value); 

I kept makinng the mistake of just passing in a float value. You need to make this an FInputActionValue reference if you're going to bind it to your enhanced action input). 

3. When you're binding your function to your Input Action. The syntax for BindAction() goes. 

BindAction(InputAction, ETriggerEvent::(WhateverTheEventIs), this(the actor it's acting on), A_The specific  actor::TheFunctinYou'reBinding). 

I really had trouble with it this morning, but I hope htis clear is up for you future Paul. 


ALSO here's the setup for the ball, in the ball maze projec tyou did. 




// Called to bind functionality to input

void AC_PlayerBall::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)

{

Super::SetupPlayerInputComponent(PlayerInputComponent);


if (UEnhancedInputComponent* BallInputComponent = CastChecked<UEnhancedInputComponent>(PlayerInputComponent)) {


BallInputComponent->BindAction(BallMove, ETriggerEvent::Triggered, this, &AC_PlayerBall::BallMovementFunction);

}



}

Tuesday, February 27, 2024

Super quick post about commenting

 Not sure why this information isnt readily available, maybe i'm just searching in the WRONG places, but here we are. But for future Paul. 


TO COMMENT OUT CODE, THE SHORT CUT IS. 

CTRL + SHIFT + /

and to undo is the same.


https://stackoverflow.com/questions/32426267/visual-studio-comment-shortcut

Sunday, February 25, 2024

Coding Knowledge update- this part has given me the most trouble.

 SO I've started making a game every monthh, r every few weeks. Just to experiment, and obviously get better at game development. 


A few days ago I started a ball project. Where the goal is to get the ball across a goal, under a certain amount of time, without dying. 

You die by hitting the edges of the maze, and if the timer reaches zero. 


RIght now it plays like this. 


Right now the code is basically being all done in side of the player character pawn. 


The first week, I added the movement controls. This was, and is continously the trickiest part. 

I'll outline it in a few steps. 


Since I was Using Enhanced Action Input; I"ll be describing my process using that. 



Step 1 - 

In the headerfile; I had to declare a few things. I had to declare where the Input Mapping was going to go. 

And I had declare where the Input Action was going to go. 

When I made a blue print based of this class, this is where I'll put the Input Mapping Context, and the INput Action , when I make em. 


The Header file contrains these lines of code


UPROPERTY(EditAnywhere, Blueprintreadwrite, Category = Input)

UInputAction* MyActionInput;

///The above is where you're going to put the Input Action that you made/make in Unreal


UPROPERTY(EditAnywhere, Category = Input)

UInputMappingContext* MyMappingContext;

///The Above line here is where you're going to put the Mapping Context that you've made in Unreal

As you can see. with the pointer after the Class, I was forward declaring in the header. That looks like this. 

class UInputAction;

class UInput;

class UInputMappingContext;

You put that near the top. 

    So the next part, is always super confusing to me, I imagine I'll look back on this fondly for the times when I thought THIS was complicated. However as of now, this part is still very confusing for me haha. 

    The next step, Is we're getting the player controller ( we need this for later also) and we're getting it by initializing our own controller class and casting from that to get the GetPlayerController Function. 
That looks like
So over on the CPP it looks like this

APlayerController* MyController

then casting from this class, to get our player controller, and that looks...

APlayerController* MyController = Cast<MyController>(GetPlayerController());


Now if this cast is succesful, now we have to get the EnhancedLocalInput Subsystem. 
(Truth be told. I dont know much about Subsystems in Unreal, but I do know the steps that initalize our Local Subsystem)

So again, 
We can check if the cast is succesfull with a simple IF statement. 

if(MyController){}

This will check if the cast will work. Once there, we can add the cast of the subsystem into body of the IF statement. That'll look like this. 

If(MyController){
    If(UEnhancedInputLocalPlayerSubsystem* MySubystem = 

}

Now for the Subsystem, now we need to call the "GetSubsystem" function, which is a function of the ULocalPlayer  class.  That looks like this. 



If(MyController)
{
If(UEnhancedInputLocalPlayerSubsystem* MySubsystem = ULocalPlayer::GetSubystem<UEnhancedInputLocalPlayerSubsystem>(MyController->GetLocalPlayer()); 
}

/// The GetSubsystem Function Template is in the ULocalPlayer Namespace

Now this a bit complicated (to 2024 Paul).
This is all to get and check if we have a subsystem. Once that part is done, THEN we can initalize the subsystem with thhe Mapping Context that we made before. 

So take that code above, and add this 

APlayerController* MyController = Cast<MyController>(GetPlayerController());

IF(MyController)
{
If(UEnhancedInputLocalPlayerSubsystem* MySubsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(MyController->GetLocalPlayer())
{
MySubsystem->AddMappingContext(MyMappingContext, 0); 
}

To quickly go over what we're seeing. 
- We're casting to the MyController type, to GetPlayer Controller
- We check with an if statement if that cast was succesful
- Inside that if statement we  Get the subsystem thru the LocalPlayersubsystem Type by callin ght eGetlocal player function
- and from there, we acces the AddmappingContxt function in the MySubsystem class

This is all done in the EventBeginPlay to use our MappingContext. 


So now that we've got that part done, we need to bind our Mapping Context, and have it access a function.

This part is much shorter, but also complicated. I still dont completely understand it, but I"ll do my best to expalin it to future me. 
You'll need to bind ur inputs in the function called AYourActor::SetupPlayerINputComponent(UInputComponent( PlayerInputComponent)

What we're going to do here is cast from an input component, and check. IF the cast is succesfull then we're going to access the BindAction() function from the UenhancedInputComponent Class. That code looks like this. 

If(UEnhancedInputComponent* MyInputComponent = CastChecked<UEnhancedInputComponent>(PlayerInputComponent)){
MyInputComponent->BindAction(InputAction, EtriggerEvent::Triggered(or whatever event you've designated in your INput Action), this ( the object it effects), AC_YourActor::WhateverMovementFunction);
}

From there its pretty simple, we just define the function that we're binding and go from there. 

I hope this helps future paul quite a bit!. 
Back to some tutorials ;)