Jump to content
ZaellixA

Convert string to variable

Recommended Posts

Hey all, back here with a question. I am looking for a way to get access to some variables which have the same name with an increasing numerical suffix.

 

I tried to do something like this but to no avail

 

// Trying to get access to objects named (in the editor) obj0, obj1, obj2, obj3, etc.

private _maxIdx = 4; // I get this from somewhere else but I define it here for completeness

// Increase an index
for[{private _i = _0}, {_i < _maxIdx}, {_i = _i + 1}] do {
  // Create the name of the variable
  private _var = "obj" + (str _i); // Parse the name of the variable as a string
  _var = call (compile _var); // Get the object variable

  // Get the position of the object
  _secPos set[_i, getPosATL _var]; // Get the position of the object placed in the sector

  // Delete the object placed at the sector objective
  deleteVehicle _var;
};

This doesn't seem to work. The only evidence I have (haven't done the testing myself unfortunately) is that the objects (obj0, obj1, obj2, etc.) are not deleted in the editor.

 

Any ideas or insights are most welcome :).

  • Like 1

Share this post


Link to post
Share on other sites
Quote

private _var = call compile format["%1", "obj" + str _i];

 

Edited by RCA3
Bad code
  • Like 2

Share this post


Link to post
Share on other sites
21 minutes ago, RCA3 said:

private _var = call compile format["%1", "obj" + str(_i)];

 

Hhhmmm... why should this work though? What I am doing is actually pretty much the same in two steps, 1) _var = "obj" + str _i, and then call compile _var.

 

Am I missing something here?

 

As a note, I haven't tested your solution yet, so I can't say whether it works or not. Thanks though :).

Share this post


Link to post
Share on other sites
// Increase an index
for[{private _i = _0}, {_i < _maxIdx}, {_i = _i + 1}] do {
                                      
  // Create the name of the variable
  private _var = "obj" + (str _i); // Parse the name of the variable as a string
                                      
  _var = missionNamespace getVariable [_var , objNull]; // *NEW* Get the object variable

  // Get the position of the object
  _secPos set[_i, getPosATL _var]; // Get the position of the object placed in the sector

  // Delete the object placed at the sector objective
  deleteVehicle _var;
};

 

  • Like 2

Share this post


Link to post
Share on other sites
Just now, Harzach said:

// Increase an index
for[{private _i = _0}, {_i < _maxIdx}, {_i = _i + 1}] do {
                                      
  // Create the name of the variable
  private _var = "obj" + (str _i); // Parse the name of the variable as a string
                                      
  _var = missionNamespace getVariable [_var , objNull]; // Get the object variable

  // Get the position of the object
  _secPos set[_i, getPosATL _var]; // Get the position of the object placed in the sector

  // Delete the object placed at the sector objective
  deleteVehicle _var;
};

 

Aha...!!! missionNamespace... of course!!!

 

Haha, to be honest, I didn't know that all the objects are saved in the mission namespace as variables. Thanks a lot, I'll give it a try and post back with results.

 

Really appreciated!

  • Like 1

Share this post


Link to post
Share on other sites
1 hour ago, RCA3 said:

private _var = call compile format["%1", "obj" + str(_i)];

 

Well, it seems that this is working (I am having my bro do the testing and let me know :D). Not sure why this works and the one I had does not. If you have any idea, please shed some light...

  • Like 1

Share this post


Link to post
Share on other sites

@Harzach, what Killzone Kid is talking about in there is unrelated. You'd need an expert on that matter: "Secure Callback", but in here we're not sending data over the network, we're just converting a string (compiling code) locally. The danger there as far as I can explain is the client (potential hacker) defining he's own variable locally and then publicVariable'ing it with malicious code into our call compile'd function, executing it through an addPublicVariableEventHandler.

 

@ZaellixA

Here's another way 😁:

Quote

private _var = call compile ("obj" + str _i);

 

I guess yours is not working because you're using the same variable for defining the compiled code as the variable you're compiling 😁:

Quote

