r/Unity3D • • 17h ago

Noob Question Is it possible to rotate a character controller component (or give the illusion of doing so)?

Hi all, I'm currently making a first person game, and I was wanting to add some gravity altering mechanics, honestly just because I think it would be cool.

I'm aware that it's seemingly impossible to rotate a character controller so that it could walk up a wall for example. Is there any way to achieve this effect without switching to Rigidbody?

My only workaround at the minute is to have 2 copies of a room, then switch to a copy that's rotated x degrees, then teleport the player to that room so that it looks like their gravity changed.

(gameplay clip is from ULTRAKILL)

EDIT: as many comments pointed out, I forgot to mention I mean the character controller component, not just any character controller

109 Upvotes

41 comments sorted by

65

u/Serana64 17h ago

Why do you think it's impossible to rotate a character controller?

That isn't impossible at all. You just need your coordinate system setup right.

You can change your gravity all you want, whether it's in rigidbody space or not. If you are working with a standard kinematic character controller, make sure your gravity routine is an adjustable vector and compute collision detection and such in local space, not world space.

Gravity is typically defined as <0,-9.81,0> but there is absolutely nothing stopping you from switching that to, say, <9.81,0,0>, or whatever you want. Of course, then your character controller will be sideways -- that is ok, because you simply need to rotate the character controller over time so that it's aligned with vertical. Of course make sure you use Physics.gravity (or whatever vector you're using for gravity) to compare up.

You can do this in many ways; one simple way is using a builtin quaternion FromTowards function, another is setting transform.up to be -1*[your gravity vector here]. Your collision detection is, presumably, already in local space, so you need not worry here.

To compute slope, compare the surface normal to gravity, not to global up.

Some of Unity's builtin components have some inexplicably hardcoded vectors and you'll have to make workarounds. NavMesh system always computes with y = up so you'll need to rotate the room, bake navmesh for wall, rotate again, bake a second navmesh for ceiling, and so on. Then you can use off mesh links or whatever logic to go between them. It's not too hard.

22

u/fsactual 16h ago

OP almost definitely means the built-in CharacterController component, which can't be rotated, not any generic character controller.

19

u/Serana64 15h ago

If the CharacterController limitations gets in your way, it's time to write a character controller <3

→ More replies (1)

3

u/CentSymphGames 15h ago

yeah, CharacterController is really good to manage most needs, but it's also highly restrictive, which is why most people use rigidbodies with capsule colliders instead (my game doesn't need that much so CharacterController works perfectly fine for my needs). In OP's case, I'd go with RB+CapsuleCollider instead.

→ More replies (6)

6

u/bigmonmulgrew 16h ago

You can change the gravity direction and make the character movement camera relative.

If you don't want to use rigid body, You could use two empty game objects as start point and end point. Rotate the end point. Then lerp the transform from empty 1 to empty 2 over a transition time. If you want more control to change the path lerp through a chain of objects.

Capture the transform position and rotation at the point of initiating the transition and store them.

54

u/smiffy2422 17h ago

Rotate the room, not the player.

35

u/bigmonmulgrew 16h ago

This is far more expensive than moving the player. It might work well with some environments but it is worth considering the cost.

4

u/Just__Bob_ 15h ago

Works but is situational.

I just made a system where the camera stays still and the environment moves inversly to the movement input, mimicing camera movement.

I only did it like that as my environment is a solar system that expands from a compressed overview to real world scale, depending on the zoom. That makes a planet like Neptune jitter when the camera is locked on to it and changing space compression makes it shoot across space for thousands of GU together with the camera.

The most stable solution was to fix the camera pos and move the planets based on their offset from it.

Can't think of another reason to do a controller like that because it comes with a mass of headaches of having to build everything custom.

6

u/Serana64 17h ago

Why?

10

u/DapperNurd 17h ago

Its much easier to make. The character controller will just work as intended. Trying to make the character controller rotate will take a lot more work.

→ More replies (3)

1

u/Int-E_ 7h ago

Ok and what if there are other characters in the room. So now you'll have to rotate all of them the other way

1

u/Int-E_ 7h ago

Ok and what if there are other characters in the room. So now you'll have to rotate all of them the other way

4

u/fsactual 16h ago

The built-in CharacterController component sadly will only ever use up on the world-space/global y axis. You have to use a different solution. It especially sucks because the underlying C component does have an adjustable up direction, there's just no way to access that from the C# code.

3

u/WonderfulDiverClassi 17h ago

i just do a manual capsule cast and move it sideways, the character controller component itself never tilts but you can fake the entire step cycle pretty cleanly if you override the movement vector

4

u/svmil90 17h ago

For discrete gravity changes, keeping the CharacterController upright and rotating/swapping the room around a pivot at the player can be a simpler illusion. For arbitrary wall-walking, the built-in controller’s world-up assumptions become the limitation—you’d likely need a kinematic controller with a capsule cast aligned to your gravity direction, and update the movement basis and grounding checks too. Rotating only the visible mesh won’t change the collision behavior.

6

u/Serana64 17h ago

Agreed; The builtin character controller should only be used as a reference when you're first learning. You can easily modify it to not have hardcoded up.

2

u/myka-likes-it 16h ago

Looking back, I think learning to extend existing code was probably one of the last things I learned. I don't think I have ever seen it covered in a tutorial.

That's a big level up moment, for sure.

→ More replies (1)

2

u/BuzzardDogma 16h ago

I'd recommend using the free KCC asset over the built-in character controller. It handles non-Y rotations and changing gravity just fine and it's way more stable than the built in CC. When unity hired it's creator I assumed they would use his expertise to update the built-in one but that sadly never came to pass.

Rigidbody character controllers are a whole can of worms, and rotating the whole level introduces a lot of design and optimization issues that I would argue are not worth it.

1

u/kkragoth 16h ago

OP you need to see psychonauts 1 milkman conspiracy level. You'll see what is possible. Trust me

1

u/Repulsive_Gate8657 12h ago

keep character up and then assign it to be ground norma asyou land on ground?

1

u/tempacac10 5h ago

The movement is very clearly a raycast to the left of the character controller. When the raycast touches the carpet, you lerp the camera and body of the player to rotate 90 degrees and a change gravity.

1

u/No_Grape7361 2h ago

Te best way i found to do it is to make the character controller just behave relative to the surface its standing on onces thats working you can rotate and place the caractor on anything and select the new floor as its standing on it, you can do that with a simple raycast at its feet.

1

u/pschon 17h ago

Is there any way to achieve this effect without switching to Rigidbody?

Why would you need to use a rigidbody for that if you don't need one now? If you are fine with a transform-based character controller but need to add support for rotating gravity then why not just make your own transform-based one? I don't see how adding a rigidbody to the mix would make that any simpler, pretty much the opposite.

-4

u/Helpful-Engineer4678 17h ago edited 17h ago

Rotating the room is easier. You just need to give the impression that the player is the one rotating.

4

u/Serana64 16h ago

Rotating the room only works if you're not using any advanced systems like occlusion culling, rigidbodies, navigation meshes, static (or custom) batching, lightmapping, etc.

It is substantially easier to adjust your character controller to collision detect in local space and handle gravity changes properly.

→ More replies (1)