I've been trying to program a transform to make the player sit down in a moving bus seat and face forward while doing so. It's been neat learning and applying different mathematical concepts, but it's been a little wild applying them, because of what feels like inconsistencies in how the engine uses frame of references.
Vector math has been mostly easy to pick up, definitely complicated but I filled in the gaps from not having taken any linear algebra in college pretty quickly. I think I learn a lot more-quickly when I can do something for myself, like make a model in my head and understand mathematical concepts spatially. That's tough when you're sitting in class with a textbook, but very easy when you're sitting with a game engine open, converting from world to local space and doing forward and right vectors, combining rotators, and doing other vector transform spatial stuff. Testing and seeing the outcomes makes it really comprehensible.
The stuff that's been the most-difficult to wrap my head around, it turns out, aren't any of the mathematical concepts. Those are really clear and consistent; it's the Unreal Engine-specific stuff that's taking a lot of trial and error to work out. The particular thing that's been making the bus work so complicated is the ways a parented player character calculates their rotation.
Normally, when you parent something, any world-space calculations become local space, which is really easy to understand. If you have an actor parented to a moving object, the frame of reference is always that of the parent - so when the parent pitches or yaws, the child rotates and yaws without their actual rotation values changing at all. This gets more complicated with player characters because you generally use a player controller, which uses absolute world-space rotation, to calculate the rotation of your player pawn.
This is called "control rotation" in the engine, and it's super-useful! It gives you an absolute world-space rotation to read and modify as-needed. It's how I make the player rotate to face the right direction when they sit down in a static chair. It's been real weird trying to get this working with the moving bus though, since the chair and the player are both parented to the bus for a ton of good reasons during travel, I thought I could just rotate the player in local space but that was giving me really wild inaccurate rotations.
Something that took me way too long to figure out, and I only just figured it out a few minutes ago, is that while the control rotation is in world space, that's... only kind-of true? If the player pawn has no parent, the control rotation should match the pawn's rotation, both being in world space. If you set the control rotation to a particular rotator, the player will move to match that rotator in world space as well! If you try to manually rotate the player when they're using pawn control rotation, it won't do anything because the controller's rotation overrides it. Cool, that all makes sense.
What tripped me up is that the engine is apparently using delta control rotation to update the player location, not actual rotation. What this means is that while you can't directly rotate the player pawn when using control rotation, in situations where the player is parented to a moving, rotating actor, you don't actually have to account for the ever-changing difference between player local rotation and world-space control rotation!
For example, if you need to yaw the player 90 degrees clockwise, and you wanna interpolate that over 3 seconds, you can just ease the control rotation from the current rotation in world-space to the same rotation + 90 degrees of yaw, still in world space, even if the object that the player is walking around in has itself yawed 20 degrees to the left during that ease function. I kept trying to find ways to account for the ever-changing difference between local and world space as the parent moved, but it turns out you can just ignore it as the engine is actually using delta rotation instead of absolute rotation when rotating the player using control rotation.
Whew, anyway now that I've written it out, maybe it'll be easy for me to remember!
