- Home /
The question is answered, right answer was accepted
Destroy One Child, Not All
I have three Scripts
Script One
Game Manager: SIMPLY(Guitar Hero Like Game)
4 Tubes, 4 Spawnners and 4 receivers Each tube has an Inactive atom parent over the Spawnners which has a variable spawnner and receiver each assigned according to their position. So Parent 1 is assigned receiver 1 and spawnner 1 through inspector, atom parent 2 is assigned receiver 2 spanner 2 etc.
So...
Script 1 Game Manager (Outside of everything, randomly picks a spawnner and instantiates the atom parents( all 4 atom parents spawnners and receivers are in a list)
GameObject atom1_child = Instantiate(atomReference[0], atomSpawnners[0].transform.position, atomSpawnners[0].transform.rotation) as GameObject;
Script Two
attached to the child gameObject(atoms) when it spawns... and collides, in my case gets within distance with the base or what I call the receiver...
buttonOccupied = true; // Has a boolean to make sure atom is inside receiever receiver.GetComponent().SA_Atom = gameObject; //Script 3 in receiver //Script 3 is a controller with the variable SA_Atom
So when this object is at a certain distance from base or ITS receiver, it self assigns itself to script 3.
Script 3 When I ray cast to a specific receiver
if (hit.collider.gameObject && SA_Atom.GetComponent().buttonOccupied == true) //If I hit the receiever...
{
Destroy(SA_Atom);
}
Heres the issue, ALL atom childs are being destroyed not just one. I tried several solutions, I cant wrap my head around it
ALSO, it doesnt destroy all atomChilds when the boolean is false, but when boolean is true and I click the receiver, it destroys all. I need it to be that ONE Specific Self assigned atom
HERES THE CODE
//Script ONE outside of anything
using UnityEngine; using System.Collections; using System.Collections.Generic;
public class script_GameManager : MonoBehaviour
{
public GameObject[] atomReference = new GameObject[4];
private float spawnTimer;
public float setTimer;
public GameObject[] atomSpawnners = new GameObject[4];
private int randomSpawnnner;
void Start()
{
spawnTimer = setTimer;
}
void Update ()
{
timerUpdate();
}
void timerUpdate()
{
spawnTimer -= Time.deltaTime;
if(spawnTimer <= 0)
{
spawnTimer = setTimer;
randomSpawnnner = Random.Range(0, 4);
atomSpawn();
}
}
void atomSpawn()
{
switch (randomSpawnnner)
{
case 0:
GameObject atom1_child = Instantiate(atomReference[0], atomSpawnners[0].transform.position, atomSpawnners[0].transform.rotation) as GameObject;
atom1_child.SetActive (true);
break;
case 1:
GameObject atom2_child = Instantiate(atomReference[1], atomSpawnners[1].transform.position, atomSpawnners[1].transform.rotation) as GameObject;
atom2_child.SetActive (true);
break;
case 2:
GameObject atom3_child = Instantiate(atomReference[2], atomSpawnners[2].transform.position, atomSpawnners[2].transform.rotation) as GameObject;
atom3_child.SetActive (true);
break;
case 3:
GameObject atom4_child = Instantiate(atomReference[3], atomSpawnners[3].transform.position, atomSpawnners[3].transform.rotation) as GameObject;
atom4_child.SetActive (true);
break;
}
}
}
//Script 2 inside parents or atoms
using UnityEngine; using System.Collections;
public class script_Atom : MonoBehaviour {
public Transform receiver;
private float receiverDistance;
public float atomSpeed;
private Transform targetReceiver;
public GameObject buttonParticle;
public bool buttonOccupied = false;
void Update()
{
//---- atom positionining and particle activation ----
targetReceiver = receiver.transform;
//easy reference to the vector 3 conversion of the receiver
receiverDistance = Vector3.Distance(transform.position, targetReceiver.transform.position);
//converts the vector 3 (x,y,z) distance into a float
if(receiverDistance > 0.1)
{
atomMove();
//atom will move if far from the zero, otherwise, stop
}//EO IF
if (receiverDistance <= 0.1 && receiverDistance >= -0.1)
{
buttonOccupied = true;
//button is inside receiver
this.receiver.GetComponent<script_buttonController>().SA_Atom = gameObject;
buttonParticle.SetActive(true);
//if atom is close to zero, activate particle system, other wise will be shut off by controller
//a new spawning atom may overrde it being true to false even if the "zero" is occupied
}
}
void atomMove()
{
transform.Translate(Vector3.down * atomSpeed * Time.deltaTime);
}
public void atomSend()
{
//Destroy(gameObject);
}
}
//script 3, attached to receivers
using UnityEngine; using System.Collections;
public class script_buttonController : MonoBehaviour {
RaycastHit hit;
public GameObject SA_Atom;
void Update()
{
if (SA_Atom)
{
}
Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);
//sets up ray cast to camera for controller
if (Input.GetMouseButtonDown(0))
{
if (Physics.Raycast (ray, out hit, Mathf.Infinity))
{
if (SA_Atom)
{
if (hit.collider.gameObject && SA_Atom.GetComponent<script_Atom>().buttonOccupied == true)
{
SA_Atom.GetComponent<script_Atom>().buttonParticle.SetActive(false);
Destroy(SA_Atom);
}
}
else if(SA_Atom == null)
{
//Do Nothing, receive no errors, AFTER Destroyed Gets a NULL ERROR
}
}
}
}
}
Answer by Gabestronaut · Dec 11, 2014 at 09:48 PM
I Solved It! Here is my solution, I added the destroy script to the script_Atom and removed it from script_Controller. I needed to be a bit more specific with gameObject hits so it turns out @taxvi was going towards the right direction as to what is being called and not assigned
public GameObject Receiver_1;
public GameObject Receiver_2;
public GameObject Receiver_3;
public GameObject Receiver_4;
//Solution GameObjects ^^^^ these are all referring to themselves once, there is 4 instances
RaycastHit hit;
public GameObject SA_Atom;
void Update()
{
Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);
//sets up ray cast to camera for controller
if (Input.GetMouseButtonDown(0))
{
if (SA_Atom)
{
if (Physics.Raycast (ray, out hit, Mathf.Infinity))
{
if (hit.collider.gameObject == Receiver_1 && SA_Atom.GetComponent<script_Atom>().buttonOccupied == true)
{
Receiver_1.GetComponent<script_buttonController>().SA_Atom.GetComponent<script_Atom>().atomSend();
}
else if (hit.collider.gameObject == Receiver_2)
{
Receiver_2.GetComponent<script_buttonController>().SA_Atom.GetComponent<script_Atom>().atomSend();
}
else if (hit.collider.gameObject == Receiver_3)
{
Receiver_3.GetComponent<script_buttonController>().SA_Atom.GetComponent<script_Atom>().atomSend();
}
else if (hit.collider.gameObject == Receiver_4)
{
Receiver_4.GetComponent<script_buttonController>().SA_Atom.GetComponent<script_Atom>().atomSend();
}
}
}
}
}
}
Accept the answer, or at least close the topic so that others don't bother reading through
So I found an EVEN BETTER solution. Ins$$anonymous$$d, it was the hit.collider.gameobject I coulda sworn collider.gameObject referred to the current GameObject however, this line
if (hit.collider.gameObject == gameObject)
narrowed all of those extra parameters above to this one line.
Thanks for the help, it definitely steered me in the wrong direction.
Answer by taxvi · Dec 09, 2014 at 07:03 AM
i think the problem is the 22nd line in the 3rd script, how about this?
if (hit.GetComponent<script_Atom>() && hit.GetComponent<script_Atom>().buttonOccupied == true)
@taxvi It was worth a shot but I get errors when I place hit.GetComponent
Also the controller gameObject does not have the atom_Script It does however have the variable SA_Atom being filled by the child being spawn. The issue is that when the child spawns and there are multiple with buttonOccupied == true, they all get destroyed ins$$anonymous$$d of just the one SA_Atom being called inside the controller script. Idk why Destroy(SA_Atom) destroys ALL child objects ins$$anonymous$$d of the one assigned to that specific controller
omg, sorry I meant:
if (hit.transform.GetComponent<script_Atom>() && hit.transform.GetComponent<script_Atom>().buttonOccupied == true)
but this will work if the object with script_Atom has a collider on it, or if the script_buttonController has it just replace script_Atom with it:
if (hit.transform.GetComponent<script_buttonController >() && hit.transform.GetComponent<script_buttonController >().buttonOccupied == true)
@taxvi I tried your new solution and still nothing. I began debugging and I believe I found the problem. TO fix it. I have no idea yet... So when the atom clones are assigning themselves to the script_Controller variable SA_Atom, somehow ID$$anonymous$$ WHY, SA_Atom IS 3 variables?
How can a gameObject variable contain 3?
I Put a debug.log on SA_Atom before it destroys, any atom in the scene that has self assigned itself to SA_Atom in the controller script is now assigning itself to all seprate script_Controller, it has somehow assigned itself to the rest of the SA_Atom variables in Other gameObject's scripts. But nowhere In my code have I hinted that. It is all also organized in the inspector in separate GameObjects. One different parent per gameObject. This is so strange.
Follow this Question
Related Questions
instantiated Gameobject trying to access child of child which is a clone itself. 2 Answers
[SOLVED] How to make to clone an object and make it parent of the transform? 1 Answer
Making a Clone a Child of Another Object 1 Answer
How can I make a game object follow an instantiated game object? 1 Answer
Prefab clones behaviour 0 Answers