1
\$\begingroup\$

I found this tutorial on youtube and it works pretty well, but I want to add more to it.

How can I draw a smooth arc path in the game view (right now the path is only visible in the editor)?

Here is the code:

public class BallLauncher : MonoBehaviour 
{

    public Rigidbody ball;
    public Transform target;

    public float h = 25;
    public float gravity = -18;

    public bool debugPath;

    void Start() {
        ball.useGravity = false;
    }

    void Update() {
        if (Input.GetKeyDown (KeyCode.Space)) {
            Launch ();
        }

        if (debugPath) {
            DrawPath ();
        }
    }

    void Launch() {
        Physics.gravity = Vector3.up * gravity;
        ball.useGravity = true;
        ball.velocity = CalculateLaunchData ().initialVelocity;
    }

    LaunchData CalculateLaunchData() {
        float displacementY = target.position.y - ball.position.y;
        Vector3 displacementXZ = new Vector3 (target.position.x - ball.position.x, 0, target.position.z - ball.position.z);
        float time = Mathf.Sqrt(-2*h/gravity) + Mathf.Sqrt(2*(displacementY - h)/gravity);
        Vector3 velocityY = Vector3.up * Mathf.Sqrt (-2 * gravity * h);
        Vector3 velocityXZ = displacementXZ / time;

        return new LaunchData(velocityXZ + velocityY * -Mathf.Sign(gravity), time);
    }

    void DrawPath() {
        LaunchData launchData = CalculateLaunchData ();
        Vector3 previousDrawPoint = ball.position;

        int resolution = 30;
        for (int i = 1; i <= resolution; i++) {
            float simulationTime = i / (float)resolution * launchData.timeToTarget;
            Vector3 displacement = launchData.initialVelocity * simulationTime + Vector3.up *gravity * simulationTime * simulationTime / 2f;
            Vector3 drawPoint = ball.position + displacement;
            Debug.DrawLine (previousDrawPoint, drawPoint, Color.green);
            previousDrawPoint = drawPoint;
        }
    }

    struct LaunchData {
        public readonly Vector3 initialVelocity;
        public readonly float timeToTarget;

        public LaunchData (Vector3 initialVelocity, float timeToTarget)
        {
            this.initialVelocity = initialVelocity;
            this.timeToTarget = timeToTarget;
        }

    }
}

I found a way to Instantiate projectile along the path. Now I just need to know how to convert that line in debug mode to make it visible in game mode

\$\endgroup\$
  • \$\begingroup\$ Debug.DrawLine as the name says, only draws the lines in debug mode (editor). Use the linerenderer, \$\endgroup\$ – Bálint May 28 at 14:52
  • \$\begingroup\$ @Bálint with a little guidance about how to convert the DrawLine code to LineRenderer, this could make a solid answer. :) \$\endgroup\$ – DMGregory May 28 at 14:58
  • \$\begingroup\$ ok, so you think i should make another post for instantiate projectiles along that path? \$\endgroup\$ – h00man13 May 28 at 16:57
  • 1
    \$\begingroup\$ @DMGregory I have 0 experience with the line renderer apart from knowing it exists. I posted the comment to 1.) nudge future answerers in a direction and 2.) make sure OP either doesn't know about line renderers or can't use them yet. Although here it's unlikely, it can usually help rule out the most obvious solutions in case they can't use them for some reason \$\endgroup\$ – Bálint May 28 at 23:15
0
\$\begingroup\$

This draws a lineRenderer instead of Debug:

public Rigidbody ball;
public Transform target;
public float h = 25;
public float gravity = -18;

public bool debugPath;

// Added Code 
public LineRenderer lineRenderer;

void Start() {
    ball.useGravity = false;

    // Added Code 
    lineRenderer.transform.position = ball.transform.position;
}

void Update() {
    if (Input.GetKeyDown (KeyCode.Space)) {
        Launch ();
    }
    if(debugPath)
        DrawPath ();
}

void Launch() {
    Physics.gravity = Vector3.up * gravity;
    ball.useGravity = true;
    ball.velocity = CalculateLaunchData ().initialVelocity;
}

LaunchData CalculateLaunchData() {
    float displacementY = target.position.y - ball.position.y;
    Vector3 displacementXZ = new Vector3 (target.position.x - ball.position.x, 0, target.position.z - ball.position.z);
    float time = Mathf.Sqrt(-2*h/gravity) + Mathf.Sqrt(2*(displacementY - h)/gravity);
    Vector3 velocityY = Vector3.up * Mathf.Sqrt (-2 * gravity * h);
    Vector3 velocityXZ = displacementXZ / time;

    return new LaunchData(velocityXZ + velocityY * -Mathf.Sign(gravity), time);
}

void DrawPath() {
    LaunchData launchData = CalculateLaunchData ();

    // Added Code 
    lineRenderer.positionCount = 1;
    lineRenderer.SetPosition(0, ball.position);


    int resolution = 30;
    for (int i = 1; i <= resolution; i++) {
        float simulationTime = i / (float)resolution * launchData.timeToTarget;
        Vector3 displacement = launchData.initialVelocity * simulationTime + Vector3.up *gravity * simulationTime * simulationTime / 2f;
        Vector3 drawPoint = ball.position + displacement;

        // Added Code 
        lineRenderer.positionCount ++;
        lineRenderer.SetPosition(lineRenderer.positionCount-1, drawPoint);
    }
}

struct LaunchData {
    public readonly Vector3 initialVelocity;
    public readonly float timeToTarget;

    public LaunchData (Vector3 initialVelocity, float timeToTarget)
    {
        this.initialVelocity = initialVelocity;
        this.timeToTarget = timeToTarget;
    }

}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.