Hope you had a smashing Christmas ?! I’ve been tinkering on a new prototype. I want the player to be able to move around the a sphere freely in 3D space. This is what I came up with so far:
// this script is attached to the player
var world : GameObject; // sphere the player moves on
var gravityVector : Vector3; // gravity to keep player on the planet
var moveSpeedMultiplyer : float= 1; // speed the player has when moving
function Start () {
rotationHorizontal = gameObject.transform.rotation.x;
rotationVertical = gameObject.transform.rotation.y;
}
function Update () {
// make sure player stays on the surface of the world
gravityVector = Vector3((world.transform.position.x-gameObject.transform.position.x),(world.transform.position.y-gameObject.transform.position.y),(world.transform.position.z-gameObject.transform.position.z));
gameObject.rigidbody.AddForce(gravityVector*gravitalForce);
// movement ////
// determin move with input //
if(Input.GetAxis("Horizontal")){
rotationHorizontal = Input.GetAxis("Horizontal")*Time.deltaTime*rotationSpeed;
}
if(Input.GetAxis("Vertical")){
rotationVertical = Input.GetAxis("Vertical")*Time.deltaTime*rotationSpeed;
}
// apply movement //
var newPosition : Vector3 = Vector3(rotationHorizontal,rotationVertical,0);
transform.Translate(newPosition*moveSpeedMultiplyer,gameObject.transform);
}
Now there are two things that are not quite right: 1) when the player is reaching either pole of the sphere he is starting to turn madly ( I’m pretty sure it has something to do on how I move the player via the Y-Axis) - How can I move the player more independently ?
2) the player is “shaking” all the time on the surface … not a lot but it’s rather annoying - Can that be fixed?
I haven tried an object that is not a perfect sphere but ideally I’d like the player to be able to walk on a rough or uneven sphere ( e.g. with little hills and stuff) .
It looks like you are incorporating physics but then you are also operating directly on the transform with transform.Translate - generally this will result in erratic behaviour when intersections are involved, because you can think of transform.Translate as ‘teleporting’ the object instantaneously rather than informing the physics engine that it’s in fact a motion that can encounter collisions. To move your character while it is under physics control, take a look at Rigidbody.AddRelativeForce. With this relative version you can simply apply transform.forward to push the object forward; multiply it to increase the force (transform.forward*500, etc.). To turn the character look at Rigidbody.AddRelativeTorque.html.
Also keep in mind that when operating on a rigidbody using forces it should be done within FixedUpdate() rather than Update(). Interacting with rigidbody forces in Update() may result in strange behaviour because the physics engine operates at fixed steps, while Update() is variable.
You can use common operators on Vector3s just like you can with numbers and it will act on all three components within them, as well as multiplying/dividing them with singular floats to increase or decrease their magnitudes (as you will see in code below). You might want to normalize and multiply it so that you have a constant force, I think the way you have it now will increase the applied force the further you get from the world (though maybe that’s desired).
Hopefully this can help you out a bit. I’m always learning and make mistakes myself, so let me know if something didn’t work like I said it would. You will still have to work at making the character stay upright; if you are using the character controller collider with the smooth-bottom capsule shape you might be able to directly edit the rotation, or perhaps a bit awkward but potentially more simple and physically acceptable is to lock the X and Z rotation of your rigidbody and instead of moving the character, to rotate the planet under him. You can also place a transform as a child and center it on the top of the character and use Rigidbody.AddForceAtPosition.html at the transform’s point, with the force away from the planet, to pull his head away from the planet in order to keep him upright. Like everything with programming there will be a number of ways to approach a given task, this one is involving the physics engine but there are also ways to do it purely with raycasts and math, maybe someone else has a better idea.
I’m not entirely sure what’s up with that; you’re not doing any more operations directly on the Transform, only moving it via rigidbody forces now? Does it spin when you aren’t providing any input? Also, what kind of colliders are involved; both the planet and the character (sphere, character capsule, box, mesh, etc.). If you can put up the latest version of your script so I can see where you are at now it might help.
I don’t have a solution, but the spinning at the poles sounds like something called “Gimbal Lock” (http://en.wikipedia.org/wiki/Gimbal_lock) if that helps in searching for one.
Basically, the post gives code on how to move around a 3d sphere. It does not, however, work in physics. There are a few changes you can make to have it work for physics though. (also remember that you would have to lock your rotation in physics.)
Lastly, when you do this stuff, all of your physics stuff needs to be done in the FixedUpdate.