February 04, 2012, 03:29:47 PM *
Welcome, Guest. Please login or register.

Login with username, password and session length
News: Please report any bugs or issues that you might be encountering with the Beta in the Support System so that we can better keep track of any oustanding issues that may come up.

GameCore Support System
 
   Home   Help Search Login Register  
Pages: [1] 2
  Print  
Author Topic: Queston about SetControllerVariable  (Read 2221 times)
pixel_legolas
Hero Member
*****
Posts: 786


View Profile
« on: August 28, 2008, 02:33:05 AM »

How do we use it? look at this:

Code:
//------------------------------------------------------------
//
// void SetControllerVariable( Object@ object, const String& in name, const String& in value)
// void SetControllerVariable( Object@ object, const String& in name, float value)
// void SetControllerVariable( Object@ object, const String& in name, int value)
// void SetControllerVariable( Object@ object, const String& in name, bool value)
// void SetControllerVariable( Object@ object, const String& in name, const Vector& in value)
//
// This function is called whenever a variable is to be set for this controller (typically
// called from another script to affect the behavior of this object)
//
// Parameters:
//
// object - The object that this controller is to act upon.
//
// name - Name of the variable being set.
//
// value - Value for the variable.
//

void SetControllerVariable( Object@ object, const String& in name, const Vector& in value)
{
if (exploded)
return;

if (name == "HitNormal")

All those different VOID, why do we have different and how do i know witch one to choose.

It says, object = the object that we use but i don't see it defined and value, where is the value?



Another thing. If i want to have another rifle and the muzzlefash position is hard to get, wouldnt this code be good:

Code:
GetFXManager().CreateFXAtPosition( fx, object.GetCurMatrix().Project( object.GetBoundingBoxCenter()));

I could just make a small bounding box at the tip of rifle and the fx will always be there. Or?
« Last Edit: August 28, 2008, 02:49:16 AM by pixel_legolas » Logged
grubert
Full Member
***
Posts: 183


Everybody is very nice, but my jacket disappeared.


View Profile WWW
« Reply #1 on: August 28, 2008, 01:12:22 PM »

I think this code will get the bounding box of the object controlled by the script. Probably your character, in this case.

Quote
All those different VOID, why do we have different and how do i know witch one to choose.

It makes no difference for you. If you put a vector, an integer, float or string, the function will recognize them all. This is why they've put it this way, repeated, in the documentation. To show us that we can use all these data types with these functions.

Quote
It says, object = the object that we use but i don't see it defined

Because probably you'll  be calling this function from inside of DynamicsAdvance() or AnimAdvance() (= the functions that get automatically called, one in each dynamics step/loop, other at each frame). And those functions already ask for an object to be given as a parameter, as you know. So, probably you'll be using this object as the one defined. Or maybe other, if you want. If you use:

Code:
Object@ your_object = GetGameManager().GetWorld().GetObject("your_object_geometry");

Quote
where is the value?

The value is being given by you inside parenthesis, and it will replace the value of a variable (that you need to have) in another controller script.


If I'm mistaking something, please someone correct me.
Logged

my portfolio and weekly posting:
http://athossampaio.blogspot.com
gekido
Guest
« Reply #2 on: August 29, 2008, 12:28:24 AM »

Quote
void SetControllerVariable( Object@ object, const String& in name, const String& in value)
void SetControllerVariable( Object@ object, const String& in name, float value)
void SetControllerVariable( Object@ object, const String& in name, int value)
void SetControllerVariable( Object@ object, const String& in name, bool value)
void SetControllerVariable( Object@ object, const String& in name, const Vector& in value)

Set functions don't return a value (hence are 'void') because you aren't getting anything back from the controller, you are 'setting' a value to whatever you want.  The important part that you're missing is in bold - ie the type of parameter that you are looking to set - whether it's a String, float, int or otherwise.

The SetControllerVariable and GetControllerVariable functions are used whenever you want to communicate information between one object and another.  This is part of the GameCore's 'Object-Oriented' nature.

For example, you have an object in your world that you want to query for some information, like 'IsAlive'.  You can't simply access a variable directly in the controller (because it's a part of the object), so instead you query it using the 'GetControllerVariable()' function that corresponds to the variable type you are requesting.

So, using the 'IsAlive' example I've mentioned.

1) object A wants to know if object B 'is alive' or not.

in object A, you would get a handle to object B, like so:

Code:
Object@ objectB = GetGameManager().GetWorld().GetObject("ObjectB");

