This is a thing I kind of miss from some other development environments, is there any way to do this in Unity?
class Foo {
private Material myMaterial = ["Assets/Materials/FooMaterial"];
private Texture2D myTexture = ["Assets/Textures/FooTexture.png"];
}
Assume for the sake of argument that I’m not going to instantiate the Foo class from a prefab, I’m going to attach it through AddComponent. So it’s not viable to assign them through the Editor. And it kind of goes against encapsulating the Foo class if anything that attaches a Foo component has to manage and pass all these variable to the Foo component and can never let the Foo component handle it.
I suppose I can assign a value in the Start function using Resources.Load() is that the only way to identify assets through script?
Resources.Load does exactly this, is there a reason you don’t want to use it?
1 Like
To keep it all in one place, I like the Factory Pattern. In Unity it can take a number of shapes, but here’s one:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MyScript : MonoBehaviour
{
public static MyScript Load(
string resourcesPath, string additionalArgument1, int otherArgument)
{
// code for if this is a pre-defined prefab that you're going
// to load, instantiate, and then customize a bit
GameObject go = Resources.Load<GameObject>( resourcesPath);
go = Instantiate<GameObject>( go);
MyScript myScript = go.GetComponent<MyScript>();
// OR: code for making a new GameObject from scratch
MyScript myScript = new GameObject( "MyScript.Create();").
AddComponent<MyScript>();
// only have ONE of the two blocks of code above!!
// jam in the arguments we need
myScript.additionalArgument1 = additionalArgument1;
myScript.otherArgument = otherArgument;
return myScript;
}
string additionalArgument1;
int otherArgument;
void Start()
{
/// etc...
}
void Update()
{
/// etc...
}
}
Remember, anything you load with Resources.Load() has to be under a folder somewhere named Resources.
Maybe the real problem is that Resources.Load doesn’t let you load Meshes, it only lets you load a GameObject that has Meshes attached to it and then you have to extract Meshes out of it, which seems like an inelegant way to handle this when I just want the Mesh. Whereas you can assign Meshes directly to serialized fields in the editor, but to take advantage of that you have to create this GameObject from a prefab rather than adding it as a component to an existing object.
Resources.Load would bother me less for Textures and Materials because you’re allowed to load them directly, I suppose.
Well, that’s a thing for sure… but never fear! Unity is AMAZINGLY flexible, and you can achieve essentially the same thing this way: you make a MeshCollection ScriptableObject instance that contains all your meshes (you have to drag the references in there), and then you can use that MeshCollection instance to retrieve meshes by name.
Here’s a quickie script I threw together, modeled after my GameObjectCollection class:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu]
public class MeshCollection : ScriptableObject
{
public Mesh[] Meshes;
public int Count
{
get
{
if (Meshes != null) return Meshes.Length;
return 0;
}
}
public Mesh Find( string searchFor, bool ignoreCase = true)
{
if (ignoreCase)
{
searchFor = searchFor.ToLower();
}
foreach( var m in Meshes)
{
var n = m.name;
if (ignoreCase)
{
n = n.ToLower();
}
if (n == searchFor)
{
return m;
}
}
return null;
}
}
You can make as many collections as you want, like for theming or skinning. You can even make a “give me a random mesh” function inside there.
You would drag all the meshes into the instance of MeshCollection in the editor, like so:

Then you can get at them by name using Find().