private _var = "obj" + (str _i); // Parse the name of the variable as a string
_var = call (compile _var); // Get the object variable

private _var = "obj" + (str _i) ; // Parse the name of the variable as a string
private _obj  = call (compile _var); // Get the object variable

Cheers.

Edited by RCA3
Bad code. Bad explanation.
  • Like 3

Share this post


Link to post
Share on other sites

Hey, thanks for the answer @RCA3. I too think that the problem with format is only related to KK's custom callback system.

 

I have done some variable reuse/reassignment (with different types) in the past with no problems. This shouldn't cause any issues as far as I understand the way it works. You may be right though and I will have another look into it.

 

Nevertheless, thank you all for the contributions :).

Share this post


Link to post
Share on other sites
16 hours ago, RCA3 said:

private _var = call compile format["%1", "obj" + str _i];

 

please don't recommend that to people I see that garbage too often. Just use getVariable. compile has bad performance and was once even a factor in the famous 3FPS bug, please only use it if there is no alternative.

  • Like 3

Share this post


Link to post
Share on other sites
2 hours ago, RCA3 said:

Well... i'm sorry then @ZaellixA, @Harzach, @Dedmen and the community. I clearly don't have a clue what i'm talking about.

Cheers.

Hey, no worries mate. You are trying to help here, nothing bad happened here. In the end, we all came out of this just a wee bit wiser 8).

 

9 hours ago, Dedmen said:

please don't recommend that to people I see that garbage too often. Just use getVariable. compile has bad performance and was once even a factor in the famous 3FPS bug, please only use it if there is no alternative.

Thanks Dedmen for the info, really appreciated.

  • Like 2

Share this post


Link to post
Share on other sites
3 hours ago, RCA3 said:

Well... i'm sorry then @ZaellixA, @Harzach, @Dedmen and the community. I clearly don't have a clue what i'm talking about.

Cheers.

 

Like @ZaellixA said, it's cool. You're a helpful and engaging member of the community.

  • Like 2

Share this post


Link to post
Share on other sites

Hey all, finally found out what the "problem" was... Nothing! The person that was performing the tests didn't create the objects in the editor correctly and this is why they were not deleted...

 

Thank you all for your contributions.

 

Just for the sake of completeness, I tried all ways proposed here and they all had the same results. Haven't performed any efficiency testing, so I can't say which one is faster, but as proposed here, the use of compile is discouraged (thanks Dedmen and Harzach).

  • Haha 3

Share this post


Link to post
Share on other sites

I'm a bit lost on this topic, I have the same question but I'm not sure how it has been answered. To convert a string to a variable is it as below?

 

private _ReSpawnedGuy		= _this select 0;
private _OrigSquadLead		= leader _ReSpawnedGuy;
private _OrigSquad 		= groupID group _OrigSquadLead;
private _ReinSquadName		= _OrigSquad + " Reinserts";
private _SQDCounter		= _OrigSquad + "_Squad_Pack_Counter";

_ReinSquadName			= missionNamespace getVariable [_ReinSquadName, objNull];
_SQDCounter			= missionNamespace getVariable [_SQDCounter, objNull];

But I'm doing something wrong as both _ReinSquadName and _SQDCounter are "<NULL-object>", the default variable state.

Share this post


Link to post
Share on other sites
3 hours ago, SophionBlack said:

both _ReinSquadName and _SQDCounter are "<NULL-object>", the default variable state.

 

Because those two variables don't exist in missionNameSpace - there are no objects with those variable names in the mission, nor have those variables been set.

  • Like 1

Share this post


Link to post
Share on other sites

Something like this? I'm sure there's a more elegant way...

private _ReSpawnedGuy = _this select 0;
private _OrigSquadLead = leader _ReSpawnedGuy;  
private _OrigSquad = groupID group _OrigSquadLead;  
private _ReinSquadName = _OrigSquad + " Reinserts"; 
private _SQDCounter = _OrigSquad + "_Squad_Pack_Counter"; 

