Announcement

Collapse
No announcement yet.

Dynamic gravity for characters

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

    Originally posted by Xaklse View Post
    I have an updated version of NinjaCharacter, this time working for 4.19 as a plugin, with several fixes and expanded functionality.
    I need to fix a grave bug that happens in online mode only, before considering a new release for everyone.
    .
    Does this by any chance has to do with movement updates and a ServerMoveHandleClientError() ?
    Have been using your NinjaCharactermovement code for a while now (currently also in 4.19). However, I recently started working on online implementation, and keep getting crashes once the client pawn moves.

    Thanks for all your work on this, and sharing this!

    regards
    Frank


    UE4Editor_PointGravity!TConsoleVariableData<int>::GetValueOnGameThread() [c:\program files\epic games\ue_4.19\engine\source\runtime\core\public\hal\iconsolemanager.h:894]
    UE4Editor_PointGravity!UNinjaCharacterMovementComponent::ServerMoveHandleClientError() [d:\unreal projects\pointgravityroot\ue4\source\pointgravity\ninjacharactermovementcomponent.cpp:3394]
    UE4Editor_Engine!UCharacterMovementComponent::ServerMove_Implementation() [d:\build\++ue4+release-4.19+compile\sync\engine\source\runtime\engine\private\components\charactermovementcomponent.cpp:8317]
    UE4Editor_Engine!UCharacterMovementComponent::ServerMoveDual_Implementation() [d:\build\++ue4+release-4.19+compile\sync\engine\source\runtime\engine\private\components\charactermovementcomponent.cpp:7935]
    UE4Editor_Engine!ACharacter::execServerMoveDual() [d:\build\++ue4+release-4.19+compile\sync\engine\source\runtime\engine\classes\gameframework\character.h:212]
    UE4Editor_CoreUObject!UFunction::Invoke() [d:\build\++ue4+release-4.19+compile\sync\engine\source\runtime\coreuobject\private\uobject\class.cpp:4551]
    UE4Editor_CoreUObject!UObject::ProcessEvent() [d:\build\++ue4+release-4.19+compile\sync\engine\source\runtime\coreuobject\private\uobject\scriptcore.cpp:1345]
    UE4Editor_Engine!AActor::ProcessEvent() [d:\build\++ue4+release-4.19+compile\sync\engine\source\runtime\engine\private\actor.cpp:687]
    UE4Editor_Engine!FObjectReplicator::ReceivedRPC() [d:\build\++ue4+release-4.19+compile\sync\engine\source\runtime\engine\private\datareplication.cpp:859]
    UE4Editor_Engine!FObjectReplicator::ReceivedBunch() [d:\build\++ue4+release-4.19+compile\sync\engine\source\runtime\engine\private\datareplication.cpp:731]
    UE4Editor_Engine!UActorChannel::ProcessBunch() [d:\build\++ue4+release-4.19+compile\sync\engine\source\runtime\engine\private\datachannel.cpp:2281]
    UE4Editor_Engine!UActorChannel::ReceivedBunch() [d:\build\++ue4+release-4.19+compile\sync\engine\source\runtime\engine\private\datachannel.cpp:2148]
    UE4Editor_Engine!UChannel::ReceivedSequencedBunch() [d:\build\++ue4+release-4.19+compile\sync\engine\source\runtime\engine\private\datachannel.cpp:296]
    UE4Editor_Engine!UChannel::ReceivedNextBunch() [d:\build\++ue4+release-4.19+compile\sync\engine\source\runtime\engine\private\datachannel.cpp:667]
    UE4Editor_Engine!UChannel::ReceivedRawBunch() [d:\build\++ue4+release-4.19+compile\sync\engine\source\runtime\engine\private\datachannel.cpp:388]
    UE4Editor_Engine!UNetConnection::ReceivedPacket() [d:\build\++ue4+release-4.19+compile\sync\engine\source\runtime\engine\private\netconnection.cpp:1540]
    UE4Editor_Engine!UNetConnection::ReceivedRawPacket() [d:\build\++ue4+release-4.19+compile\sync\engine\source\runtime\engine\private\netconnection.cpp:933]
    UE4Editor_OnlineSubsystemUtils!UIpNetDriver::TickDispatch() [d:\build\++ue4+release-4.19+compile\sync\engine\plugins\online\onlinesubsystemutils\source\onlinesubsystemutils\private\ipnetdriver.cpp:237]
    UE4Editor_Engine!TBaseUObjectMethodDelegateInstance<0,UNetDriver,void __cdecl(float)>::ExecuteIfSafe() [d:\build\++ue4+release-4.19+compile\sync\engine\source\runtime\core\public\delegates\delegateinstancesimpl.h:659]
    UE4Editor_Engine!TBaseMulticastDelegate<void,float>::Broadcast() [d:\build\++ue4+release-4.19+compile\sync\engine\source\runtime\core\public\delegates\delegatesignatureimpl.inl:937]
    UE4Editor_Engine!UWorld::Tick() [d:\build\++ue4+release-4.19+compile\sync\engine\source\runtime\engine\private\leveltick.cpp:1317]
    UE4Editor_UnrealEd!UEditorEngine::Tick() [d:\build\++ue4+release-4.19+compile\sync\engine\source\editor\unrealed\private\editorengine.cpp:1693]
    UE4Editor_UnrealEd!UUnrealEdEngine::Tick() [d:\build\++ue4+release-4.19+compile\sync\engine\source\editor\unrealed\private\unrealedengine.cpp:401]
    UE4Editor!FEngineLoop::Tick() [d:\build\++ue4+release-4.19+compile\sync\engine\source\runtime\launch\private\launchengineloop.cpp:3339]
    UE4Editor!GuardedMain() [d:\build\++ue4+release-4.19+compile\sync\engine\source\runtime\launch\private\launch.cpp:166]
    UE4Editor!GuardedMainWrapper() [d:\build\++ue4+release-4.19+compile\sync\engine\source\runtime\launch\private\windows\launchwindows.cpp:144]
    UE4Editor!WinMain() [d:\build\++ue4+release-4.19+compile\sync\engine\source\runtime\launch\private\windows\launchwindows.cpp:223]
    UE4Editor!__scrt_common_main_seh() [f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl:253]

    Comment


      Nope, the problem I have occurs with control rotation and online mode, no crash.
      I remember there were crashes ages ago, but I'm not sure if they were related to what you mention.
      WreckMan: Rise of a Hero
      SonicGDK / Ashura: Dark Reign
      Heaven of Relics / Relic Madness

      Comment


        Originally posted by Xaklse View Post
        Nope, the problem I have occurs with control rotation and online mode, no crash.
        I remember there were crashes ages ago, but I'm not sure if they were related to what you mention.
        When I enable 'Ignore Client Movement Error Checks and Correction' in the movement component it seems to stop crashing. I guess those checks and corrections can't be used together with the altered gravity on the movement?

        thanks
        Frank

        Comment


          turns out that wasn't the culprit, still get the crashes.

          Comment


            Ninja Character plugin for Unreal Engine 4.19.2 is up! Go to >> https://github.com/Xaklse/UnrealEngine << and grab the ZIP file (not the green button) from the link posted at the top part (if error 404: log in to Github, link your UE4 account to Github).

            This is for C++-based game projects.

            And I didn't fix my online bug related to ControlRotation yet.
            WreckMan: Rise of a Hero
            SonicGDK / Ashura: Dark Reign
            Heaven of Relics / Relic Madness

            Comment


              Awesome, having a look now !
              LinkedIn | Atmosphere Modelisation | Nvidia GameWorks builds - 4.19.2 : VXGI2.0, Blast, HairWorks, Flow - Plugins: VictoryBP | 4.17.2 | 4.16.2 | 4.15.3 | 4.14.3

              Comment


                Originally posted by Xaklse View Post
                Ninja Character plugin for Unreal Engine 4.19.2 is up! Go to >> https://github.com/Xaklse/UnrealEngine << and grab the ZIP file (not the green button) from the link posted at the top part (if error 404: log in to Github, link your UE4 account to Github).

                This is for C++-based game projects.

                And I didn't fix my online bug related to ControlRotation yet.
                Xaklse, thanks for your work but your link does not work. Getting still 404. (i am logged in)
                I browsed your github repositories and there aren't any unreal releated projects. Perhaps it is configured to private? Don't know.
                Can you please post the zip in this thread?

                EDIT:
                Have you done something?
                I just saw that i got an email (after linking) that invited me for joining Epic Games organization on github.
                I see your repository now.
                If you haven't done anything so just linking the UE4 account to github doesn't give me access.
                I also have to join the epic games organization on github.
                Anyway it works now.
                Last edited by Ionpainter; 07-19-2018, 11:16 AM.

                Comment


                  Hey Xaklse

                  First of all, thanks for the update!

                  Got a few questions though:

                  - On a spherical world, I still get a gimbal lock with the spring arm. I used to fixed this by setting the absolute rotation on the spring arm, and have the control inputs add to that rotation (without using controller yaw/pitch nodes). However this needed quite a lot of extra math. I tried using the pawn from your example, however has the same result. Is this still needed to avoid gimbal lock?

                  - Setting gravity direction each tick (with only Align Component to Gravity enabled), makes the pawn rotate snappy (is custom direction evaluated each tick?). I tried interpolating the gravity direction, which didn't work either.

                  My previous setup completely ignored the control rotation. I first set the gravity direction each frame, then according to the gravity I set the actor rotation (using MakeRotFromXY), then set spring arm rotation, then capsule rotation. This all felt a bit like an overkill (cause there was also a lot of extra math needed for other mechanics like aiming and so on). So I was wondering if this is still needed with your update, or that I'm simply doing things wrong.

                  If this all sounds too trivial, please drop me a PM, so I can elaborate the issues I'm having!

                  Thanks!

                  Frank
                  Last edited by Frank Post; 07-19-2018, 06:17 PM.

                  Comment




                    I don't have any problems with gimbal lock; aside from the C++ code I added, I also rely on some blueprint nodes embedded in the character blueprint, make sure you didn't miss those.
                    WreckMan: Rise of a Hero
                    SonicGDK / Ashura: Dark Reign
                    Heaven of Relics / Relic Madness

                    Comment


                      Hey Xaklse

                      I actually tested with your example player. I only added a custom gravity direction on event tick, so the gravity turns spherical. And only enabled 'Align Component to Gravity'
                      Still get jittery movement (I also noticed in your video), and the yaw/pitch gets in a gimbal lock.


                      Click image for larger version

