Robot arm turret rotation only on Z axis!

I am finishing my shmup and I almost got the thing working!
But the problem is:
I have an orthographic view and I need to make my Robot arm ( a turret ) follow my target with It´s X and Y angle calculation.
I have the script almost working using :

void Update()
{
// many stuff here

//The rotation here:
float angle = Mathf.Atan2(relative.x, relative.z) * Mathf.Rad2Deg;
transform.rotation = Quaternion.Slerp(Quaternion.Euler(transform.rotation.x, transform.rotation.y, transform.rotation.z), Quaternion.Euler(0, 0, angle), Time.time * 1.0F);

// many stuff here
}

So could some one wash my brain with a little of wisdom here and give this poor developer bastard a hint! T_T

PS: UNITY ROCCKSSSSS!

After finishing this project I´ll send it to the UNION project ( I can´t wait ) :smile:

I think you want to rotate turret around Y axis, and also for smoothing you should use Time.deltaTime:

....
transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(0, angle, 0), Time.deltaTime * 1.0F);
....

Note: for better performance you should cache transform (and other frequently used components) to some variable and use only that, like:

private Transform m_transform;
void Start()
{
  m_transform = transform;
}

“colargol”

Thanks for the reply my developer friend!
But the problem is that I use the ortographic view for my game with the Z axis controlling the rotation ( a 2D game ) and the deth of my GameObjects, so if I use the code:

transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(0, angle, 0), Time.deltaTime * 1.0F);

My object will start rotating to the up or down on Y axis, so I could never use that. But Time.deltaTime I use in another gameObject just like the code you pasted here but on the Z axis for a smooth transition.
But thanks for the reply!

Ok, and when you change it to this, it will help?

transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(0, 0, angle), Time.deltaTime * 1.0F);

I get confused by this line, where you calculate rotation around Y:

float angle = Mathf.Atan2(relative.x, relative.z) * Mathf.Rad2Deg;

For Example the image above ( not my real robot and 1 Min fast character designed for this example ) Needs to rotate on Z:

See this I am talking about. :expressionless:

If “relative” is vector to target, then this should be it:

float angle = Mathf.Atan2(relative.y, relative.x) * Mathf.Rad2Deg;
transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(0, 0, angle), Time.deltaTime * 1.0F);

float angle = Mathf.Atan2(relative.x, relative.z) * Mathf.Rad2Deg;

OPS sorry I copied wrong, the right thing is:

float angle = Mathf.Atan2(transform.position.x, transform.position.y ) * Mathf.Rad2Deg; // My Bad T_T, Now it´s right!!

My original code fixed here is:

void Update()
{
// many stuff here

//The rotation here:
float angle = Mathf.Atan2(transform.position.x, transform.position.y) * Mathf.Rad2Deg;
transform.rotation = Quaternion.Slerp(Quaternion.Euler(transform.rotation.x, transform.rotation.y, transform.rotation.z), Quaternion.Euler(0, 0, angle), Time.time * 1.0F);

// many stuff here
}

And I know that Quaternion.Euler(transform.rotation.x, transform.rotation.y, transform.rotation.z) is the same as transform.rotation, but I try to implement that way so I can change specific axis.

Also you can use Quaternion.Inverse() to change the rotation direction movement like:

transform.rotation = Quaternion.Slerp(Quaternion.Euler(transform.rotation.x, transform.rotation.y, transform.rotation.z),
Quaternion.Inverse(Quaternion.Euler(0, 0, angle)), Time.time * 1.0F);

But still on Z axis!!

http://unity3d.com/support/documentation/ScriptReference/Quaternion.Inverse.html

//first you need direction to target (now you are using transform.position in angle calculation)
Vector3 relative_pos = target_transform.position - transform.position;

float angle = Mathf.Atan2(relative_pos.y, relative_pos.x) * Mathf.Rad2Deg;


//you want to change only rotation around Z axis 
transform.eulerAngles.z = Mathf.LerpAngle(transform.eulerAngles.z, angle, Time.deltaTime * 1.0f);

Note: you cannot use transform.rotation.x (or y, z, w) inside Quaternion.Euler(), because rotation is quaternion, not euler angles

colargol

Thanks my friend , as I saw your post now I am gointo to try it tomorow!

I´ll post here later and thanks for sharing your knowledge with me !!

Later I´ll post what I found about creating a prefab that needs a target and how to instantiate the prefab linked with a “tag” so you can instantiate turrets, homing missiles and other objects that needs a target on prefabs in C Sharp.

See ya later!

I haven´t tried yet but in the documentation it says:

Transform.eulerAngles :
“Only use this variable to read and set the angles to absolute values. Don’t increment them, as it will fail when the angle exceeds 360 degrees. Use Transform.Rotate instead.”

also,
“Do not set one of the eulerAngles axis separately (eg. eulerAngles.x = 10; ) since this will lead to drift and undesired rotations. When setting them to a new value set them all at once as shown above. Unity will convert the angles to and from the rotation stored in Transform.rotation”

but tomorow i´ll try that, but this seems to be a big problem → "as it will fail when the angle exceeds 360 degrees "
I think that´s why I haven´t used Transform.eulerAngles…but after I try it out I´ll post here!!

See ya!

colargol

I fixed the code with this:

//first you need direction to target (now you are using transform.position in angle calculation)
Vector3 relative_pos = target.transform.position - transform.position;

float angle = Mathf.Atan2(relative_pos.y, relative_pos.x) * Mathf.Rad2Deg;

//you have to consider to store in a variable
float NewZangle = Mathf.LerpAngle(transform.eulerAngles.z, angle, Time.time * 1.0f);

//you want to change only rotation around Z axis, but my sprite got fixed with the position adding + 270 degrees
transform.eulerAngles = new Vector3( 0,0, NewZangle+270F);

And on My shotField collider I have done this:

Lots of codes…Declaration and collision triggers…
IEnumerator Shoot()
{
//OBS : transform.eulerAngles.z to make the bullet follow the collider direction
//EnemyTiro1Prefab is another gameObject
Vector3 Eposition = new Vector3(transform.position.x, transform.position.y,0);
Instantiate(EnemyTiro1Prefab , Eposition, Quaternion.Euler(0, 0, transform.eulerAngles.z));
yield return new WaitForSeconds(0.2f);
}

Also if you Want to instantiate a prefab with an attached TAG on it you should do this on C sharp:

On the prefab:

public GameObject target;

void Start ()
{
//!!!Important HERE : How to allocate a target scripting!!!
target = GameObject.Find(“Player”);
//your code…
}

Very simple!!
And thanks to your advice and knowledge here I could make my perfect turret code, for all my turrets in 2D.
Thanks my developer friend!! :wink: