I am trying to make the object face the direction it is moving in while moving it on a sphere, but instead of facing the direction, it rotates somewhat independently from the movement.
Here is what I have right now:
Code for object movement and rotation:
void Wander()
{
int rDirChange = Random.Range(0, 10);
if (rDirChange > dChange)
{
mDirection = new Vector3((mDirection.x Random.Range(-30, 30)), 0, (mDirection.y Random.Range(-30, 30))).normalized;
Vector3 tMovement = mDirection * moveSpeed;
Movement = Vector3.SmoothDamp(Movement, tMovement, ref smoothMovement, 0.5f);
}
}
private void FixedUpdate()
{
GetComponent<Rigidbody>().MovePosition(GetComponent<Rigidbody>().position (transform.TransformDirection(Movement) * Time.fixedDeltaTime));
if (rotTimer > 60)
{
curPosition = transform.position;
moveDirection = curPosition - oldPosition;
oldPosition = curPosition;
rotTimer = 0;
}
else
{
rotTimer = 1;
}
transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(moveDirection), Time.deltaTime * 0.5f);
}
}
Code for attracted objects:
public void gravityAttractor(Transform body)
{
Vector3 targetDirection = (body.position - transform.position).normalized;
Vector3 bodyUp = body.up;
body.rotation = Quaternion.FromToRotation(bodyUp, targetDirection) * body.rotation;
body.GetComponent<Rigidbody>().AddForce(targetDirection * gravity);
}
Code for planet thing:
GravityAttractor Level;
private void Awake()
{
Level = GameObject.FindGameObjectWithTag("Level").GetComponent<GravityAttractor>();
GetComponent<Rigidbody>().useGravity = false;
GetComponent<Rigidbody>().constraints = RigidbodyConstraints.FreezeRotation;
}
private void FixedUpdate()
{
Level.gravityAttractor(transform);
}
CodePudding user response:
Some general points first
Stop using
GetComponentrepeatedly over and over again! Rather use it once and store the reference in order to reuse it later.whenever physics is involved you don't want to set any position or rotation via the
Transformcomponent at all as this breaks the physics and collision detection. Rather go through theRigidbodycomponent!then you shouldn't use
MovePositionif additionally you want to add some forces sinceMovePositionwould simply overrule the forces and velocity. You should rather simply set thevelocitywhich then still allows to add additional forces.
Then getting the movement direction is as simple as
var direction = _rigidbody.velocity.normalized;
So I would rather use something like e.g.
[SerializeField] private Rigidbody _rigidbody;
private void Awake ()
{
if(!_rigidbody) _rigidbody = GetComponent<Rigidbody>();
}
void Wander()
{
var rDirChange = Random.Range(0, 10);
if (rDirChange <= dChange) return;
mDirection = new Vector3((mDirection.x Random.Range(-30, 30)), 0, (mDirection.y Random.Range(-30, 30))).normalized;
Vector3 tMovement = mDirection * moveSpeed;
Movement = Vector3.SmoothDamp(Movement, tMovement, ref smoothMovement, 0.5f);
_rigidbody.velocity = Movement;
}
private void FixedUpdate()
{
// Get the direction the Rigidbody is actually moving in
var targetRotation = Quaternion.LookRotation(_rigidbody.velocity);
_rigidbody.rotation = targetRotation;
// Or if you still want to interpolate
// _rigidbody.rotation = Quaternion.Slerp(_rigidbody.rotation, targetRotation, Time.deltaTime * 0.5f);
}
