• 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 /
  • Help Room /
avatar image
0
Question by SeanM3D · Jan 15, 2016 at 02:17 PM · parameterstransformslinking

Wiring Transform Channels Between a Source and a Target

Hallo everyone,

I am trying to create a script that let's me wire transform channels criss-cross between a source and a target object, akin to the 3ds Max "Wire Parameters" dialog. My goal is to make channel linkages like this:

Source TransX drives Target RotY

Source TransZ drives Target TransX

and so forth.

I made a very primitive attempt (so far only for the TransX, TransY and TransZ target channels) with a terrible amount of code duplication. I now need to generalize my solution, making my code much more concise by ideally packaging the whole linkage code into a single funtion (if possible). Can anyone show me a slick way to do thay?

Needless to say, I am open to alternative solutions!

Attached is also a screenshot, showing how the Inspector interface looks like. It's basically a bunch of public enums.

Thanks so much for any help!

My code:

 using UnityEngine;
 using System.Collections;
 
 public enum Channel
 {
     TransX, TransY, TransZ, RotX, RotY, RotZ, None
 }
     
 public class WireParameters : MonoBehaviour 
 {
     public GameObject Source;
 
     private Transform ThisTransform = null;
 
     public Channel TransX;
     public Channel TransY;
     public Channel TransZ;
 
     public Channel RotX;
     public Channel RotY;
     public Channel RotZ;
 
     public float Factor;
 
     public void Start()
     {
         ThisTransform = transform;
     }
 
     public void LinkTransX (Channel TransX)
     {
         switch(TransX)
         {
         case Channel.TransX: 
             ThisTransform.position = new Vector3(Source.transform.position.x, ThisTransform.position.y, ThisTransform.position.z) * Factor;
             break;
 
         case Channel.TransY: 
             ThisTransform.position = new Vector3(Source.transform.position.y, ThisTransform.position.y, ThisTransform.position.z) * Factor;
             break;
 
         case Channel.TransZ: 
             ThisTransform.position = new Vector3(Source.transform.position.z, ThisTransform.position.y, ThisTransform.position.z) * Factor;
             break;
 
         case Channel.RotX: 
             ThisTransform.position = new Vector3(Source.transform.localRotation.x, ThisTransform.position.y, ThisTransform.position.z) * Factor;
             break;
 
         case Channel.RotY: 
             ThisTransform.position = new Vector3(Source.transform.localRotation.y, ThisTransform.position.y, ThisTransform.position.z) * Factor;
             break;
 
         case Channel.RotZ: 
             ThisTransform.position = new Vector3(Source.transform.localRotation.z, ThisTransform.position.y, ThisTransform.position.z) * Factor;
             break;
 
         case Channel.None:
             ThisTransform.position = new Vector3(ThisTransform.position.x, ThisTransform.position.y, ThisTransform.position.z) * Factor;
             break;
         }
     }
 
     public void LinkTransY (Channel TransY)
     {
         switch(TransY)
         {
         case Channel.TransX: 
             ThisTransform.position = new Vector3(ThisTransform.position.x, Source.transform.position.x, ThisTransform.position.z) * Factor;
             break;
 
         case Channel.TransY: 
             ThisTransform.position = new Vector3(ThisTransform.position.x, Source.transform.position.y, ThisTransform.position.z) * Factor;
             break;
 
         case Channel.TransZ: 
             ThisTransform.position = new Vector3(ThisTransform.position.x, Source.transform.position.z, ThisTransform.position.z) * Factor;
             break;
 
         case Channel.RotX: 
             ThisTransform.position = new Vector3(ThisTransform.position.x, Source.transform.localRotation.x, ThisTransform.position.z) * Factor;
             break;
 
         case Channel.RotY: 
             ThisTransform.position = new Vector3(ThisTransform.position.x, Source.transform.localRotation.y, ThisTransform.position.z) * Factor;
             break;
 
         case Channel.RotZ: 
             ThisTransform.position = new Vector3(ThisTransform.position.x, Source.transform.localRotation.z, ThisTransform.position.z) * Factor;
             break;
 
         case Channel.None:
             ThisTransform.position = new Vector3(ThisTransform.position.x, ThisTransform.position.y, ThisTransform.position.z) * Factor;
             break;
         }
     }
 
     public void LinkTransZ (Channel TransZ)
     {
         switch(TransZ)
         {
         case Channel.TransX: 
             ThisTransform.position = new Vector3(ThisTransform.position.x, ThisTransform.position.y, Source.transform.position.x) * Factor;
             break;
 
         case Channel.TransY: 
             ThisTransform.position = new Vector3(ThisTransform.position.x, ThisTransform.position.y, Source.transform.position.y) * Factor;
             break;
 
         case Channel.TransZ: 
             ThisTransform.position = new Vector3(ThisTransform.position.x, ThisTransform.position.y, Source.transform.position.z) * Factor;
             break;
 
         case Channel.RotX: 
             ThisTransform.position = new Vector3(ThisTransform.position.x, ThisTransform.position.y, Source.transform.localRotation.x) * Factor;
             break;
 
         case Channel.RotY: 
             ThisTransform.position = new Vector3(ThisTransform.position.x, ThisTransform.position.y, Source.transform.localRotation.y) * Factor;
             break;
 
         case Channel.RotZ: 
             ThisTransform.position = new Vector3(ThisTransform.position.x, ThisTransform.position.y, Source.transform.localRotation.z) * Factor;
             break;
 
         case Channel.None:
             ThisTransform.position = new Vector3(ThisTransform.position.x, ThisTransform.position.y, ThisTransform.position.z) * Factor;
             break;
         }
     }
 
     public void Update()
     {
         LinkTransX(TransX);
         LinkTransY(TransY);
         LinkTransZ(TransZ);
     }
 }


