• Advertisement
Sign in to follow this  

Unity Accessing arbitrary variables at runtime

This topic is 4310 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, This is my first post and first of all let me say thanks for all the help the gamedev community has provided regarding programming (especially OpenGL). On to my question: I have a C++ program and I would like to be able to get and set variables while my app is running. What is a good way to provide access to program variables? For the sake of context, this is an OpenGL app that has enough variables that binding keys, etc is impractical. I've written a little console (like a simple version of what you get in Quake, etc when you press tilde). I can enter commands to check and change variables in the console. However, the way I've written it I have to code a separate function for each variable I want to get/set. When I parse/interpret the command line i resolve a function pointer, pass it the params and execture it. Is there some better (more general way) to do this? I'm sure others have this type of functionality in games or other programs. What approach have you used / do you suggest? Has anyone gone so far as to create a simple debugging environment (like a lightweight gdb) or something like an interpretive language interface, where you can call your functions directly? Thanks in advance, Frank.

Share this post


Link to post
Share on other sites
Advertisement
You could do it in a general way using .Net reflection, but that obviously only works if you're using a .Net language.

You could also do it in a general way if you expose things through a scripting language and have your console execute that scripting language.

I don't have any experience exposing my code through a scripting language, though, so I don't know if there's any languages or tools that would let you automatically expose everything.

You could also store every variable you want to be able to modify in a hash table indexed by a string and have your console automatically look up the variable in the hash table.

Share this post


Link to post
Share on other sites
For your console class I could imagine something like

Console.BindInt( "PlayerX", &player->x );


And then from the console, while in the game, you could type

SET PlayerX 400

Share this post


Link to post
Share on other sites
It's pretty simple to do a basic command line in the program, you could (for example) have something like std::map<std::string, boost::function<void (const std::string&)> >, then tokenize each command line by spaces and pass to the function described by the map at the first string in the command.

Share this post


Link to post
Share on other sites
Hi,

Thanks for the help. .Net reflection looks pretty powerful. Alas, I'm not using .Net. I implemented a map for functions (get, set, etc) and a function to bind variables, as recommended. It's definitely better than a single function for each variable!

I'm now trying to template it to avoid creating BindFloat, BindString, etc..., and perhaps to avoid using switches in the my get/set/print... functions (and to learn about templates). I've created a function:

template <typename T>
Console.Bind(string & const name, T *ptr, boundVar_t type)

But it seems silly that I need the boundVar_t tag. Is there a better (implicit) way to keep track of the type so I can do the appropriate thing with the data later? Can T be saved directly somehow?

Thanks again,
Frank


Here's are some snippets from my current implementation:

// type tag
typedef enum {
intt, floatt, stringt // must specify every possible type :(
} type_t;

typedef struct {
string name;
type_t type;
void *ptr;
} boundVar_t;

//: Bind variable
void Console::Bind(string const &name, T *ptr, boundVar_t type)
{
boundVar_t newBind;
newBind.name = name;
newBind.type = type;
newBind.ptr = (void*) ptr;
variableList.push_back(newBind);
}


// ... somewhere in Console.Set

