I’ve got a list of Transforms which are Empty children of an object in my scene, named Mount_000 through Mount_007, and at runtime I want to pick a random Mount and attach a gun to it. So I did this:
foreach (Transform child in attachedParts[attachedParts.Count - 1]){
// do whatever you want with child transform here
if(child.name.Contains("Mount")){
dirtyMounts.Add(child);
}
if(child.name.Contains("Hardpoint")){
dirtyHardPoints.Add(child);
}
}
int chosenMount = Random.Range(0,dirtyMounts.Count - 1);
Debug.Log("Chose mount #"+ chosenMount + ", which is "+mounts[chosenMount]);
newPart.SetParent(mounts[chosenMount] as Transform);
Debug.Log(newPart.parent);
foreach (Transform child in attachedParts[attachedParts.Count - 1]){
// to this...
foreach (Transform child in attachedParts){
Also, you should change this:
int chosenMount = Random.Range(0,dirtyMounts.Count - 1);
// to this:
/* as the upper bound is exclusive */
int chosenMount = Random.Range(0,dirtyMounts.Count);
attachedParts[ ] is a list of Gameobjects which are known to have children. I’m trying to grab the last item from that list and get its children when I do foreach (Transform child in attachedParts[attachedParts.Count - 1])
Here, I seperated it out into another variable for clarity; didn’t change the result:
Transform lastAttachedPart = attachedParts[attachedParts.Count - 1];
foreach (Transform child in lastAttachedPart){
// do whatever you want with child transform here
if(child.name.Contains("Mount")){
dirtyMounts.Add(child);
}
if(child.name.Contains("Hardpoint")){
dirtyHardPoints.Add(child);
}
}
Debug.Log(dirtyMounts);
//int randomAttachmentPoint = Random.Range(0,dirtyMounts.Count - 1);
int chosenMount = Random.Range(0,dirtyMounts.Count);
Debug.Log("Chose mount #"+ chosenMount + ", which is "+dirtyMounts[chosenMount]);
newPart.SetParent(dirtyMounts[chosenMount] as Transform);
Debug.Log(newPart.parent);
Nope. I already fixed that in the second post anyway.
I feel like there must be something fundamental about Lists that I’m not grokking. Look at my debug statements results. There’s no reason I can think of for the second thing to return null if the first thing doesn’t return null, but that’s what keeps happening at runtime.
I can’t remember why I cast to Transform during SetParent(). I think I might have been flailing about earlier trying to get it to work without really understanding what was wrong? Anyway, I removed the cast and added a few Debugs to test the newPart is Null theory. No dice.
Here’s the whole script for greater context:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BossMaker : MonoBehaviour {
[SerializeField]
private Transform corePrefab;
[SerializeField]
private List <Transform> botParts = new List<Transform> ();
private List <Transform> sanitizedBotParts = new List<Transform> ();
[SerializeField]
private int maxBranches = 4;
private int branchesSolved;
private List <Transform> attachedParts = new List<Transform> ();
private List <Transform> dirtyMounts;
private List <Transform> dirtyHardPoints;
void Awake(){
//Clean up after sloppy IDE users
foreach(Transform p in botParts)
{
if(p!= null){
sanitizedBotParts.Add(p);
}
}
}
// Use this for initialization
void Start () {
GenerateBoss();
}
// Update is called once per frame
void Update () {
}
private void GenerateBoss(){
branchesSolved = 0;
Transform core = (Transform) Instantiate(corePrefab, transform.position, transform.rotation) as Transform;
attachedParts.Add(core);
for (var i = 1; i< maxBranches; i++){
dirtyMounts = new List<Transform>();
dirtyHardPoints = new List<Transform>();
int randomPart = Random.Range(1,sanitizedBotParts.Count - 1);
Transform newPart = Instantiate(sanitizedBotParts[randomPart], transform.position, transform.rotation) as Transform;
attachedParts.Add(newPart);
Transform lastAttachedPart = attachedParts[attachedParts.Count - 1];
foreach (Transform child in lastAttachedPart){
// do whatever you want with child transform here
if(child.name.Contains("Mount")){
dirtyMounts.Add(child);
}
if(child.name.Contains("Hardpoint")){
dirtyHardPoints.Add(child);
}
}
//int randomAttachmentPoint = Random.Range(0,dirtyMounts.Count - 1);
int chosenMount = Random.Range(0,dirtyMounts.Count);
Debug.Log("New Part is " +newPart);
Debug.Log("Chose mount #"+ chosenMount + ", which is "+dirtyMounts[chosenMount]);
newPart.SetParent(dirtyMounts[chosenMount]);
Debug.Log("After Assigning, new parent is "+newPart.parent);
Debug.Log(" ");
}
}
}
And this is running 32 times when I run the game to procedurally generate a structure, so the fact that some parts appear in the world, just not properly parented, means they can’t all be null. But as you can see, no matter what part it returns, the end parent is always, always Null.
Seeing your full code, it looks like you’re trying to parent newPart to itself or a child of itself which is going to fail every time.
// create a new part:
Transform newPart = Instantiate(sanitizedBotParts[randomPart], transform.position, transform.rotation) as Transform;
// add it to the attachedParts list:
attachedParts.Add(newPart);
// get the last item from the attachedParts list, which is newPart
Transform lastAttachedPart = attachedParts[attachedParts.Count - 1];
At this point, newPart and lastAttachedPart are the same thing. Then you run your selection code, which selects a random child of lastAttachedPart / newPart and finally you try to parent it to itself.