Instantiate On Container Child

Greetings, everyone. I’m new to Unity development, and I’ve been watching lots of tutorials lately. I appreciate the help in advance; answers provided here have helped a lot.

I’ve put together some rudimentary code–I’m just testing some things right now–but I’m stuck because I know before I even finish that there must be a better way to do what I want to do. Here’s what I’m planning:

A hex-based tile board that instantiates an object in the center of whichever hex tile is touched.

I’m currently using the mouse in place of a touch screen, but this is just test code, anyway. I’ve figured out how to spawn the object in the center of the container I touched (a simple 3D cylinder for testing). But here’s where I’m stuck:

I could create a unique name for each of the 19 hex tiles I intend to have in the end, and then just copy/paste this code 19 times for each container. However, I know there has to be a better way, something like grabbing the child GameObject of the Collider hit by the Ray and Instantiating the “sphere” on that specific child, but I can’t figure out how to make it work. Any ideas?

In Unity, I’ve got an EmptyGameObject called “SpawnPoint” as a child of the Cylinder, and that’s where I’m aiming to spawn the sphere. Right now I’m cheating by using a Vector3 to put the sphere where I want it, but that’s just me practicing.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GameManager : MonoBehaviour 
{    
    public GameObject sphere;
    public GameObject cylinder;

void Update ()
{
	if (Input.GetButtonDown("Fire1"))
	{
		RaycastHit hitInfo;

		Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);

		if (Physics.Raycast (ray, out hitInfo)) 
		{
			Debug.Log ("Raycast hit:" + hitInfo.collider.gameObject.name);

			if (hitInfo.collider.gameObject.name == "Cylinder")
			{
				Vector3 spawnPoint = new Vector3 (cylinder.transform.position.x, cylinder.transform.position.y, -200.0f);
				Instantiate (sphere, spawnPoint , transform.rotation);
			}
		}
	}
}

}

Hi,
There are several ways to accomplish this. Here is a method that came into my mind for the requirement.

Create two scripts ‘HexTile’ which should be assigned to all the 19 tiles and a ‘GameManager’ for managing the inputs. Dont forget to add a collider to each hex tiles

//Script to be added to all the hex tiles
public class HexTiles : MonoBehaviour
{
    //Function to add a sphere to this hex
   public void AddSphere(GameObject prefab)
    {
        //Instantiate the sphere prefab
        GameObject obj = Instantiate(prefab);
        //Make the sphere child of this hex tile
        obj.transform.SetParent(this.transform);
        //Reset sphere's position to the tile's center
        obj.transform.localPosition = Vector3.zero;        
    }
}

And here is the modified GameManager script

public class GameManager : MonoBehaviour
{

    public GameObject sphere;

    void Update()
    {
        if (Input.GetButtonDown("Fire1"))
        {
            RaycastHit hitInfo;
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

            if (Physics.Raycast(ray, out hitInfo))
            {
                Debug.Log("Raycast hit:" + hitInfo.collider.gameObject.name);

                //Try to get the HexTiles script from the hit object
                HexTiles tile = hitInfo.collider.GetComponent<HexTiles>();

                //If its a valid tile
                if (tile != null)
                    tile.AddSphere(sphere);
            }
        }
    }

}

Hope this helps !