GetComponent problem.

Jan 30, 2010 at 10:12 PM
Edited Jan 30, 2010 at 10:16 PM

just wondering if the Engine.GetComponent<> function is limited to predefined game objects

the reason i ask is that this line of code returns "Cannot Find Item LeftWall"

ExampleBlock leftWall = Engine.GetComponent<ExampleBlock>("LeftWall");

when it exists in the scene xml file and the code exampleblock is from the example scripts.


Jan 30, 2010 at 10:19 PM

No, it's not limited like that. But you cannot get a component that has a script. Rather, you must get the script instead. This is because by default, components are 'encapsulated' by their scripts.

From the documention -

A scripted component itself will be ‘encapsulated’ at play-time. That means that a scripted component won’t be accessible via GetComponent. This is done for a good reason. For reasons of modularity, a scripted component should not be accessed directly. This is because its script acts as a wrapper over the component. Anything you want to do to a scripted component should be done through its script with GetScript.

This encapsulation feature can be turned off by setting your game’s Configuration/Ox.xml <EncapsulateScriptedComponents> tag to false.

Jan 30, 2010 at 11:44 PM

Just to make completely clear, you'd simply do Engine.GetScript<ScriptType>("LeftWall").

Jan 31, 2010 at 1:15 AM

yeah i got it :)

got another problem though

wallCollisions = new ExampleBlock[4];

wallCollisions[0] = engine.GetScript<ExampleBlock>("TopWall");

wallCollisions[1] = engine.GetScript<ExampleBlock>("LeftWall");

wallCollisions[2] = engine.GetScript<ExampleBlock>("RightWall");

wallCollisions[3] = engine.GetScript<ExampleBlock>("BottomWall");


it absolutely refuses to get "BottomWall". ive deleted and renamed it, tried everything i can think of, what am i doing wrong?


Jan 31, 2010 at 9:03 AM

Did you forget to set that component's ScriptClass property to ExampleBlock? If not, send me your project and I'll take a look.


Jan 31, 2010 at 10:23 AM

please excuse the very messy code. it doesnt get tidied up until it works :D the problem is in exampleball.cs

there is also a commented out line in Blocks.cs that has the same error. > // iball = Engine.GetScript<ExampleBall>("iBalls");

thanks :)

Jan 31, 2010 at 10:53 AM
Edited Jan 31, 2010 at 10:54 AM

For -

iball = Engine.GetScript<ExampleBall>("iBalls");

- you're trying to access it before you've even loaded the document it's in. That can't possibly work :)

For the "RottenWall" script, the problem is more subtle. "ExampleBall" *is* created before "RottenWall" (look in the xml file to see this). Therefore trying to access "RottenWall" in "ExampleBall"s constructor can't work. You *could* rearrange the objects in the xml file so that "RottenWall" comes before "ExampleBall", or you could split the file in two where the first document has the independant objects and the second has the dependant objects.

Neither solution is great, so I'm open to suggestions on how to change the engine to make such temporal dependencies easier to deal with.


Jan 31, 2010 at 10:59 AM

ahhhhhhh. so i did a bit of tweaking in the xml file and it works :P thanks.

perhaps you could create an option for build priority in the scene editor to output the xml file in a certain order ? maybe that would work.

thanks for the pointer ;)

Jan 31, 2010 at 11:09 AM
Edited Jan 31, 2010 at 11:09 AM

Oh, BTW, I was wrong about "iBalls". It actually has the same problem as the "RottenWall".

Jan 31, 2010 at 11:29 AM

>> perhaps you could create an option for build priority in the scene editor to output the xml file in a certain order ?

It might, but it's pretty heavy-handed.

I noticed in your code, you're just setting up references to peer objects and not actually interfacing with them. This is likely a very common case. Therefore, I'm thinking about adding a "SetUpPeerReferencesHook" that is called after all objects in a document are created but before the first Update. You could do your order-independant initialization code in there.


Jan 31, 2010 at 12:18 PM

im afraid that im too stupid to understand what you have written :(

Jan 31, 2010 at 12:41 PM
Edited Jan 31, 2010 at 12:54 PM


Objects in the same document can be thought of as 'peers'. An object that loads objects from a document other than its own can be thought of as having a 'parent-to-children' relationship to objects it's loading.

In your code, your ExampleBall object stores references to ExampleBlocks that are its peers. Since this is incongruent with the 'peers-are-independant-of-each-other' 'rule', a virtual method hook is needed for wiring them up as you have done in your constructor. Since this hook method is called after all the object constructors of a document is called, you can override it wire initialize reference from one object to its peers. The wiring, in your case, would be implemented as -

protected override void SetUpPeerReferencesHook()
batCollisions = Engine.GetScript<BatScript>("Bat");
wallCollisions = new ExampleBlock[4];
wallCollisions[0] = Engine.GetScript<ExampleBlock>("TopWall");
wallCollisions[1] = Engine.GetScript<ExampleBlock>("LeftWall");
wallCollisions[2] = Engine.GetScript<ExampleBlock>("RightWall");
wallCollisions[3] = Engine.GetScript<ExampleBlock>("RottenWall");
   colSkin = batCollisions.skint;

This would work fine no matter what order 'peer' objects are created. The only thing you couldn't do is depend on SetUpPeerReferences being called in a certain order. As a library writer, it could even be my privilege to say that object creation order is undefined (could happen in any order regardless of what you expect). This may have to become the case if Cut/Paste is ever implemented in the editors.

This make any more sense?

Jan 31, 2010 at 12:55 PM

Perhaps SetUpPeerReferencesHook would be better named DocumentLoadedHook?


Jan 31, 2010 at 12:59 PM
Edited Jan 31, 2010 at 1:00 PM

yeah, looks great. :) would save a lot of hassle i think.

i dont think the name really matters although DocumentLoadedHook is a little more friendly

thank you

Jan 31, 2010 at 1:12 PM

Okay, its in the source.

Jan 31, 2010 at 1:15 PM

Ah crap, hold on...

Jan 31, 2010 at 1:18 PM

Okay, now it's in the source and CORRECT :)