- Home /
Rotate child objects to another object?
I'm making a turret defense and below is an example of what I'm trying to do:
Blue base rotates horizontally towards the ball. (Working fine)
Red barrel should rotate vertically and point to the ball. This does not work. I can get it working on the blue base, but when I apply it to the red barrel it goes crazy.
How can I make the red child only rotate vertically to the ball, while the blue base does the horizontal rotation? I've been at this for hours and can't get it going properly.
Thanks!
Answer by andrew-lukasik · Feb 22, 2015 at 08:17 PM
Hi. Use this function:
// ROTATE TURRET //
private void RotateTurret ( Transform turretTransform , Vector3 target , float degreesOfFreedom , float rotationSpeed , bool lockX , bool lockY , bool lockZ = true ) {
float _angleBetweenTargetAndTransformForward = Vector3.Angle( target-turretTransform.parent.position , turretTransform.parent.forward );
if( _angleBetweenTargetAndTransformForward<degreesOfFreedom/2 ) {
//apply rotation:
turretTransform.rotation = Quaternion.Slerp( turretTransform.rotation , Quaternion.LookRotation( target-turretTransform.position ) , Time.deltaTime*rotationSpeed );
//apply axis lock:
Vector3 rotationLocalEuler = turretTransform.localRotation.eulerAngles;
if( lockX ) rotationLocalEuler.x = 0f;
if( lockY ) rotationLocalEuler.y = 0f;
if( lockZ ) rotationLocalEuler.z = 0f;
turretTransform.localRotation = Quaternion.Euler( rotationLocalEuler );
}
}
EDIT: second version, where turret try to follow it's target even when it can't reach it fully:
// ROTATE TURRET 2 //
private void RotateTurret2 ( Transform turretTransform , Vector3 target , float degreesOfFreedom , float rotationSpeed , bool lockX , bool lockY , bool lockZ = true ) {
//apply rotation:
turretTransform.rotation = Quaternion.Slerp( turretTransform.rotation , Quaternion.LookRotation( target-turretTransform.position ) , Time.deltaTime*rotationSpeed );
//apply axis locks and constrains:
Vector3 rotationLocalEuler = turretTransform.localRotation.eulerAngles;
if( lockX ) rotationLocalEuler.x = 0f;
else {
if( rotationLocalEuler.x>180f ) rotationLocalEuler.x = rotationLocalEuler.x-360f;
rotationLocalEuler.x = Mathf.Clamp( rotationLocalEuler.x , -degreesOfFreedom/2 , degreesOfFreedom/2 );
}
if( lockY ) rotationLocalEuler.y = 0f;
else {
if( rotationLocalEuler.y>180f ) rotationLocalEuler.y = rotationLocalEuler.y-360f;
rotationLocalEuler.y = Mathf.Clamp( rotationLocalEuler.y , -degreesOfFreedom/2 , degreesOfFreedom/2 );
}
if( lockZ ) rotationLocalEuler.z = 0f;
else {
if( rotationLocalEuler.z>180f ) rotationLocalEuler.z = rotationLocalEuler.z-360f;
rotationLocalEuler.z = Mathf.Clamp( rotationLocalEuler.z , -degreesOfFreedom/2 , degreesOfFreedom/2 );
}
turretTransform.localRotation = Quaternion.Euler( rotationLocalEuler );
}
There is one requirement to these functions - turretTransform Must have a parent gameobject (ideally in same place & rotation, because calculations are partially based on local rotations).
Then you can use it like this for example:
void Update () {
if (targetTransform!=null) {
RotateTurret( transform, targetTransform.position , Mathf.Infinity , 5f , true , false );
}
}
^ where Mathf.Infinity will mean no constrains on how much this turret can rotate around. But change it to 180f and it will became constained to 180 deegrees of movement in given axis.
In your case I would use it like this:
public Transform turretTransform;
public Transform barrelTransform;
public Transform targetTransform;
void Update () {
if( targetTransform!=null ) {
RotateTurret( turretTransform , targetTransform.position , Mathf.Infinity , 3f , true , false );
RotateTurret( barrelTransform , targetTransform.position , 90f , 2f , false , true );
}
}
Code and prosper :)
Cool thanks, I'm not home now, but I will try this when I get a chance!
Hey thanks, it works!
However, if the object moves outside of the turrets 'freedom' range, the function disables entirely, rather than letting the turret move to it's max range.
I've been trying to modify this part of the function
if( _angleBetweenTargetAndTransformForward => degreesOfFreedom/2 ) {
//Target is out of rotation range, modify move to $$anonymous$$/max range ins$$anonymous$$d.
}
However, I can't seem to figure out how to get the max range using this:
Quaternion.LookRotation( target-turretTransform.position );
Any idea? Thanks!
This will do the job:
// ROTATE TURRET 2 //
private void RotateTurret2 ( Transform turretTransform , Vector3 target , float degreesOfFreedom , float rotationSpeed , bool lockX , bool lockY , bool lockZ = true ) {
//apply rotation:
turretTransform.rotation = Quaternion.Slerp( turretTransform.rotation , Quaternion.LookRotation( target-turretTransform.position ) , Time.deltaTime*rotationSpeed );
//apply axis locks and constrains:
Vector3 rotationLocalEuler = turretTransform.localRotation.eulerAngles;
if( lockX ) rotationLocalEuler.x = 0f;
else {
if( rotationLocalEuler.x>180f ) rotationLocalEuler.x = rotationLocalEuler.x-360f;
rotationLocalEuler.x = $$anonymous$$athf.Clamp( rotationLocalEuler.x , -degreesOfFreedom/2 , degreesOfFreedom/2 );
}
if( lockY ) rotationLocalEuler.y = 0f;
else {
if( rotationLocalEuler.y>180f ) rotationLocalEuler.y = rotationLocalEuler.y-360f;
rotationLocalEuler.y = $$anonymous$$athf.Clamp( rotationLocalEuler.y , -degreesOfFreedom/2 , degreesOfFreedom/2 );
}
if( lockZ ) rotationLocalEuler.z = 0f;
else {
if( rotationLocalEuler.z>180f ) rotationLocalEuler.z = rotationLocalEuler.z-360f;
rotationLocalEuler.z = $$anonymous$$athf.Clamp( rotationLocalEuler.z , -degreesOfFreedom/2 , degreesOfFreedom/2 );
}
turretTransform.localRotation = Quaternion.Euler( rotationLocalEuler );
}
Amazing, thanks! Works like a charm. :)
Just curious, did you convert this from javascript? Because the default "bool lockZ = true" value doesn't work in C#. (I had to remove it)
Well I would be rather surprised to learn that I worked in JS all this time :) I'm not sure what could give errors here it's just a simple syntax to set default value for parameter. But often error's message text pretty much explains what was wrong in that line.
Your answer

Follow this Question
Related Questions
Rotate on Z axis 2 Answers
Lock rotation of object 4 Answers
How to rotate torso (sub mesh) of a model? 0 Answers
Coordinate Transformation 1 Answer
Turret rotation angle 1 Answer