I have a GameObject with a MeshFilter and Renderer and Material but it also has a bunch of other components such as scripts attached.
In response to a game even I want to swap the mesh and materials out with that of another asset.
I’ve loaded the other asset and I can get access to it’s MeshFilter and Renderer (and hence Materials) but it’s flaky. Sometimes the new mesh doesn’t render. Sometimes after a save the original asset prefab seems to have been modified! The new mesh shows it’s MeshFilter referencing the mesh in “*scene” and not “*asset” and I don’t know what that means.
I definitely don’t want to Instantiate the new mesh because I have all the state of the original object but I just need to change the appearance.
Surely someone has encountered this before, but I can’t find a solution.
1 Like
Instantiating a new mesh won’t change any of the other components.
–Eric
Instantiating a new mesh creates a new GameObject which is NOT what I want. Forget I mentioned Instantiate then. How do I change the mesh on an existing GameObject?
No, instantiating a mesh just instantiates a mesh. Not a game object.
var aMesh : Mesh;
function Start () {
var meshInstance : Mesh = Instantiate(aMesh);
GetComponent(MeshFilter).mesh = meshInstance;
}
–Eric
Ah, but I don’t have the mesh yet, I need to load it from a resource. And also what about the materials?
And is the Instantiate necessary? Why can’t I just assign the mesh to my existing GameObject without Instantiate?
Well it’s not quite working. Here is my code:
public void OnTypeChanged()
{
Vector3 newScale = new Vector3(1, 1, 1);
GameObject go;
switch (Type)
{
case NodeType.TREE:
go = Resources.Load("Meshes/BanyanTree") as GameObject;
newScale = new Vector3(0.15f, 0.15f, 0.15f);
break;
case NodeType.ROCK:
go = Resources.Load("Meshes/RockMesh") as GameObject;
newScale = new Vector3(0.5f, 0.5f, 0.5f);
break;
default:
go = GameObject.CreatePrimitive(PrimitiveType.Sphere);
break;
}
MeshFilter mf1 = go.GetComponent(typeof(MeshFilter)) as MeshFilter;
MeshFilter mf2 = GetComponent(typeof(MeshFilter)) as MeshFilter;
mf2.mesh = Instantiate(mf1.mesh) as Mesh;
transform.localScale = newScale;
if (Type == TreeNodeTypeWatcher.NodeType.NONE)
{
renderer.material = null;
}
else
{
renderer.material = Instantiate(go.renderer.material) as Material;
}
}
So I import a package such as RockMesh from another project and place the RockMesh prefab into my “Resources/Meshes” folder. Now I hit this code when I change the type of a placed GameObject from NONE to ROCK. The object appears now as a rock. Good, right? Wrong 
If I then drag my RockMesh prefab onto the scene, the mesh reference in its MeshFilter is now set to None! The collider is still there so I see the wireframe of the mesh, but there’s no mesh to draw in it anymore.
What removed the Mesh from my prefab?
I’m even more confused now, maybe my understanding of Instantiate is wrong, but here’s what happens when I use the above code:
-
Import the RockMesh package. The mesh prefab has a MeshFilter with a mesh named “RockMesh”.
-
Change the type on my object to ROCK so that the above code runs.
-
The ROCK object’s MeshFilter now has mesh “RockMesh Instance(Clone)” and the RockMesh prefab’s MeshFilter has “RockMesh Instance” as it’s Mesh.
How did the prefab change? If you look at the code, the prefab was loaded as GameObject “go”, its MeshFilter was retrieved as mf1, and mf1 was Instantiated to mf2’s Mesh.
Now save and quit and restart Unity and the prefab’s MeshFilter’s Mesh is now “None (Mesh)”
Sorry for yet another post but more to add:
I don’t even have to save and quit! Something modifies the prefab without me even saving!
I import the mesh, change a game object to ROCK, then quit without saving. When I get back in the editor here is what’s odd…
In the project view I can see the RockMesh mesh assigned to the RockMesh prefab.
When I click that prefab and look in the Inspector I see “None (Mesh)” and the MeshFilter’s Mesh.
If I try to reassign the MeshFilter, I see “* Assets *” in grey with “RockMesh - RockMesh” listed under that. When I try to select that mesh, the selction snaps back to “None (Mesh)”
I’m thoroughly confused. I can’t see how an asset is being modified without me saving my project.
Seems that Changing:
Resources.Load("…
to
Instantiate(Resources.Load(…
Did the trick. I’m guessing I was somehow manipulating the original asset and not a clone of it, but I can’t see how since I’m not actually manipulating the loaded resources, so I’d still like to hear some insights on this.
1 Like