Unity 3.x Game Development Essentials ch 8 problem

Started by
7 comments, last by nickme 11 years, 9 months ago
hi
i follow the book mentioned in my title and got to the end of chapter 8. but as my screenshot i included below shown, FireSystem and SmokeSystem were children of campfire, but the length of the partilcleEmitter array was zero when when i print it. so the for loop was never executed and the particles never enabled. i can heard the audio played but there was no fire or smoke. when i clicked on the SmokeSystem and FireSystem in the hierarchy window, i can see the them in scene window.

i guess the version in the book was outdated and the new version regarding this feature is different. another thing is that when i add particle system to my unity, the options available were different. that may indicated that the versions were different.

the following is my inventory script:


//
// attach to FPC(player)
//
using UnityEngine;
using System.Collections;

public class Inventory : MonoBehaviour {

public static int charge = 0;
public AudioClip collectSound;
public Texture2D[] meterCharge;
public Renderer meter;

bool haveMatches = false;
bool Lit = false;
public GUITexture matchGUIprefab;
GUITexture matchGUI;
public GUIText textHints;

void Start () {
charge = 0;
}

void CellPickup() { // this function is calls by PowerCell
AudioSource.PlayClipAtPoint(collectSound, transform.position);
charge++;
meter.material.mainTexture = meterCharge[charge];
}

void OnControllerColliderHit(ControllerColliderHit col) {
if (!Lit && col.gameObject.name == "campfire") {
if (haveMatches) {
LightFire(col.gameObject);
} else if (!haveMatches) {
textHints.SendMessage("ShowHint",
"I could use this campfire to signal for help..\nIf only i could light it..");
}
}
}

void MatchPickup() {
AudioSource.PlayClipAtPoint (collectSound, transform.position);
GUITexture matchHUD = Instantiate(matchGUIprefab, new Vector3(0.15f, 0.1f, 0.0f),
transform.rotation) as GUITexture;
matchGUI = matchHUD;
haveMatches = true;
matchGUI.enabled = true;
}

void LightFire(GameObject campfire) {
ParticleEmitter [] fireEmitters;

fireEmitters = campfire.GetComponentsInChildren<ParticleEmitter>();
print(" **** Outside emitter. fireEmitter.length : "+fireEmitters.Length); // for debugging
foreach (ParticleEmitter emitter in fireEmitters) {
emitter.emit = true;
}
campfire.audio.Play ();
Destroy (matchGUI);
haveMatches = false;
Lit = true;
}
}
Advertisement
This may seem like an obvious question, but did you add a ParticleEmitter component to the object named "campfire"? Note that GetComponentsInChildren<ParticleEmitter>" will only look for components of the "ParticleEmitter" type, so if you attached some other component that wouldn't work.
hi jefferytitan:

i did have FireSystem and SmokeSystem particle components inside the firecamp gameobject. i had included the screenshot below. please take a look.
Interestingly enough I think I did the old version of the same tutorial! Ah, that coconut shy. ;)

Edit: I initially gave a wrong answer, hopefully this is better.

One possibility is based on the fact that GameObject.GetComponentsInChildren only returns Components on active GameObjects. You could try the overload where you pass a boolean "includeInactive" just in case the GameObject is being deactivated somehow.

A second possibility is that the class structure has changed since I worked with it, and the Particle System you have does not contain a ParticleEmitter (note the Shiruken Particle System is new).

Another possibility is that you have another GameObject called campfire which has no ParticleEmitters.
hi jefferytitan:

