active/ desactive gameObject + childrens

hello

I’m creating a script that make some economy of performances:

i have a house in my scene that is heavy in polygons, so i created the same version of this house in lowpoly, and put it on the same place.

The goal is that when i am away from this house (50 units), the highPoly house disapear, and the lowPoly appear at the same time. When i’m closer, the lowPoly disapear and the highPoly appear.

i notice that all the 2 houses have some children so when some house disapear, the house’s children must disapear also, and this is the problem… here is my script:

var OperantA : Transform;// highPoly house
var OperantB : Transform;// Player
var LowPoly : Transform;// lowPoly house
var distance = 50;

function Update(){
if (Vector3.Distance(transform.position, OperantB.position) <distance){
OperantA.active = true;
LowPoly.active = false;
}
if (Vector3.Distance(transform.position, OperantB.position) >distance){
OperantA.active = false;
LowPoly.active = true;
}
}

with this code, the house GameObject is desactivated but not the childrens…

i tried to change the world “active” with “SetActiveRecursively” and happend the same…

could someone help me?

You could use this same script in all the children and then use BroadcastMessage to call a function to do this on all children.

or you could use a GetComponentsInChildren(scriptname) and calling the function directly(this way is faster, so…)

thank you for this sollutions.

Well GetComponentsInChildren only works when the childrens are active (so when the house is inactive, can’t turn active), and the script itself is not applied to the houses, because if it turn inactive, the script will not work for it come again active…

The sollution of BroadcastMessage seems to be much beter. Well i readed the script refference about it, but i don"t know how i have to write it in my script. Can you give me an idea?

(well i precise that this script can not be assigned to the objects that will appear / disapear, so the script must work for an object hiden that is on the same place then the houses but is only for measure the distance beetween the player and the house).

use a recursive function if you don;t want to thave to put a script on every gameObject that you want to disappear

public function doInvisable() : void {
	setVisible(gameObject, false);	
}

public function doVisable() : void {
	setVisible(gameObject, true);	
}

private function setVisible(go_parent_fp : GameObject, b_visible_fp : boolean) : void {
	var go_child : GameObject;
	for (go_child in go_parent_fp.transform) {
		setVisible(go_child.gameObject, b_visible_fp);
		if ( go_child.renderer != null ) {
			go_child.renderer.enabled = b_visible_fp;
		}
	} 	
}

thank you very much!

So i’m beggining in script and i don’t realy understand many words you use in the script :sweat_smile: so i don’t realy get the sense. Well can you just tell me how i can use it? Should i add this to my first script?

i realy tried your script in much ways, but nothing happend… can you be more clear please?

for now i finded a solution:

When the distance is away, the LowPoly is created with “instantiate” from a prefab and the Highpoly is destructed with “Destruct”. (All children also!! :slight_smile: )

When the distance is close, the HighPoly is created wrom a prefab and the LowPoly is destructed, (the same way then before).

Well, for now, this script is enough for me, but i’m not very experimented in scripts so mabe someone could tell me a more simple solution, if it exist :slight_smile:

Ah, yes, if someone is interrested to use this script that enable a best performance of 3d rendering from the computer with playing on the hi/lo Poly depending on the distance, i put it here :slight_smile:

var Player : Transform;// dragdrop the player here in the hyerarchy
var HiPoly : Transform;// dragdrop the HiPoly complete Prefab
var LoPoly : Transform;//dragdrop the LoPoly complete Prefab
var distance = 100;//distance beetween the "mesure" object and the player... (the mesure object is an empty object that contain this script and define the place where the 2 objects will appear/disapear)
var score1 = 0;
var score2 = 0;

function Update(){

	if ((Vector3.Distance(transform.position, Player.position) <distance)  (score1 == 0)){
		HiPolyYesLoPolyNo();
	}

	if ((Vector3.Distance(transform.position, Player.position) >distance)  (score2 == 0)){
		LoPolyYesHiPolyNo();
		}
}

function HiPolyYesLoPolyNo(){
	var LoPolyDestroy = GameObject.FindWithTag("TagFromLoPolyPrefab");//for destroy the LowPoly, we need his Tag (defined before making a prefab with)
	score1 ++;
	Instantiate(HiPoly, transform.position, transform. rotation);
	Destroy(LoPolyDestroy);
	score2 = 0;
}

function LoPolyYesHiPolyNo(){
	var HiPolyDestroy = GameObject.FindWithTag("TagFromHiPolyPrefab");// the same here, we need a tag in this prefab, for he can be destroy after autocreation.
	score2 ++;
	Instantiate(LoPoly, transform.position, transform. rotation);
	Destroy(HiPolyDestroy);
	score1 = 0;
}

If I got that right, your hierarchy looks something like this
House > LowPolyHouse > Something else
House > HighPolyHouse > Something else

This code worked at my workspace when hierarchy was something like above. I did similar script few moments ago in similar purposes as you are. This is base idea from that. Everything is initially deactivated and after 3 seconds highpoly house is activated. In my workspace also those childrens gets activated.

using UnityEngine;

public class disappaearer : MonoBehaviour 
	{
	Transform hide1;
	Transform hide2;
	Transform hide3;
	Transform hide4;
		
	/**
	* Start	
	*/
	void Start () 
		{
		hide1 = transform.Find("HighPolyHouse" );
		hide2 = transform.Find("HighPolyHouse/some_child" );
		hide3 = transform.Find("LowPolyHouse" );
		hide4 = transform.Find("LowPolyHouse/some_child" );
		hide1.gameObject.SetActiveRecursively( false );	
		hide2.gameObject.SetActiveRecursively( false );
		hide3.gameObject.SetActiveRecursively( false );
		hide4.gameObject.SetActiveRecursively( false );		
	
		StartCoroutine("Wait");	
		}
		
	/**
	* Wait some time before action	
	*/		
	IEnumerator Wait()
		{
		yield return new WaitForSeconds(3f);
		hide1.gameObject.SetActiveRecursively( true );
		}
	}

yees, you get exacly the idea!!

Is your script in c#?
i’m used to javascript :sweat_smile:

Well i can see in the big lines of your script, i see that you have a fonction for make the link between the parent and children!!! is great!!!

Hi,

I’m used to script in C#. I didn’t made any links. Those parts ( Find() ) are just indicating hierarchy I’m having. And if I call

hide1.gameObject.SetActiveRecursively( false ); or
hide1.gameObject.SetActiveRecursively( true );

it directly affects to child objects also. There is no need to any additional bindings. Script reference also indicates:

“Sets the active state of this and all the game objects children to state.”

It should work as it is. You can test this using script I attached and at least in my work space it works like a charm.

hihi, ok, thank you very much for ll this precisions!
I will try… well, mabe i should learn c# one day :roll: