- Home /
Using a switch statement to set tile type based on texture.
So I couldn't find any answers to this in all my searching so sorry if its already been answered.
I'm building a tile based board game and I have a set of code that will chose a tile material from an array at random (using a string created on the table).
public void SetTexture() {
if (!flipped) {
textures = (Resources.LoadAll ("Tiles", typeof(Texture2D))).Cast<Texture2D> ().ToArray ();
int tileNum = ojbTable.getNextNumber () - 1;
Texture newTex = textures [tileNum];
GetComponent<Renderer> ().material.mainTexture = newTex;
flipped = true;
}
}
What I want it to do is once it chooses the material to look at the file name of said material (they are all named as Stars1, Stars2, Nebula1, Nebula2, etc.) and set a an int variable to a specific number based on what material the tile has (eg. Star = 1, Nebula = 2, etc.)
I'm not sure if this can be done with a switch statement (using wildcards for the numbers) or if there is a better way to do it. Part of the problem is that I don't want a specific material number to apply to a specific type in case I change the materials or names.
Thanks
Answer by AlwaysSunny · Mar 24, 2015 at 09:25 PM
Sounds like a non-standard approach; going through the basement to get to the attic. I don't like dealing with strings if I can help it. Furthermore, wherever possible, it's wise to atlas your textures together. You seem to be using the words texture and material interchangeably, but they're different. Gotta watch out for that.
I've never dealt with the Resources.Load family, so I'm not up to snuff on any associated best practices. I'm not even sure whether it's possible to pull a texture2D's "name" as such.
I would advise you to reconsider your approach to building and texturing your world to adhere to standard practices for tile based games. This means atlasing your textures, and (unless you've got at most ~100 tiles alive concurrently) not using individual game objects for each tile. Instead set the UVs of each tile to match an atlas position, and merge your tiles into as few compound objects as possible. This isn't as tough as it sounds, and there's plenty of good info around which teaches how this is done.
Regardless of your approach, tying two sets of data together is a job often suited to a new class. Either that, or you'll have to maintain your own records and make several changes each time you change anything, which, as you've already pointed out, would be a bummer.
Consider creating an object (new class) which holds a Texture2D and a string name, both of which you'll assign in the inspector. Another class will hold a list or array of these objects so you can edit them in the inspector. Just make your CustomTextureObject serializable, and it'll show up. This way you're making a little library of CustomTextureObjects you can edit as needed without breaking anything. (In the case of atlasing, this could hold the index of the associated texture in the atlas instead of a texture). Then you can have an arbitrary association between names, numbers, textures; whatever you like. You could have a "category" variable for instance, to grab any random texture within a category. Opens up a lot of options.
[System.Serializable]
public class CustomTextureObject {
pubic string name; // can find by string name
public int index; // can find by index
public Texture2D texture;
}
// this class would work well as a singleton so you never need a reference to it
public class MyTextures : MonoBehaviour {
public List<CustomTextureObject> CTOs; // populate in inspector
public Texture2D GetTextureNamed( string name ) {
foreach (CustomTextureObject cto in CTOs) if (cto.name == name) return cto.texture;
return null; // if not found
}
}
I've never used a serialized class before and I'm not even sure how I would. Nor have I ever dealt with having textures/materials (not really sure what the difference is other then name at least in a practical sense) in the same image and pulling just the part that I want out of it. I'm still pretty new to my coding/unity experience. Thank you for your answer though, I am going to look into serializable classes (if thats even the right word).
In this case, making that class serializable will allow a list or array of them to be visible in the inspector. Otherwise you couldn't see the exposed list. Serialization is (mostly?) about saving and loading data.
The documentation would explain the difference between materials and textures. A material may have zero or more textures and an assigned shader which tells the gpu how to draw objects with that material.
I sometimes go a little crazy when I suggest "best practices" because I wound up learning their importance the hard way. However, don't get bogged down with that. Just make it work however you can and that'll be a good learning experience. Not all situations call for strict adherence to strong design practices, esp. when you're first starting out.
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
Using C# delegates and events to detect similar tiles. 2 Answers