- Home /
make a script unique to the gameobject it is attached to
Okay lets try this again: I posted a similiar question to this one before but i see that things got complicated and people probably didnt understand what i wanted to accomplish. Im going to try again but try to make it more clear and simple to understand.
In my project i can spawn several gameobjects and all these objects carry a script. Becuase of this i will have several instances of the same script running in the scene. What i want to figure out is how i can make this script only behave to the gameobject i am accessing.
The variable that i want to be unique for every single gameobject is an int (stateCount) that i use in a switch-statement. This int tracks the state of the gameobject and its behaviour and since all the gameobjects react to this they will follow along even though i only wanted to access 1 gameobject.
Do i need to make a new class for this int? Can i get a ID for each gameobject spawned and that way will make each script unique? Do i need to make a new way on how i handle the changing of this int?
If i didnt make myself clear this time, please let me know in the comments section if you dont understand. Rather that then people ignoring the question since it seems complicated and obscure.
So basically, you want to add a script and assign a unique id when you instantiate it through code?
Because your question is indeed a bit vague :p In theory, every variable (unless it is static) belongs only to the instance of that script (if you add a script to a GameObject, its values are unique in a way that when you change them, only its values are changed, not the values of other GameObjects with the same script attatched).
to make a unique identifier for each object, you could do something like this...
public class Example : $$anonymous$$onoBehaviour
{
private static newIndex = 0;
public int myUniqueValue; // your unique value
private void Awake()
{
myUniqueValue = newIndex;
newIndex++;
}
}
Where the next unique value is stored in a static variable, which is shared between all objects. Then when you instantiate an object, we copy that value and increment the original, so that the next time you instantiate a script, the vaue is 1 higher resulting in an unique id
EDIT:
Looking at your other question, I might have misunderstood your actual problem/misunderstanding :p If I did, Where/when do you call PlaceShip()?
So once i add the script to the gameobject (and not that it already has it when its instantiated) its values and variables are unique only to the gameobject and not all other?
I tried out ur example it kind of broke. This int can only be between 0 and 1 since its used in a switch statement.
switch(stateCount)
{
default:
mousePos = new Vector3(mousePos.x, mousePos.y, 9);
transform.position = Camera.main.ScreenToWorldPoint(mousePos);
gameObject.GetComponent<BoxCollider>().enabled = false;
break;
case 1:
transform.position = new Vector3($$anonymous$$athf.Round(currentPos.x),
$$anonymous$$athf.Round(currentPos.y), $$anonymous$$athf.Round(currentPos.z));
gameObject.GetComponent<BoxCollider>().enabled = true;
break;
}
default = stateCount = 0 and case 1 = stateCount = 1. I managed to get the int to 2 which makes the whole function broken so i dont know if this is gonna work for me or i am doing something wrong. Im more interested in the idea u suggested of assigning the script to the prefab AFTER it is instantiated and if this will make the variable only change to the instance of the script and not the script of the prefab so to say
void PlaceShip()
{
if(Input.Get$$anonymous$$ouseButtonDown(0))
{
Ray ray = Camera.main.ScreenPointToRay(mousePos);
RaycastHit hit;
if(Physics.Raycast(ray, out hit))
{
if(hit.collider.tag == "playerTile" && stateCount == 0)
{
Debug.Log("placement");
stateCount++;
}
else if (hit.collider.tag == "submarine" && stateCount == 1)
{
Debug.Log("picked");
stateCount = 0;
}
}
}
}
I click a UI button in the scene to instantiate a object. I can place it on a grid and i can click on the object to pick it up
Everything is in the same script (Ship.cs) The functions are in Update() and called through different methods (changing of int and input)
Answer by vittu1994 · Apr 23, 2016 at 03:51 PM
Okay i fixed my problem now with the help i got. The issue was that i needed to call PlaceShip() somewhere else and not in the ship script. I did a script that focuses on raycasts on the camera that will call the function from the ship script. The problem was that i couldnt access the ship i was currently holding since the way i used raycast was to detect tiles where i could place the ship, not that i was using the raycast to detect the ship.
The thing i did was to create a parent where i assigned the gameobject to when spawned. Through the camera/ray script i managed to access this parent then do a foreach loop to detect the child (the ship) and access through a empty gameobject variable called aquiredship in the camera script. There i could access the ship script and from there it was easy. Whenever i had a ship selected, the aquiredship variable got access to it and whenever i didnt want it selected i just set the variable to null
Answer by troien · Apr 23, 2016 at 11:28 AM
So once i add the script to the gameobject (and not that it already has it when its instantiated) its values and variables are unique only to the gameobject and not all other?
Well, when you instantiate a gameobject, all scripts attatched to it are instantiated aswell, unless their variables are static, they are unique in that when you change them, no other gameobjects with the same script will change aswell.
Unless ofcourse you accidentally change the variable of all instances to this other value. Which is what I think is happening (But I'm not sure because I don't have all the info).
If all objects have the same script, and each script does exactly the same thing in it's update loop, then the results will all be the same. The values aren't shared, they just happen to have the same value because they all did the same.
For instance, in the Update loop, "Input.GetMouseButtonDown(0)" is true for each instance of a script. (As it doesn't check where the mouse is, it just checks if the button is held down) So each script is gonna say, yes button is clicked, lets raycast. Yes we raycast agains something, lets put our own stateCount to 0 or 1. So each instance sets its own value to the same value individually.
That's why I asked when PlaceShip is called. It should only be called only on the object of which you want stateCount to change, if you just call PlaceShip in update, then each gameObject with this script attatched will do the exact same thing, as for everyone, the mousebutton is held down, and the ray from the mouse position to the world will hit the exact same object
I converted this comment to an answer since it addresses pretty much all cases. The OP should have linked at least his first question as it contains at least some code. And by looking at those snippets we can see that that's exactly what's happening. He checks the mouse button on every instance and does the same thing on all instances.
The solution is to either:
do this placement code on a single script. That should be on the camera since you cast the ray from there. The script would have to check what the ray actually hits and tell those single instance to do something.
If that code stays on each instance the script should check if the object the ray hits is "itself". So you would check it
hit.collider
is the same asGetComponentInChildren<Collider>()
. This of course only works when the object only has one collider. If it has multiple colliders you would have to iterate through all of them or go up the hierarchy to find the parent which you can compare.
The second solution has many drawbacks: If you have many objects, this is extremely inefficient since all instances do cast their own ray. Each instance will check if the object their ray hits is their own object and in the end only one object will actually do something.
The first approach is the one that makes the most sense. Having a seperate script on the camera which casts only one single ray to deter$$anonymous$$e which object is under the mouse cursor. That script can either use Send$$anonymous$$essage to tell that object to do something or use GetComponent<Ship>()
on the object you've hit to access the Ship-script instance on that one ship object.
Your answer
Follow this Question
Related Questions
instantiate gameobject[] 1 Answer
How to create an individual altered ScriptableObject? 2 Answers
Instantiate a COMPLETELY Unique Instance of an Object 1 Answer
Accessing variable in a specific instance of a prefab 1 Answer
Does attaching a script to a GameObject makes the GameObject an instance of the class? 3 Answers