Search Unity

Draw Cylinder Between 2 Points

Discussion in 'Scripting' started by slgooding, May 21, 2009.

  1. slgooding

    slgooding

    Joined:
    Jan 12, 2009
    Posts:
    112
    I'm back again...

    I have 2 coordinate points and need to draw a cylinder between the 2 points. I really have no clue...and my math skills are lacking...sigh.

    I appreciate any help, or simply pointing me in the right direction.

    Thanks again,

    Lee
     
  2. HiggyB

    HiggyB

    Unity Product Evangelist

    Joined:
    Dec 8, 2006
    Posts:
    6,183
    1. Make a cylinder prefab.

    2. Instantiate cylinder, use one of the points as the point of instantiation.

    3. Look at Transform.LookAt to make the cylinder face the other point.

    4. Scale the cylinder based on the distance between the two points.


    Work through each step, post questions along the way. Ready? Set? GO! :)
     
    yyylny likes this.
  3. slgooding

    slgooding

    Joined:
    Jan 12, 2009
    Posts:
    112
    Got it working. Thanks!

    Code (csharp):
    1. // Create a bond between 2 points
    2. // cylinderRef is a gameObject mesh cylinder with the cylinder pivot at the base pointing along the +Z.
    3.  
    4. var cylinderRef : Transform;
    5. var aTarget : Transform;
    6. var spawn : Transform;
    7.  
    8. function Start() {
    9.     // Find the distance between 2 points
    10.     var bondDistance : Vector2;
    11.     cylinderRef.localScale.z = bondDistance.Distance(spawn.position,aTarget.position)/2;
    12.    
    13.     cylinderRef.position = spawn.position;        // place bond here
    14.     cylinderRef.LookAt(aTarget);            // aim bond at atom
    15. }
    16.  
    17. function Update () {
    18. }
     
  4. windmaomao

    windmaomao

    Joined:
    Jun 11, 2009
    Posts:
    50
    For some reason, I can't get the following script work.

    I have a cylinder created from menu editor directly (pointing up in world). now I want it to orient from p1 to p2.

    Code (csharp):
    1.  
    2.     void create_cylinder(Vector3 p1, Vector3 p2) {
    3.         Vector3 pos = Vector3.Lerp(p1,p2,(float)0.5);
    4.         GameObject segObj = (GameObject)Instantiate(cylinder);
    5.         segObj.transform.position = pos;
    6.         segObj.transform.LookAt(p2);
    7.     }
    8.  
    the code runs, but it doesn't point to the direction from p1 to p2, I don't know what I did wrong, and I tried to add the upward direction in LookAt function, but still no luck, and I have trouble understanding what it says in the manual.

    please help. thanks.

    Fang
     
  5. GargerathSunman

    GargerathSunman

    Joined:
    May 1, 2008
    Posts:
    1,571
    LookAt makes the z-axis for the object with the script face directly towards the second object.

    Now, if the object is modeled so that the z-axis is pointing somewhere it shouldn't...... LookAt won't make the face you want point at the second object.
     
  6. windmaomao

    windmaomao

    Joined:
    Jun 11, 2009
    Posts:
    50
    thanks GargerathSunman,

    but how do I modify the z-axis of the object already in the editor, I tried to rotate all the angles of the cylinder.

    I want the top or bottom face of the cylinder to face any direction I want, not the script face of the cylinder body. How can I do this ? Seriously, i need help on this one.

    thanks.
     
  7. windmaomao

    windmaomao

    Joined:
    Jun 11, 2009
    Posts:
    50
    I actually got it working finally by doing,

    Code (csharp):
    1.  
    2.     void create_vessel(Vector3 p1, Vector3 p2) {
    3.         Vector3 pos = Vector3.Lerp(p1,p2,(float)0.5);
    4.         GameObject segObj = (GameObject)Instantiate(vesselSegment);
    5. //      segObj.transform.localScale.x = Vector3.Distance(p1,p2);
    6.         segObj.transform.position = pos;       
    7.         segObj.transform.up = p2-p1;
    8.     }
    9.  
    but the localScale.x = line gave me the following error that I don't know how to get rid of ,

    Assets/Standard Assets/Scripts/IOTest.cs(188,34): error CS1612: Cannot modify the return value of `UnityEngine.Transform.localScale' because it is not a variable

    please help.

    Fang
     
    kiber_ likes this.
  8. Pia

    Pia

    Joined:
    Feb 16, 2009
    Posts:
    78
    Try this:

    Code (csharp):
    1.  
    2. Vector3 newScale = segObj.transform.localScale;
    3. newScale.x = Vector3.Distance(p1,p2);
    4. segObj.transform.localScale = newScale;
    5.  
    or shorter, but also more unclear:

    Code (csharp):
    1.  
    2. segObj.transform.localScale = new Vector3(Vector3.Distance(p1,p2), segObj.transform.localScale.y, segObj.transform.localScale.z);
    3.  
     
  9. GargerathSunman

    GargerathSunman

    Joined:
    May 1, 2008
    Posts:
    1,571
    That's a good solution....

    Just so you know for future reference, though, you can only change a model's natural z-axis by modifying it in a 3D editor.

    However, you CAN create an empty game object, make the other its child, and then rotate the object inside so that the face you want lines up with the empty's z-axis.
     
  10. windmaomao

    windmaomao

    Joined:
    Jun 11, 2009
    Posts:
    50
    thanks PIA, it worked. The manual should be improved. Still not sure why localScale's x cannot be accessed.

    thanks GargerathSunman for the z-axis thing, I wish this can be documented as well in the unity manual.

    great :)
    Fang
     
  11. motorway

    motorway

    Joined:
    Dec 21, 2008
    Posts:
    47
    Please, help! I've a similar question. I have a cylinder in a scene and want to change its height with the bottom standing at a constant height.
    For ex., I've a cylinder at -3,2,-2 position in the Inspector and scale 1,1,1. So the height is 1 as I see. I want to change this height (y) to some value with the bottom at the same place. How?
     
  12. HiggyB

    HiggyB

    Unity Product Evangelist

    Joined:
    Dec 8, 2006
    Posts:
    6,183
    That's an incorrect statement, it can be "accessed", it's just that you cannot set the x-component individually, you must apply an all new vector for the localScale value. That should be documented, along with some reasoning, but I wanted to clarify that it is possible to access it, just not set it by itself.

    You mean like having entire page dedicated to this topic? How do I fix the rotation of an imported model? :)
     
  13. HiggyB

    HiggyB

    Unity Product Evangelist

    Joined:
    Dec 8, 2006
    Posts:
    6,183
    Scale the model as needed, then adjust its vertical position so the bottom rests in the same place. When doing that note where your model's local origin is, with our default cylinder it's in the middle so if you make the cylinder taller you will need to "raise" the model to keep the base resting on the ground.
     
  14. motorway

    motorway

    Joined:
    Dec 21, 2008
    Posts:
    47
    Nearly this I thought but exactly don't know how.
    Does this
    Code (csharp):
    1. transform.localScale.y=1.5
    mean that cylinder is scaling 1.5 times along y relative to the coords. of its center?
    So it goes up and down from the center?
    And about the position:
    Code (csharp):
    1. cyl.transform.position = Vector3(-1,x, -2);
    means that what goes to this point? The center of cylinder?
     
  15. HiggyB

    HiggyB

    Unity Product Evangelist

    Joined:
    Dec 8, 2006
    Posts:
    6,183
    To stop you, make sure to set localScale as an entire vector value, not just one of its components:

    Code (csharp):
    1. transform.localScale = Vector3(1.0, 1.5, 1.0);

    That means you are scaling the whole model/mesh, and that scaling always happens around the model's own pivot point. So when you scale it by a y-value of 1.5 like that, it will be 1.5 times its original height.


    I don't understand where you got "x" in your calculation above, sorry. :p

    This is all so easy to understand if you take two minutes and go through this visually inside of Unity. Ready? Let's do it...

    First, we have a new default cylinder being viewed from the side. By default a cylinder is 2 units tall and so to get the bottom of the cylinder to rest on my chosen "floor" (the world's x-z plane) it must be at a world position of 0,1,0:


    Now we scale the cylinder by 1.5 in along its y-axis, this will make the cylinder taller and do so around the cylinder's pivot point (thus pushing the bottom of the cylinder below my chosen "floor" as it's now 3 units tall, I added a red line to make the "floor" level easy to spot):


    So to compensate, and keep the cylinder bottom on the "floor" I have to raise it in the y-direction. I know the old height (2.0) and the new height (2.0 x 1.5 = 3.0) and so I apply half the delta ( (3.0 - 2.0) / 2.0 = 0.5) in the y-direction:
     
  16. motorway

    motorway

    Joined:
    Dec 21, 2008
    Posts:
    47
    Thanks, now it is more clear. I thought that cylinder height is 1 by default, because of scale values 1,1,1. So it is 2, now it is better. My respects to you :wink:
     
  17. HiggyB

    HiggyB

    Unity Product Evangelist

    Joined:
    Dec 8, 2006
    Posts:
    6,183
    I'm glad to be of service! :)
     
  18. malcolmr

    malcolmr

    Joined:
    Feb 18, 2010
    Posts:
    51
    Then the documentation on Transform.localScale is wrong: