Using rigidbody.AddTorque to have character look at cursor

I’m attempting to build a 2.5D arcade style free roaming space shooter. I’ve modified the ShipControls.js found here. In the original script the player controlled the ship with the keyboard only. I’ve modified the script with a mouselook, so the ship will now always point towards my cursor.

The original script used some code that read the objects angularVelocity amount and used that to bank the ship in the direction of the turn. It actually looked great on my ship, but I’ve lost that ability with mouselook.

I’ve been trying to work out a solution for a couple days, but my brain is fried. This stuff is keeping me awake at night.

I’ve tried to find a way to use torque to match the ships orientation to the point returned from a raycast, but have been unsuccessful. I’ve also tried to think of some value produced by the transform.rotation of the mouselook that I could use to initiate the banking effect, but no dice.

I’m at the point to where I’m thinking of rewriting the code entirely without a rigidbody, but I’m not sure how to get the banking effect with mouselook in any case.

So, to get to the point, I’m looking for a way to do the following:

  • Code a physics based “object look at mouse” script, or;
  • Find a way to use the transform.rotation in the current script to bank the ship during a turn;

It could be something incredibly simple that I’m missing… I’ve been struggling with this for far too long and my brain is mush.

I’ll attach my code here. I’ve tried to write most of it longhand, as I am a beginner, and I apologize for the number of notes; I wrote them for my own benefit. Note also that it still contains some of the code for the original key-press turning control that I have yet to remove.

@script RequireComponent (Rigidbody)

//Inspector variables
 
   	var hoverHeight 								: float = 3;									//Height ship will hover
    var hoverHeightStrictness						: float = 1.0;									//Strictness to hover height
    var forwardThrust								: float = 20000.0;								//Player thrust
    var backwardThrust								: float = 10000.0;								//Player backwards thrust
    var strafeThrust								: float = 10000.0;								//Player strafing thrust
    var bankAmount									: float = 0.1;									//Amount for ship to bank when turning
    var bankSpeed									: float = 0.2;									//Speed ship will bank when turning
    var bankAxis									: Vector3 = new Vector3(0.0, 0.0, -1.0);		//Axis ship will bank towards
    var turnSpeed									: float = 8.0;									//Speed at which ship will turn
 	var boostSpeed									: float = 1.5;									//Amount that booster will increase speed
    var forwardDirection							: Vector3 = new Vector3(0.0, 0.0, 1.0);			//Forward directional Axis of the ship
    var strafeDirection								: Vector3 = new Vector3(1.0, 0.0, 0.0);			//Side to side directional Axis of the ship
 	var mass										: float = 5.0;									//Mass of the ship
    var sqrdSpeedThresholdForDrag 					: float = 25.0;									//Positional drag
    var superDrag 									: float = 2.0;									//Positional drag
    var fastDrag 									: float = 0.5;									//Positional drag
    var slowDrag 									: float = 0.01;									//Positional drag
    var sqrdAngularSpeedThresholdForDrag 			: float = 5.0;									//Angular drag
    var superADrag 									: float = 32.0;									//Angular drag
    var fastADrag 									: float = 16.0;									//Angular drag
    var slowADrag 									: float = 0.1;									//Angular drag
 	var playerControl 								: boolean = true;								//Variable to set whether ship is player controlled or not
 	
 //Private variables
 
    private var bank 								: float = 0.0;									//Used to calculate banking
 	private var thrust 								: float = 0;									//Thrust rate controller
    private var turn 								: float = 0;									//Turn rate controller
    private var strafe								: float = 0;									//Strafe rate controller
    private var thrustGlowOn 						: boolean = false;								//Sets the thrustGlowOn private variable to be false
    private var boostGlowOn							: boolean = false;								//Sets the boostGlowOn private variable to be false
    private var leftThrustGlowOn					: boolean = false;								//Sets the leftThrustGlowOn private variable to be false
    private var rightThrustGlowOn					: boolean = false;								//Sets the rightThrustGlowOn private variable to be false
    
	function SetPlayerControl(control : boolean)													//Calling the playercontrol inspector variable for control functions
    {
        playerControl = control;
    }
 
 
    function Start()
    {
        gameObject.rigidbody.mass = mass;															//Sets the rigidbody mass to be equal to the mass inspector variable
    }
 
    function FixedUpdate()
    {
        if (Mathf.Abs(thrust) > 0.01)																//Sets the rididbody drag to equal inspector variables based on velocity
        {
            if (rigidbody.velocity.sqrMagnitude > sqrdSpeedThresholdForDrag)
                rigidbody.drag = fastDrag;
            else
                rigidbody.drag = slowDrag;
        }
        else
            rigidbody.drag = superDrag;
 
        if (Mathf.Abs(turn) > 0.01)																	//Sets the rigidbody angular drag to equal inspector variables based on angular velocity
        {
            if (rigidbody.angularVelocity.sqrMagnitude > sqrdAngularSpeedThresholdForDrag)
                rigidbody.angularDrag = fastADrag;
            else
                rigidbody.angularDrag = slowADrag;
        }
        else
            rigidbody.angularDrag = superADrag;
            
        if (Mathf.Abs(strafe) > 0.01)																	//Sets the rigidbody angular drag to equal inspector variables based on angular velocity
        {
            if (rigidbody.velocity.sqrMagnitude > sqrdSpeedThresholdForDrag)
                rigidbody.drag = fastDrag;
            else
                rigidbody.drag = slowDrag;
        }
        else
            rigidbody.drag = superDrag;
            
		 if (Mathf.Abs(strafe) > 0.01 && Mathf.Abs(thrust) > 0.01)																	//Sets the rigidbody angular drag to equal inspector variables based on angular velocity
        {
            if (rigidbody.velocity.sqrMagnitude > sqrdSpeedThresholdForDrag)
                rigidbody.drag = fastDrag;
            else
                rigidbody.drag = slowDrag;
        }
        else
            rigidbody.drag = superDrag;
            
 
 
        transform.position = Vector3.Lerp(transform.position, new Vector3(transform.position.x, hoverHeight, transform.position.z), hoverHeightStrictness);				//Hovers the ship
 
//Ship banking based on angularVelocity

        var amountToBank : float = rigidbody.angularVelocity.y * bankAmount;						//Sets the amountToBank variable to be equal to the angular velocity multiplied by the bankAmount inspector variable
 
        bank = Mathf.Lerp(bank, amountToBank, bankSpeed);											//Sets the bank private variable to be between the current bank angle and the amountToBank inspector variable
 																									//at the speed defined in the bankSpeed inspector variable
        var rotation 				: Vector3 = transform.rotation.eulerAngles;						//Sets the rotation variable to be equal to rotation in eularangles (x, y, z)
        rotation					= rotation * Mathf.Deg2Rad;										//Converts the rotation variable from degrees to radians
        rotation.x					= 0;															//Sets the x axis rotation value
        rotation.z					= 0;															//Sets the z axis rotation value
        rotation					= rotation + bankAxis * bank;									//Adds the value of the rotation variable to the product of the bankAxis and bank variables
        rotation					= rotation * Mathf.Rad2Deg;										//Converts the rotation variable from radians to degrees
        transform.rotation			= Quaternion.Euler(rotation);									//Banks the ship based on the above information
    }
 

//Thrust Controls   
 
 	function Thrust (item : float)																	//Sets the thrust variable to return a value between 1.0 and -1.0
    {
        thrust = Mathf.Clamp(item, -1.0, 1.0 );
    }
 
    function Turn (item : float)																	//Sets the turn variable to return a value between 1.0 and -1.0 and multiplies it by the turnSpeed inspector variable
    {
        turn = Mathf.Clamp(item, -1.0, 1.0 ) * turnSpeed;
    }
    
    function Strafe (item : float)																	//Sets the strafe variable to return a value between 1.0 and -1.0
    {
    	strafe = Mathf.Clamp(item, -1.0, 1.0);
    }
 
//Game Loop

    function Update ()
    {
    
//Game loop variables
        
        var theThrust 						: float = thrust;										//Sets theThrust variable to be equal to the value of the thrust variable
        var theStrafeThrust 				: float = strafe;										//Sets theStrafeThrust variable to be equal to the value of the strafe variable
 		
 		if (playerControl)																			//Checks to see if this ship is controllable
        {
            thrust = Input.GetAxis("Vertical");														//Sets the thrust variable to be equal to Input.GetAxis("Vertical")
            boost = Input.GetAxis("Boost") * boostSpeed;											//Sets the boost variable to be equal to Input.GetAxis("Boost") multiplied by the boostSpeed inspector variable value
            strafe = Input.GetAxis("Horizontal");													//Sets the strafe variable to be equal to Input.GetAxis("Horizontal")
        }
 
 //Thrust movement
 
        if (thrust > 0.0 && boost < 0.0)															//If Input.GetAxis("Vertical") is pressed and Input.GetAxis("Boost") isn't pressed
        {
            theThrust *= forwardThrust;																//Multiplies theThrust variable with the forwardThrust inspector variable
            if (thrustGlowOn == false)																//If the thrustGlowOn variable is set to false													
            {
                thrustGlowOn = false;																//Sets the thrustGlowOn variable to false and broadcasts thrustGlowOn
                BroadcastMessage("SetThrustGlow", thrustGlowOn, SendMessageOptions.DontRequireReceiver);
            }
        }
        
        else if (thrust > 0.0 && boost > 0.0)														//If Input.GetAxis("Vertical") and Input.GetAxis("Boost") are both pressed
        {
        	theThrust = theThrust * forwardThrust * boost;											//Multiplies theThrust variable with the value of the forwardThrust and boostSpeed inspector variables
        	if (boostGlowOn == false)																//If the boostGlowOn variable is set to false
        	{
        		boostGlowOn = false;																//Sets the boostGlowOn variable to false and broadcasts boostGlowOn
        		BroadcastMessage("SetBoostGlow", boostGlowOn, SendMessageOptions.DontRequireReceiver);	
        	}
        }
        
        else
        {
            theThrust *= backwardThrust;															//Multiplies theThrust variable with the backwardThrust inspector variable
            if (thrustGlowOn == true)																//If the thrustGlowOn variable is set to true
            {
                thrustGlowOn = false;																//Sets the thrustGlowOn variable to false and broadcasts thrustGlowOn
                BroadcastMessage("SetThrustGlow", thrustGlowOn, SendMessageOptions.DontRequireReceiver);
            }
        }
        
        if (strafe >= 0.1)																			//If the positive Input.GetAxis("Horizontal") key is pressed
        {
        	theStrafeThrust *= strafeThrust;														//Multiplies theStrafeThrust variable with the strafeThrust inspector variable
        	if (leftThrustGlowOn == false)															//If the leftThrustGlowOn variable is set to false
        	{
        		leftThrustGlowOn = false;															//Sets the leftThrustGlow variable to false and broadcasts leftThrustGlowOn
        		BroadcastMessage("SetThrustGlow", leftThrustGlowOn, SendMessageOptions.DontRequireReceiver);
        	}
        }
        
        else if (strafe <= 0.1)																						//If the negative (Input.GetAxis("Horizontal") key is pressed
        {
        	theStrafeThrust *= strafeThrust;														//Multiplies theStrafeThrust variable with the strafeThrust inspector variable
        	if (rightThrustGlowOn == false)															//If the rightThrustGlowOn variable = false
        	{
        		rightThrustGlowOn = false;															//Sets the rightThrustGlowOn variable to false and broadcasts rightThrustGlowOn
        		BroadcastMessage("SetThrustGlow", rightThrustGlowOn, SendMessageOptions.DontRequireReceiver);
        	}
        }
 
		var playerPlane 			= new Plane(Vector3.up, transform.position);
		var ray 					= Camera.main.ScreenPointToRay (Input.mousePosition);
		var hitdist					= 0.0;
		
		if (playerPlane.Raycast (ray, hitdist)) 
		{
			var targetPoint 		= ray.GetPoint(hitdist);
			var targetRotation 		= Quaternion.LookRotation(targetPoint - transform.position);
 			transform.rotation 		= Quaternion.Slerp(transform.rotation, targetRotation, turnSpeed * Time.deltaTime);
		}
		
 		
		rigidbody.AddRelativeTorque(Vector3(0, 1, 0) * turn * Time.deltaTime);						//Applies angular torque to the ship on the y axis multiplied by the turn variable by actual time
        
        rigidbody.AddRelativeForce(forwardDirection * theThrust * Time.deltaTime);					//Applies force in the axis direction set in the forwardDirection inspector variable, multiplied by
        																							//theThrust variable by actual time
        rigidbody.AddRelativeForce(strafeDirection * theStrafeThrust * Time.deltaTime);				//Applies force in the axis direction set in th sideDirection inspector variable, multiplied by
        																							//theStrafeThrust variable by actual time
        
}

