Making an object in game face the direction it's traveling while viewing from above.

I am using the below code to move my ship along the X and Y axis in my environment but I cannot get the ship to face the direction in which the ship is moving.

Every resource I have searched for suggests ‘rotating’ the ship to match the transform’s rotation, but the transform does not rotate - everything simply moves along the X and Y axis (there is no rotation).

I think what I need to do is somehow extract the ‘travel direction’ from the below script and use that to rotate my ship in a way that makes the ship face the direction of travel - but I am at a loss as to how to accomplish this.

Any advice would be appreciated.

(possibly extraneous information)
I could fix this by allowing the game object that has the ship attached to it to rotate, but then when i push ‘left’ on the joystick the ship will not move ‘left’ according to the user’s point of view, it will move to the ship’s left - but this is not the behavior I desire.

static var blackhole : Vector3 = Vector3.one;

@script RequireComponent( CharacterController )

var moveJoystick : Joystick;
var rotateJoystick : Joystick;


var forwardSpeed : float = 4;
var backwardSpeed : float = 4;
var sidestepSpeed : float = 4;					

private var thisTransform : Transform;
private var character : CharacterController;

private var velocity : Vector3;	

function Start()
{
	// Cache component lookup at startup instead of doing this every frame		
	thisTransform = GetComponent( Transform );
	character = GetComponent( CharacterController );	

	// Move the character to the correct start position in the level, if one exists
	var spawn = GameObject.Find( "PlayerSpawn" );
	if ( spawn )
		thisTransform.position = spawn.transform.position;
}

function OnEndGame()
{
	// Disable joystick when the game ends	
	moveJoystick.Disable();
	rotateJoystick.Disable();	

	// Don't allow any more control changes when the game ends
	this.enabled = false;
}

function Update()
{
	//transform.LookAt(PlayerRelativeControl.blackhole, Vector3.forward);
	var movement = thisTransform.TransformDirection( Vector3( 0, moveJoystick.position.y, moveJoystick.position.x ) );

	//Only x and y movement
	movement.z = 0;
	movement.Normalize();


	// Apply movement from move joystick
	var absJoyPos = Vector2( Mathf.Abs( moveJoystick.position.x ), Mathf.Abs( moveJoystick.position.y ) );	
	if ( absJoyPos.y > absJoyPos.x )
	{
		if ( moveJoystick.position.y > 0 )
			movement *= forwardSpeed * absJoyPos.y;
		else
		{
			movement *= backwardSpeed * absJoyPos.y;
		}
	}
	else
	{
			movement *= sidestepSpeed * absJoyPos.x;
	}
	
	//velocity = character.velocity;	
	movement += velocity;	
	movement *= Time.deltaTime;
	
	// Actually move the character	
	character.Move( movement );

}

– To recap, my ship is moving along the X and Y axis in my environment, I am viewing the ship from ‘above’ (from the Z axis), and the ship is currently always facing one direction while moving (literally the top of the screen) which is useless because it needs to look like it is traveling in the direction of movement.

How do I get the ship to look like it is traveling in the direction of its movement?

Update from the bottom of the thread

Thanks again for the help, this all seems to be going in the right direction but I must have something messed up with my object that is causing it to behave incorrectly - I will post more information in an attempt to get assistance in finding the problem:

-The ‘object’ that I have the above script attached to is a character controller object with a Rotation of X:0 Y: 90 Z: 0
(If I have it 0,0,0 my ship doesn’t move along the x/y window how I want it to)

-The actual 3d ‘ship’ model is then attached to the above object (for information’s sake, this ‘ship’ has a Rotation of X:0 Y:0 Z:0)

When I made the most recent edit BigMisterB mentioned above, the behavior of the ship changed from flicking instantly to opposite facing directions to the following:

  • The ship appears to spin in circles most of the time (while the user is inputing a ‘direction’ for the ship to move).
  • Occasionally the ship flickers back and forth facing opposite directions (like it used to before this edit).
  • The ship occasionally locks in a direction (while using the joystick) and will drift in the direction indicated by the user.

I am not quite sure what is happening at this point.

Thank you for any assistance.

Edit:

Here are some things I’ve noticed in Unity itself while I’m running the game:

-The Y rotation of the game object appears to only change in increments of 90 when the user attempts to move the ship (actually, pretty much only 90 and 270 (or 89.99999 and 269.999)).

-The Z rotation of the game objects starts at 0 every time the game is ‘played.’ While issuing a command, with the joystick, the Z rotation switches to many different numbers, but always locks on “180” after the user ends the joystick command.

transform.forward = velocity

That locks the ship pointing in one direction (in my cause toward the top of the screen - for what it’s worth) and the ship loses its ability to move along the X axis, can move along the Y axis.

  • This results in a ship that’s pointing strait toward the top of my screen and is only able to move up and down on the screen. No horizontal movement along the X.

Any other tips?

Unity is also giving this message -repeatedly- while running program:

Look rotation viewing vector is zero
UnityEngine.Transform:set_forward(Vector3)
PlayerRelativeControl:Update() (at Assets/Standard Assets (Mobile)/Scripts/PlayerRelativeControl.js:84)

Fairly easy… you already have the movement, just face that direction… Literally…

var lookAt = movement;
lookAt.z = 0; // if z is the up direction
if(lookAt.magnitude > 0) transform.LookAt(transform.position + lookAt);

Almost there!

When I use this code, the ship seems to flicker back and forth (facing direction) with every frame, and the ship barely moves - as if it is moving (and facing) in one direction, then immediately moving (and facing) the opposite direction).

When I stop issuing movement commands the ship is facing immediately opposite of the direction I was intending on making the ship move.

What am I not quite getting here?

Thanks for the assistance so far.

Oh… sorry

var lookAt = movement;
lookAt.z = 0; // if z is the up direction
if(lookAt.magnitude > 0) transform.LookAt(transform.position + lookAt, transform.forward);

You need to use the forward vector of the transform in the LookAt… this will point the top of the camera towards the front of the object. :wink:

Thanks again for the help, this all seems to be going in the right direction but I must have something messed up with my object that is causing it to behave incorrectly - I will post more information in an attempt to get assistance in finding the problem:

-The ‘object’ that I have the above script attached to is a character controller object with a Rotation of X:0 Y: 90 Z: 0
(If I have it 0,0,0 my ship doesn’t move along the x/y window how I want it to)

-The actual 3d ‘ship’ model is then attached to the above object (for information’s sake, this ‘ship’ has a Rotation of X:0 Y:0 Z:0)

When I made the most recent edit BigMisterB mentioned above, the behavior of the ship changed from flicking instantly to opposite facing directions to the following:

  • The ship appears to spin in circles most of the time (while the user is inputing a ‘direction’ for the ship to move).
  • Occasionally the ship flickers back and forth facing opposite directions (like it used to before this edit).
  • The ship occasionally locks in a direction (while using the joystick) and will drift in the direction indicated by the user.

I am not quite sure what is happening at this point.

Thank you for any assistance.

Edit:

Here are some things I’ve noticed in Unity itself while I’m running the game:

-The Y rotation of the game object appears to only change in increments of 90 when the user attempts to move the ship (actually, pretty much only 90 and 270 (or 89.99999 and 269.999)).

-The Z rotation of the game objects starts at 0 every time the game is ‘played.’ While issuing a command, with the joystick, the Z rotation switches to many different numbers, but always locks on “180” after the user ends the joystick command.

Is there other information I could post that could help result in an answer?

The answers in this thread absolutely do not work. Thread should probably be deleted as if the OP eventually found a solution it was not shared.