This gets you a handle (pointer) that you can then use to call functions on object B.

You can then ask object B if it's alive, like so:

Code:
bool isBalive = objectB.GetControllerVariableBool("IsAlive");

Note that the Get functions need to know what kind of information is being returned, so there are specific calls for each variable type (bool, int, etc).

Now that we know whether it's alive or not, we can then tell it what we want it to do:

Code:
if (isBalive)
{
    objectB.SetControllerVariable( "IsAlive", false);
}

basically this says 'if object B is alive, then tell it to be NOT alive'.

Using this same basic technique you can communicate any information that you want between objects as desired. Any time you need to pass information to or from an object that is specific to the script / gameplay (and not something that is provided by a standard GameCore function, like GetPosition() ), you would use the Set/Get ControllerVariable functions to do so.

Now, to complete the above example, ObjectB needs to handle the information that is being passed to it and then do whatever is necessary as a result.  Note that this isn't done automatically (we can't guess what you might want to do with the information), so it's up to you to handle the query from the recieving object end.

When it comes down to it, the SetControllerVariable() and GetControllerVariable() functions aren't really 'functions', but function 'templates' that you then flesh out however you need / want.

So, for objectB, we need to add the function definition to recieve the information being sent:

Code:

// in the 'globals' area of the script, we have a variable defined that the script uses:
// note that this 'isAlive' variable exists only in Object B and needs to be handled elsewhere in the script.
bool isAlive = true;

void SetControllerVariable( Object@ object, const String& in name, bool value)
{
if (name == "IsAlive")
{
                // someone is trying to set whether we're alive or not, let's handle it
                isAlive = value;
}
}

and we need to handle the 'Get' query as well:

Code:
bool GetControllerVariableBool( const String& name)
{
   if (name == "IsAlive")
      return isAlive;
}

=================

Quote
It says, object = the object that we use but i don't see it defined

It's the first function parameter - and is passed into the script automatically when the function is called.  This is probably the confusing part - even though you only say 'SetControllerVariable("MyVariableName", myVariable)', the recieving script automatically gets the first parameter passed in from the engine.

Quote
where is the value?

value is another variable, the last parameter, and is the information that you are passing to the second object.

Quote
GetFXManager().CreateFXAtPosition( fx, object.GetCurMatrix().Project( object.GetBoundingBoxCenter()));

I could just make a small bounding box at the tip of rifle and the fx will always be there. Or?

Quote
I think this code will get the bounding box of the object controlled by the script. Probably your character, in this case.

Grubert is correct - calling 'object.GetBoundingBoxCenter()' gets the center of the object on a whole - ie for everything included in the OPR file. 

BoundingBox is not the same thing as physics box.  BoundingBox is an automatically calculated box that wraps the entire object (ie everything in the OPR file).  You can see an object's bounding box under the 'options' menu (view bounding box). When you select an object the selection box is also the size of the object's bounding box.

What you COULD do for placing a muzzle flash is place a bone or 'hidden' object in the model and use the GetMesh() functions to get the position of that object when placing your muzzleflash effects.  This is one way to do this.  Having a bone is probably the best option, because your rifle may be moving around due to animations etc - having a bone positioned at the end of the rifle is what I was planning on doing for the FPS template enhancements that I'm working on.

Hope this clarifies things a bit.
« Last Edit: August 29, 2008, 12:30:09 AM by gekido » Logged
pixel_legolas
Hero Member
*****
Posts: 786


View Profile
« Reply #3 on: August 29, 2008, 12:59:32 AM »

It definitly makes more sense now. But i feel i need to learn more about programming to know all different things. I know that bool is a right/false thing and that float basically is numners that can change. Constants are...well constant Smiley

But it really cleared out alot Smiley Thanks
Logged
gekido
Guest
« Reply #4 on: August 29, 2008, 01:02:32 AM »

Added what I wrote above into the docs and fleshed it out a bit to cover ControllerSettings as well:

http://www2.gamecore.ca/docs/scripting-reference/classes/Object/controller-functions

Getting a good understanding of ControllerSettings and ControllerVariables and how they are used (and just how useful they really are) is probably the most crucial thing that you need to know about scripting in GameCore.  Once you figure them out, the rest is gravy (with a bit of math on the side) ;}

Quote
constants are, well, constant

Just a clarifications - const isn't a variable type itself - it's a modifier of a variable type.

So for example:

const String& in value

