Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Swap dots for line

Discussion in 'Scripting' started by davii, Dec 18, 2015.

  1. davii

    davii

    Joined:
    May 9, 2015
    Posts:
    25
    Hey, this script creates a prediction line for a projectile. Very similar to the angry birds prediction line (pull back, dotted prediction line created, let go and the projectile follows the line)

    The prediction line is currently made from dots (as in actual dot images). Could anyone help me in getting this line to not be made from dots, but from just a solid line? The line is already as I want it, I'm just really struggling to figure how to show the line as solid...

    Code (CSharp):
    1.     //Calculate path
    2.     void CalculatePath(){
    3.         Vector2 vel = GetForce(Input.mousePosition) * Time.fixedDeltaTime / GetComponent<Rigidbody2D>().mass;
    4.         for(int i = 0; i < dots; i++){          
    5.             ind[i].GetComponent<Renderer>().enabled = true;
    6.             float t = i/30f;
    7.             Vector3 point = PathPoint(transform.position, vel, t);
    8.             point.z = -1.0f;
    9.             ind[i].transform.position = point;
    10.         }
    11.     }
    12.    
    13.     //Get point position
    14.     Vector2 PathPoint(Vector2 startP, Vector2 startVel, float t){
    15.         return startP + startVel * t;
    16.     }
    17.    
    18.     //Hide all used dots
    19.     void HidePath(){
    20.         for(int i = 0; i<dots; i++)    ind[i].GetComponent<Renderer>().enabled = false;
    21.     }
    22.    
    23.     //Show all used dots
    24.     void ShowPath(){
    25.         for(int i = 0; i<dots; i++) ind[i].GetComponent<Renderer>().enabled = true;
    26.     }
     
  2. larku

    larku

    Joined:
    Mar 14, 2013
    Posts:
    1,422
    You'll get lots of results by google searching for something like: algorithm to reduce the number of points in a curve
     
    davii likes this.
  3. davii

    davii

    Joined:
    May 9, 2015
    Posts:
    25
    But it's not a reduction in dots I'm after, it's to show the line instead of the dots?

    The dots are just put across the curve the script makes, I don't want the dots at all, just some advice on how to have the curve that script creates visible.
     
  4. larku

    larku

    Joined:
    Mar 14, 2013
    Posts:
    1,422
    davii likes this.
  5. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,848
    I'll put in a vote for Vectrosity. We use it in High Frontier for drawing orbit lines, along with a few other things, and it works great. Really top-notch code; I highly recommend it.
     
    davii likes this.
  6. davii

    davii

    Joined:
    May 9, 2015
    Posts:
    25
    I have looked at both of those, however I'm just struggling to apply it to the code above. The LineRenderer looks like exactly what I'm looking for, lets say I wanted this:

    Code (CSharp):
    1.         LineRenderer lineRenderer = gameObject.AddComponent<LineRenderer>();
    2.         lineRenderer.SetColors(c1, c2);
    Does anyone know how to add that to the code I have? I really don't know how to add it to the points I already have?
     
  7. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,848
    The code you have looks like a correct start (you'd put this in CalculatePath). Then you'd need to add calls to SetVertexCount and SetPosition. See the example in the manual.
     
    davii likes this.
  8. davii

    davii

    Joined:
    May 9, 2015
    Posts:
    25
    Okay, my calculatepath now looks like this.

    Code (CSharp):
    1.     void CalculatePath(){
    2.         Vector2 vel = GetForce(Input.mousePosition) * Time.fixedDeltaTime / GetComponent<Rigidbody2D>().mass;
    3.  
    4.         LineRenderer lineRenderer = gameObject.AddComponent<LineRenderer>();
    5.         lineRenderer.SetColors(c1, c2);
    6.         lineRenderer.SetWidth(0.2F, 0.2F);
    7.         lineRenderer.SetVertexCount(lengthOfLineRenderer);
    8.  
    9.         for(int i = 0; i < dots; i++){          
    10.             ind[i].GetComponent<Renderer>().enabled = true;
    11.             float t = i/30f;
    12.             Vector3 point = PathPoint(transform.position, vel, t);
    13.             point.z = -1.0f;
    14.             ind[i].transform.position = point;
    15.         }
    16.     }
    And the manual says to add this to update

    Code (CSharp):
    1.     void Update() {
    2.         LineRenderer lineRenderer = GetComponent<LineRenderer>();
    3.         float t = Time.time;
    4.         int i = 0;
    5.         while (i < lengthOfLineRenderer) {
    6.             Vector3 pos = new Vector3(i * 0.5F, Mathf.Sin(i + t), 0);
    7.             lineRenderer.SetPosition(i, pos);
    8.             i++;
    9.         }
    10.     }
    I got an error saying that the game object didn't have a line render, so I added one, and now it's giving me the following errors.

    LineRenderer.SetPosition index out of bounds!
    UnityEngine.LineRenderer:SetPosition(Int32, Vector3)
    ballshot:Update() (at Assets/scripts/in_game/ballshot.cs:59)

    NullReferenceException: Object reference not set to an instance of an object
    ballshot.CalculatePath () (at Assets/scripts/in_game/ballshot.cs:142)
    ballshot.Aim () (at Assets/scripts/in_game/ballshot.cs:94)
    ballshot.Update () (at Assets/scripts/in_game/ballshot.cs:64)

    ullReferenceException: Object reference not set to an instance of an object
    ballshot.CalculatePath () (at Assets/scripts/in_game/ballshot.cs:142)
    ballshot.Aim () (at Assets/scripts/in_game/ballshot.cs:98)
    ballshot.Update () (at Assets/scripts/in_game/ballshot.cs:64)

    Full code

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using System.Linq;
    5.  
    6.  
    7. public class ballshot : MonoBehaviour
    8. {
    9.     public float power = 1.0f;
    10.     public float sensitivity = 0.2f;
    11.     public float life = 2.0f, cooldown = 1.0f;
    12.     public float dead_sens = 25f;
    13.    
    14.     public int dots = 20;
    15.     public float interval = 1/30.0f;
    16.    
    17.     private Vector3 startPos;  
    18.     private bool shot = false, aiming = false, hit_ground = false;  
    19.    
    20. //    public GameObject shadow, shad;
    21.     private GameObject Dots;
    22.     private List<GameObject> ind;
    23.     private scoreScript scoreScript;
    24.  
    25.  
    26.     public Color c1 = Color.yellow;
    27.     public Color c2 = Color.red;
    28.     public int lengthOfLineRenderer = 20;
    29.  
    30.  
    31.     // Use this for initialization
    32.     void Start (){
    33.     //    shadow = (GameObject) Instantiate(shadow);
    34.         scoreScript = GameObject.Find("scoreScript").GetComponent<scoreScript>();
    35.         //power = GameObject.Find("gameScript").GetComponent<gameScript>().power;
    36.        
    37.         dots = dots - GameObject.Find("gameScript").GetComponent<gameScript>().round;
    38.         if(dots < 5)
    39.             dots = 5;
    40.         Dots = GameObject.Find("dots");
    41.         transform.GetComponent<Rigidbody2D>().isKinematic = true;
    42.         transform.GetComponent<Collider2D>().enabled = false;
    43.         startPos = transform.position;
    44.         ind = Dots.transform.Cast<Transform>().ToList().ConvertAll(t => t.gameObject);
    45.         for(int i = 0; i<dots; i++){
    46.             ind[i].GetComponent<Renderer>().enabled = false;
    47.         }
    48.     }
    49.  
    50.     // Update is called once per frame
    51.    
    52.     void Update (){
    53.     //    shadow.transform.position = new Vector3(gameObject.transform.position.x, shadow.transform.position.y, gameObject.transform.position.z);
    54.         LineRenderer lineRenderer = GetComponent<LineRenderer>();
    55.         float t = Time.time;
    56.         int i = 0;
    57.         while (i < lengthOfLineRenderer) {
    58.             Vector3 pos = new Vector3(i * 0.5F, Mathf.Sin(i + t), 0);
    59.             lineRenderer.SetPosition(i, pos);
    60.             i++;
    61.         }
    62.  
    63.        
    64.         Aim();
    65.         if(hit_ground){
    66.             if(life<=0){
    67.                 Destroy(gameObject);
    68.                 //Destroy(shadow);
    69.                 scoreScript.DestroyedBall(gameObject);
    70.             }
    71.             else if(life>0){
    72.                 life -= Time.deltaTime;
    73.                 Color startColor = GetComponent<Renderer>().material.GetColor("_Color");              
    74.                 GetComponent<Renderer>().material.SetColor("_Color", new Color(startColor.r, startColor.g, startColor.b, life));
    75.             //    shadow.GetComponent<Renderer>().material.SetColor("_Color", new Color(startColor.r, startColor.g, startColor.b, life));
    76.             }
    77.         }
    78.     }
    79.    
    80.     //Collisions
    81.     void OnCollisionEnter2D(Collision2D other){
    82.         if(other.gameObject.tag == "Floor"){
    83.             hit_ground = true;      
    84.         }
    85.     }
    86.    
    87.    
    88.     void Aim(){
    89.         if(shot) return;
    90.         if(Input.GetAxis("Fire1") == 1){
    91.             if(!aiming){
    92.                 aiming = true;
    93.                 startPos = Input.mousePosition;
    94.                 CalculatePath();
    95.                 ShowPath();
    96.             }
    97.             else{
    98.                 CalculatePath();
    99.             }      
    100.         }
    101.         else if(aiming && !shot){
    102.             if(inDeadZone(Input.mousePosition) || inReleaseZone(Input.mousePosition)){
    103.                 aiming = false;
    104.                 HidePath();
    105.                 return;
    106.             }
    107.             transform.GetComponent<Rigidbody2D>().isKinematic =  false;          
    108.             transform.GetComponent<Collider2D>().enabled = true;
    109.             transform.GetComponent<Rigidbody2D>().AddForce(GetForce(Input.mousePosition));      
    110.             shot = true;
    111.             aiming = false;
    112.             scoreScript.Shot();
    113.             HidePath();
    114.         }
    115.     }
    116.    
    117.     Vector2 GetForce(Vector3 mouse){
    118.         return (new Vector2(startPos.x, startPos.y)- new Vector2(mouse.x, mouse.y))*power;
    119.        
    120.     }
    121.    
    122.     bool inDeadZone(Vector2 mouse){
    123.         if(Mathf.Abs(startPos.x - mouse.x) <= dead_sens && Mathf.Abs(startPos.y - mouse.y) <= dead_sens)
    124.              return true;
    125.         return false;
    126.     }
    127.     bool inReleaseZone(Vector2 mouse){
    128.         if(mouse.x <= 0)
    129.             return true;
    130.            
    131.         return false;
    132.     }
    133.    
    134.     //
    135.     /*  Path and dots */
    136.     //
    137.     //Calculate path
    138.     void CalculatePath(){
    139.         Vector2 vel = GetForce(Input.mousePosition) * Time.fixedDeltaTime / GetComponent<Rigidbody2D>().mass;
    140.  
    141.         LineRenderer lineRenderer = gameObject.AddComponent<LineRenderer>();
    142.         lineRenderer.SetColors(c1, c2);
    143.         lineRenderer.SetWidth(0.2F, 0.2F);
    144.         lineRenderer.SetVertexCount(lengthOfLineRenderer);
    145.  
    146.         for(int i = 0; i < dots; i++){          
    147.             ind[i].GetComponent<Renderer>().enabled = true;
    148.             float t = i/30f;
    149.             Vector3 point = PathPoint(transform.position, vel, t);
    150.             point.z = -1.0f;
    151.             ind[i].transform.position = point;
    152.         }
    153.     }
    154.  
    155.  
    156.    
    157.     //Get point position
    158.     Vector2 PathPoint(Vector2 startP, Vector2 startVel, float t){
    159.         //return startP + startVel * t + 0.5f * Physics2D.gravity * t * t;
    160.         return startP + startVel * t;
    161.     }
    162.    
    163.     //Hide all used dots
    164.     void HidePath(){
    165.         for(int i = 0; i<dots; i++)    ind[i].GetComponent<Renderer>().enabled = false;
    166.     }
    167.    
    168.     //Show all used dots
    169.     void ShowPath(){
    170.         for(int i = 0; i<dots; i++) ind[i].GetComponent<Renderer>().enabled = true;
    171.     }
    172. }
    173.  
    I'm gonna try and fix the errors, but I really don't understand this code at all. I may look for an easier solution :| Thanks for any help though.
     
  9. JonathanMulvaney

    JonathanMulvaney

    Joined:
    Sep 23, 2012
    Posts:
    8
    Hi davii,
    These guys have a couple of great videos about creating a projectile path using the lineRenderer:

    Part 1 -- Breakfast With Unity: Projectile Path


    Part 2 -- Breakfast With Unity: Projectile Path


    I'm not sure if it is exactly what you are looking for, but I hope it helps a bit.

    -Jonathan