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

instantiate along a line while dragging

Discussion in 'Scripting' started by glebski, Aug 16, 2013.

  1. glebski

    glebski

    Joined:
    Nov 21, 2009
    Posts:
    367
    Hi

    I am trying to create a wall made from cubes during game play. A user clicks mouse on screen to set the initial position, then drags and releases at the end position. My script at the moment creates the first and last prefab as well as a prefab at the midpoint between the two. The first prefab appears as expected. The midpoint and last prefab appear after I release and click the button again. (also three more prefabs are created on second click). What I would like is to see all prefabs as they change position in order to visualize their placement as I hold the button down and drag.

    Thanks

    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class instance : MonoBehaviour {
    5.  
    6. public GameObject myPrefab;
    7.  
    8. public Vector3 startPoint;
    9. public Vector3 midPoint;
    10. public Vector3 endPoint;
    11.  
    12.     void Start () {
    13.    
    14.     }  
    15.  
    16. void Update () {
    17.  
    18.        if ( Input.GetMouseButtonDown(0) ) {
    19.        
    20.         startPoint = Input.mousePosition;
    21.         startPoint.z = 1.0f;
    22.         Make();
    23.  
    24.        }
    25.          if ( Input.GetMouseButton(0) ) {
    26.                    
    27.          endPoint = Input.mousePosition;
    28.          endPoint.z = 1.0f;
    29.          midPoint = (endPoint-startPoint)/2.0f + startPoint;
    30.          midPoint.z = 1.0f;
    31.          
    32.        }
    33. }
    34. void Make () {
    35.              
    36.     Vector3 startPos = Camera.main.ScreenToWorldPoint(startPoint);
    37.     Vector3 midPos = Camera.main.ScreenToWorldPoint(midPoint);
    38.     Vector3 endPos = Camera.main.ScreenToWorldPoint(endPoint);
    39.              
    40. Instantiate(myPrefab, startPos, Quaternion.identity);
    41. Instantiate(myPrefab, midPos, Quaternion.identity);
    42. Instantiate(myPrefab, endPos, Quaternion.identity);
    43. }
    44. }
     
  2. glebski

    glebski

    Joined:
    Nov 21, 2009
    Posts:
    367
    For anyone who is interested, this is how I did it. Works as expected now. Creating three blocks at start, midpoint and end. Now the NEXT STEP is this... How do I fill the created line with cubes, or any other prefab so they don't overlap? I know the distance between start point and end point and can round it up or down. I know the dimensions of the cube or other prefab. Instead of instantiating one object at midpoint I can divide the distance by prefab width. That would give me the number of prefabs to create, but then how do I space them along the line?

    Thanks for any help.

    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class instance : MonoBehaviour {
    5.  
    6. public GameObject myPrefab;
    7. public Vector3 startPoint;
    8. public Vector3 midPoint;
    9. public Vector3 endPoint;
    10. public float mouseDistance;
    11. public bool trackMouse = false;
    12. private GameObject endBlock;
    13. private GameObject midBlock;
    14. private GameObject startBlock;
    15.  
    16. void Update () {
    17.        
    18.        Vector3 startPos = Camera.main.ScreenToWorldPoint(startPoint);
    19.        Vector3 endPos = Camera.main.ScreenToWorldPoint(endPoint);
    20.        Vector3 midPos = Camera.main.ScreenToWorldPoint(midPoint);
    21.  
    22.        if (Input.GetMouseButtonDown(0)) {
    23.         startBlock = (GameObject) Instantiate(myPrefab, startPos, Quaternion.identity);
    24.         midBlock = (GameObject) Instantiate(myPrefab, midPos, Quaternion.identity);
    25.         endBlock = (GameObject) Instantiate(myPrefab, endPos, Quaternion.identity);
    26.         startPoint = Input.mousePosition;
    27.         startPoint.z = 1.0f;
    28.         trackMouse = true;
    29.        }
    30.        
    31.         if (Input.GetMouseButtonUp(0)) {
    32.         trackMouse = false;
    33.         mouseDistance = 0;
    34.         }
    35.        
    36.         if (trackMouse){
    37.         startBlock.transform.position = startPos;
    38.         midBlock.transform.position = midPos;
    39.         endBlock.transform.position = endPos;
    40.         endPoint = Input.mousePosition;
    41.         endPoint.z = 1.0f;
    42.         midPoint = (endPoint-startPoint)/2.0f + startPoint;
    43.         midPoint.z = 1.0f;
    44.         mouseDistance = (endPoint - startPoint).magnitude;
    45.         }    
    46.     }
    47. }
     
  3. hpjohn

    hpjohn

    Joined:
    Aug 14, 2012
    Posts:
    2,190
    Amazing
    Copied from my post from just 14 hours ago
     
  4. glebski

    glebski

    Joined:
    Nov 21, 2009
    Posts:
    367
    I suppose I need to make an array to which game objects need to be added as distance increases and remove them from the array if distance shrinks. Then update the position of each object in the array while the mouse is being dragged. I haven't done much array stuff that can dynamically change size like that, plus having the objects within it updating too. Any help with logic would be appreciated. Thank you.
     
  5. glebski

    glebski

    Joined:
    Nov 21, 2009
    Posts:
    367
    I've done it! Well... to a point. I used a Bresenham Line drawing algorithm I got from wikipedia.
    Now I can build a line from prefabs. Still have a few questions. At the moment I am creating and destroying the prefabs, which I am told is a slow process. How do I speed it up?
    Secondly, I would like the line to be persistent, so I can draw one line and it remains on screen when I draw a new one. Because I'm destroying objects with tag "lines", which is what the prefab is tagged as, should I change the tag once I create the line?
    Thirdly, I would like the lines to maintain editability, so if I click on the end block, I can change the line again. Or delete it all together.

    Anyway, here is the code. Someone may find it useful.

    Code (csharp):
    1. public var myPrefab : GameObject;
    2. private var startPoint : Vector3;
    3. private var endPoint : Vector3;
    4. public var startPos : Vector3;
    5. public var endPos : Vector3;
    6.  
    7. function Update() {
    8.     startPos = Camera.main.ScreenToWorldPoint(startPoint);
    9.     endPos = Camera.main.ScreenToWorldPoint(endPoint);
    10.  
    11.     if (Input.GetMouseButtonDown(0)) {
    12.                 startPoint = Input.mousePosition;
    13.                 startPoint.z = -12.0f;
    14.     }
    15.     if (Input.GetMouseButton(0)) {
    16.                 endPoint = Input.mousePosition;
    17.                 endPoint.z = -12.0f;
    18.                 myPoints = GameObject.FindGameObjectsWithTag("lines");
    19.                 for (points in myPoints) {
    20.                 Destroy(points);
    21.                 }
    22.     drawLine(startPos.x,startPos.y,endPos.x,endPos.y);
    23.     }              
    24. }
    25.        
    26.  function drawLine(x0:int, y0:int, x1:int, y1:int)
    27.  {
    28.     dx= Mathf.Abs(x1-x0);
    29.     dy= Mathf.Abs(y1-y0);
    30.     if (x0 < x1) {sx=1;}else{sx=-1;}
    31.     if (y0 < y1) {sy=1;}else{sy=-1;}
    32.     err=dx-dy;
    33.     loop = true;
    34.    
    35.     while (loop) {
    36.          Instantiate(myPrefab, Vector3(x0, y0, -12), Quaternion.identity);
    37.          if ((x0 == x1)  (y0 == y1)) loop=false;
    38.          e2 = 2*err;
    39.          if (e2 > -dy) {
    40.            err = err - dy;
    41.            x0 = x0 + sx;
    42.          }
    43.          if (e2 <  dx) {
    44.            err = err + dx;
    45.            y0 = y0 + sy;
    46.         }
    47.     }
    48. }
     
    Last edited: Aug 23, 2013
  6. Saddamjit_Singh

    Saddamjit_Singh

    Joined:
    Dec 4, 2015
    Posts:
    22
    Hello Sir,

    Just used you code .

    It's giving many errors like-

    Assets/Scripts/NewBehaviourScript.js(41,12): BCE0005: Unknown identifier: 'err'.
    Assets/Scripts/NewBehaviourScript.js(42,22): BCE0005: Unknown identifier: 'sx'.
    etc...


    Any help?