Draw Cylinder Between 2 Points

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

1. 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

Unity Product Evangelist

Joined:
Dec 8, 2006
Posts:
6,185
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!

3. 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

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.

Fang

5. GargerathSunman

Joined:
May 1, 2008
Posts:
1,572
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

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

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

Fang

Joined:
Feb 16, 2009
Posts:
78
9. GargerathSunman

Joined:
May 1, 2008
Posts:
1,572
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

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

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?

Unity Product Evangelist

Joined:
Dec 8, 2006
Posts:
6,185
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?

Unity Product Evangelist

Joined:
Dec 8, 2006
Posts:
6,185
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

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?
Code (csharp):
1. cyl.transform.position = Vector3(-1,x, -2);
means that what goes to this point? The center of cylinder?

Unity Product Evangelist

Joined:
Dec 8, 2006
Posts:
6,185
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.

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

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:

Unity Product Evangelist

Joined:
Dec 8, 2006
Posts:
6,185
I'm glad to be of service!

18. malcolmr

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