4 Replies - 815 Views - Last Post: 30 June 2012 - 07:25 AM Rate Topic: -----

#1 Kain6622  Icon User is offline

  • D.I.C Head

Reputation: 14
  • View blog
  • Posts: 248
  • Joined: 18-March 10

Rotation Problem in Unity

Posted 29 June 2012 - 10:45 AM

Hi, I'm currently working on a project with a few of my friends and have run into an issue regarding rotations. The project is a space flying game, the issue that I'm having is getting independent axis rotations mainly with concerns to the yaw and roll. As the project stands you can fly about levitate and rotate about the yaw. What I'm trying to achieve is the functionality for the ship to roll when yawing, the issue is when I perform the roll rotation it messes up the yaw due to the change in local coordinate system, so instead of it still yaw left or right it will yaw left/ right and down/up. I know the issue lies with the transformations but not matter what I do it doesn't seem to fix the issue, is there anyway that I can get the yaw to constantly have the up vector (0,1,0) and for it not to change when I perform the roll? (I've also tried to use the Rigid body but again I get the same problem)

Bellow is the CS script:
//using UnityEngine;
//using System.Collections;
//
using UnityEngine;
using System.Collections;

// Class: Movement
// Description: Controller how the players ship navigates
//				around the scene
public class Movement : MonoBehaviour {
	Rigidbody _rbody;												// for the physical properties and behaviours
	Vector3   m_Position 		= new Vector3(0.0f, 0.0f, 0.0f);	// keep track of the position in the world
	Vector3   m_TransFroce 		= new Vector3(0.0f, 0.0f, 0.0f); 	// the translation force variable
	Vector3   m_RotForce 		= new Vector3(0.0f, 0.0f, 0.0f );	// the rotation force variable
	float 	  Pitch 			= 0.0f;								// Pitch rotation value
	float 	  Yaw 				= 0.0f;								// Yaw rotation value
	float 	  Roll 				= 0.0f;								// Roll rotation value
	float 	  AmbientSpeed 		= 200.0f;							// translation speed
	float 	  RotationSpeed 	= 20.0f;							// rotation speed
	Quaternion PrevRotation 	= Quaternion.identity;				// keep track of the previous rotation
	Quaternion CurRotation 		= Quaternion.identity;				// the currently applied rotation
	
	void Start()
	{
		_rbody = gameObject.GetComponent<Rigidbody>();	
	}
	
	void FixedUpdate ()
	{
		ControlRotation();
		ControlMotion ();
		transform.RotateAroundLocal(Vector3.up, m_RotForce.y);
		transform.RotateAroundLocal( transform.forward, Roll);
		
		
		transform.Translate((m_Position+m_TransFroce));
	}
	
	void ControlMotion(){
		
		// Levitation
		if(Input.GetKey("c")){
			m_TransFroce.y += 2.0f * Time.deltaTime;
			if( m_TransFroce.y > 3.0f )
				m_TransFroce.y = 3.0f;
		}else if(Input.GetKey("v")){
			m_TransFroce.y -= 2.0f * Time.deltaTime;
		}
		
		if(Input.GetKey("w")){
			m_TransFroce.z += 2.0f * Time.deltaTime;
			if( m_TransFroce.z > 3.0f )
				m_TransFroce.z = 3.0f;
		}else if(Input.GetKey("s")){
			m_TransFroce.z -= 2.0f * Time.deltaTime;
			if( m_TransFroce.z < -3.0f )
				m_TransFroce.z = -3.0f;
		}
	}
	
	void ControlRotation(){
		if(Input.GetKey("a"))
		{
			m_RotForce.y -= 2.0f * Time.deltaTime;
			Roll -= 2.0f * Time.deltaTime;
			Roll = Mathf.Clamp(Roll, -20, 20);
			
			if( m_RotForce.y < -3.0f )
				m_RotForce.y = -3.0f;
		}
		else if(Input.GetKey("d"))		{
			m_RotForce.y += 2.0f * Time.deltaTime;
			Roll += 2.0f * Time.deltaTime;
			Roll = Mathf.Clamp(Roll, -20, 20);
			
			if( m_RotForce.y > 3.0f )
				m_RotForce.y = 3.0f;
			if( Roll != 0.0f )
				Roll -= Roll * Time.deltaTime;
		}
		else{
			if( m_RotForce.y != 0.0f ){
			
				m_RotForce += -m_RotForce * Time.deltaTime;
			}
			if( Roll != 0 )
				Roll += -Roll * Time.deltaTime;
		}
	}
	
};



Please Advise

Is This A Good Question/Topic? 0
  • +

Replies To: Rotation Problem in Unity

#2 Kain6622  Icon User is offline

  • D.I.C Head

Reputation: 14
  • View blog
  • Posts: 248
  • Joined: 18-March 10

Re: Rotation Problem in Unity

Posted 29 June 2012 - 12:37 PM

Ok I solved the problem with a bit of trial and error turned out I needed to use transform.RotateAround to get it to work:

transform.RotateAround(transform.position, Vector3.up, m_RotForce.y);
transform.RotateAround(transform.position, transform.forward, -Roll );



Not i've got a simpler problem... well i hope anyway, I'm trying to cap the Roll rotation to 30 degrees either side of the object/camera, I know how to clamp the rotation speeds but I'm unsure of how one camps the actual rotation from the transform? Thanks
Was This Post Helpful? 1
  • +
  • -

#3 ButchDean  Icon User is offline

  • Ex-Pro Games Programmer
  • member icon

Reputation: 894
  • View blog
  • Posts: 3,383
  • Joined: 26-November 10

Re: Rotation Problem in Unity

Posted 29 June 2012 - 05:15 PM

If I understand you correctly you could evaluate the dot product to ensure that your rotation does not go beyond 30 degrees.
Was This Post Helpful? 0
  • +
  • -

#4 Kain6622  Icon User is offline

  • D.I.C Head

Reputation: 14
  • View blog
  • Posts: 248
  • Joined: 18-March 10

Re: Rotation Problem in Unity

Posted 30 June 2012 - 02:21 AM

hmm interesting Idea but I'm failing to see how the Dot product could be used this way? But either way I found a solution, not sure how efficient it is but here goes nothing:

zCurVal = transform.localEulerAngles.z-180.0f;

// if we're out of the bounds of the chosen restricted angle
if( (zCurVal > -150 && zCurVal < 150) && transform.localEulerAngles.z != 0 ){
	Vector3 tmp = transform.localEulerAngles; // get the current rotation local to the ship

        // adjust the ship rotation a fraction before the bound
        // to stop locking
	tmp.z = zCurVal+(zCurVal*0.00001f)+180.0f; 
			
	transform.localEulerAngles = tmp; // apply the updated rotation
}else{ // rotate as normal
    	transform.RotateAround(transform.position, transform.forward, -Roll );
}



This limits the rotation but is a bit chunky when it hits the bound, hence why I have the zCurVal multiplied by 0.00001f to minimise the obviousness of it. Not sure if there is a better way to do it (well i know there will be a better way to do it but just not coming to mind at the current time).

Now refering back to my code in my first post, you can see that I have a section that slows the Yaw to a stop when turning if a key is not down (A and D in this instance), I'm wanting to do something similar for the pitch but instead of it stopping I want it to rotate the pitch smoothly back so that the up vector returns to (0,1,0), at the current time I can have it snapping back or rotating back to origin with some oscillation (flicker motion left and right) when it reaches the correct rotation code is as follows:

if( zCurVal != 0.0f ){
	Vector3 tmp = transform.localEulerAngles;
	Roll = 0.0f; // dont roll anymore
	tmp.z += (zCurVal/8.0f)  * Time.deltaTime; // roll the local z rotation back to central
	transform.localEulerAngles = tmp;
}



Is there any advice you can give me on stopping oscillations of this form of rotation? Thanks
Was This Post Helpful? 0
  • +
  • -

#5 ButchDean  Icon User is offline

  • Ex-Pro Games Programmer
  • member icon

Reputation: 894
  • View blog
  • Posts: 3,383
  • Joined: 26-November 10

Re: Rotation Problem in Unity

Posted 30 June 2012 - 07:25 AM

The dot product would have allowed you to limit your rotations without too much math. For instance we know that cos 30 degrees is 0.87, which is a nice single, easily achievable float to deal with. Plug that in to your dot product calculation and whenever that limit is broken in that it tends to 1 you will know that you have gone beyond your 30 degree boundary. Always keep things simple.

On the oscillation front, how severe are they? Are they fast or slow for instance?
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1