0

I'm a little stuck. I'm trying to draw a cylinder between two spheres while keeping its size always the same on the Z axis in Game View. The aim is to get a collider around the gizmos line by turning off the cylinder's Mesh Renderer to make it invisible. It would also be good to replace the Gizmos line with a LineRenderer but I would always need it to be the same size as the sphere on both sides.

enter image description here

This is my code:

GameObject newSphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);
// currentPosPoint = mouse click
newSphere.transform.position = currentPosPoint; 
// this way all the spheres appear of the same size even if in a different position on the Z axis
newSphere.transform.localScale = Vector3.one * ((new Plane(cam.transform.forward, 
                                                           cam.transform.position).GetDistanceToPoint(
                                                           newSphere.transform.position)) / radiusPoint);
// if the sphere is not the first
if (count > 1) {
    Vector3 start = posSphere1;
    Vector3 end = posSphere2;
    GameObject newCyl = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
    // I find the central position between the two spheres
    Vector3 pos = Vector3.Lerp(start, end, 0.5f);
    newCyl.transform.position = pos;
    // I find the rotation of the cylinder
    Vector3 dirV = Vector3.Normalize(end - start);
    Vector3 cylDefaultOrientation = new Vector3(0,1,0);
    Vector3 rotAxisV = dirV + cylDefaultOrientation;
    rotAxisV = Vector3.Normalize(rotAxisV);
    newCyl.transform.rotation = new Quaternion(rotAxisV.x, rotAxisV.y, rotAxisV.z, 0);
    float dist = Vector3.Distance(end, start);
    // it is from this point that I cannot get out of it
    // I resize the cylinder like the sphere
    newCyl.transform.localScale = Vector3.one * ((new Plane(cam.transform.forward, 
                                                            cam.transform.position).GetDistanceToPoint(
                                                            newCyl.transform.position)) / radiusPoint);
    // I assign the length of the cylinder to join its two ends to the spheres
    Vector3 newScale = newCyl.transform.localScale;
    newScale.y= dist/2;
    newCyl.transform.localScale = newScale;      
}

As you can see the cylinders are the same size as the sphere only if they are oriented on the X axis.

Do you have any suggestions to always get the same size of cylinders? As I said it is not needed to use cylinders, the target is to get a collider around the gizmos line, any change would be good.

  • The cylinders are the same size as the ball in the back... They can't be the same size as both balls because the balls are different sizes... If you want the balls to actually be the same size and also look like they are the same size, is there a reason you don't make your camera `orthographic` ? – Ruzihm May 17 '19 at 16:38
  • If you really need to use a `perspective` camera with different size spheres, you'll want to make a *procedural mesh* of a truncated cone going between the spheres. [this question](https://stackoverflow.com/questions/33612439/drawing-3d-polygon-on-unity-3d/36718553) might help you. – Ruzihm May 17 '19 at 17:29
  • Thanks, creating meshes would use too many resources as the spheres can be moved and at each new position the mesh should be recreated on the fly. Perhaps it would be better to use LineRenderer to join the spheres, something I have already tried, but with it I would have to resize startWidth and endWidth to get apparently the same dimensions at the extremes. I found a lot of discussion about it but none really resolved. Do you have any links to suggest or do you think of any approach to it? –  May 17 '19 at 17:47

1 Answers1

1

Use an object with a LineRenderer, and set the start/endwidth based on the start and end positions.

GameObject go = new GameObject("LineRenderer Object")
LineRenderer lr = go.AddComponent<LineRenderer>() as LineRenderer;

Vector3 start = posSphere1;
Vector3 end = posSphere2;

Plane camPlane = new Plane(cam.transform.forward, cam.transform.position)

float startWidth = camPlane.GetDistanceToPoint(start)) / radiusPoint);
float endWidth = camPlane.GetDistanceToPoint(end)) / radiusPoint);

// Make sure line renderer width curve is linear
lr.widthCurve = AnimationCurve.Linear(0f, startWidth , 1f, endWidth);

Make sure you put the GameObject somewhere like in an array so you can Destroy it.

Ruzihm
  • 19,749
  • 5
  • 36
  • 48
  • 1
    Thanks for your sharing, great. An observation, the setting of the last line "lr.widthCurve" would seem wrong, leaving it the line is triangular, commenting it everything is fine. I looked at the manual but it still unclear, I have to go deeper. –  May 17 '19 at 19:57
  • @valter Ah, I see. The guide I was following wasn't clear. I edited my answer. See if that works for you. – Ruzihm May 17 '19 at 20:09