- Home /
Beginner question about 'SetParent'; Why is it necessary to make the script work?
Hi! ---First of all there is no problems with the script and my game will run---
I've got some "past" experience in Unity and I'm quite familiar with the basics on coding in C#. Currently I'm learning to create an endless ball game (from a "beginner" book), where you control a ball which is rolling down a lane, where you need to avoid random generated obstacles.
I've understood almost everything in the provided code, except the last line of code in a method that is bugging me. The statement spawns an obstacle, but it also sets the obstacle as the parent to the 'tile' it's spawned on. Why is this necessary, because without the component 'SetParent' the game won't run. I understand what the 'SetParent' does, but anyone able to explain why the 'SetParent' is mandatory for my game to run and what does it do in this case?
The raw script below (from the book) covers spawning tiles and spawning obstacles, the line of code is located at the very bottom ( newObstacle.SetParent(spawnPoint.transform); ). Thanks a lot!
using UnityEngine;
using System.Collections.Generic; // List
/// <summary>
/// Controls the main gameplay
/// </summary>
public class GameController : MonoBehaviour
{
[Tooltip("A reference to the tile we want to spawn")]
public Transform tile;
[Tooltip("A reference to the obstacle we want to spawn")]
public Transform obstacle;
[Tooltip("Where the first tile should be placed at")]
public Vector3 startPoint = new Vector3(0, 0, -5);
[Tooltip("How many tiles should we create in advance")]
[Range(1, 15)]
public int initSpawnNum = 10;
[Tooltip("How many tiles to spawn initially with no obstacles")]
public int initNoObstacles = 4;
/// <summary>
/// Where the next tile should be spawned at.
/// </summary>
private Vector3 nextTileLocation;
/// <summary>
/// How should the next tile be rotated?
/// </summary>
private Quaternion nextTileRotation;
/// <summary>
/// Used for initialization
/// </summary>
void Start()
{
// Set our starting point
nextTileLocation = startPoint;
nextTileRotation = Quaternion.identity;
for (int i = 0; i < initSpawnNum; ++i)
{
SpawnNextTile(i >= initNoObstacles);
}
}
/// <summary>
/// Will spawn a tile at a certain location and setup the next
position
/// </summary>
public void SpawnNextTile(bool spawnObstacles = true)
{
var newTile = Instantiate(tile, nextTileLocation,
nextTileRotation);
// Figure out where and at what rotation we should spawn
// the next item
var nextTile = newTile.Find("Next Spawn Point");
nextTileLocation = nextTile.position;
nextTileRotation = nextTile.rotation;
if (!spawnObstacles)
return;
// Now we need to get all of the possible places to spawn the
// obstacle
var obstacleSpawnPoints = new List<GameObject>();
// Go through each of the child game objects in our tile
foreach (Transform child in newTile)
{
// If it has the ObstacleSpawn tag
if (child.CompareTag("ObstacleSpawn"))
{
// We add it as a possibilty
obstacleSpawnPoints.Add(child.gameObject);
}
}
// Make sure there is at least one
if (obstacleSpawnPoints.Count > 0)
{
// Get a random object from the ones we have
var spawnPoint = obstacleSpawnPoints[Random.Range(0,
obstacleSpawnPoints.Count)];
// Store its position for us to use
var spawnPos = spawnPoint.transform.position;
// Create our obstacle
var newObstacle = Instantiate(obstacle, spawnPos,
Quaternion.identity);
// Have it parented to the tile
newObstacle.SetParent(spawnPoint.transform);
}
}
}
Answer by bhavinbhai2707 · Jan 24, 2018 at 08:02 PM
well we cant tell much with just one script because there are many possibilities and we don't know how the Game is actually working(probably upload a video to let us know whats happening with and without setParent), i am also confused what is spawnPoint here?? considering spawnpoint is active Gameobject in scene then, according to me one of the main reason that can be is the obstacle is being parented to newObstacle and another script is trying to access the childs of spawnPoint to perform some task[for eg: GameObject.Destroy(spawnPoint.transform.getChild(0));
] Or, as written by you the newObstacle is being parented to the Tile if thats true then look at the foreach statement near line 75
foreach (Transform child in newTile)
{
// If it has the ObstacleSpawn tag
if (child.CompareTag("ObstacleSpawn"))
{
// We add it as a possibilty
obstacleSpawnPoints.Add(child.gameObject);
}
}
this chunk of code is actually accessing the child of the Tile GameObject and is assigning those child to a list , so that makes clear that if we dont use setParent then this chunk of code wont work which may result in unexpected behaviour.
and also using too much of var is not really a not good programming Practice. i hope this helps :)
@bhavinbhai2707 Aha! I think I got it now!
As you said the newObstacle is being parented to the Tile. On my Tile prefab i have 3 spawnpoints (childs) with the tag "ObstacleSpawn", so we want to use the new position of the randomly picked spawnPoint and not the one on the prefab, which i can't access. Hopefully i understood that correct.
Thanks a lot, you're a great great help that I really appreciate!