thanks for your reply.
1) i think the gameObject campfire was active because a few lines after the GetComponentsInChildren() statement, i called [color=#282828][font=helvetica, arial, verdana, tahoma, sans-serif]

[background=rgb(250, 251, 252)]campfire.audio.Play (); which i can hear the audio[/background]

[/font]
[color=#282828][font=helvetica, arial, verdana, tahoma, sans-serif]

[background=rgb(250, 251, 252)]2) i suspect this is the case and that is why i asked for helpt[/background]

[/font]
[color=#282828][font=helvetica, arial, verdana, tahoma, sans-serif]

[background=rgb(250, 251, 252)]3) i am very sure that i only have one GameObject named campfire.[/background]

[/font]

[color=#282828][font=helvetica, arial, verdana, tahoma, sans-serif]

[background=rgb(250, 251, 252)]about the 1) : you suggest overloading, i would like to try that out. can you be more specific? the campfire object have no script, how can it pass out bool to show it is active?[/background]

[/font]

To answer yours answers: wink.png

  1. Okay, what I meant was call the method like this:

    fireEmitters = campfire.GetComponentsInChildren<ParticleEmitter>(true);

  2. For debugging purposes I think you could try something like this:
    allComponents = campfire.GetComponentsInChildren<Component>(true);

    Then you could loop through all the Components returned and print their type to debug and see what your FireSystem actually contains. Or get the FireSystem GameObject directly and call that method on it so you have less debug to scroll through.

hi Jefferytitan :

i tried your suggestions and i get errors. the new codes for LIghtFire() was included below:


1 void LightFire(GameObject campfire) {
2 ParticleEmitter[] fireEmitters;
3 Component[] ACs;

4 fireEmitters = campfire.GetComponentsInChildren<ParticleEmitter>(true);
5 ACs = campfire.GetComponentsInChildren<Component>(true);

6 print(" **** fireEmitter.length : " + fireEmitters.Length); // Length = 0
7 print(" **** AC.length : " + ACs.Length); // Length = 79

8 foreach (Component A in ACs) {
9 print (A.name);
10 if (A.name == "FireSystem" || A.name == "SmokeSystem")
11 A.particleEmitter.emit = true; // game clash here.
12 }

13 foreach (ParticleEmitter emitter in fireEmitters) {
14 emitter.emit = true;
15 }
16 campfire.audio.Play ();
17 Destroy (matchGUI);
18 haveMatches = false;
19 Lit = true;
20 }

at line 11, the console window shows that there was no particleEmitter attached to the component. and then it clash. i tried particleSystem, it also generated error.

about the line 9 where it prints the names of the components, the FireSystem and SmokeSystem are among the printed. i looked up in the Unity Component hierarchy and found that both ParticleSystem and ParticleEmitter are children of Component.


5 ACs = campfire.GetComponentsInChildren<Component>(true);

6 print(" **** fireEmitter.length : " + fireEmitters.Length); // Length = 0
7 print(" **** AC.length : " + ACs.Length); // Length = 79

8 foreach (Component A in ACs) {
9 print (A.name);
10 if (A.name == "FireSystem" || A.name == "SmokeSystem")
11 A.particleEmitter.emit = true; // game clash here.
12 }

13 foreach (ParticleEmitter emitter in fireEmitters) {
14 emitter.emit = true;
15 }
16 campfire.audio.Play ();
17 Destroy (matchGUI);
18 haveMatches = false;
19 Lit = true;
20 }

at line 11, the console window shows that there was no particleEmitter attached to the component. and then it clash. i tried particleSystem, it also generated error.

about the line 9 where it prints the names of the components, the FireSystem and SmokeSystem are among the printed. i looked up in the Unity Component hierarchy and found that both ParticleSystem and ParticleEmitter are children of Component.


Okay, it's good that they're being returned in the list of Components. You can get more information by adding something like the following after line 9:
print (A.GetType().FullName);

If you get the type name you'll know what it is, then you can research that type in the Unity API reference. Perhaps Shiruken doesn't use a separate ParticleEmitter, but has all the properties in one object?
hi

it had been a long time since i last posted the query. i almost give up on working on this book any more. what happened was that the version of unity was 3.5.2. it was a bad version. the particle package was bad. after the version 3.5.3 came out, i downloaded it and it all runs fine.

bye

This topic is closed to new replies.

Advertisement