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
GetComponent
repeatedly 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
Transform
component at all as this breaks the physics and collision detection. Rather go through theRigidbody
component!then you shouldn't use
MovePosition
if additionally you want to add some forces sinceMovePosition
would simply overrule the forces and velocity. You should rather simply set thevelocity
which 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);
}