- Home /
Modifying Gravity for Local Player
Hello everyone - I'm working on a personal project that involves a character moving around a horizontal cylinder while moving in a set direction. The gravity for the character needs to be constantly pulling them towards the center of the cylinder (which does appear to be working correctly), but when I move the character along their forward vector, I am seeing it 'slide' either farther up (+Y) or down (-Y) the cylinder.
If I remove the forward movement, the character stays oriented correctly and doesn't slide in either direction (which is what I would expect/want). As soon as I do though...well, hence the problem.
The object's rigidbody has all rotational axis locked, and I am not using gravity.
Any insight or help would be appreciated.
Thanks!
Code Snippet:
//----------------------------------------
// Class Variables
//----------------------------------------
// Private
private float _RotationSpeedMod = 1f;
private float _RotationSpeedBase = 120f;
private float _RotationSpeedMax = 165f;
private Vector3 _VecGravity = new Vector3();
private Transform _MyTransform;
// Public
public float _RotationSpeed = 0;
public float _Gravity = -9.81f;
public float _MovementSpeed = 10.0f;
public float _MaxVelocity = 2.0f;
// Awake
void Awake()
{
_MyTransform = transform;
}
// Update is called once per frame
void Update ()
{
// DeltaTime Value
float DeltaTime = Time.deltaTime;
// Rotate Left
if (Input.GetKey(KeyCode.LeftArrow))
{
transform.RotateAround(Vector3.zero, Vector3.right, DeltaTime * _RotationSpeed );
_RotationSpeed += _RotationSpeedMod;
if (_RotationSpeed > _RotationSpeedMax)
{
_RotationSpeed = _RotationSpeedMax;
}
}
// Rotate Right
else if (Input.GetKey(KeyCode.RightArrow))
{
transform.RotateAround(Vector3.zero, Vector3.right, DeltaTime * -_RotationSpeed );
_RotationSpeed += _RotationSpeedMod;
if (_RotationSpeed > _RotationSpeedMax)
{
_RotationSpeed = _RotationSpeedMax;
}
}
else
{
_RotationSpeed = _RotationSpeedBase;
}
}
// Physics Update
void FixedUpdate()
{
// DeltaTime Value
float DeltaTime = Time.deltaTime;
// Compute Gravity Vector
Vector3 VecUp = _MyTransform.up;
Vector3 VecFwd = _MyTransform.forward;
Vector3 VecTemp = new Vector3();
float GravityRate = _Gravity * DeltaTime;
float MovementRate = _MovementSpeed * DeltaTime;
Vector3 VecGravity = new Vector3(VecUp.x * GravityRate, VecUp.y * GravityRate, VecUp.z * GravityRate);
Vector3 VecMovement = new Vector3(VecFwd.x * MovementRate, VecFwd.y * MovementRate, VecFwd.z * MovementRate);
Debug.Log( "VecGravity: " + VecGravity );
Debug.Log( "VecMovement: " + VecMovement );
VecTemp = VecMovement + VecGravity;
//VecTemp = VecGravity;
Debug.Log( "VecTemp: " + VecTemp );
_MyTransform.rigidbody.velocity += VecTemp;
Debug.Log( "Vel: " + _MyTransform.rigidbody.velocity );
// Limiter
if( _MyTransform.rigidbody.velocity.magnitude > _MaxVelocity )
{
VecTemp = _MyTransform.rigidbody.velocity;
VecTemp.Normalize();
VecTemp.Set( VecTemp.x * _MaxVelocity, VecTemp.y * _MaxVelocity, VecTemp.z * _MaxVelocity );
_MyTransform.rigidbody.velocity = VecTemp;
}
Debug.Log( "Magnitude: " + _MyTransform.rigidbody.velocity.magnitude );
}
Answer by FakeBerenger · Nov 18, 2012 at 10:58 AM
I think the problem is the calculation of your vectors VecUp and Fwd. You're using the player's transform, you should use [closest point on cylinder's axis from the player] -> the player's pos, for the up.
Also, you should use Time.fixedDeltaTime in FixedUpdate.
Good catch on the Time.fixedDeltaTime!
As for the up vector of the player, it should be set when the player uses the Left or Right keys (and indeed, it does work properly when the player is not moving along the X-axis, only rotating around the cylinder).
$$anonymous$$odifying it to use the normalized directional vector from the cylinder->player's position will also suffice, but as the player slides up/down, it will start to rotate the player out of alignment for what it should be.
I did give your suggestions a go, but still no luck, unfortunately.