0
\$\begingroup\$

I am trying to switch out the mesh of a game object. I have this script:

public GameObject rockPile;
MeshFilter rockMesh;
private string[] rockMeshes = new string[] {"rocks-0", "rocks-25", "rocks-50"};
private int rockIndex = 0;

void Start()
{
   rockMesh = rockPile.GetComponent<MeshFilter>();
}

void Update()
{
    if (Input.GetMouseButtonDown(0)) { // click

        rockMesh.sharedMesh = Resources.Load<Mesh>(rockMeshes[rockIndex]); // <-- not working

        if (rockIndex == rockMeshes.Length - 1) {
            rockIndex = 0;
        } else {
            rockIndex++;
        }
    }
}

However the mesh isn't changing when I click on the object. The meshes for the rocks are part of imported .fbx files. If I search Assets for the strings I'm using in the rockMeshes array, they are there, but they are not the names of the imported fbx files. I'm not sure the right way to reference the meshes or store them.

File structure:

Assets/
├─ 3d/
│  ├─ rockMesh0.fbx  <-- rocks-0 mesh in this file
│  ├─ rockMesh25.fbx  <-- rocks-25 mesh in this file
│  ├─ rockMesh50.fbx  <-- rocks-50 mesh in this file
\$\endgroup\$
5
  • 1
    \$\begingroup\$ Resources.Load is no longer recommended. The recommended way to load assets at runtime is via Addressables. \$\endgroup\$
    – Philipp
    Aug 16 at 13:54
  • 1
    \$\begingroup\$ Also consider the option to convert rockMeshes from string[] to a Mesh[] and assign the meshes via drag&drop in the inspector. That way you avoid the whole "loading resources at runtime" problem alltogether. \$\endgroup\$
    – Philipp
    Aug 16 at 14:02
  • \$\begingroup\$ Now that you've corrected the code as I suggested, this example works for me out of the box. My best guess is that you don't have an asset named "rocks-0" in the root of a folder called "Resources", but since you haven't shown us your asset setup I can only speculate about this. \$\endgroup\$
    – DMGregory
    Aug 16 at 14:46
  • \$\begingroup\$ @DMGregory I added the file structure - as I mentioned in the question I'm not sure the right way to reference the meshes or store them, so would welcome your advice. Thanks! \$\endgroup\$
    – inorganik
    Aug 19 at 14:47
  • \$\begingroup\$ Looks like you need to re-read the documentation on Resources.Load. See how it requires that the assets to load live under a folder called "Resources"? \$\endgroup\$
    – DMGregory
    Aug 19 at 14:48
0
\$\begingroup\$

I used @Philipp's suggestion and made a public meshes array, assigned those in Unity, and was able to set the mesh using the sharedMesh property:

public GameObject rockPile;
public MeshFilter[] meshes;
MeshFilter rockMesh;
private int rockIndex = 0;

void Start()
{
    rockMesh = rockPile.GetComponent<MeshFilter>();
}

void Update()
{
    if (Input.GetMouseButtonDown(0)) { // click

        rockMesh.sharedMesh = meshes[rockIndex].sharedMesh

        if (rockIndex == meshes.Length - 1) {
            rockIndex = 0;
        } else {
            rockIndex++;
        }
    }
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.