- Home /
How assign gameobjects to a string and reference them again?
Hello UnityAnswers- I need help figuring and setting this up. Here is the situation- I would like to set, store/recall creatures with buttons that are automatically assigned to them when I allow them in my party.
I have no idea on how to set this properly, so I'll attempt something we can start on...I know it's lame, but it's all I understand to tackle this yet :(
On Beasts speech
Long story short--
if you say yes:
do something like ( Hero.Beast[i] = gameObject;
) ???
On Hero's script
static var Beast : GameObject [];
function OnGUI(){
var LineupInt : int = -1; var LineupStrings : String[] = ["Beast1", "Beast2", "Beast3"]; LineupInt = GUI.Toolbar (Rect (25, 25, 250, 30), LineupInt, LineupStrings);
if(LineupInt == 0) // press Button1
if (Beast.length > 0){
if(Beast[1] != null)
Beast[1].SetActiveRecursively(false);
else if(Beast[1] == null)
Best[1].SetActiveRecursively(true); }
if(LineupInt == 1) // press Button2
if (Beast.length > 0){
if(Beast[2] != null)
Beast[2].SetActiveRecursively(false);
else if(Beast[2] == null)
Best[2].SetActiveRecursively(true); }
etc
So, how do I tell the Hero's script Beast[] string to assign someone to the next available number, then reference them again specifically with the buttons?
Thanks for any help! ( ps- how bad is my attempt too? I'M TRYING! :)
EDIT: My answer
Okay, here is the set up:
in the dialogue script, if you accept the offer to join your team, I said this
Hero.Beast.Push (gameObject); to add to the array
in the Hero's script I put this
static var Beast = new Array();
var beast1 = false; var beast2 = false; var beast3 = false; var beast4 = false;
function OnGUI () {
var LineupInt : int = -1; var LineupStrings : String[] = ["Beast1", "Beast2", "Beast3"]; LineupInt = GUI.Toolbar (Rect (25, 25, 250, 30), LineupInt, LineupStrings);
// Beast ONE
if (LineupInt ==0) if(Beast[0] != null){ print(Beast[0]);
// The first is set at the start of the level- will edit later
// Beast TWO
}if(LineupInt ==1) if(!beast2) if(Beast[1] != null) {
print("Beast 2 is stored");
LineupStrings[1].name = Beast[1].name; //(???) see comment
Beast[1].transform.position = transform.position + transform.right * -4 + transform.up *7; Beast[1].transform.parent = transform; Beast[1].SetActiveRecursively(false);
LineupInt = -1; beast2 = true;
}if(LineupInt ==1) if(beast2){
print("Beast 2 is released"); Beast[1].SetActiveRecursively(true); Beast[1].transform.parent = null;
LineupInt = -1; beast2 = false;
//And so on and so forth for each button in the toolbar
Thank you so much Jahroy- I appreciate your above and beyond help. What stuck out the most for me was your mentioning of "Push"; (I couldn't really grasp the rest of your examples at my exp Level yet, but I will be referencing back as my unity exp grows- so your examples wont be wasted!).
As for the 'see comment' mentioned above, how on earth do you change the name of a toolbar button? Is it possible? This button method works for me so far, but it sure would nice to know specifically who you call out ins$$anonymous$$d of just clicking Beast1/2/3.
Try putting your 4 beasts into an array. Then you have some options about how to create dynamic labels for your buttons. $$anonymous$$y example code shows two different methods. The first one uses the function getBeastNames(). This function loops over the array named beastArray and returns an array of strings that contains the name of each beast. This can be passed to GUI.Toolbar(). The second example uses a for loop to iterate over an array of beasts. It draws a button for each beast and uses its name for the button label. I'll add an answer with some new code, too...
Answer by jahroy · Apr 23, 2011 at 03:13 AM
I'm not sure exactly what you're trying to do, but you can add elements to an array of arbitrary size by using Push().
var activeBeastArray = new Array();
for ( var currentBeast : Beast in someArrayOfBeasts ) {
if ( heroWelcomesBeast(currentBeast) ) {
activeBeastArray.Push(currentBeast);
}
}
print(activeBeastArray.length + " beasts have been welcomed out of " + someArrayOfBeasts.length);
Also, there's no need to have so many if statements in your code in this situation. Why not replace your code with this:
lineupInt = GUI.Toolbar(someRect, lineupInt, labelArray);
if ( Beast.length > 0 ) {
if ( Beast[LineupInt] ) { Beast[LineupInt].SetActiveRecursively(false); } }
If Beast[LineupInt] is null, you probably don't want to call a function on it like you suggest. Calling a member function of a null object doesn't usually go over very well (it will throw a null pointer exception).
What is the function SetActiveRecursively supposed to do? It's very difficult to determine what you want to accomplish based on your post. Is the list of Beasts static and there should always be one active Beast?
In that case you might have something like this:
var beastArray : Beast [];
function OnGUI () { var lineupInt = GUI.Toolbar(someRectangle, lineupInt, getBeastNames());
setActiveBeast();
}
/ iterate over array of beasts and set isActive to true if the current beast was selected. set isActive to false otherwise this will leave one active beast */
function setActiveBeast () { for ( var i = 0; i < beastArray.length; i ++ ) { beastArray[i].isActive = ( i == lineupInt ); } }
class Beast { var name : String; var isSelected : boolean; }
function getBeastNames () { var theNames = new Array();
for ( var i = 0; i < beastArray.length; i ++ ) { theNames.Push(beastArray[i].name); }
return theNames; }
Anyways... Not sure if any of that is helpful. Good luck.
EDIT: after original poster's comments
OK... How about something like this:
var beastArray : Beast [];
var buttonStartX = 10; var buttonStartY = 10; var buttonWidth = 100; var buttonHeight = 20;
function OnGUI() {
/ print a button for each beast in beastArray /
for ( var i = 0; i < beastArray.length; i ++ ) {
/* if a beast's button gets clicked, he will go bezerk */
if ( GUI.Button(getButtonRect(i), beastArray[i].name) ) {
beastArray[i].goBezerk();
}
} }
/ function to help arrange a list of buttons vertically /
function getButtonRect ( theOffset ) { var yPos = buttonStartY + theOffset * buttonHeight;
return Rect(buttonStartX, yPos, buttonWidth, buttonHeight);
}
/ Definition of Beast class In this code a Beast object has a Transform associated with it. This script will allow you to create an array of Beasts in the Inspector. You could drag a Transform (or some other object type after changing the code) onto each Beast object. */
class Beast { var name : String; var myTransform : Transform;
function goBezerk () { Debug.Log("My name is " + name = " and I am going bezerk!"); } }
This code will iterate through an array of Beast objects. It will draw a button for each Beast. If the button is clicked, the corresponding Beast will do something (call one of its functions or have a function called on it). How you populate the array of Beasts is another question. If you use this code, you could at least drag and drop Beast objects into the Inspector for testing purposes.
Hope this helps...
Thank you for responding first of all! (Btw, SetAcitiveRecursively(true/false completely turns on/off a game object, but I already got storing and recalling down) This is way over my head, so can I ask you for a little more help? You said it was difficult to imagine my goal; I just want for each button to be set to a specific gameobject through code, in order from 1 to 2 - to basically set each one using the next available button.
Okay- I just tried this as an array to set the first beast and it worked using these- static var Beast = new Array(); (in awake function) Beast.length = 1; Beast.Push (GameObject.FindWithTag("BeastType"));... so how do I set something to be next in the array through another script? I've tried Hero.Beast.length += 1; Hero.Beast.Push (gameObject);, but it doesn't seem to work
Ok, I just edited my response. If you're using dynamic arrays you don't need to manually change the length. Just call Push and your array will grow as it adds new elements. The new code in my response uses builtin (typed) arrays in s$$anonymous$$d. You can edit those in the Inspector. You can also turn dynamic arrays into builtin arrays like this: builtInBeastArray : Beast [] = beastArray.ToBuiltin(Beast);
Hey, can I bug you with one more question? The way lineupInt is set makes the 1st button HUGE until you get more things in the array. Is there a way to set each button to always be one size? Thanks
Your code declares a rectangle of a fixed size to hold your toolbar. I would recommend writing a function that returns a rectangle with an appropriate size based on how many buttons there are in the list. You could also write code that draws each button separately with a for loop. The example above shows exactly how to do this. It even uses a function named getButtonRect() to align the buttons vertically based on their position in the list. Check it out...
Answer by jahroy · Apr 24, 2011 at 07:32 PM
Here's some code that shows you how to use an array of beasts to draw your toolbar and process the result. The name of the beast will be used as the label on the buttons.
It's still hard to determine from your code, but my guess is that you want your hero to be able to add beasts to his posse from a toolbar. If my understanding is correct, you should be able to use just one array of beasts to accomplish this.
Hopefully this code will help:
/* * An array of beasts that will be used to draw the toolbar. * * This array could get populated a number of ways. * The simplest way for testing purposes would be to drag * and drop GameObjects into the Inspector. * * I'm using an array of GameObjects because I'm trying to * mimmick your code as much as possible. In all likelihood, * you'll want to create a class named Beast, which would * contain a GameObject and some other info about your beasts. * You can find example code to create a class in my first answer. * */
var beastChoices : GameObject [];
function OnGUI () {
var lineupInt = -1;
/* set the string of arrays from the array of GameObjects */
var lineupStrings = getBeastNames();
lineupInt = GUI.Toolbar(Rect(25, 25, 250, 30), lineupInt, lineupStrings);
/*
* Now that you have an array of beasts, you don't have to have a bunch of
* if statements. You can take the result of the Toolbar selection and
* reference the associated beast.
*
*/
/* this is how you get the chosen beast */
var chosenBeast = beastChoices[lineupInt];
/* now you can write a function that does stuff to the chosen beast */
doStuffToBeast(chosenBeast);
/*
* OR you could loop over all the beasts in the array and call one
* function on the chosen beast and a different function on the other beasts.
*
*/
for ( var i = 0; i < beastChoices.length; i ++ ) {
print("Current beast: " + beastChoices[i].name);
/* do stuff to the beast chosen in the toolbar */
if ( lineupInt == i ) {
doStuffToBeast(beastChoices[i]);
}
/* reset all the other beasts */
else {
resetBeast(beastChoices[i]);
}
}
}
function doStuffToBeast ( theBeast ) { print("Doing stuff to " + theBeast.name + " because it was selected");
theBeast.transform.position = transform.position + 10;
theBeast.transform.parent = transform;
theBeast.SetActiveRecursively(false);
}
function resetBeast ( theBeast ) { print("Reset " + theBeast.name + " because it was NOT selected");
theBeast.transform.parent = null;
theBeast.SetActiveRecursively(true);
}
function getBeastNames () { if ( ! beastChoices ) { Debug.Log("Beast array is null!"); return; }
var theNames = new Array();
/* for each beast in the array, add name to array named theNames */
for ( var i = 0; i < beastChoices.length; i ++ ) {
theNames.Push(beastChoices[i].name);
}
/* convert the dynamic array into a builtin array */
var theBuiltinArray : String [] = theNames.ToBuiltin(String);
return theBuiltinArray;
}
Alright- I tried the second method of your examples and can't figure out why I am getting error messages. I think something is off/missing. Note- I could not use any bit of the code with beastChoices : GameObjects[];, it only takes New array(); for that, and then it doesn't like how getbeastNames is set up for lineupInt. I will put the erro message in the next comment
Assets/$$anonymous$$y scripts/EdensPage.js(73,25): BCE0023: No appropriate version of 'UnityEngine.GUI.Toolbar' for the argument list '(UnityEngine.Rect, int, Array)' was found.
also, the bunch of if statements I put did have a purpose- it checked if the creature was currently active or not, so it could be 'released' or 'recalled' only when I clicked its lineup button. without those booleans, the game will continually either store/ not store the animal because it's not told to check on press
It should be GameObject [] not GameObject*s* []. Check out this page: http://unity3d.com/support/documentation/ScriptReference/Array.html
I changed my getBeastNames() function so that it returns a builtin array rather than a dynamic one. The for loop in my code replaces the unneccessary if statements in your code. It takes the result of the toolbar and calls a function only on the beast that was chosen. $$anonymous$$y example demonstrates how you could optionally call one function on the chosen beast and a different function on the other beasts.
Oops, that was a typo on my part. I did put GameObject in the actual script, but for some reason it still only likes array. It works now anyway!
Answer by superventure · Apr 25, 2011 at 07:18 AM
Okay- here is the finished result
static var Beast = new Array ();
var lineupStrings : String[]=["empty1", "empty2", "empty3", "empty4"];
function OnGUI () {
var lineupInt = -1;
lineupInt = GUI.Toolbar( Rect (370,25,370,30), lineupInt, lineupStrings());
for ( var i = 0; i < Beast.length; i ++ ) {
if ( lineupInt == i )
if (!Beast[i].transform.IsChildOf(transform)){ //**see comment**
doStuffToBeast(Beast[i]);
lineupStrings[i] = Beast[i].name;
lineupInt = -1;
}else {
resetBeast(Beast[i]);
}
}
function doStuffToBeast ( theBeast ){
print("Doing stuff to " + theBeast.name + " because it was selected");
theBeast.transform.position = transform.position + transform.right * -4 + transform.up *7;
theBeast.transform.parent = transform;
theBeast.SetActiveRecursively(false);
}
function resetBeast ( theBeast ){
print("Reset " + theBeast.name + " because it was NOT selected");
theBeast.transform.parent = null;
theBeast.SetActiveRecursively(true);
}
Again, thank you so much for sticking with me through this and patiently helping me to understand. I really do appreciate your efforts, you helped me with a big issue I'll be using throught out my game
I had to add some type of checker to see if they are currently stored or not (I hope I can explain clearly) or they would quickly cycle through both dostuff and resetbeast without it when you click their button, so its looks like nothing happen, but it really did both in the blink of an eye
Your answer
![](https://koobas.hobune.stream/wayback/20220613124556im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
How to declare a multidimensional array of strings in c#? 2 Answers
Reverse a String? 0 Answers
Assigning array element to variable 1 Answer
How do I check for strings in an array to match up with the index of another array? 1 Answer
Splitting String only on a "space". Using my method --- FIXED 2 Answers