- Home /
Other, I found another answer to the question
Generating lines between procedurally instantiated gameobjects, within a certain radius
Hello, I'm attempting to use linerenderer or Debug.Drawline to "connect" GameObjects that are randomly placed near each other. I am not sure how to make this work, as I am not sure if Physics.OverlapSphere or Physics.SphereCast should be used to find the locations of the nearby game objects. Below is my script for the instantiation and the attempt at line drawing that is not working.
These are my functions: (CreateStar selects the prefab to be instantiated, StarGen find the position and places the star, and CreateTravelRoutes is supposed to connect nearby stars to each other) I can't get this last function to work. Any help would be greatly appreciated!!
GameObject CreateStar(Star starData, Vector3 starPos)
{
float starGenPercentage = Random.value;
if (starGenPercentage <= .1)
{
GameObject starObj = Instantiate(starM);
starObj.name = starData.starName;
starObj.transform.position = starPos;
return starObj;
}
else if (starGenPercentage > .1 && starGenPercentage <= .55)
{
GameObject starObj = Instantiate(starK);
starObj.name = starData.starName;
starObj.transform.position = starPos;
return starObj;
}
else if (starGenPercentage > .55 && starGenPercentage <= .70)
{
GameObject starObj = Instantiate(starF);
starObj.name = starData.starName;
starObj.transform.position = starPos;
return starObj;
}
else if (starGenPercentage > .70 && starGenPercentage <= .85)
{
GameObject starObj = Instantiate(starG);
starObj.name = starData.starName;
starObj.transform.position = starPos;
return starObj;
}
else if (starGenPercentage > .85 && starGenPercentage <= .95)
{
GameObject starObj = Instantiate(starA);
starObj.name = starData.starName;
starObj.transform.position = starPos;
return starObj;
}
else
{
GameObject starObj = Instantiate(starB);
starObj.name = starData.starName;
starObj.transform.position = starPos;
return starObj;
}
}
public void StarGen()
{
int failCount = 0;
float mapLength = mapDimensions;
float mapHeight = mapDimensions;
float mapDepth = mapDimensions;
for (int i = 0; i < starCount; i++)
{
//Giving stars names upon generation
Star starData = new Star("Star" + i, Random.Range(1, 10));
Debug.Log("Created " + starData.starName + " with " + starData.planetCount + " number of planets.");
//Generating Star Positions, based on a center point of (0,0,0)
Vector3 starPos = new Vector3(Random.Range(-mapLength / 2, mapLength / 2), Random.Range(-mapHeight / 2, mapHeight / 2), Random.Range(-mapDepth / 2, mapDepth / 2));
//Setting a collider to be used so that stars are not generated on top of each other
Collider[] posCollider = Physics.OverlapSphere(starPos, minStarDist);
if (posCollider.Length == 0)
{
GameObject starObj = CreateStar(starData, starPos);
CreateTravelRoutes(starPos);
starList.Add(starObj);
}
else
{
i--;
failCount++;
}
if (failCount > starCount)
{
break;
}
}
}
void CreateTravelRoutes(Vector3 starPos)
{
List<GameObject> starsList = starList;
Transform origin;
Transform destination;
foreach (GameObject starObj in starsList)
{
if (Physics.SphereCast(starObj.transform.position, maxTravelDist, transform.forward, out RaycastHit hit, 0.1f) == true)
{
origin = starObj.transform;
destination = hit.rigidbody.gameObject.transform;
Debug.DrawLine(origin.position, destination.position, Color.white, 100);
//LineRenderer lineRenderer = GetComponent<LineRenderer>();
//lineRenderer.SetPosition(0, origin.position);
//lineRenderer.SetPosition(1, destination.position);
}
}
}
Answer by unity_ek98vnTRplGj8Q · Jul 10, 2020 at 09:52 PM
I would recommend using OverlapSphere because it will give you all colliders in the radius you give it which is what you want. I also recommend using a LineRenderer, since Debug.DrawLine will only show up in the editor scene view and not in your game view (unless this is what you want of course).
Here's a basic function that should do what you want, let me know if this works for you I haven't tested it
void CreateTravelRoutes (GameObject thisStar) {
//Pass in the star game object that you are checking
//I also recommend putting all your stars in a unique layer for efficiency
//and to make sure you don't detect any non star objects
Collider[] starsInRadius = Physics.OverlapSphere (thisStar.transform.position, maxTravelDist, starLayerMask);
foreach(Collider c in starsInRadius){
//Don't draw a line to the same star that you are checking
if(c.gameObject == thisStar) continue;
//Make a new line renderer for each path since you may have multiple per star
LineRenderer lr = thisStar.AddComponent(typeof(LineRenderer)) as LineRenderer;
lr.positionCount = 2;
lr.SetPosition(0, thisStar.transform.position);
lr.SetPosition(1, c.gameObject.transform.position);
}
}
So I tried it, and it didn't draw any lines. Do I need to find a way to call the draw line function in the update function? Currently the StarGen function calls the others, would this create the line in the start frame and then it goes away for every other frame?
Also does:`Layer$$anonymous$$ask starLayer$$anonymous$$ask = Layer$$anonymous$$ask.Get$$anonymous$$ask("Star");` Work for the layermask?
Yea that should be fine for the layer mask, as long as the layer name that they are in is exactly "Star". No you shouldn't have to do anything in the update function (unless the stars are moving, in which case you need to update the positions of the lines). One the line renderer is created it will stay active and visible. I would look at your stars and see if the line renderers are on them and if they have points set (this can all be checked in the inspector). I would also put some Debug.Log() statements in this function to see if it is correctly seeing the other stars. If it isn't try removing the layer mask paramerter from OverlapSphere.
Hey thanks for the response! I really appreciate the help, haven't been able to get it working though. Eventually! lol Thanks for pointing me in the right direction though
I checked the prefabs and they all have the linerenderer, and there's no positions set for them in the inspector, so then unless there's an issue reassigning the prefab as starObj it should still be there right?
A debug statement like Debug.Log("Detected " + starsInRadius.Length + "stars within travel radius")
Sorry for the late reply, but yes something like that would be good. Also you don't need to have the line renderer on the prefab, this script will place the line renderer on the stars that need it. If you already have a linerenderer on the prefab, then this script will still add an additional line renderer, so if you don't see that then its likely that its not detecting the stars in the radius. Have you tried removing the layer mask to see if that is the issue?
Thanks for the reply, sorry for my late response I was away from my computer for a while. I added in a bunch of checks and updated the code a bit. I did try removing the layer mask, which wasn't the issue. I switched to instead of trying to detect nearby objects, just putting all the stars into an array, generating a vector3 positions array, and then drawing lines to each star positions within a certain distance. As of now I'm not sure if it works because it is taking a VERY long time to load, so I likely need to adjust the code somehow. I will probably post another question with the updated code.