- Home /
AddRelativeTorque not rotating
I'm trying to make a fireball curve towards a player but it appears to not be working.
The fireball is off the ground, ignoring gravity and does not have constraints. It has a mass of 1, drag and angular drag are 0.
HomingStrength is set to 1000.
UpdateHoming_Dumb() is called in FixedUpdate().
void UpdateHoming_Dumb()
{
Rigidbody rigidBody = GetComponent<Rigidbody>();
if (Vector3.Dot(rigidBody.velocity, homingTarget.position - transform.position) >= 0)//if target is in front of spell
{
if (Vector3.Dot(Vector3.Cross(rigidBody.velocity.normalized, Vector3.up), homingTarget.position - transform.position) >= 0)//if target is to the left of spell
{
Debug.Log("LEFT" + rigidBody.velocity);
rigidBody.AddRelativeTorque(Vector3.up * -homingStrength);
}
else//if target is to the right of spell
{
Debug.Log("RIGHT" + rigidBody.velocity);
rigidBody.AddRelativeTorque(Vector3.up * homingStrength);
}
}
else//if target is behind spell (over shot)
{
//Debug.Log("BACK");
}
}
It reaches the AddRelativeTorque line, but it does nothing.
Is the body kinematic? Forces don't affect kinematic bodies.
It's fairly non-traditional to use PhysX bodies and forces to achieve ho$$anonymous$$g projectiles. Not that it's a bad idea, just worth mentioning.
Also note that you should generally normalize the arguments for Dot and Cross. Not sure what the difference is when failing to do so, but I recall it supposedly matters.
You're asking the bodies to rotate about their own "up" axis. Depending on your scenario, it may be more appropriate to use the world "up" axis ins$$anonymous$$d. Do you observe any change in the body's rotation at all? On the wrong axis, for instance?
Does any other code affect the bodies' movement in any way?
Should I be manually handling the movement ins$$anonymous$$d?
The direction detection using the Dot and Cross methods are working. So I guess it doesn't matter (or at least in this case?). But I might try changing it when I get back home.
It's a racing game with slopes and stuff so I used the body's up vector. I noticed no change in the rotation at all (the velocity remained constant). Unless you're talking about the rotation of the transform? In that case, I need to check again.
The only other code touching the movement is the setting of the initial velocity with AddForce when it spawns.
Answer by Torigas · Jul 20, 2015 at 12:57 PM
I just tested your code and it works just fine.
"Just fine" meaning: The object turns. Needless to say, you use the velocity of your object to determine the movement direction. So you should have a velocity at the start. I took the liberty of rewriting your code a little to work:
using UnityEngine;
using System.Collections;
[RequireComponent(typeof(Rigidbody))]
public class HomingTest : MonoBehaviour {
public Transform homingTarget;
public float homingStrength = 1000.0f;
Rigidbody rigidBody;
public float epsilon = 0.01f;
// Use this for initialization
void Start () {
rigidBody = GetComponent<Rigidbody>();
rigidBody.AddForce(transform.forward,ForceMode.Impulse);
}
// Update is called once per frame
void FixedUpdate () {
UpdateHoming_Dumb();
rigidBody.AddForce(transform.forward,ForceMode.Acceleration);
}
void UpdateHoming_Dumb()
{
float homingDir = Vector3.Dot(-transform.right, homingTarget.position - transform.position);
if (homingDir >= epsilon)//if target is to the left of spell
{
Debug.Log("LEFT");
rigidBody.AddRelativeTorque(Vector3.up * -homingStrength);
}
else if(homingDir <= -epsilon)//if target is to the right of spell
{
Debug.Log("RIGHT");
rigidBody.AddRelativeTorque(Vector3.up * homingStrength);
}
else
{
Debug.Log("STRAIGHT");
rigidBody.AddTorque(rigidBody.angularVelocity*-1,ForceMode.VelocityChange);
}
}
}
Ok it works (starts turning) when I add AddForce after AddTorque. But wouldn't this affect the speed as well?
Yes it changes the speed.
But you use rigidbody.velocity in your script. That's Vector3(0,0,0) if you don't add any force. So if you use rigidbody.velocity to get a crossproduct and so forth, things might go awry. I assume you left it at 0 and then the rest didn't work as expected. Nevertheless, I hope my script helps a little =)
Ok I got the horizontal ho$$anonymous$$g working. Thank you so much! :D
But I can't get the vertical ho$$anonymous$$g to work.
void UpdateHo$$anonymous$$g_Dumb()
{
if (Vector3.Dot(transform.forward, ho$$anonymous$$gTarget.position - transform.position) >= 0)//if target is in front of spell
{
//UpdateHo$$anonymous$$g_Dumb_Horizontal();
UpdateHo$$anonymous$$g_Dumb_Vertical();
rigidBody.velocity = transform.forward * speed;
}
}
void UpdateHo$$anonymous$$g_Dumb_Horizontal()
{
Debug.Log(rigidBody.angularVelocity);
float ho$$anonymous$$gDir = Vector3.Dot(-transform.right, ho$$anonymous$$gTarget.position - transform.position);
if (ho$$anonymous$$gDir >= epsilon)//if target is to the left of spell
{
rigidBody.AddRelativeTorque(transform.up * -ho$$anonymous$$gStrength);
}
else if (ho$$anonymous$$gDir <= -epsilon)//if target is to the right of spell
{
rigidBody.AddRelativeTorque(transform.up * ho$$anonymous$$gStrength);
}
else
{
rigidBody.AddTorque(new Vector3(rigidBody.angularVelocity.x, 0, rigidBody.angularVelocity.z) * -1, Force$$anonymous$$ode.VelocityChange);//dampen angular velocity
}
}
void UpdateHo$$anonymous$$g_Dumb_Vertical()
{
float ho$$anonymous$$gDir = Vector3.Dot(transform.up, ho$$anonymous$$gTarget.position - transform.position);
Debug.Log(ho$$anonymous$$gDir);
if (ho$$anonymous$$gDir >= epsilon)//if target is above spell
{
rigidBody.AddRelativeTorque(transform.right * ho$$anonymous$$gStrength);
}
else if (ho$$anonymous$$gDir <= -epsilon)//if target is below spell
{
rigidBody.AddRelativeTorque(transform.right * -ho$$anonymous$$gStrength);
}
else
{
rigidBody.AddTorque(new Vector3(0, rigidBody.angularVelocity.y, 0) * -1, Force$$anonymous$$ode.VelocityChange);//dampen angular velocity
}
}
This time it was the axis..axes...axii.. y'know:
void UpdateHo$$anonymous$$g_Dumb()
{
if (Vector3.Dot(transform.forward, ho$$anonymous$$gTarget.position - transform.position) >= 0)//if target is in front of spell
{
UpdateHo$$anonymous$$g_Dumb_Horizontal();
UpdateHo$$anonymous$$g_Dumb_Vertical();
rigidBody.velocity = transform.forward * speed;
}
}
void UpdateHo$$anonymous$$g_Dumb_Horizontal()
{
//Debug.Log(rigidBody.angularVelocity);
float ho$$anonymous$$gDir = Vector3.Dot(-transform.right, ho$$anonymous$$gTarget.position - transform.position);
if (ho$$anonymous$$gDir >= epsilon)//if target is to the left of spell
{
rigidBody.AddRelativeTorque(transform.up * -ho$$anonymous$$gStrength);
}
else if (ho$$anonymous$$gDir <= -epsilon)//if target is to the right of spell
{
rigidBody.AddRelativeTorque(transform.up * ho$$anonymous$$gStrength);
}
else
{
rigidBody.AddTorque(new Vector3(0, rigidBody.angularVelocity.y,0)*-1, Force$$anonymous$$ode.VelocityChange);//dampen angular velocity
}
}
void UpdateHo$$anonymous$$g_Dumb_Vertical()
{
float ho$$anonymous$$gDir = Vector3.Dot(transform.up, ho$$anonymous$$gTarget.position - transform.position);
//Debug.Log(ho$$anonymous$$gDir);
if (ho$$anonymous$$gDir >= epsilon)//if target is above spell
{
rigidBody.AddRelativeTorque(transform.right * -ho$$anonymous$$gStrength);
}
else if (ho$$anonymous$$gDir <= -epsilon)//if target is below spell
{
rigidBody.AddRelativeTorque(transform.right * ho$$anonymous$$gStrength);
}
else
{
rigidBody.AddTorque(new Vector3(rigidBody.angularVelocity.x, 0, 0) * -1, Force$$anonymous$$ode.VelocityChange);//dampen angular velocity
}
}
Okay this is what I used in case anyone stumbles upon this.
I changed the AddRelativeTorque to use Vector presets(?) ins$$anonymous$$d of the transform values (which I thought was a great idea). If someone, cough Torigas cough, could explain this to me, that'd be amazing. :D
Thanks!
void UpdateHo$$anonymous$$g_Dumb()
{
if (Vector3.Dot(transform.forward, ho$$anonymous$$gTarget.position - transform.position) >= 0)//if target is in front of spell
{
UpdateHo$$anonymous$$g_Dumb_Horizontal();
UpdateHo$$anonymous$$g_Dumb_Vertical();
}
else
{
rigidBody.angularVelocity = Vector3.zero;//kill angular velocity
}
rigidBody.velocity = transform.forward * speed;
}
void UpdateHo$$anonymous$$g_Dumb_Horizontal()
{
float ho$$anonymous$$gDir = Vector3.Dot(-transform.right, ho$$anonymous$$gTarget.position - transform.position);
if (ho$$anonymous$$gDir >= epsilon)//if target is to the left of spell
{
rigidBody.AddRelativeTorque(Vector3.up * -ho$$anonymous$$gStrength);
}
else if (ho$$anonymous$$gDir <= -epsilon)//if target is to the right of spell
{
rigidBody.AddRelativeTorque(Vector3.up * ho$$anonymous$$gStrength);
}
else
{
rigidBody.AddTorque(new Vector3(0, rigidBody.angularVelocity.y, 0) * -1, Force$$anonymous$$ode.VelocityChange);//dampen angular velocity
}
}
void UpdateHo$$anonymous$$g_Dumb_Vertical()
{
float ho$$anonymous$$gDir = Vector3.Dot(transform.up, (ho$$anonymous$$gTarget.position - transform.position).normalized);
if (ho$$anonymous$$gDir >= epsilon)//if target is above spell
{
rigidBody.AddRelativeTorque(Vector3.right * -ho$$anonymous$$gStrength);
}
else if (ho$$anonymous$$gDir <= -epsilon)//if target is below spell
{
rigidBody.AddRelativeTorque(Vector3.right * ho$$anonymous$$gStrength);
}
else
{
rigidBody.AddTorque(new Vector3(rigidBody.angularVelocity.x, 0, 0) * -1, Force$$anonymous$$ode.VelocityChange);//dampen angular velocity
}
}
Your answer
Follow this Question
Related Questions
Returning a rigidbody back to its original x and z rotations through physics forces. 2 Answers
Get result (force & torque) of AddForceAtPosition? 2 Answers
How to get Satisfying Collision Physics 1 Answer
How to make a object jump constantly at y and move to the next position to z (perfectly) 0 Answers