How to extend diagonal line renderer line over a certain duration

Viewed 814

I created a diagonal line renderer by attaching the following script to an empty game object. How can I extend the line at both ends for a half its length and how can I also extend the line by say 1 unit along the x-axis? Both over a certain period of time.

public class DiagonalLine : MonoBehaviour {

bool firstLineComplete = false;
LineRenderer diagLine;

public Vector3 startPoint = new Vector3 (0, 0, 0);
public Vector3 endPoint = new Vector3 (1.0f, 1.0f, 0);

public float lineDrawSpeed;
// Use this for initialization
void Start () {

    diagLine = gameObject.AddComponent<LineRenderer>();
    diagLine.material = new Material (Shader.Find ("Sprites/Default"));
    diagLine.startColor = diagLine.endColor = Color.green;
    diagLine.startWidth = diagLine.endWidth = 0.15f;

    diagLine.SetPosition (0, startPoint);
    diagLine.SetPosition (1, endPoint);

    }
}

enter image description here

2 Answers

This is basic vector math.

You have the line with (from end to start):

 Vector3 v = start - end;

and then you extend on each side by half if it:

 extensionA = start + (v * 0.5f);
 extensionB = end + (v * -0.5f);

If you need to extend by 1 then normalize:

 Vector3 v = (start - end).normalized;
 extensionA = start + v;
 extensionB = end + (v * -1f);

Break your problem into pieces:

1.Extend line by x units on both sides:

This is done with the Ray class. Create a new Ray instance from the startPoint and endPoint variables then use the Ray.GetPoint function to extend the line. You have to do this on both sides to get the new extended lines.

A simple wrapper for the Ray class to simplify this:

Vector3 extendLine(Vector3 startPoint, Vector3 endPoint, ExtendDirection extendDirection, float extendDistance)
{
    Ray ray = new Ray();

    //Start
    if (extendDirection == ExtendDirection.START_POINT)
    {
        ray.origin = startPoint;
        ray.direction = startPoint - endPoint;
    }

    //End
    else if (extendDirection == ExtendDirection.END_POINT)
    {
        ray.origin = endPoint;
        ray.direction = endPoint - startPoint;
    }

    //Extend
    Vector3 newUnityPoint = ray.GetPoint(extendDistance);
    //Debug.DrawLine(ray.origin, newUnityPoint, Color.blue);
    return newUnityPoint;
}

public enum ExtendDirection
{
    START_POINT, END_POINT
}

Extend to the Left end

Vector3 newStartPos = extendLine(startPoint, endPoint, ExtendDirection.START_POINT, 4);
diagLine.SetPosition(0, newStartPos);

Extend to the Right end

Vector3 newEndPos = extendLine(startPoint, endPoint, ExtendDirection.END_POINT, 4);
diagLine.SetPosition(1, newEndPos);

2.For animating/moving it over time, use coroutine and Time.deltaTime. Increment a variable with Time.deltaTime every frame to then use Vector3.Lerp to lerp the from and to value.

See this function for example.

With both combined, below is a complete function to extend both lines over time:

bool isRunning = false;

IEnumerator extentLineOverTime(LineRenderer targetLineRenderer, float extendDistance, float duration)
{
    //Calculate Left from extension length
    Vector3 fromValLeftPos = targetLineRenderer.GetPosition(0);
    //Calculate Right from extension length
    Vector3 fromValRightPos = targetLineRenderer.GetPosition(1);

    //Calculate Left to extension length
    Vector3 newLeftPos = extendLine(fromValLeftPos, fromValRightPos, ExtendDirection.START_POINT, extendDistance);
    //Calculate Right to extension length
    Vector3 newRightPos = extendLine(fromValLeftPos, fromValRightPos, ExtendDirection.END_POINT, extendDistance);

    //Make sure there is only one instance of this function running
    if (isRunning)
    {
        yield break; ///exit if this is still running
    }
    isRunning = true;

    float counter = 0;


    while (counter < duration)
    {
        counter += Time.deltaTime;

        //Move to left overtime
        Vector3 tempLeftPos = Vector3.Lerp(fromValLeftPos, newLeftPos, counter / duration);
        targetLineRenderer.SetPosition(0, tempLeftPos);

        //Move to Right overtime
        Vector3 tempRightPos = Vector3.Lerp(fromValRightPos, newRightPos, counter / duration);
        targetLineRenderer.SetPosition(1, tempRightPos);

        yield return null;
    }
    isRunning = false;
}

USAGE:

LineRenderer diagLine;

public Vector3 startPoint = new Vector3(0, 0, 0);
public Vector3 endPoint = new Vector3(1.0f, 1.0f, 0);

// Use this for initialization
void Start()
{
    diagLine = gameObject.AddComponent<LineRenderer>();
    diagLine.material = new Material(Shader.Find("Sprites/Default"));
    diagLine.startColor = diagLine.endColor = Color.green;
    diagLine.startWidth = diagLine.endWidth = 0.15f;

    diagLine.SetPosition(0, startPoint);
    diagLine.SetPosition(1, endPoint);

    //Extend Line Over time
    StartCoroutine(extentLineOverTime(diagLine, 4, 3));
}

The StartCoroutine(extentLineOverTime(diagLine, 4, 3)); will extend the line 4 units away from both sides within 3 seconds.

Related