Can I store a mesh in a class variable ?

No soup for you, and no answer for me =[


Of course Unity has been screaming at me : You are trying to create a MonoBehaviour using the ‘new’ keyword. This is not allowed. But following the Burgzerg Arcade series, he says this is ok ignore the warning. Guess I need to find out the correct way to create, declare, then assign a variable that is a class variable. I feel Bunny83 has most closely identified the problem, however I am still bamboozled.

Revised Description :

So I make a class with some variables :

#pragma strict

public class CubeFace extends MonoBehaviour
{
	public var faceMesh : Mesh;
	public var faceMeshFilter : MeshFilter;
	
	public var cubeVerts : Vector3[];
	public var sphereVerts : Vector3[];
	public var uvs : Vector2[];
	public var norms : Vector3[];
	public var tris : int[];
}

public class CubeToSphereMap extends MonoBehaviour
{
	// this is the main body of the script
}

Within the main body of the script, I declare and assign :

private var meshUp : CubeFace;
private var meshDown : CubeFace;
// 4 more

Then through some functions, all those variables get populated :

theFace = new CubeFace();

theFace.cubeVerts = SomeCalculatedVerts;
theFace.sphereVerts = SomeMoreCalculatedVerts;
theFace.uvs = SOmeUvCoordinates;

theFace.tris = commonTris;
theFace.norms = commonNorms;

After all that happens, I build my mesh with the information :

if ( useCube )
{
	theMesh.vertices = theFace.cubeVerts;
}
else
{
	theMesh.vertices = theFace.sphereVerts;
}

theMesh.uv = theFace.uvs;
theMesh.triangles = theFace.tris;
theMesh.normals = theFace.norms;

theMesh.RecalculateBounds();
theMesh.RecalculateNormals();

Ok, now directly after that , the very next line, I have tried :

//theFace.faceMesh = new Mesh();
theFace.faceMesh = theMesh;
theFace.faceMeshFilter = go.GetComponent( MeshFilter );

Now in anything before where I have needed to call upon the mesh reference again, I simply use theMesh.vertices = modifiedVerts; Now when I try to do exactly the same thing, except this time the myMesh variable isn’t on this script, it’s a variable of another class variable :

//meshUp.faceMeshFilter.mesh.vertices = meshUp.sphereVerts;
Debug.Log( "cacheMesh " + meshUp.faceMesh );
Debug.Log( "filter " + meshUp.faceMeshFilter );

And it throws a null. And I throw something too …



Original Question

I have a class that stores the same type of information for 6 gameObjects. It creates those gameObjects and their meshes. So this is on an empty gameObject, and the 6 mesh objects have no script :

public class CubeFace extends MonoBehaviour
{
	public var faceMesh : Mesh;
	public var faceMeshFilter : MeshFilter;
	// etc
}

public class CubeToSphereMap extends MonoBehaviour
{
	private var meshUp : CubeFace;
	// etc
}

I have no problem generating the meshes, and both sets of vertices are yielding the expected results :

function ConstructFace( theFace : CubeFace, theName : String, theRotation : Vector3, theMaterial : Material )

The problem came while trying to modify the vertices variable of the mesh reference that was stored in the variable of the class.

theMesh.vertices = theFace.cubeVerts; // sphereVerts; // both work happily, I have my mesh
// etc etc etc
theMesh.RecalculateNormals();
// NOW HERE I am trying to store a reference to my mesh
// to modify the vertices later
theFace.faceMesh = theMesh;
theFace.faceMeshFilter = go.GetComponent( MeshFilter );

So the mesh is made, but when I try to modify the verts, I get the null reference to the Mesh, and after trying another approach the MeshFilter.

meshUp.faceMesh.vertices = meshUp.sphereVerts;
meshUp.faceMeshFilter.mesh.vertices = meshUp.sphereVerts;
Debug.Log( "cacheMesh " + meshUp.faceMesh );
Debug.Log( "filter " + meshUp.faceMeshFilter );

Huh ?!

  • 6 variables of the class CubeFace are made.

  • information is happily stored to those class variables

  • meshes are happily made reading the information of the CubeFace class

  • but when I try to access either faceMesh or faceMeshFilter, I get a null reference exception : NullReferenceException: Object reference not set to an instance of an object
    CubeToSphereMap.ShowAsSphere () (at Assets/_Scripts/CubeToSphereMap.js:100)

     Debug.Log( "cacheMesh " + meshUp.faceMesh );
     Debug.Log( "filter " + meshUp.faceMeshFilter );
    

I hope it is not something obvious, run out of ideas and need suggestions. Many Thanks =]

8531-cubemapsphere.jpg

The image is to show I have no problem at all making my meshes, the problem is storing that Mesh/MeshFilter in a variable.

Ok I know what your problem is:

You are never assigning meshUp/meshDown etc - here’s why:

You pass the value for meshUp to ConstructFace (it's probably null), in ConstructFace you create a new CubeFace but assigning that to the variable of the parameter does not change the private variable in your class. That’s not how it works (it kinda does in C# with the ref keyword) but not here.

I suggest you return the CubeFace from ConstructFace:

  function ConstructFace(theName : String, theRotation : Vector3, theMaterial : Material ) : CubeFace
  {
     ...
     return theFace;
  }

Then:

  meshUp = ConstructFace("CubeFace_Up", Vector3.right * 270, mtlUp );

Have you tried recalculating bounds?

My knowledge of meshes is shallow, but I have a couple of theories in my head. As a debugging step, anywhere you assign the mesh you created to a MeshFilter, replace it by assigning a Mesh.Instantiate()'ed copy of the mesh and see what happens.

First of all this line:

    public class CubeFace extends MonoBehaviour

and this line:

    theFace = new CubeFace();

don’t work together. Your CubeFace class is derived from MonoBehaviour, but you can’t created an instance with “new”. MonoBehaviour classes have to be attached to a gameobject and can only be created with AddComponent.

Also you always talk about “main body” and “some functions” but when exactly is your mesh created? In other words when are your “some functions” called?

What is “go” and are you sure that this gameobject has a MeshFilter / MeshRenderer?

Also is that all happening at runtime? Or do you try to save the meshes as assets in the editor?