TheRapidSloth TheRapidSloth - 3 months ago 7
C# Question

How do I create objects in between two points with an offset?

I am wondering on how to do this
in Pic1 SEG3.For example, I know how to do whats in SEG1/SEG2 with this

Vector3 position = controlPoints[i].position + j *(controlPoints[i + 1].position - controlPoints[i].position) / segCount;
(For more about the code visit here its an old question I asked about dividing between two points),

but I want to know how to do this in SEG3(which we'll come around in second). As you can see in SEG2 when I move it, the subPoints will always stay in the center, but I want to know how to move it like in SEG3 so that sub points stay specific distance(int distanceCP) away from the controlPoints, would anyone know how to do this??

Pic1





Here is the code that does SEG1/SEG2.

public class Points : MonoBehaviour
{
public Transform[] points;
public GameObject GameObj;
public float GameObjectAmount = 2;
void Start()
{
duplicateObject(GameObj, (int) GameObjectAmount);
}
public void duplicateObject(GameObject original, int howmany)
{
howmany++;
for (int i = 0; i < points.Length-1; i++)
{
for (int j = 1; j < howmany; j++)
{
Vector3 position = points[i].position + j * (points[i + 1].position - points[i].position) / howmany;
Instantiate(original, position, Quaternion.identity);
}
}
}
}

Answer

This can be done with Unity's Ray API. You can use it to modify both controlPoints.

controlPoint1 = somePos;
controlPoint2 = someOtherPos;

then use Ray's GetPoint function to get the offset of controlPoint1.

var offsetDistance = 5;
Ray myRay= new Ray();
offsetRayFrom.origin = controlPoint1 ;
offsetRayFrom.direction = controlPoint2 - controlPoint1 ;
Vector3 newFromDisance = offsetRayFrom.GetPoint(offsetDistance);
controlPoint1 = newFromDisance; //Change 'From' Distance

Now, do the-same thing to the controlPoint2 position, but flip the origin and direction values, then you can now use those two new values(Vector3) in your for loop.

I couldn't understand your code so I modified my personal position to chunk positions function to include offset parameter. It is commented. You can read the comments to understand what's going on under the hood.

It takes the 2 positions (controlPoint1 and controlPoint2), then a Vector3 array to store the result, followed by chunk amount(howmany), bool to tell it if to use offset or not, then finally the distance offset. I did not make the function return an array. I made it to fill in what array that is passed in to the result parameter. This is good for memory management.

void posToChunkDistances(Vector3 from, Vector3 to, Vector3[] result, int chunkAmount, bool useOffset = false, float offsetDistance = -1f)
{

    //Change from and to values if we want to use offset
    if (useOffset)
    {
        Debug.Log("Use Offset");

        //Un-Comment to Allow negative offset?
        //offsetDistance = Mathf.Abs(offsetDistance);

        //Find new 'From' Distance
        Ray offsetRayFrom = new Ray();
        offsetRayFrom.origin = from;
        offsetRayFrom.direction = to - from;
        Vector3 newFromDisance = offsetRayFrom.GetPoint(offsetDistance);
        from = newFromDisance; //Change 'From' Distance


        //Find new 'To' Distance
        Ray offsetRayTo = new Ray();
        offsetRayTo.origin = to;
        offsetRayTo.direction = from - to;
        Vector3 newToDisance = offsetRayTo.GetPoint(offsetDistance);
        to = newToDisance; //Change 'To' Distance
    }

    //divider must be between 0 and 1
    float divider = 1f / chunkAmount;
    float linear = 0f;

    if (chunkAmount == 0)
    {
        Debug.LogError("chunkAmount Distance must be > 0 instead of " + chunkAmount);
        return;
    }

    if (chunkAmount == 1)
    {
        result[0] = Vector3.Lerp(from, to, 0.5f); //Return half/middle point
        return;
    }

    for (int i = 0; i < chunkAmount; i++)
    {
        if (i == 0)
        {
            linear = divider / 2;
        }
        else
        {
            linear += divider; //Add the divider to it to get the next distance
        }
        // Debug.Log("Loop " + i + ", is " + linear);
        result[i] = Vector3.Lerp(from, to, linear);
    }
}

Usage:

public GameObject testCubePrefab;
public Transform dst1;
public Transform dst2;

void Start()
{
    int myDistances = 2;
    Vector3[] distancesResult = new Vector3[myDistances];
    posToChunkDistances(dst1.position, dst2.position, distancesResult, myDistances, true, 5f);

    for (int i = 0; i < distancesResult.Length; i++)
    {
        Instantiate(testCubePrefab, distancesResult[i], Quaternion.identity);
    }
}