Ninja Character - Dynamic gravity for characters & objects

Hi! Thanks for your answer, it seems to work better now, i missed that part ^^
But now I have another problem, the camera stays straight and doesn’t turn with the character so at the end the character is seen upside down.
I made another gif to explain!

Thanks in advance for your help ^^

It’s hard to tell you what’s exactly wrong, but make sure the character blueprint has the checkbox Capsule Rotates Control Rotation ticked.
If you’re starting a project, I think it’s better to duplicate my blueprints and customize them afterwards.

do you have ‘inherit Pitch/Yaw/Roll’ enabled on your spring arm?

@Xaklse Im a complete disaster at quaterions/rotational calculations. Having trouble isolating the yaw rotation from the player relative to the gravity direction. Do you already have a function in your code that can extract those relative rotations/directions?

@Xaklse thank you for all of your hard work! It is amazing that you released it for free, I was actually working through how to do essentially this exact same thing but it was daunting because I haven’t written c++ in years and I’m new to Unreal, so that is a lot to learn all in parallel. I do have a question (you may have answered this elsewhere but I didn’t see it so apologies if it is a duplicate) do you know if there is a way to add the plugin into 4.26 without needing to build the engine from source? Thanks again for your work and I look forward to trying it out on a game I’m starting this weekend (though to be fair this functionality will come later in the project, gotta get the basics working first, you know?!).

Hi, @Xaklse I have an issue hopefully you can help me with. I have a level that has portals on the walls and ceilings. When I run through a portal on the ground I instantly teleport on either the ceiling or the wall. My issue is I can’t seem to find a way to rotate the capsule so the feet are aligning with the ceiling or wall. I always just fall down to the ground. I’ve tried all the “Set rotation” types I can think of to the capsule and Actor. When looking into your character movement component, I see options like “gravity direction mode” and “Gravity Vector A/B” but they’re all greyed out. I would love to be able to get an instant rotate on the capsule. I’m using your demo character and Player controller. Figured I would use it until I figured this out. Any ideas? Thanks!

I crafted something for you:



/**
 * Gets the yaw rotation angle of a view rotation.
 * @note You can easily feed an FRotator to parameter Matrix
 * @param Matrix - the view rotation from which to extract the yaw rotation
 * @param Forward - the fixed forward vector reference
 * @return yaw rotation angle in degrees with sign
 */
static float GetYaw(const FRotationMatrix& Matrix, const FVector& Forward)
{
#if !(UE_BUILD_SHIPPING || UE_BUILD_TEST) && WITH_EDITORONLY_DATA
    check(Forward.IsNormalized());
#endif

    // Obtain orthonormal axes from matrix
    const FVector AxisX = Matrix.GetScaledAxis(EAxis::Type::X);
    const FVector AxisY = Matrix.GetScaledAxis(EAxis::Type::Y);

#if !(UE_BUILD_SHIPPING || UE_BUILD_TEST) && WITH_EDITORONLY_DATA
    const FVector AxisZ = Matrix.GetScaledAxis(EAxis::Type::Z);
    check(FVector::Orthogonal(AxisZ, Forward));
#endif

    // Obtain angle (with sign) between X axis and forward vector
    const float YawAngle = FMath::RadiansToDegrees(FMath::Acos(AxisX | Forward));
    return ((AxisY | Forward) < 0.0f) ? YawAngle : YawAngle * -1.0f;
}

First, obtain player’s CapsuleUp, feed it to FVector::VectorPlaneProject(GravDir, CapsuleUp), normalize the result, and feed it to the GetYaw function as Forward; use player’s FRotator as Matrix; hope it works this way, it’s tricky stuff.

.

I’m not aware of a way to upgrade a compiled plugin to a more modern engine. The character code usually changes with major versions though, so NinjaCharacter code may work apparently, but…

.

Try to use the “Set Fixed Gravity Direction” blueprint node, feed reverse wall normal to “New Gravity Direction”. Let me know if you don’t understand.

Hi Xaklse

First of all, thank you for spending time on this, really appreciated!!!

The following part isn’t really clear to me:

this will always result in a zero vector right? since the Gravity and Capsule up are always opposite?

So in your case you have CapsuleUp and GravityDir aligned? There is no valid solution unless you have more information.
In a standard Unreal world, yaw rotation is calculated against vector (1,0,0); so which vector would be your reference? Camera’s forward vector?

They aren’t aligned, but projecting opposite vectors returns a 0 vector right? Since the capsule up will always be opposite of the gravity direction.

let’s say i’m on a flat surface ( or at the exact poles of a sphere), then it would be FVector::VectorPlaneProject(FVector(0,0,-1),FVector(0,0,1))

FVector::VectorPlaneProject(GravDir, CapsuleUp) this will always be 0,0,0

Cant use the camera as reference vector either, since it’s constrained to the player (inheriting control rotation). The biggest culprit of this issue is the lack of a fixed reference vector in ‘player space’

I did find this somewhere on stackoverflow:

but dont know how this translates to UE4 matrices. (and if it actually works)

There is no yaw rotation in a world with arbitrary gravity, unless you use FVector::ForwardVector as reference, or another one derived from camera rotation, control rotation, anything rotation… unless I’m overlooking something important.

Here’s a video showing the set Fixed Gravity Direction causes a desync in rotation of the server to the clients, but if not called then the clients and server match up. Let me know if the video isn’t of good enough quality and I’ll make a better version to make it easier to see.

Yes exactly thats the problem :slight_smile: however it’s a spherical world we use, so Im thinking of ways to get a reference vector based on spherical coordinates relative to the player somehow…

@err0s Did you also try setting the server function to reliable? And maybe test some different values for (min) net update frequency on the player replication properties

honestly I don’t know how to do that, I’m new to ue4 c++ but have experience with c++17.

Ok so I set the component replicates option for both the capsule collider and mesh, and the planal rotational problem is fixed however the mesh is rotated, with respect to z, incorrectly

You can set an event to reliable on the event properties:

reliableevent.PNG

The update frequency settings can be found on your character properties under ‘replication’
repsettings.PNG

I don’t know if this solves the issue, but might be worth a try. Could be there’s package loss between server/client causing irregularities between both (not sure if that’s even possible testing locally though)

I tried those settings and it wasn’t fixed, the problem is replication from server to client, or client to server to other client. when looking through the server’s viewport the clients update correctly but the server doesn’t send those updates to the other clients. The fix I mentioned above solves the server to client where the “component replicates” option is set to true, but then it breaks the character rotation so when running around it looks like the character is turned to face a direction that isn’t the movement direction and then with multiple setting fixed gravity calls the rotation gets even more out of sync and might go from being turned 90 to the left of the forward vector of the capsule to 110 or some other odd number.

ah sorry I misunderstood. Then try multicasting the function (same drop down where you chose ‘server’). If that doesnt work I have no idea what else… then it might be code related

multicast didn’t make a difference but for some reason the client to client replication is working just not server to client (I should clarify this is not because the multicast I switched it back to the settings seen in the video I posted), so which ever viewport is also the server doesn’t update it’s rotation to the clients’ viewports, which for the most part won’t matter in a dedicated server architecture just a p2p architecture.

Thanks for the video!

I reproduced the same problem over here, it’s caused by the server-owned Character which locally executes a function that must be only called as an RPC for the clients.
This wasn’t really tested properly I’m afraid, excess of confidence. I’ll take a look eventually.