Hi guys,
i just had a “last minute” request from my client.
I already did a game with a 3d character which needs to pick up 10 items.
Now my clients wants the itema to be picked up in order, for example i got a GameObject spawned 10 times, i need each Clone to have a number from 1 to 10 and the player must pickup the objects in order.
I have no idea how to achieve this…
How can i spawn 10 copies of the same gameObject, assing a value and then check if the player picks up the right one?
No need for script (it would help of course) i need to understand the logic…
One easy way to do this is to have a static value and have it start at zero, then when you spawn a cube assign the cube id value to the static value, then increment the static value number by 1 for each spawned cube. I know you didn’t need a code example but here is what I used for my upcoming game to do this exact thing.
Block.cs
public int assignId = 0;
void Start()
{
orginalColor = renderer.material.color;
assignId = Matching.instance.blockAssignIds;
Matching.instance.blockAssignIds++;
}
Matching.cs
public int blockAssignIds = 0;
public void Start()
{
for (int x = 0; x < maxSize; x++)
{
for (int y = 0; y < maxSize; y++)
{
GameObject blocks = Instantiate(emptyBlocks, new Vector3(y, x, 0), Quaternion.identity) as GameObject;
}
}
}
Empty block is just a prefab with the block.cs script attached to it. It will assign a unique id to each one.
I’m trying to understand the code before using it and i’m doing this thing in JS.
I actually got only one thing that i don’t understand, “assignId = Matching.instance.blockAssignIds;” i got an error instance its not a member of Matching…
I’m trying to understand the code before actually using it but i cannot figure out this error…
Anyway, thank you again because this code is already helping me a lot!
It would appear that Dex intended to implement Matching as a Singleton but didn’t provide any further implementation details. I personally think Singletons that derive from MonoBehaviour are dumb and not actually Singletons but that’s beyond the scope of this thread.
You actually don’t need a static variable at all. You can just have a variable on the player that represents the next ID that needs to be picked up
// in whatever class you are using to manage the player
// we'll call it PlayerMgmt
public class PlayerMgmt : MonoBehaviour
{
public int NextId;
}
// in the class that manages the pickup
public class Whatever : MonoBehaviour
{
public int id;
// assuming this is how you pick stuff up
void OnTriggerEnter(Collider other)
{
(if other.gameObject.tag == "player") // some way of determine player
{
int nextId = other.gameObject.GetComponent<PlayerMgmt>().NextId;
if (nextId == id)
{
// do pickup or whatever then increment
other.gameObject.GetComponent<PlayerMgmt>().NextId++;
}
else
{
Debug.Log("failsauce");
}
}
}
}
Then - assuming you’re spawning via code you can do this, otherwise just assign id via Inspector.
int i = 0;
for (var x = 0; x <maxSize; x++)
{
for (var y = 0; y < maxSize; y++)
{
GameObject thing = Instantiate(...);
// assign id
thing.GetComponent<Whatever>().id = i++;
}
}
KelsoMRK is right I was using a Singleton to pass Matching information around my scripts. I stripped out all of the code just to show you that quick example I used. If you wanted to use the instance variables you would have to make a static variable, but remember that static variables are saved scene to scene and you have to manual adjust them from scene to scene if you want different values.
Then you can call any public function inside of Matching.
KelsoMRK I had a question for you, why do you think singleton from mono are dumb? Not trying to switch topics of this post just curious? I understand they aren’t good for things like enemies since the static value remains the same but if you have variables for the overall game like a count down or something why wouldn’t you use them? I find it a lot smoother and easier to call MyScript.instance.timer -= 10; vs MyScript myScript; myScript.GetComponent().timer -= 10;
Because a MonoBehaviour, assumedly, is attached to a GameObject. While the Singleton pattern will prevent duplicate instances of the class there’s no way to prevent duplicate instances of a GameObject containing that MonoBehaviour from being instantiated into your scene.
I also have yet to see a MonoBehaviour Singleton example that correctly seals the class and gives it a private constructor (the latter of which doesn’t even work on MonoBehaviour derivatives)
To your final example: I would do my best to not make that class inherit from MonoBehaviour.
Hope this isn’t too off-topic, but I’ve found the MonoBehavior pseudo-Singleton to be a rather useful pattern in Unity. Yes, it isn’t a true Singleton, but for many purposes it works as well or better. For example, you can have parameters which are adjustable in level. As a result, you can have different levels with different configurations of the object.
In a typical game, there are a number of these “only one instance, but tied to an actual object in the scene” classes - many UI items, for example.
At that point you’d just have to ask yourself “Self, does this absolutely positively HAVE to be a single instance at all times?” I’m not sure UI items would fall into that category especially. You may think you only ever need one - but what’s the harm in having the possibility of having two at some point? Is that possibility out-weighed by the huge refactoring effort that would be removing the singleton from your code base?
One reason I like to use a Singleton as mono is it allows me to adjust values in the inspector during run time. I make any player or global attributes in this script since it only has one instance anyways and it makes adjusting certain things like speed and damage really easy and fast. I do like not having it as mono though so I don’t have to attach it to anything.
Indeed - an out-of-the-box Inspector window is handy - but I would still seriously question using a Singleton to manage the player.
Here’s a scenario. I made a shooter where the class that controls the player’s stats is a Singleton. Everything works good, my game is super successful, makes tons of money, and gains a huge community. Now, that huge community demands that I make my shooter co-op multiplayer. Part of that multiplayer is displaying the stats of my teammates in some GUI elements on the screen. In order to re-use my state management code I now need to refactor the entire project to not use a Singleton. Or I need to duplicate the code in another class that isn’t a Singleton so that player’s besides myself will work on my client instance and do a less-major refactor of the code to check for those differences.
This is not to say that it isn’t a valid way of doing things, it’s just one that I shy away from. If I use Singletons at all it’s typically for stateless IO type of operations. IE - a Single that listens to TCP/IP ports or writes data to the disk or executes database queries or contacts web services. Other than that I generally say - ok, I’m really only ever going to have one of these things but I’m going to leave the option available to have more than one.