Name:	ninja.PNG
Views:	1
Size:	15.9 KB
ID:	1506315

                      Click image for larger version

Name:	gravity.PNG
Views:	1
Size:	56.8 KB
ID:	1506313

                      In my previous setup I didn't notice the choppy movement, because I was rotating the player and capsule each frame. However I couldn't use the control rotation at all, and had to add a workaround to drive the camera (in worldspace). Huge downside was the controller rotation and all the controller functionality couldn't be used, since i was unable to get that propely working spherical. Using the forward vector and gravity direction to create a rotation.

                      Click image for larger version

Name:	setrot.PNG
Views:	1
Size:	47.8 KB
ID:	1506314

                      I wonder where the choppy movement comes from, it kinda looks like the rotation isn't actually updated each tick. I did notice a treshold in gravity change per frame in one of the functions, could that be causing that? It does happen somewhere in code I think, interpolating the gravity between frames from BP didn't make a difference.

                      I had plenty of rotation issues before, and most of the time fixed those by setting each axis separately, Im not sure if that would also fix the gimbal lock though.

                      hope you can help me on this, or give me some pointers where to look! Most I did was in BP since I only know some C++ basics.



                      thanks!

                      cheers
                      Frank

                      Comment


                        choppy movement was caused by line 3967


                        // Abort if angle between new and old capsule 'up' axis almost equals to 0 degrees.
                        if ((DesiredCapsuleUp | CurrentCapsuleUp) >= THRESH_NORMALS_ARE_PARALLEL)
                        {
                        return;
                        }

                        When I disable that check, the character (capsule) rotation looks smooth. I'm not sure if I can simply disable that check though, might impacts performance? (see no hit in my current test level, but not sure about replication and multiple active characters)


                        Comment


                          Interesting finding. It would impact performance yeah, I will look into lowering the 1 degree change requirement and/or make it configurable.
                          I assume you still experience gimbal lock, right?
                          WreckMan: Rise of a Hero
                          SonicGDK / Ashura: Dark Reign
                          Heaven of Relics / Relic Madness

                          Comment


                            Yeah gimbal lock remains. Did a quick debug, but need to investigate a bit further. I also read about the native yaw/pitch funcions causing locks for people making 360dof controls. I think they just do a rotation.x+=, and dont use quaternions to add rotation. Which is destined to cause gimbal locks. Was planning on looking into that first, and maybe override the add control yaw/pitch functions to add rotation according to the component rotation.

                            thanks
                            Frank

                            Comment


                              I tried adding override functions for the addinput yaw and pitch (from pawn.cpp). I used the forward vector of the movement component to make those relative, however that didn't seem to fix it.
                              ​​​​

                              Comment


                                After some debugging I noticed the controller Z axis gets mirrored when approaching the opposite pole (I think according to the gravity Z value).

                                I changed OnCharMovementAxisChanged function in NinjaCharacter.css to

                                Code:
                                void ANinjaCharacter::OnCharMovementAxisChanged(const FVector& OldAxisZ, const FVector& CurrentAxisZ)
                                {
                                    // Rotate the control rotation of the Controller if needed.
                                    if (bCapsuleRotatesControlRotation && Controller != nullptr)
                                    {
                                        FTransform trans = GetTransform();
                                        const FQuat QuatRotation = FQuat::FindBetweenNormals(OldAxisZ, CurrentAxisZ);
                                
                                        trans.ConcatenateRotation(QuatRotation * ControllerRotation.Quaternion());
                                        trans.GetRotation().Normalize();
                                
                                        Controller->SetControlRotation(trans.GetRotation().Rotator());
                                    }
                                }

                                Added to NinjaCharacter.h:

                                Code:
                                #include "GameFramework/Pawn.h"
                                
                                public:
                                    FRotator ControllerRotation;
                                
                                public:
                                    virtual void AddControllerPitchInput(float Val) override;
                                    virtual void AddControllerYawInput(float Val) override;
                                and added to NinjaCharacter.css:

                                Code:
                                void ANinjaCharacter::AddControllerPitchInput(float Val)
                                {
                                
                                    if (Val != 0.f && Controller && Controller->IsLocalPlayerController())
                                    {
                                
                                        ControllerRotation.Pitch += Val;
                                
                                    }
                                }
                                
                                
                                void ANinjaCharacter::AddControllerYawInput(float Val)
                                {
                                    if (Val != 0.f && Controller && Controller->IsLocalPlayerController())
                                    {
                                        ControllerRotation.Yaw += Val;
                                    }
                                
                                }
                                This makes the controller rotation match the gravity (movement component), and stops the gimbal lock. However, because of using the transform to make the rotations relative, enabling the option Orient Rotation to Movement doesn't work correct anymore. So unfortunately it still might not be the correct approach... Any ideas to get those rotations relative using something else than the transform?

                                cheers
                                Frank
                                Last edited by Frank Post; 08-02-2018, 06:15 PM.

                                Comment

                                Working...
                                X