alt text

screenshot.jpg (182.5 kB)
Comment
Add comment · Show 2
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 hexagonius · Jan 15, 2016 at 02:50 PM 0
Share

Not everyone, including me, knows what a transform channel is. What is this supposed to do?

avatar image SeanM3D hexagonius · Jan 15, 2016 at 03:03 PM 0
Share

The transform channels are:

transform.positon.x

transform.positon.y

transform.positon.z

transform.rotation.x

transform.rotation.y

transform.rotation.z

transform.localscale.x

transform.localscale.y

transform.localscale.z

I want to wire these criss-cross between a source and a target object.

2 Replies

· Add your reply
  • Sort: 
avatar image
1

Answer by hexagonius · Jan 15, 2016 at 03:37 PM

Sounded interesting, so I tried and came up with this. It misses out on Rotation and I didn't test it, but it at least gives the idea :)

 using UnityEngine;
 using System.Collections;
 
 public enum Channel
 {
     TransX,
     TransY,
     TransZ,
     RotX,
     RotY,
     RotZ,
     ScaleX,
     ScaleY,
     ScaleZ,
     None
 }
 
 public class WireParameters : MonoBehaviour 
 {
     public GameObject Source;
 
     private Transform ThisTransform = null;
 
     public Channel TransX;
     public Channel TransY;
     public Channel TransZ;
 
     public Channel RotX;
     public Channel RotY;
     public Channel RotZ;
 
     public float Factor;
 
     public void Start()
     {
         ThisTransform = transform;
     }
 
     public void LinkTransX (Channel TransX)
     {
         Vector3 oldPosition = ThisTransform.position;
         oldPosition.x = SourcePosition (TransZ) == 0 ? oldPosition.x : SourcePosition (TransZ);
         ThisTransform.position = oldPosition * Factor;
 
         Vector3 oldScale = ThisTransform.localScale;
         oldScale.x = SourceScale (TransZ) == 0 ? oldPosition.x : SourceScale (TransZ);
         ThisTransform.localScale = oldScale;
     }
 
     public void LinkTransY (Channel TransY)
     {
         Vector3 oldPosition = ThisTransform.position;
         oldPosition.y = SourcePosition (TransZ) == 0 ? oldPosition.y : SourcePosition (TransZ);
         ThisTransform.position = oldPosition * Factor;
 
         Vector3 oldScale = ThisTransform.localScale;
         oldScale.y = SourceScale (TransZ) == 0 ? oldPosition.y : SourceScale (TransZ);
         ThisTransform.localScale = oldScale;
     }
 
     public void LinkTransZ (Channel TransZ)
     {
         Vector3 oldPosition = ThisTransform.position;
         oldPosition.z = SourcePosition (TransZ) == 0 ? oldPosition.z : SourcePosition (TransZ);
         ThisTransform.position = oldPosition * Factor;
 
         Vector3 oldScale = ThisTransform.localScale;
         oldScale.z = SourceScale (TransZ) == 0 ? oldPosition.z : SourceScale (TransZ);
         ThisTransform.localScale = oldScale;
     }
 
     float SourcePosition(Channel channel){
         if (TransX == Channel.TransX)
             return Source.transform.position.x;
         if (TransX == Channel.TransY)
             return Source.transform.position.y;
         if (TransX == Channel.TransZ)
             return Source.transform.position.z;
         return 0f;
     }
 
     float SourceScale(Channel channel){
         if (TransX == Channel.TransX)
             return Source.transform.localScale.x;
         if (TransX == Channel.TransY)
             return Source.transform.localScale.y;
         if (TransX == Channel.TransZ)
             return Source.transform.localScale.z;
         return 0f;
     }
 
     public void Update()
     {
         LinkTransX(TransX);
         LinkTransY(TransY);
         LinkTransZ(TransZ);
     }
 }
