Swapping Texture via Script...

I am trying to swap a texture that is in the project but not in the hierarchy. Essentially I am creating a primitive and applying a material that has a texture on it. Then, when I interact with that primitive I want to change the mainTexture. My code looks like this:

function OnMouseDown(){
	
	var tex : Texture2D = Texture("zipOutFumeHoodDown");
	renderer.material.mainTexture = tex;
}

I know this is not correct but I am not sure how to do it. Just to clarify I want to grab a texture from my project that is not currently in the hierarchy. Does that make sense?

Thanks.

– Clint

Declare the texture variable outside the function and then drag the texture from the Project View onto the corresponding slot in the Inspector.
Note that if you use a lot of different textures, it might be a good idea to make a manager instead of having texture variable all over the place.

Thanks Talzor…

Thing is I am attaching the script at runtime so dragging the Texture doesn’t seem to be an option to me (unless there is a way to do this so it stays but what I have seen here .

What I was hoping for is the syntax for doing this without having to drag anything from the GUI (i.e. How do I get a texture reference from an item in my project that is a texture).

Hopefully that provides more insight in what I am trying to accomplish.

Thanks,

– Clint

I believe Unity will exclude assets that are not part of a scene when building a game. A way around this is to attach assets that you may use via scripting to a manager object that you can the access from script. This object can be any design that you desire. You could probably even use a wizard to set up the object for you. Of course the wizard would have to be written :slight_smile: Another option is to have a directory distributed with your game where you could use the .Net API to load a texture from disk. A third option would be to use the WWW class, but then you would have to be running a server that would need to be available.

I that case I’d strongly suggest making a manager e.g.

public class TextureManager : MonoBehaviour {
	public Texture2D[] textures;

	private static TextureManager instance = null;
	public static TextureManager get {
		get {
			return instance;
		}
	}

	void Awake() {
		if (instance == null)
			instance = this;
		else
			Debug.LogWarning("You have more than one TextureManager in the scene.");
	}


	public Texture2D GetTexture(string name) {
		foreach (Texture2D texture in textures) {
			if (texture.name == name) //IF we have found the texture
				return texture; //THEN return it
		}
		
		return null; //We didn't find a texture with name "name"
	}
}

Attach this to an empty game object in your scene and fill out the “textures” array with your texture. You can now get a texture from anywhere in you code by using

TextureManager.get.GetTexture("MyTexture");

There isn’t any easy way to get an texture (or any asset) without having it in you scene somewhere. This is because Unity only includes the assets that are actually used. I really, really recommend the manager solution :smile:.

Ahh, to slow… I shouldn’t have run the spellcheck :lol:. All credit goes to Ifrog.

Thanks a ton Talzor!!! :stuck_out_tongue:

I see the benefit with that and will definitately look at that as a good way to implement it…

Regards,

– Clint

Thanks lfrog as well :smile:

– Clint

Hopefully last time bothering you all on this for a while. :wink: The example provided looked to be CS so I converted it to JS. Is my conversion proper?

class TextureManager {
	
	var textures : Array;
	private var instance : TextureManager;	
	
	function Awake(){
		if (instance == null){
			instance = this;
		} else {
			Debug.Log("You have more than one Texture Manager in the scene");
		}
	}
	
	function GetTexture(name : String){
	
		for(var texture in textures){
			if (texture.name == name){
				return texture;
			}
		}
		
		return null;
	
	}
	
}

Thanks again,

– Clint

Nah, you actually gave a useful example :smile:

Well… there was a reason I wrote it in C#, namely that I’ve never really used JS for anything “seriously”, so I don’t know how to get the same level of “elegance” in the code, but here’s my best shot anyway.

public var textures : Texture2D[];
private static var instance : TextureManager;   

static function Get() : TextureManager {
	return instance;
}
   
function Awake(){
	if (instance == null)
		instance = this;
	else
		Debug.Log("You have more than one Texture Manager in the scene");
}

function GetTexture(name : String) : Texture2D{   
	for(var texture : Texture2D in textures){
		if (texture.name == name)
			return texture;
	}

	return null;
}

which must be in a file named TextureManager.js and is then accessed as TextureManager.Get().GetTexture("TextureName");

The key part of both the C# and JS scripts are the existence of the static variable (called instance). Being declared as static means that all instances of the class share this field, which means that you don’t need an instance of the class to asses it. In our case we use this to asses the instance of the manager without actually having to hold a reference to it everywhere in the code.

This process could be automated further like this:

http://unity3d.com/Documentation/ScriptReference/EditorUtility.FindAsset.html

d.

1 Like

As I understand it, he needs the texture swapping functionally for the actually game, not as an editing functionality. If he uses FindAssest() Unity won’t include the texture in his build and he’ll have to add them himself (which AFAIK isn’t even possible if he’s making deploying to a web-player). But please correct me if I’m wrong :smile:.

You use FindAsset from editor code to autopopulate an array. Then at runtime you search from this array - works a treat.

Ahh, I see. That’s a great idea.

Cool guys!

Thanks for all the info and help… I’ll plug away at it a bit more.

Regards,

– Clint

Okay, next silly question… :sweat_smile:

Now I added the menuItem code but do not know how to essentially loop through my project folder and find textures to add to my array.

Here is my code:

public var textures : Texture2D[]; 
private static var instance : TextureManager;    

@MenuItem("GameObject/Get Textures")
static function GetTextures(){
	
	// I assume I will be looping here but not sure on the metric
	textures.add();	// Not sure what to add here
}

I have also attached a capture of the folder in the project I would want to grab textures from.

Thanks for the help!

– Clint

22890--818--$texturetoget_237.png

I think I got it. :wink:

FindObjectsOfType

I believe will do the trick.

Thanks,

– Clint

Nope, that doesn’t work. :frowning:

Anyone, have some ideas?

Thanks,

– Clint

I am trying to use the FindAsset to store a list of all the textures in a specific folder.

Here is my code:

import UnityEditor;

private static var textures : Texture2D[]; 
private static var instance : TextureManager;    

@MenuItem("GameObject/Get Textures")
static function GetTextures(){	
	textures = EditorUtility.FindAsset("zipOuts/", Texture2D);
	
	print(textures.length);
	
}

The intent is to get a list of all the assets from the zipOut folder but I am getting the error.

"Cannot convert ‘UnityEngine.Object’ to ‘(UnityEngine.Texture2D)’

Any ideas?

Thanks,

– Clint