Keeping velocity when floating origin repositions

steve54321

New member
We are using a floating/moving origin approach whenever the character gets farther away from the origin. On reposition of the origin, we use CC.SetPosition(<newpos>), but this brings the character to an abrupt halt (f.e. while running or falling).
How can we keep the velocity of the CC? I doesn't seem to work to save the CC.Velocity value, do a CC.SetPosition() and reassign the velocity as it seems to be ignored. Using CC.AddForce() works but I don't know what I need to pass as force parameter to keep the exact speed/velocity as before the reposition.
 
I would guess that the velocity gets ignored because you're setting it immediately after SetPosition, i.e. within the same FixedUpdate cycle - try waiting until the next FixedUpdate to set the velocity.
 
Thank you very much, that fixed it partly! It seems I also need to copy over the CC.MotorThrottle in the next FixedUpdate(), else without setting the MotorThrottle I get a small hitch on reposition. This fixes the reposition on walking/running.
But the problem still exists on falling. Is it possible that there is an internal variable like "fall speed" that I need to copy over, too?
 
GravityAmount gets set to 0 when using SetPosition, so maybe try that. I've not tried setting it manually before though.
 
Awesome thanks, with also copying the GravityAmount in the next update the falling is now smooth, too.

There is one (minor) flaw: when there is a reposition and the player is in first person view, falls down and has a weapon equipped (f.e. the assault rifle) the weapon gets noticeable repositioned (looks like to the default position in the middle of the screen). Same when walking but this is less noticeable. Is there a way to also take over the weapon swaying values?
 
When you say it gets repositioned, do you mean just the spring position of the item gets reset? If so, I would try taking a look at FirstPersonPerspectiveItem, e.g. PositionSpring.Value.
 
After some debugging it seems to be the springs that cause the hitch on setting a new position. In detail the code here
private void FirstPersonPerspectiveItem.SnapSprings(bool fromEquip) ... m_PositionSpring.Reset(); m_RotationSpring.Reset(); m_PivotPositionSpring.Reset(); m_PivotRotationSpring.Reset(); ... UnityEngineUtility.AddUpdatedObject(m_Object, true);
seems to reset the FPV weapon springs. When I comment this code I can reposition the character without any hitches in the weapon swaying/bobbing. Unless you have a better idea to fix that, I will add code to avoid these code parts in my use case.
 
Hello, allow me to bump this thread, I'm trying to use UCC in a large scene with the floating origin method, but the results aren't great : I'm using a simple third person adventure character, and not only does he often get into some sort of short halt when moving his transform, the camera's rotation is also affected as it faces in the forward direction - which in turns leads the player to move astray while he maintains the same movement input.
So my first question would be when exactly do you call the properties you mentioned ? In my current script the environment and the player are moved in LateUpdate, the velocity and MotorThrottle in the next FixedUpdate (I use a bool to wait for it), and the gravity in the next Update. Is this the correct way to do it ?
And secondly, how are we supposed to handle the camera ? More specifically in my case the third aventure one.
Hope you can help me out with this ! Thanks in advance.
 
Hey, maybe Andrew can help out here, too.

Did you verify that the halting only happens on reposition of the floating origin? I did not have any problems with the camera (I am using FPV and TPV. fyi: my floating origin does only do repositioning and not do any reset of rotation).

Here is my callback on repositioning the floating origin and the FixedUpdate:

Code:
void onOriginReposition(Vector3 deltaVec) {

        // Keep the same velocity as before (it is reset on SetPosition())
        saveMotorThrottle = uccCharacter.MotorThrottle;
        saveExternalForce = uccCharacter.ExternalForce;
        saveVelocity = uccCharacter.Velocity;
        saveGravityAmount = uccCharacter.GravityAmount;
        bResetVelocityInFixedUpdate = true;

        Item item = uccCharacter.GetComponent<Opsive.UltimateCharacterController.Inventory.Inventory>().GetActiveItem(0);
        Opsive.UltimateCharacterController.FirstPersonController.Items.FirstPersonPerspectiveItem fpvItem = null;
        if (item != null) {
            fpvItem = ((Opsive.UltimateCharacterController.FirstPersonController.Items.FirstPersonPerspectiveItem)item.FirstPersonPerspectiveItem);
            fpvItem.bIgnoreSnapSprings = true;  // <-- here I needed to change the Opsive code
        }

        uccCharacter.SetPosition(uccCharacter.transform.position - deltaVec, false);

        if (fpvItem != null) {
            fpvItem.bIgnoreSnapSprings = false;
        }
    }

    public override void FixedUpdate() {

        if (bResetVelocityInFixedUpdate) {
            bResetVelocityInFixedUpdate = false;

            uccCharacter.Velocity = saveVelocity;
            uccCharacter.GravityAmount = saveGravityAmount;
            uccCharacter.MotorThrottle = saveMotorThrottle;

            if (saveExternalForce.sqrMagnitude > 0.0001f) {  // only used if char is in godmode
                uccCharacter.AddForce(saveExternalForce, 0, false, false);
            }
        }
 
Well thanks a lot steve54321, you just made my day ! The main thing I had to change was the SetPosition void : I hadn't seen the snapAnimator bool and had used the function with only the new position. With the bool set to false, the whole animation and camera issues go away ! I also used the FixedUpdate void for the gravity amount and without waiting for the next one as you did, and stored the physics values before calling SetPosition. I just have one last question : when do you call onOriginReposition ? Is it on Update or LateUpdate ?
Thanks again <3
 
I am happy that it worked out for you!
My floating origin code checks for reposition on each Update() call and calls onOriginReposition callback within this Update().
 
Top