- Home /
SetActive true not working on game object,GameObject not reappearing after SetActive(true) was called on it
Now, there are a lot of questions related to this "mysterious" method, but mine, as i think, is a little bit specific.
So i am making a minecraft clone with unity 2017 and I have a class which represents the world generation process and the camera movement.
In it, i involve a feature to hide blocks 40 blocks away from the player in all axises and I use the set active method for this. But when i use set active true it doesn't seem like it is working. Here is the code. In case something else could be affecting this i posted the whole class. But the "hotspot" is the foreach loop in the end of Update()
Hope you will enjoy answering my nooby question.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class WorldGenerationScript : MonoBehaviour {
//Block prefabs
public GameObject dirtBlock;
public GameObject stoneBlock;
//World GameObject
public GameObject world;
//Camera
public Camera mainCamera;
// Use this for initialization
void Start () {
//Instantiate the world
world = new GameObject();
world.name = "World";
//Generate the world in bound of XYZ
for (int x = 0; x <= 100; x++) {
for (int y = 0; y <= 5; y++){
for (int z = -10; z <= 100; z++){
//What whe should do for every block in bound of XYZ
GameObject block;
if (y == 5) {
block = Instantiate(stoneBlock, new Vector3(x, y, z), stoneBlock.transform.rotation);
block.transform.parent = world.transform;
}
if (y < 5) {
block = Instantiate(dirtBlock, new Vector3(x, y, z), dirtBlock.transform.rotation);
block.transform.parent = world.transform;
}
}
}
}
}
// Update is called once per frame
void Update () {
//Camera moving control
if (Input.GetKey(KeyCode.UpArrow)) {
//Move forward
transform.Translate(new Vector3(0f, 0f, 0.2f));
}
if (Input.GetKey(KeyCode.DownArrow)) {
//Move forward
transform.Translate(new Vector3(0f, 0f, -0.2f));
}
if (Input.GetKey(KeyCode.LeftArrow)) {
//Move forward
transform.Translate(new Vector3(-0.2f, 0f, 0f));
}
if (Input.GetKey(KeyCode.RightArrow)) {
//Move forward
transform.Translate(new Vector3(0.2f, 0f, 0f));
}
if (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift)) {
//Move down
transform.Translate(0f, -0.2f, 0f);
}
if (Input.GetKey(KeyCode.Space)) {
//Move up
transform.Translate(0f, 0.2f, 0f);
}
foreach (Transform block in world.GetComponentsInChildren<Transform>()) {
if (Vector3.Distance(block.position, mainCamera.transform.position) > 40) {
block.gameObject.SetActive(false);
} else {
block.gameObject.SetActive(true);
}
}
}
}
Thanks in advance :)
Do not put foreach loop inside an update function. Run in at the start function to store all the transform inside an list afterwards use a forloop to compare the distance in update. You should also only update this when the camera changed position (provided your blocks doesn't move) Also put in a Debug.log in the if and else statement to see if conditions is satisfied to set it back to true Check if this script is inside attached to a block or not as block. setactive(false) stops it's update function too
Answer by andyborrell · Dec 04, 2017 at 10:59 AM
The problem is that GetComponentsInChildren doesn't return inactive objects by default. So on line 78 you are not iterating over the inactive objects. So they never get turned active again.
Do GetComponentsInChildren(true) to include inactive objects.
https://docs.unity3d.com/ScriptReference/Component.GetComponentsInChildren.html