switch (variableList[hash].type) {
case intt:
*((int*)variableList[hash].ptr) = (int)valueParsedFromCommandline; break;
case floatt:
*((float*)variableList[hash].ptr) = (float)valueParsedFromCommandline; break;

// ...

Share this post


Link to post
Share on other sites
Im not sure what you were looking to do, How about you wrap the variables themselves in templates, some sort of convinance class.


template<class T>
class BindVar
{
BindVar(std::string, *T);
Get();
Set(T);

T *item
}

// Usage
int *variable_to_bind = myengine::getvar();
BindVar<int> bv = new BindVar<int>("Master", variable_to_bind);
Console::Get().AddToHash(bv)

Share this post


Link to post
Share on other sites
Hi,

When etothex originally mentioned boost, I didin't look at it very carefully. I've now read the tutorials. It looks very useful, thanks snk_kid. I'll try it your way first, Paul, then I'll try boost.

Thanks again,
Frank

Share this post


Link to post
Share on other sites
I'd use a vector of variants, and a map of value names to variant indicies.

Share this post


Link to post
Share on other sites
Quote:
Original post by snk_kid
I suggest investigating boost libraries, in particular Boost.Variant.


Oh, hell yes!

I like to think that I have a bit of experience in this as I've spent the last month and a half writing my console, and I'm just finishing it up for functions.

For variables, I'm using boost::variant, and I'm storing them in a std::map<std::string, boost::variant> object. The variant can be a pointer, and I've created the visitors, so when it is a pointer, it's de-referenced and value it points to is get or set.

Share this post


Link to post
Share on other sites

enum { success, failure, /* more status results */ } status;

// Functions to read to and write to void pointers:
typedef status(*set_func)(string const& src, void* dest);
typedef status(*get_func)(string& src, void const* dest);

// A value that knows how to be read from and written to:
struct console_value {
void* v;
set_func set;
get_func get;

console_value(void* v_, set_func set_, get_func get_ ):
v(v_), set(set_), get(get_) {}
};

// the names of the user-modifiable values:
typedef std::map< string, console_value > value_map;

// you have to write the actual string <-> value conversions
status parse_value( string const& value, double& d );
status parse_value( string const& value, int& d );
status parse_value( string const& value, string& d );
// etc.

status print_value( string& result, double d );
status print_value( string& result, int d );
status print_value( string& result, string const& d );
// etc.

// helper code:
template<typename T>
struct setter_getter {
private:
static status set_data( string const& value, T* t ) {
return parse_value( value, *t );
}
static status get_data( string& result, T const* t ) {
return print_value( result, *t );
}
public:
static status set_helper( string const& value, void* v ) {
return set_data( value, reinterpret_cast<T*>(v) );
}
static status get_helper( string& value, void const* v ) {
return set_data( value, reinterpret_cast<T const*>(v) );
}
};

template <typename T>
void Bind(value_map& vm, string & const name, T *ptr)
{
typedef setter_getter<T> set_get;
console_value cv( ptr, set_get::set_helper, set_get::get_helper );
vm[name] = cv;
}


and voila. You just have to pass pointers to the data.

You can even have read-only parameters with very little work, or parameters that are not strictly variables.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
  • Advertisement
  • Popular Tags

  • Advertisement
  • Popular Now

  • Similar Content

    • By Innoc uous
      I'm working on a space game, and I suck at art. I would love to get some help from someone who is more skilled than me. Things I need include modular space ship parts and GUI elements. Nothing too fancy, just functional so I can get a prototype put together. This could potentially become a serious project, but for now this is just a hobby project.
       
      In this video, you can see a few things I already completed
      :2018-02-24 20-08-13.flv2018-02-24 20-08-13.flv
    • By Innoc uous
      If you want to incorporate noise into your shaders, the Turbulance Library has you covered. Using code I gathered from this library, I made a cginc file that contains all you need to easily implement noise into your unity shaders. Who knows how this stuff works, but man, does it work well!
       
      https://pastebin.com/LLCUpJut
       
      Here is an example of what you can create using these noise functions.
       
    • By Nio Martinez
      I'll be buying a new laptop as my workstation for building games, Mostly 3D but not hard core. 
       
      I'm stuck at choosing between these 2 specs below. Does this really matter and if so, can some one tell my how and why it matters. 
      Choice1:
      Intel core i5-8250U (8th gen Kabylake refresh)(6 MB Smart Cache, 1.6 GHz Base with Turbo Boost up to 3.4 GHz) 4 cores 8 threads
      RAM 8 GB DDR4 (2400 MHz)
      GPU 2 GB DDR5 Nvidia MX150 256 bit
      SSD: yes
      Choice2:
      Intel core i7-7500U 2.70GHz Base Processor (4M Cache, up to 3.50 GHz Boost) 2 Cores, 4 Threads
      RAM 4 GB DDR4 (1800 MHz)
      GPU 2 GB DDR5 Nvidia GeForce 940MX 256 bit
      SSD: No
       
    • By Manuel Berger
      Hello fellow devs!
      Once again I started working on an 2D adventure game and right now I'm doing the character-movement/animation. I'm not a big math guy and I was happy about my solution, but soon I realized that it's flawed.
      My player has 5 walking-animations, mirrored for the left side: up, upright, right, downright, down. With the atan2 function I get the angle between player and destination. To get an index from 0 to 4, I divide PI by 5 and see how many times it goes into the player-destination angle.

      In Pseudo-Code:
      angle = atan2(destination.x - player.x, destination.y - player.y) //swapped y and x to get mirrored angle around the y axis
      index = (int) (angle / (PI / 5));
      PlayAnimation(index); //0 = up, 1 = up_right, 2 = right, 3 = down_right, 4 = down

      Besides the fact that when angle is equal to PI it produces an index of 5, this works like a charm. Or at least I thought so at first. When I tested it, I realized that the up and down animation is playing more often than the others, which is pretty logical, since they have double the angle.

      What I'm trying to achieve is something like this, but with equal angles, so that up and down has the same range as all other directions.

      I can't get my head around it. Any suggestions? Is the whole approach doomed?

      Thank you in advance for any input!
       
    • By devbyskc
      Hi Everyone,
      Like most here, I'm a newbie but have been dabbling with game development for a few years. I am currently working full-time overseas and learning the craft in my spare time. It's been a long but highly rewarding adventure. Much of my time has been spent working through tutorials. In all of them, as well as my own attempts at development, I used the audio files supplied by the tutorial author, or obtained from one of the numerous sites online. I am working solo, and will be for a while, so I don't want to get too wrapped up with any one skill set. Regarding audio, the files I've found and used are good for what I was doing at the time. However I would now like to try my hand at customizing the audio more. My game engine of choice is Unity and it has an audio mixer built in that I have experimented with following their tutorials. I have obtained a great book called Game Audio Development with Unity 5.x that I am working through. Half way through the book it introduces using FMOD to supplement the Unity Audio Mixer. Later in the book, the author introduces Reaper (a very popular DAW) as an external program to compose and mix music to be integrated with Unity. I did some research on DAWs and quickly became overwhelmed. Much of what I found was geared toward professional sound engineers and sound designers. I am in no way trying or even thinking about getting to that level. All I want to be able to do is take a music file, and tweak it some to get the sound I want for my game. I've played with Audacity as well, but it didn't seem to fit the bill. So that is why I am looking at a better quality DAW. Since being solo, I am also under a budget contraint. So of all the DAW software out there, I am considering Reaper or Presonus Studio One due to their pricing. My question is, is investing the time to learn about using a DAW to tweak a sound file worth it? Are there any solo developers currently using a DAW as part of their overall workflow? If so, which one? I've also come across Fabric which is a Unity plug-in that enhances the built-in audio mixer. Would that be a better alternative?
      I know this is long, and maybe I haven't communicated well in trying to be brief. But any advice from the gurus/vets would be greatly appreciated. I've leaned so much and had a lot of fun in the process. BTW, I am also a senior citizen (I cut my programming teeth back using punch cards and Structured Basic when it first came out). If anyone needs more clarification of what I am trying to accomplish please let me know.  Thanks in advance for any assistance/advice.
  • Advertisement