Comment
Add comment · 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
0

Answer by SeanM3D · Jan 18, 2016 at 10:31 AM

Thanks a lot for your very helpful response, hexagonius! I took your nicely refactored code and fixed some functional issues and now came up with this solution for simple unidirectional constraining:

 using UnityEngine;
 using System.Collections;
 
 public enum Channel
 {
     TransX,
     TransY,
     TransZ,
     RotX,
     RotY,
     RotZ,
     ScaleX,
     ScaleY,
     ScaleZ,
     None
 }
 
 [ExecuteInEditMode]
 public class WireParams : MonoBehaviour 
 {
     public GameObject Source;
 
     private Transform ThisTransform = null;
 
     public Channel TransX = Channel.None;
     public float TransXFactor = 1.0f;
 
     public Channel TransY = Channel.None;
     public float TransYFactor = 1.0f;
 
     public Channel TransZ = Channel.None;
     public float TransZFactor = 1.0f;
 
     public Channel RotX = Channel.None;
     public float RotXFactor = 1.0f;
 
     public Channel RotY = Channel.None;
     public float RotYFactor = 1.0f;
 
     public Channel RotZ = Channel.None;
     public float RotZFactor = 1.0f;
 
     public Channel ScaleX = Channel.None;
     public float ScaleXFactor = 1.0f;
 
     public Channel ScaleY = Channel.None;
     public float ScaleYFactor = 1.0f;
 
     public Channel ScaleZ = Channel.None;
     public float ScaleZFactor = 1.0f;
 
     public void Start()
     {
         ThisTransform = transform;
     }
 
     public void LinkTransX (Channel TransX)
     {
         if(TransX != Channel.None)
         {
             Vector3 oldPosition = ThisTransform.position;
             float newPositionX;
 
             newPositionX = SourceTransform (TransX) * TransXFactor;
             ThisTransform.position = new Vector3(newPositionX, oldPosition.y, oldPosition.z);
     
         }
     }
 
     public void LinkTransY (Channel TransY)
     {
         if(TransY != Channel.None)
         {
             Vector3 oldPosition = ThisTransform.position;
             float newPositionY;
 
             newPositionY = SourceTransform (TransY) * TransYFactor;
             ThisTransform.position = new Vector3(oldPosition.x, newPositionY, oldPosition.z);
         }
     }
 
     public void LinkTransZ (Channel TransZ)
     {
         if(TransZ != Channel.None)
         {
             Vector3 oldPosition = ThisTransform.position;
             float newPositionZ;
 
             newPositionZ = SourceTransform (TransZ) * TransZFactor;
             ThisTransform.position = new Vector3(oldPosition.x, oldPosition.y, newPositionZ);
         }
     }
 
     public void LinkRotX (Channel RotX)
     {
         if(RotX != Channel.None)
         {
             Vector3 oldRotation = ThisTransform.localEulerAngles;
             float newRotationX;
 
             newRotationX = SourceTransform (RotX) * RotXFactor;
             ThisTransform.localEulerAngles = new Vector3(newRotationX, oldRotation.y, oldRotation.z);
         }
     }
 
     public void LinkRotY (Channel RotY)
     {
         if(RotY != Channel.None)
         {
             Vector3 oldRotation = ThisTransform.localEulerAngles;
             float newRotationY;
 
             newRotationY = SourceTransform (RotY) * RotYFactor;
             ThisTransform.localEulerAngles = new Vector3(oldRotation.x, newRotationY, oldRotation.z);
         }
     }
 
     public void LinkRotZ (Channel RotZ)
     {
         if(RotZ != Channel.None)
         {
             Vector3 oldRotation = ThisTransform.localEulerAngles;
             float newRotationZ;
 
             newRotationZ = SourceTransform (RotZ) * RotZFactor;
             ThisTransform.localEulerAngles = new Vector3(oldRotation.x, oldRotation.y, newRotationZ);
         }
     }
 
     public void LinkScaleX (Channel ScaleX)
     {
         if(ScaleX != Channel.None)
         {
             Vector3 oldScale = ThisTransform.localScale;
             float newScaleX;
 
             newScaleX = SourceTransform (ScaleX) * ScaleXFactor;
             ThisTransform.localScale = new Vector3(newScaleX, oldScale.y, oldScale.z);
         }
     }
 
     public void LinkScaleY (Channel ScaleY)
     {
         if(ScaleY != Channel.None)
         {
             Vector3 oldScale = ThisTransform.localScale;
             float newScaleY;
 
             newScaleY = SourceTransform (ScaleY) * ScaleYFactor;
             ThisTransform.localScale = new Vector3(oldScale.x, newScaleY, oldScale.z);
         }
     }
 
     public void LinkScaleZ (Channel ScaleZ)
     {
         if(ScaleZ != Channel.None)
         {
             Vector3 oldScale = ThisTransform.localScale;
             float newScaleZ;
 
             newScaleZ = SourceTransform (ScaleZ) * ScaleZFactor;
             ThisTransform.localScale = new Vector3(oldScale.x, oldScale.y, newScaleZ);
         }
     }
 
     float SourceTransform(Channel channel)
     {
         if (channel == Channel.TransX)
             return Source.transform.position.x;
         
         else if (channel == Channel.TransY)
             return Source.transform.position.y;
         
         else if (channel == Channel.TransZ)
             return Source.transform.position.z;
         
         else if (channel == Channel.RotX)
             return Source.transform.localEulerAngles.x;
         
         else if (channel == Channel.RotY)
             return Source.transform.localEulerAngles.y;
         
         else if (channel == Channel.RotZ)
             return Source.transform.localEulerAngles.z;
 
         else if (channel == Channel.ScaleX)
             return Source.transform.localScale.x;
 
         else if (channel == Channel.ScaleY)
             return Source.transform.localScale.y;
 
         else if (channel == Channel.ScaleZ)
             return Source.transform.localScale.z;
         
         else
             return 0f;
     }
 
 
     public void Update()
     {
         LinkTransX(TransX);
         LinkTransY(TransY);
         LinkTransZ(TransZ);
         LinkRotX(RotX);
         LinkRotY(RotY);
         LinkRotZ(RotZ);
         LinkScaleX(ScaleX);
         LinkScaleY(ScaleY);
         LinkScaleZ(ScaleZ);
     }
 }
 
 

If anybody has suggestions for further improvements I'm all ears! For instance it would be cool to condense the six Linkxxx(xxx) functions to only three.

Comment
Add comment · 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

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.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

37 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 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

Issue with animation parameters, they're not there! 1 Answer

How to deal with a lot of parameters without using reflection? 0 Answers

Victory Condition, Argument Out Of Range? 0 Answers

iOS/Xcode: Duplicate Symbols 1 Answer

How to use an implicit generic list as a parameter? 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