Got it working perfectly. Is there any reason why I wouldn’t want to use this? Will this adversely affect performance or develop issues later on down the line? Thanks!

var turnSpeed									: float = 15000.0;
var turnSmooth									: float = 2.0;

var playerPlane 			= new Plane(Vector3.up, transform.position);
var ray 					= Camera.main.ScreenPointToRay (Input.mousePosition);
var hitdist					= 0.0;
		
if (playerPlane.Raycast (ray, hitdist)) 
{
var targetPoint 		= ray.GetPoint(hitdist);
var targetRotation 		= Quaternion.LookRotation(targetPoint - transform.position);
var targetAngle			= targetRotation.eulerAngles.y;
var currentAngle		= transform.eulerAngles.y;
var upAngleSmooth		= currentAngle + turnSmooth;
var downAngleSmooth		= currentAngle - turnSmooth;


//Turn coditions
if (targetAngle > upAngleSmooth)
{
    if (targetAngle - currentAngle > 180.0)
    {
        rigidbody.AddTorque(Vector3(0, -1, 0) * turnSpeed * Time.deltaTime);
    }
    else if (targetAngle - currentAngle < 180.0)
    {
        rigidbody.AddTorque(Vector3(0, 1, 0) * turnSpeed * Time.deltaTime);
    }
 				
}	
else if (targetAngle < downAngleSmooth)
{
    if (currentAngle - targetAngle > 180.0)
    {
        rigidbody.AddTorque(Vector3(0, 1, 0) * turnSpeed * Time.deltaTime);
    }
    else if (currentAngle - targetAngle < 180.0)
    {
        rigidbody.AddTorque(Vector3(0, -1, 0) * turnSpeed * Time.deltaTime);
    }
}

}