the variable type is a 'String' that happens to be 'const' - ie not modifiable.  You don't really need to worry about the 'const' part (for the most part) when working with the controller settings. Simply defining a parameter like so:

Code:
object.SetControllerVariable("MyVariableName", myValue);

By having the variable defined (and used) at the same time with the quotations - "MyVariableName" - automatically means that it's not a variable that's going to be modified.

But this is getting into semantics really and doesn't affect the discussion at hand.

What you DO need to be aware of is that there are 5 variations of the 'Set' function, one for the following variable types:

Code:
String
float
int
bool
Vector



« Last Edit: August 29, 2008, 01:10:36 AM by gekido » Logged
Squat
Hero Member
*****
Posts: 592


View Profile
« Reply #5 on: August 29, 2008, 01:09:46 AM »

math potatoes?
Logged
gekido
Guest
« Reply #6 on: August 29, 2008, 01:10:58 AM »

mmmm...math potatoes...
Logged
pixel_legolas
Hero Member
*****
Posts: 786


View Profile
« Reply #7 on: August 29, 2008, 03:39:02 AM »

I feel i need to go through a basic template and try to reproduce all lines. I will then see all connections with values and more.

It took me some days to figure out how the opr and gsl files are connected but it's pretty easy once you know it Smiley

I haven't checked the documentation since BV 1.5 so i will look at it now Smiley
Logged
Squat
Hero Member
*****
Posts: 592


View Profile
« Reply #8 on: August 29, 2008, 03:29:21 PM »

I'm further irritated that these seemingly logical explanations simply are not getting me the ability to read a variable from one object to another. It may be working, not sure, but I can't tell. Ok, somebody please for the love of all that is necessary, correct this code so I see the story in the console.

2 Objects: reader writer

Scripts:
reader.gsl
Quote
void Initialize( Object@ object)
{
   Object@ writer = GetGameManager().GetWorld().GetObject("writer");
   String what_I_heard = writer.GetControllerVariableString("Story");
   print(what_I_heard);
}
Note: I improvised adding void Initialize and embracing it in brackets. Otherwise I got an identifier error. These kinds of things omitted from the explanations are like Tonya Harding on my Nancy knowledge. Am I right to do that? I think NOT! It ain't workin...

writer.gsl
Quote
String Story = "I'm telling the wrong story.";

void SetControllerVariable( Object@ object, const String& in name, String value)
{
   if (name == "Story")
   {
   Story = "Once upon a time, I told the right story. The end.";
   }
}

   
bool GetControllerVariableString( const String& name)
{
   if (name == "Story")
   {
   return Story;
   }
   return false;
}

Note: I get "not all paths return a result" if I just do:

Quote
   if (name == "Story")
   return Story;

Also, why am I asking "if (name == "Story")" and what is "name"?

The current result I am getting is a blank line printed to the console.
« Last Edit: August 29, 2008, 03:39:10 PM by Squat » Logged
gekido
Guest
« Reply #9 on: August 29, 2008, 06:05:12 PM »

The problem is likely that you are doing the call from object to object in the Initialize function.

This is something that you can run into sometimes and is directly related to the fact that the Init function is run as soon as the object is loaded - so for a world that has 3 objects in it (for example):

ObjectA
ObjectB
ObjectC

The editor loads them and init's the scripts as they are loaded - so ObjectA's Init function is run before ObjectC's - so if you are requesting information from ObjectC before it may have been loaded, then strange things might happen.

Basically the solution is that if you are doing object->object communication, it should NOT be done in the initialize function.  Initialize should be used to prepare that object and ONLY that object - so reading controller settings from the object's OPR, that type of thing is about all that you want to do in the Initialize function.

Object-Object communication should be done either in the dynamics advance, anim advance or camera setup functions.  Dynamics advance is processed multiple times a frame, but anim advance and camera setup are each processed exactly once per frame - so it depends on what you are doing with the information.

So an updated version of your scripts would be:

Scripts:
reader.gsl
Code:
void DynamicsAdvance( Object@ object)
{
   Object@ writer = GetGameManager().GetWorld().GetObject("writer");
   String what_I_heard = writer.GetControllerVariableString("Story");
   print(what_I_heard);
}

The way you are using the SetControllerVariable() function in writer.gsl is sort of backwards.

This section:

Code:
void SetControllerVariable( Object@ object, const String& in name, String value)
{
   if (name == "Story")
   {
   Story = "Once upon a time, I told the right story. The end.";
   }
}

