Search Unity

Question How do I drag and drop instances of a prefab on top of an already existing grid/mesh ?

Discussion in 'Scripting' started by maker_10101, Apr 15, 2022.

  1. maker_10101

    maker_10101

    Joined:
    Apr 10, 2022
    Posts:
    1
    Hello everyone!

    This is my first post on the forum. I’m “relatively” new to Unity (and programming as a whole), so please forgive me if this question is too basic or if I made some noob mistakes in the code.

    I’ve been working on my project (2d mobile strategy game) for a while, but I got stuck and can’t find a way out. I’m having trouble with "in-game" drag and drop of the main player (black dot) on top of an already existing grid.

    So, to recap everything shortly:
    1. My game consists of a constant "catch-up" battle between a prey and a hunter. You play as the prey (the black dots, which are instances of a prefab) against the red dots (hunters).
    2. I built a grid (that eventually is going to shrink in size, mid-game).
    3. I then managed to randomly spawn the “dots” on top of the grid. I also used Physics2D.OverlapCircle to avoid overlaps with the other dots’ instances during spawn.
    4. Here comes the part where I’m stuck. I want to be able to drag and drop the “dots” on top of the grid (and nowhere else), but I can’t. I mean, I can drag them once they’re spawned, but I cannot find a way to drop them “exclusively” on top of the grid’s vertices (the green gizmos that can be seen in the Scene View --> see attached JPEG). BTW I’m using the Unity Event System for the drag and drop feature (like IPointerDownHandler, IBeginDragHandler, IEndDragHandler etc.).
    5. I’ve seen many tutorials and read tons of forum posts about the drag and drop topic, but I couldn’t find anything that solves my problem (i.e. dragging a prefab instance on top of an existing mesh/grid once they're spawned on it). I’m using this method because it’s easier for me to control the grid, that can be considered as the real “protagonist” (in the sense that everything revolves around it).

    Also, here’s the “gameGrid” and “Prey” scripts:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. [ExecuteInEditMode]
    6. public class gameGrid : MonoBehaviour
    7. {
    8.     public int xCells;
    9.     public int yCells;
    10.  
    11.     public Vector3[] vertices;
    12.  
    13.     [SerializeField]
    14.     private Vector3 gridOffset;
    15.  
    16.     public float cellSize_x;
    17.     public float cellSize_y;
    18.  
    19.     public bool narrow = false;
    20.     public bool fine;
    21.  
    22.     public bool onTarget;
    23.  
    24.     public Mesh mesh;
    25.  
    26.     private void Awake()
    27.     {
    28.         onTarget = false;
    29.      
    30.     }
    31.  
    32.     void Update()
    33.     {
    34.         Generate();
    35.     }
    36.  
    37.  
    38.     private void Generate()
    39.     {
    40.         GetComponent<MeshFilter>().mesh = mesh = new Mesh();
    41.         mesh.name = "Procedural Grid";
    42.  
    43.         vertices = new Vector3[(xCells + 1) * (yCells + 1)];
    44.  
    45.         for (int i = 0, y = 0; y <= yCells; y++)
    46.         {
    47.             for (int x = 0; x <= xCells; x++, i++)
    48.             {
    49.                 Vector3 celloffset = new Vector3(x * cellSize_x, y * cellSize_y, 0);
    50.                 vertices[i] = new Vector3(x, y) + gridOffset + celloffset;
    51.             }
    52.         }
    53.         mesh.vertices = vertices;
    54.  
    55.         int[] triangles = new int[xCells * yCells * 6];
    56.  
    57.         for (int ti = 0, vi = 0, y = 0; y < yCells; y++, vi++)
    58.         {
    59.             for (int x = 0; x < xCells; x++, ti += 6, vi++)
    60.             {
    61.                 triangles[ti] = vi;
    62.                 triangles[ti + 3] = triangles[ti + 2] = vi + 1;
    63.                 triangles[ti + 4] = triangles[ti + 1] = vi + xCells + 1;
    64.                 triangles[ti + 5] = vi + xCells + 2;
    65.             }
    66.         }
    67.         mesh.triangles = triangles;
    68.  
    69.     }
    70.  
    71.  
    72.     void OnDrawGizmos()
    73.     {
    74.         Gizmos.color = Color.green;
    75.  
    76.         if (vertices == null)
    77.         {
    78.             return;
    79.         }
    80.  
    81.         for (int i = 0; i < vertices.Length; i++)
    82.         {
    83.             Gizmos.DrawSphere(vertices[i], 0.07f);
    84.         }
    85.  
    86.     }
    87.  
    88. }
    89.  


    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class Prey : MonoBehaviour
    6. {
    7.     [Header("Prefab")]
    8.     public GameObject blackDot;
    9.  
    10.     public gameGrid thegamegrid;
    11.  
    12.     public int black_dotsLimit;
    13.  
    14.     [HideInInspector]
    15.     public int black_dotsAmount;
    16.  
    17.     public bool preyisSpawned;
    18.  
    19.     private void Awake()
    20.     {
    21.         thegamegrid = FindObjectOfType<gameGrid>();
    22.         the_avoider = FindObjectOfType<avoid_collision>();
    23.     }
    24.  
    25.  
    26.     void Start()
    27.     {
    28.         preyisSpawned = false;
    29.         StartCoroutine(spawn_prey());
    30.     }
    31.  
    32.     private IEnumerator spawn_prey()
    33.     {
    34.  
    35.         while (black_dotsAmount < black_dotsLimit)
    36.         {
    37.             var pref = Random.Range(0, thegamegrid.vertices.Length);
    38.             Vector3 prey_position = thegamegrid.vertices[pref];
    39.  
    40.             static bool CheckforCollision(Vector3 prey_position, float radius)
    41.             {
    42.                 return Physics2D.OverlapCircle(prey_position, radius, LayerMask.GetMask("Prey", "Hunter"));
    43.             }
    44.  
    45.  
    46.             if (!CheckforCollision(prey_position, 0.5f))
    47.             {
    48.          
    49.                 (Instantiate(blackDot, prey_position, transform.rotation) as GameObject).transform.SetParent(thegamegrid.transform);
    50.  
    51.                 black_dotsAmount++;
    52.  
    53.             }
    54.  
    55.  
    56.             yield return new WaitForSeconds(0.01f);
    57.  
    58.         }
    59.  
    60.         preyisSpawned = true;
    61.  
    62.     }
    63. }
    64.  


    Is there a solution through the "onDrop" method that I’m missing? I can’t grasp how to make the Vector3[] vertices the only droppable area. And finally, if it can help, I'm currently using Unity 2020.3.20f1.

    I appreciate any help you can provide.

    Here's a screenshot where I highlight the required movements:
    thereddot_sample.jpg
     
    Last edited: Apr 15, 2022