- Home /
The question is answered, right answer was accepted
Tightening up turning radius with AddRelativeForce (or other options)
Hi, how is everyone? I tried asking this in the forums, but I guess no one wanted to help there, so I'm asking it here.
I have been working on this game project for a school studio project (and possibly it might end up being more if I could get this one thing working correctly). The idea is to be a arcade space racing game, subsequently, I want to have physics that are quick (like the ability to turn yaw-wise in a quick fashion).
The issue I keep running into is how to pull this off? I have the script working, I have barrel rolls, strafing, but I am using rigidbody.AddRelativeForce as the means of propulsion/movement. This due to the fact that I couldn't find anyway outside of using Unity's physics system for this. I tried transform.Translate, but that would only propel the ship in one direction, along the z-axis, and not the direction the ship is pointing in. So I am also open to figuring out a non-Unity physics-based method to get this working (if anyone knows, otherwise I'll stick to using rigidbody physics) as the physics system seems laggy/lazy to me turning-wise.
So can anyone help me? Here is my script for just the ship's basic controls.
Thanks for any help.
using UnityEngine;
using System.Collections;
public class PlayerShip_Easy : MonoBehaviour
{
private float shipSpd = 300.0f;
private float turnSpd = 150.0f;
private float rotSpd = 50.0f;
private float strafeSpd = 50.0f;
float rollRate = 0.0f;
float pitchRate = 0.0f;
float yawRate = 0.0f;
float invert = -1.0f;
void Update ()
{
float roll = Input.GetAxis("Roll");
float pitch = Input.GetAxis("Pitch");
float yaw = Input.GetAxis("Yaw");
float strafe = Input.GetAxis("Strafe");
if (Input.GetAxis("Pitch") > 0)
{
pitchRate -= pitch * invert * turnSpd * Time.deltaTime;
pitchRate = Mathf.Clamp(pitchRate, -45.0f, 45.0f);
transform.rotation = Quaternion.Euler(pitchRate, yawRate , 0);
}
else if (Input.GetAxis("Pitch") < 0)
{
pitchRate += pitch * turnSpd * Time.deltaTime;
pitchRate = Mathf.Clamp(pitchRate, -45.0f, 45.0f);
transform.rotation = Quaternion.Euler(pitchRate, yawRate , 0);
}
if (Input.GetAxis("Yaw") > 0)
{
yawRate += yaw * turnSpd * Time.deltaTime;
yawRate = Mathf.Clamp(yawRate, -60.0f, 60.0f);
transform.rotation = Quaternion.Euler(pitchRate, yawRate, 0);
}
else if (Input.GetAxis("Yaw") < 0)
{
yawRate += yaw * turnSpd * Time.deltaTime;
yawRate = Mathf.Clamp(yawRate, -60.0f, 60.0f);
transform.rotation = Quaternion.Euler(pitchRate, yawRate, 0);
}
rigidbody.AddRelativeForce(pitch, yaw, shipSpd);
}
Have you tried using transform.forward to in a funciton like the following?
transform.position += transform.forward; // lerp it for smoother movement.
transform.forward is the vector the ship is curently facing and always has a length of 1.
The same logic applies to transform.up, transform.down, transform.right, transform.left and transform.back.
Read more about it here:
http://docs.unity3d.com/ScriptReference/Transform.html
Specifically transform.forward:
http://docs.unity3d.com/ScriptReference/Transform-forward.html
AddTorque? Or AddRelativeTorque?
You can also manipulate the Velocity directly.
Never use transform.position or Translate with a rigidbody unless you are trying to teleport and negate the Physics system.
But I put the transform in because he doesn't really use rigidbodies at all, excpet for the last line. So I posted that thinking it'd do for a solution.
Here's the code for moving Rigidbodies forward:
rigidB.AddForce( transform.forward * multiplierFloat );
@Baste put together a better answer below anyway.
It'd work. Don't get me wrong.
But in the question he states a desire for a Physics based solution :)
Answer by Baste · Jan 29, 2015 at 12:55 PM
If you want more direct control over how the ship moves, setting the velocity vector instead of adding force would work better.
That will make the movement of whatever you're moving less "realistic", but unless you're making a simulator of some sort, you usually get results that feel better (more responsive controls, etc.) if you set the velocity directly.
So I'd try to continue turning the ship like you're doing, but replacing the rigidbody.AddRelativeForce with:
rigidbody.velocity = transform.forward * shipSpd;
That will give you a very tight turn radius. In fact, you'll always be moving directly forward. If that's too arcadey, and you want to keep some of the speed in the last direction you were moving, just Lerp between your current velocity and that velocity:
Vector3 forward = transform.forward * shipSpd;
float turnFactor = .1f;
rigidbody.velocity = Vector3.Lerp(rigidbody.velocity, forward, turnFactor * Time.deltaTime);
changing the turnFactor value will change your turn radius; the higher the turnFactor, the tighter the turn. Hope that helps!
Wait...
float forward = transform.forward * shipSpd;
Shouldn't that be
Vector3 forward = transform.forward * shipSpd;
Hi, thanks for the response. Just give me a sec to try out the idea. :P
BRILLIANT!!
Thanks for the help, it worked like a charm!
I would give a thumbs-up, but the system is saying that I can't (lack 15 rep points :'( .... )