Should be more like:

Code:
void SetControllerVariable( Object@ object, const String& in name, String value)
{
   if (name == "Story")
   {
   Story = value;
   }
}

This means that you can edit what the variable 'Story' is set to from other objects, like your 'reader.gsl' script, like so:

Code:
void DynamicsAdvance( Object@ object)
{
   Object@ writer = GetGameManager().GetWorld().GetObject("writer");

   String first_version = writer.GetControllerVariableString("Story");
   // outputs "I'm telling the wrong story."
   print( first_version);

   // update 'writer.gsl' with a new story
   writer.SetControllerVariable("Story", "Once upon a time, I told the right story. The end.");

   // read the new story and output it to the screen
   what_I_heard = writer.GetControllerVariableString("Story");
   print(what_I_heard);
   // outputs "Once upon a time, I told the right story. The end."
}

NOW, as a final 'gotcha' with this, because the DynamicsAdvance() is called quite a bit, this same 'loop' will repeat, so the first time it will output:

Quote
I'm telling the wrong story.

But then every other iteration (time that DynamicsAdvance() is called), it will output the second version:

Quote
Once upon a time, I told the right story. The end.

So you'll see the console fill up with the second line repeatedly.

What you need to do to trigger actions once (and only once) is wrap them with a flag to see if it's been completed yet or not, like so:

Code:
bool doneStoryYet = false;

void DynamicsAdvance( Object@ object)
{
   // if we're not done the story yet, then process this section of script
   if (!doneStoryYet)
   {
      Object@ writer = GetGameManager().GetWorld().GetObject("writer");

      String first_version = writer.GetControllerVariableString("Story");
      // outputs "I'm telling the wrong story."
      print( first_version);

      // update 'writer.gsl' with a new story
      writer.SetControllerVariable("Story", "Once upon a time, I told the right story. The end.");

      // read the new story and output it to the screen
      what_I_heard = writer.GetControllerVariableString("Story");
      print(what_I_heard);
      // outputs "Once upon a time, I told the right story. The end."
     
      // we're done, don't need to do this again
      doneStoryYet = true;
   }
   // after outputing the two lines once, the script effectively does nothing afterwards.
}

A good example of this kind of 'one time setup' is in the old character script's DynamicsAdvance() function:

Code:

