Raffaele Tasso
Raffaele Tasso

Reputation: 67

MeshFilter.sharedMesh changes remains after stopping game

I'm using the following code to flip the UV on the backside of a cube:

Vector2[] uvs = GetComponent().sharedMesh.uv;
uvs[7] = new Vector2(0, 0);
uvs[6] = new Vector2(1, 0);
uvs[11] = new Vector2(0, 1);
uvs[10] = new Vector2(1, 1);
GetComponent().sharedMesh.uv = uvs;

It flips the uv as expected, but if I comment out everything and hit play in unity editor, I see that the uv remains flipped (as if the code produced a permanent change to the uv).

If I close and reopen Unity editor, and then hit play, the uv is again in it initial (non flipped) status.

This is not really issue in this case, but it caused me many troubles during debug, can someone explain this behaviour?

Upvotes: 0

Views: 1141

Answers (2)

Programmer
Programmer

Reputation: 125455

There are two ways to retreive mesh:

1.GetComponent<MeshFilter>().sharedMesh

MeshFilter.sharedMesh points to the original mesh of the model which means that when you modify it, all of the instantiated prefabs from this model will also be modified. It is recommended that you only use MeshFilter.sharedMesh to read the mesh but do not use the data returned from MeshFilter.sharedMesh to modify it.

This is why you are seeing the current effect and should only be used if you want to affect every other prefabs/GameObjects that uses this mesh.

2.GetComponent<MeshFilter>().mesh

MeshFilter.mesh points to the current copy of the original mesh. When you call MeshFilter.mesh, a copy of the original mesh is made and returned.If a copy already exist, it is returned. This makes it possible to modify a mesh without modifying the original mesh or affecting other prefabs/GameObjects that uses this mesh.

MeshFilter.mesh is what you should be using to modify your mesh.

Upvotes: 2

Doh09
Doh09

Reputation: 2385

You are modifying the 3d model/mesh directly, which stores the changes instead of resetting them as you exit playmode.

Source:

https://docs.unity3d.com/Manual/ModifyingSourceAssetsThroughScripting.html

Direct Modification

IMPORTANT NOTE

The method presented below will modify actual source asset files used within Unity. These modifications are not undoable. Use them with caution.

Now let’s say that we don’t want the material to reset when we exit play mode. For this, you can use renderer.sharedMaterial. The sharedMaterial property will return the actual asset used by this renderer (and maybe others).

The code below will permanently change the material to use the Specular shader. It will not reset the material to the state it was in before Play Mode.

Bonus knowledge:

The same thing happens, to my knowledge, if you modify ScriptableObjects.

Upvotes: 1

Related Questions