_ReinSquadName = missionNamespace setVariable ["ReinSquadName", _ReinSquadName];  
_SQDCounter = missionNamespace setVariable ["SQDCounter", _SQDCounter];

ReinSquadName = missionNamespace getVariable ["ReinSquadName", objNull];  
SQDCounter = missionNamespace getVariable ["SQDCounter", objNull]; 

 

  • Like 2
  • Thanks 1

Share this post


Link to post
Share on other sites
17 hours ago, SophionBlack said:

To convert a string to a variable is it as below?

private _OrigSquad 		= groupID group _OrigSquadLead;
private _ReinSquadName		= _OrigSquad + " Reinserts";
private _SQDCounter		= _OrigSquad + "_Squad_Pack_Counter";

Here, yes;  _ReinSquadName and _SQDCounter are now private variables containing the given strings as they were joined.

 

 

_ReinSquadName			= missionNamespace getVariable [_ReinSquadName, objNull];
_SQDCounter			= missionNamespace getVariable [_SQDCounter, objNull];

Here, no; missionNamespace is the global namespace attached to the mission.  It doesn't see private variables in scripts.

 

You can either declare a global variable using the private variable, and the global variable gets created in missionNamespace:

ReinSquadName = _ReinSquadName;

or you can use setVariable to the missionNamespace as @Harzach showed.  With setVariable to missionNamespace, you can use the public param to broadcast it for multiplayer.

 

When doing getVariable, you would want to make sure the default is the right data type, or you could end up with errors in code, but that depends of course on how you're using it; here it sounds like you were specifically watching for objNull instead of string, for purpose of a test.

 

  • Like 2
  • Thanks 1

Share this post


Link to post
Share on other sites
20 hours ago, SophionBlack said:

I'm a bit lost on this topic, I have the same question but I'm not sure how it has been answered. To convert a string to a variable is it as below?

Hey there  SophionBlack. You already got quite some info on your issue. I'll just add what I did to solve my issue. Well actually, as i said above, there was no problem apart from the fact that the variables were not named prorperly in the editor. Nevertheless my approach was the following.

  1. Create a string containing the name of the object/entity as it is named in the editor.
  2. Use compile to turn that string into actuall code, effectively turning it into a statement. Of course you have to call that code to be effectively used...
  3. Use the returned value of compile as the right-hand side of an assignment statement to save the entity/object (which is the string turned into code) into a variable.
  4. Use the variable at will, according to my needs.

This is how I actually got access in script to the objects I wanted to use, without having to hardcode each and every one of their names. Of course this means that they have to be named accordingly in the editor, which as I have already mentioned was not the case initially. As you can see, this approach can introduce problems if you are not careful enough. Nevertheless, it served me quite well in occassions, such as when you want to get access to many practice targets where they may be named, for example, pTarg0, pTarg1pTarg2, ...

 

A code snippet is shown below demonstrating the said steps (numbered for ease of reference)

// Assume the variables are named obj0, obj1, obj2 in editor

// Create some parameters
private _nObj = 3; // Define number of objects to get
private _objs = []; // Iniitalise array to hold the objects


// Create the strings holding the names of the objects (1)
for ({private _i = 0}; {_i < nObj}; {_i = _i + 1}) do {
  private _temp = "obj" + (str _i); // Here the the string "obj0", "obj1" and "obj2" are created (1)
  
  _objs pushBack call (compile _temp); // Here I compile the string held in _temp to create the code [obj0], [obj1] and [obj2] and then add it to the array (2) + (3)
};

// At this point the array objs contains [obj0, obj1, obj2] which are the objects of interest
// Now you could possibly make the array global or whatever. I go with setVariable here for demonstration
missionNamespace setVariable ["myArrayOfObjects", objs, true]; // I also make it public with the last argument

The only difference here from the steps mentioned above is that I actually push back the objects into an array instead of using them in an assignment.

 

I am not sure how close is that to what you want to achieve. If not, apologies for the clutter but if it helps anyhow and you would require clarifications and or more info please don't hesitate to ask.

  • Like 1
  • Thanks 1

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now

×