void DynamicsAdvance( Object@ object, float seconds)
{
       // first-time character setup that requires other objects/players
if (!setupComplete)
{
// check to see if the player has a 'default weapon' that we need to load
                // WeaponFile is a ControllerSetting in the player's OPR file
String weaponFile = object.GetControllerSettingString( "WeaponFile");

                // if there's a default weapon specified, then let's try to load it.
if (weaponFile.GetLength() > 0)
{
                       // add the weapon to the world
PushFullPath( object.GetFullPath());
Object@ newObject = GetGameManager().GetWorld().AddObject( weaponFile, weaponFile);
PopPath();

                        // if the weapon loaded successfully, then...
if (newObject != null)
{
                               // then we can safely add it to the player's inventory and setup some basic variables for the weapon.
Player@ player = GetGameManager().GetPlayer(object);
player.AddToInventory(newObject);
@weapons[0].info = @newObject;
weapons[0].shotOffset = weapons[0].info.GetControllerSettingVector("ShotOffset", Vector(0, 1.0, 0.5));
weapons[0].info.SetControllerVariable("PlayerWeapon", true);
weapons[0].info.SetControllerVariable("Carrier", object);
}
}
                // now that the weapon has been loaded, we set this to true so that this chunk of code isn't run again
setupComplete = true;
}

.... rest of dynamics advance function down here...

Hopefully this won't confuse things even more ;}
Logged
Jim
Jr. Member
**
Posts: 85



View Profile WWW
« Reply #10 on: August 29, 2008, 06:17:39 PM »

I haven't read the entire thread, but if you look at the space shooter sample I provided, it has examples of using these scripting functions.
Logged

www.gamecreation.ca - gamecore stuff.
Squat
Hero Member
*****
Posts: 592


View Profile
« Reply #11 on: August 30, 2008, 02:01:25 AM »

writer.gsl:
line 5: 'Story' is not declared
line 5: Cant' implicitly convert from 'String&' to 'int'
Quote
{void SetControllerVariable( Object@ object, const String& in name, String value)

   if (name == "Story")
   {
   Story = value;
   }
}

reader.gsl:
line 18: 'what i heard' is not declared
line 18: Cant' implicitly convert from 'String&' to 'int'
Quote
bool doneStoryYet = false;

void DynamicsAdvance( Object@ object)
{
   // if we're not done the story yet, then process this section of script
   if (!doneStoryYet)
   {
      Object@ writer = GetGameManager().GetWorld().GetObject("writer");

      String first_version = writer.GetControllerVariableString("Story");
      // outputs "I'm telling the wrong story."
      print( first_version);

      // update 'writer.gsl' with a new story
      writer.SetControllerVariable("Story", "Once upon a time, I told the right story. The end.");

      // read the new story and output it to the screen
      what_I_heard = writer.GetControllerVariableString("Story");
      print(what_I_heard);
      // outputs "Once upon a time, I told the right story. The end."
     
      // we're done, don't need to do this again
      doneStoryYet = true;
   }
   // after outputing the two lines once, the script effectively does nothing afterwards.
}

So using my infinite logistical prowess, I put "String" in front of those variables and WHALLA!!!!...

...would I be posting all this if it worked? I get a blank line. Again.

No error.

No output.

at least 100 syntax alterations

The only logical question that comes to mind at this point is this:
WTF?

Is it just me...or is the reader.gsl writing the variable?

Can Reader be scripted to just read the variable from writer, not have to be the one to set it?

Is it possible to define that variable once and still read it?

Can I drop out the part of your code giving the 3 other options for the variable and just have the variable be set to my story?

LOL, Is it possible to have one object define a variable and have another object read it and print it to the console?

Why didn't you declare 'what_i_heard' or 'Story' as a string somewhere? Mine gives errors. Did yours? Is it a typo or does it mean I'm missing a whole entire paragraph.

Why did you leave out ',float seconds' from the dynamicadvance when I see it everwhere and it's not appearing to do anything at all when set that way.

Where did the word "return" go?

How is it going to print "// outputs "I'm telling the wrong story."

BTW: I noticed that under dynamics advanced, when I add the ',float seconds' my framerate takes a massive hit.

« Last Edit: August 30, 2008, 03:39:58 AM by Squat » Logged
Squat
Hero Member
*****
Posts: 592


View Profile
« Reply #12 on: August 30, 2008, 03:20:54 AM »

BTW, I'm really only experienced in Flash and in there it has movieclips and to access a variable from one movieclip to another was merely to path to it like so "_root.MovieMc.variablename". From any other object, anywhere. If one movie clip contained another, _parent and _this could be used to grab variables depending on how far in the nesting the current object was. An example would be to get the variable from a button inside a movieclip would be "x = _root.MyMovie.MyButton.MyVariable"

Here's what I'm trying to accomplish, working in Flash.

writerMC:
onClipEvent(load){
var story = "Great Story!";
}

readerMC:
onClipEvent(enterFrame){
heard = _root.writerMC.story;
trace(heard);
}

Hell, I can just do this:
writer....story = "scary story";
reader.....trace(_root.writer.story);

one line each script

Seems the 40 lines we're trying to get working could maybe be truncated somehow? I dunno. I know all languages are different, but goddamn that's some serious convolution right there if I've ever seen it.

Oh, and to write the variable is the same thing:
readerMC:
_root.writerMC.story = "NOW THAT'S A STORY FOLKS!";
 
Do we have anything like that?
« Last Edit: August 30, 2008, 03:24:07 AM by Squat » Logged
gekido
Guest
« Reply #13 on: August 30, 2008, 12:25:40 PM »

you have the variable Story defined at the top of your script right?  Like the original post you made:

Code:
String Story = "I'm telling the wrong story.";

You cannot access variables from a script outside of that script - to use C++ type lingo, all scripts defined in a script are considered 'Private' and only have scope within that script.  You must use accessor functions (ie the Set & GetControllerVariable functions) to modify and access the internal variables.
Logged
Squat
Hero Member
*****
Posts: 592


View Profile
« Reply #14 on: August 30, 2008, 01:28:21 PM »

Defining Story was one of my over 100x syntax alterations.

I need a working sample please.
« Last Edit: August 30, 2008, 02:12:51 PM by Squat » Logged
Pages: [1] 2
  Print  
 
Jump to:  

 
Powered by MySQL Powered by PHP bluBlur Skin © 2006, hbSkins
Powered by SMF 1.1.14 | SMF © 2006-2011, Simple Machines LLC
Valid XHTML 1.0! Valid CSS!