Download

Modifying The Heck Out Of Character Movement?

Hey, all.

So I’m working on building a sci-fi game where there will be different planets (and such) with different gravity. I want that to effect everything from character movement to balistics. I also want to implement what I think are some very unique movements that I haven’t seen in games before. I’m just getting started and I figured the first thing I should work on is the character movement.

I followed a very basic tutorial just to set up a project and now I’m ready to start developing my custom movement. Now the basic tutorial did set up foward/back, strafing, camera movement, and jumping in the character class; and it just occured to me that I don’t even know the walking speed, jump height, etc… I want those to ultimately be modified based on, for example gravity. Like, lower gravity = higher jumping.

Before I even start on that how can I access and change the jump height, movement speed, etc.?

I did do a quick google search and got some results that showed me how to set up a custom movement mode class, but that class is completely blank and I have no idea where to start. I feel like I need to actually see the default movement code to know how to modify it to get the results I want.

Is there a way I can edit the CharacterMovementComponent? Which I think is a class the the tutorial code seems to referencing to get the basic functions? And if so, should I? Or would I be setting up a class that calls that one and modifies or overrides specific funtions from it?

CharacterMovementComponent is part of your CharacterClass. Most, if not all of what you want is already there for you.

I did this little mock-up in my character class just as an example


void ASBCharacter::BeginPlay()
{
    Super::BeginPlay();

    UCharacterMovementComponent* CharMovement = GetCharacterMovement();
    if (CharMovement)
    {
        CharMovement->JumpZVelocity = MyFloat;
        CharMovement->MaxWalkSpeed = MyOtherFloat;
        etc...
    }

}

So from your code example I guess I can program the specifics like JumpZVelocity in my character class. Which is awesome so thanks for that.

But there’s no part of the code in my character class (from the tutorial) that actually specifically defines how the movement will work. Like accelleration, top speed, jumpZVelocity etc., etc., etc… And yet it still works.

So that tells me these things must be difined *somewhere, *the code I have is simply calling default behaviors. My question is, exactly where is it calling them from and how do I get at that and change it?

Because without being able to see all of the default movement code that my class seems to be calling, find what part of it I want to change and editing it: I would have to come back here and ask exactly how for every single thing I want to change.

Here’s the code anyway. As you can see, there is no JumpZVelocity in it anywhere, and yet it must be calling something from somwhere that has that defined. Because I can jump in the project I set up, so it’s getting a default JumpZVelocity without my having to specify one? I don’t know. I don’t understand C++


// Called to bind functionality to input
void ApCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
    Super::SetupPlayerInputComponent(PlayerInputComponent);
    // set up gameplay key bindings
    InputComponent->BindAxis("forward", this, &ApCharacter::forward);
    InputComponent->BindAxis("strafeRight", this, &ApCharacter::strafeRight);

    // ***rewrite to enable custom sensitivity/axis inversion
    InputComponent->BindAxis("rotate", this, &ApCharacter::AddControllerYawInput);
    InputComponent->BindAxis("pitch", this, &ApCharacter::AddControllerPitchInput);

    InputComponent->BindAction("jump", IE_Pressed, this, &ApCharacter::OnStartJump);
    InputComponent->BindAction("jump", IE_Released, this, &ApCharacter::OnStopJump);
}

void ApCharacter::forward(float Value)
{
    if ((Controller != NULL) && (Value != 0.0f))
    {
        // find out which way is forward
        FRotator Rotation = Controller->GetControlRotation();
        // Limit pitch when walking or falling
        if (GetCharacterMovement()->IsMovingOnGround() || GetCharacterMovement()->IsFalling())
        {
            Rotation.Pitch = 0.0f;
        }
        // add movement in that direction
        const FVector Direction = FRotationMatrix(Rotation).GetScaledAxis(EAxis::X);
        AddMovementInput(Direction, Value);
    }
}

void ApCharacter::strafeRight(float Value)
{
    if ((Controller != NULL) && (Value != 0.0f))
    {
        // find out which way is right
        const FRotator Rotation = Controller->GetControlRotation();
        const FVector Direction = FRotationMatrix(Rotation).GetScaledAxis(EAxis::Y);
        // add movement in that direction
        AddMovementInput(Direction, Value);
    }
}

void ApCharacter::OnStartJump()
{
    bPressedJump = true;
}
void ApCharacter::OnStopJump()
{
    bPressedJump = false;
}

Mmmm… derp. Found this.

So that should be really helpful and I think pretty much answers my question?

But I’ve got a couple more now. I thought I saw something in my searching that said UE4 doesn’t support a prone stance???

Also, since I’m writing my movement code in my player character class will that be a problem later when I want to make NPCs that have the same movement options? Should I be making a seperate character class that’s just general character movement and then call it in my player character class so I can also call it in any other character class?

Yes, that should answer your question. All that functionality is inside CharacterMovementComponent class as you linked. UE4 doesn’t support prone out of the box, but isn’t so difficult to create your own. You would just be modifying capsule half height and movement functions the same way that crouch would.

If you need the same functionality on many different characters, then I would suggest creating an ActorComponent class and writing all functionality in that. All you would need to do then is add this component to every character that you want movement to be modified for. As an example, this component would pull information from the world to modify the character movement based on which planet you’re at.

Some example code from the component to get you started.

You would just need to add a way to gather information about your world to tell the component which properties to modify and at what value.


// Called when the game starts
void USBEnergyComponent::BeginPlay()
{
    Super::BeginPlay();

    AActor* Character = (GetOwner();
    if (Character)
    {
        UCharacterMovementComponent* CharMovement = Character->FindComponentByClass<UCharacterMovementComponent>();
        if (CharMovement)
        {
            CharMovement->MaxWalkSpeed = myfloat;
        }
    }

}

Updated the code snippet, made a mistake

If the exposed functionality of the default CharacterMovementComponent isn’t enough, you can also create your own UCharacterMovementComponent:

Thanks to Demeese and sqwyd, both very helpful!

I will make an ActorComponent class so I can start making NPCs with the same movment.

Is there anyway I can see the CharacterMovementComponent source code? I wouldn’t be comfortable making my own without seeing everything in the existing one so I know everything I need to account for in mine.

But I would like to make my own. For example I would like the jump functionality to take factors about the environment (gravity) and character (height/weight customizable, with modifiers on actions) into account and calculate velocity based on those variables. So I could just call the jump in my actor component and all of that would already be taken care of.

You’ll need the engine source to see that code. Gitlab clone whichever version you’d like and start exploring!