Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by Juice-Tin · Feb 22, 2015 at 06:34 PM · rotationcoordinatesturret

Rotate child objects to another object?

I'm making a turret defense and below is an example of what I'm trying to do: alt text

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!

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

· Add your reply
  • Sort: 
avatar image
2
Best Answer

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 :)

Comment
Add comment · Show 5 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Juice-Tin · Feb 22, 2015 at 09:06 PM 0
Share

Cool thanks, I'm not home now, but I will try this when I get a chance!

avatar image Juice-Tin · Feb 23, 2015 at 01:06 AM 0
Share

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!

avatar image andrew-lukasik · Feb 23, 2015 at 10:26 AM 0
Share

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 );
     }
avatar image Juice-Tin · Feb 25, 2015 at 02:58 AM 0
Share

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)

avatar image andrew-lukasik · Feb 25, 2015 at 02:56 PM 0
Share

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

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

21 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

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


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges