I want to have a character move inside a moving spaceship (the spaceship is effectively a ‘moving platform’ that the player should be able to move inside (relative to the space ship)). The ship needs to be physics driven (forces need to affect it), but shouldn’t be affected by the mass/rigidbody of the player himself. The player should collide with the walls inside the ship. The player should be able to enter/exit the spaceship by walking on/off the ‘floor’ of the spaceship.
What I have so far:
The walls of the ship each have box colliders attached, and the ship has a non-kinematic rigidbody attached (to enable me to fly the ship once I’m onboard with a special set of controls that add forces to the ship’s rigidbody).
The player is a simple capsule with no rigidbody, but a box collider.
The way I have this working right now is to use a raycast downwards from my player’s normal to detect when I enter/exit the spaceship (done in Update). When I cast down onto part of the spaceship, I parent the player to the spaceship, so the movements of the spaceship affect the player without awkward sliding/bouncing that I’ve found when using the player capsule with a ridigbody). The player can move about fine (using transform.rotate and transform.translate as my movement primitives).
The problem I have now is that the player does not stop when it collides with walls on the ship as the player moves around inside the ship. I have OnCollisionEnter events firing when the player collides with walls of the ship, but have not figured out a way to make the player stop going through walls. Presumably I can just use some transform foo to make the transform stop moving in the direction of the wall on an oncollision event?
I’d also like to add artificial gravity to this, but I think I can figure out how to do that with a combination of raycasting to find the ‘downward’ direction and applying some kind of non-rigidbody force-like effect to my character to have him ‘fall’ to the floor after he jumps, etc.
So you can do moving platforms. Its nasty hard. Especially once you add in nav meshes.
Something I did in an airship game is:
-have all physics and nav mesh that is important to characters on the ship static.
-Parent all characters on the ship to the static version of the ship.
-Create a “visual proxy” for all characters.
-Parent the “visual proxy” for all characters to the moving ship.
-Set local positon of visual proxy == local position of character physics.
-when exiting the spaceship just move the physics object to the visual object (assuming the visual object is in “Real space”) -then always set visual proxy postion == physics position.
The above saved me from dealing with all the physics issues that would arise. You can also use rigidbodies with the above method.
Hi! I found this conversation and I was interested in your approach!
Can you explain more clearly what you mean by “visual proxy”? I tried looking for it but I couldn’t find anything…
Thank you very much, hoping you will read this!
If I understand correctly, we could have the spaceship in a unity scene with its own physics world and the outdoors/space in another scene + own physics world, and running the two unity scenes at the same time.
It’s not clear yet if we can just have multiple “physics worlds” in one unity scene.
I tried this approach some time ago, I don’t know if I just did it wrong, but having more scenes “loaded” inside the same scene doesn’t give results for this specific problem. If you keep the ship still, you need to move the entire world around it (loaded in a different ship) and this of course creates a lot of complexity when it comes to positioning and AI behaviour, unless you work only with local coordinates and stuff. I was looking for a simpler approach, but nothing seems to work apart from what is suggested by hoesterey (and another tutorial that I found years ago, now disappeared) but I don’t understand how to create this visual proxy…
Seems to me that the visual proxy is just a separate object. All the navigation and collisions are happening on your stationary ship, and the separate “Proxy” object just copies that movement but relative to your moving ship. That way you can work with static navmeshes and still have characters walking around on a moving platform (ie a spaceship).
I wonder, how would you hide your static object? Would you just remove the mesh renderer so that the object exists, but its invisible and sitting at some arbitrary point in the world?
Hiding the static object is not exactly a problem, since you can work with camera culling and just not render it on the player camera. I think I’m starting to get how everything is done!
create two separate instances of the player and the ship, dividing them between “static” and “dynamic” gameobjects
the static player will actually move inside the static spaceship, use objects inside the static spaceship and so on
if the player is controlling the ship, it will be the “dynamic” ship that actually moves
when the player moves inside the static spaceship, the dynamic player will be a non-rigidbody child of the dynamic spaceship, with the same local transform of the static player inside the static spaceship
of course, the main camera will be stuck on the eyes of the dynamic player
Now I suppose I should try if it works and fail miserably
I checked that topic briefly, I will have a deeper look at it later. However, today I tried the solution that I wrote before, and I must say that IT WORKS!
Now, I tried to write a little guide with screenshots but I’m actually sleepy as hell, if someone is interested I could write a better tutorial tomorrow!
Hi! This is a conversation of 2 years ago, I actually forgot about it but, at the time, I tried it and it was working. The only downside to it is that it’s literally a workaround, and it creates a noticeable overhead.
But there’s this:
This is a much better solution! This character controller will simply work inside the ship, without having to use a proxy ship. Check it out, it could be even better!