I found the problem in the character movement component (UCharacterMovementComponent::UpdateBasedMovement). It seems like they simply didn’t think about the case of switching pawns on a moving platform, which results in a large over-correction, but there’s overall some pretty dodgy stuff going on so it’s nice that it works at all. Bad news is that you can’t fix this in Blueprint. Good news is that the function has an early return when not on a dynamic base so you can work around the issue by setting the mobility of your elevator to static immediately after possessing, and setting the mobility to movable before you update the elevator’s position again. Do the same for detaching/unpossessing.
I have updated my test blueprint, it’s messy but you’ll get the idea.
Hey Grim thanks for looking into this. I’m not able to get your solution to work for me though… With multiple blueprints, I have to use interfaces in this instance so I’m not sure if there is a communication delay between toggling the mobility… Either way, I like the idea. I tried to completely stop the elevator timeline, then possess the turret, and then restart the elevator timeline but that did not work either… I went as far letting the elevator rise, stop it and wait for a while, then possess the turret and it still jumped, even though the elevator timeline had been stopped for a few seconds. However, if I tried using the turret after that initial possess while the elevator was still stopped then it would not jump. So its almost as if there is a stored value tracking its change in position that it needs to express… I’m having a hard time believing something seemingly so simple is causing this much troubleshooting, ha! But you were able to prevent the issue with your setup? Wonder what I can do differently?
It fixed the issue for my simple test setup. It’s probably also a bit of luck that because the flow must be like Possess → SetMobility(Static) → Movement Comp Tick → SetMobility(Movable) → UpdatePlatform. If the timeline gets updated before the movement comp tick then it would obviously not work anymore. I don’t think the order in which classes tick or timelines get updated is guaranteed (apart from prerequisite actors and tick groups) so this might not even work anymore for my test setup in a packaged build as the order may be switched around. It’s even trickier for a more complex project like yours. In C++ this would be a lot easier to work around as you could just override the method in your own subclass. Not saying there is no workaround when using only Blueprint, it probably just involves a lot more trial and error.
I also only stepped through a small section of the code so I can’t rule out that there are more problems with the based movement when switching pawns. One thing you should try:
Disable collision between the turret and the pawn, set the platform mobility to static immediately after possessing the turret (put the node directly behind the possess node) and just leave it at that, don’t move the platform any further. If the pawn still teleports now when you possess/unpossess there’s an additional problem.
Thanks Grim, so yeah still unable to get this problem fully sorted, however your final note (disable collision, set platform mobility to static after possess, stop elevator) does work. Which is progress! Earlier when I tried stopping the platform the turret would still jump the first time I possessed it, but not again after. Not sure what to make of this, but its movement in the right direction maybe, haha.
I’m completely out of ideas at this point that don’t involve rethinking the level design and story… Kicking myself for not testing this much earlier in the design but I just didn’t foresee this, of all things, being the preventative issue. Thanks for lending your brain on this, I’ll report back if I find a solve that works for my situation.
I just tried one other thing which worked for me too. Try setting the mobility of your elevator only to movable when you actually move it, so your nodes look like SetMobility(Movable) → Move Elevator → SetMobility(Static). Apparently the character doesn’t care whether its base is actually movable to follow it, which means at least you won’t get stuck in the floor or something. Stuff like imparting base velocity probably won’t work correctly anymore though, but that’s very subtle and I doubt your players will notice. It might affect other things, so don’t do crazy physics stuff on the elevator.
Okay, makes sense. I’ve been trying to get this workflow to work for my setup but wondering if you have any thoughts about how I’m handling this or recommendations for trying this differently. I’m guessing that because this is working in your setup and not mine that there is some issue with when timeline ticks and possession are actually hitting and I’m just not able to catch my elevator in a Static Mobility stage when I want it to. I’ve tried a few dozen remixes of these blueprints but haven’t gotten any different results. I’ve even tried stopping the elevator timeline before the possession, then possessing the turret, then setting mobility to static, then resuming play on the elevator timeline and that didn’t work either. I’m using interfaces but unsure how that impacts the timing we’re after. Another question, I tried this a few times and it didn’t work but am curious as to why we would set the elevator platform to static mobility after the possession? Wouldn’t I want the platform to be static and then possess the turret? Would that “clear out” any accumulated location values because now its no longer moving? That just sounds right to me but I do not understand what is happening behind the scenes on these nodes so could be completely off. I’ve attached a few screenshots of my BPs below that I think mirror your setup above, albeit leverage interfaces to communicate between BPs… Is your setup within the Level BP or attached to the actors? Maybe if I did all of this within Level BP I’d have better control over timing / sequence order?
I think your issue is that you have an actor as elevator, and are setting the mobility on the default scene root. The function in C++ that we want to exploit for the workaround takes a UPrimitiveComponent* so you should set the mobility on your actual mesh component. Also, you only need to set the mobility as you did in your first picture, around the SetWorldLocation, so the mobility is basically always static except when you actually move the elevator. You don’t need any other interface messages and such for the mobility, and they won’t lead to predictable results anyway.
EDIT: If that doesn’t work post a picture of your elevator blueprint sc hierarchy.
Yoooo! Fixed! Attaching a screenshot of the Elevator BP for future readers.
Grim and Everynone, thank you both so much for troubleshooting this with me! Cannot believe the headache this caused. Couldn’t have solved this myself. Thanks again!
New to the thread, read through it all, saw your final post and thought, yay, let me check the screenshot! Broken link -_-
Any chance to update the link or share it with me some other way? I have a similar issue with my actor not attaching to another actor after I possess because one uses movement component and the other doesn’t(flying pawn thingy).
Hope I could get the quick fix instead of doing my own investigations.
Ok, I’m not sure if I stumbled upon a fix here, but my pawn suddenly follows the movement of the parent. All I did was take the child pawn/character’s MovementComponent->SetMovementMode(Flying) in blueprints(I don’t know C++ yet).
Not sure this will solve it for the original issue though, but worth a try. Hope it helps someone.