IDToPointer assert on async levelload

Hi,

I have in my project (unity 4.1.0) a couple of scenes

  • Init (which load Menu asynchronously)
  • Menu
  • Other scenes

When I play the Menu-scene in editor, everything works fine, however when I load the scene asynchronous from Init, I get the following error: (no back-trace)

ms_IDToPointer->find (obj->GetInstanceID ()) == ms_IDToPointer->end ()

This error does not show when I load the Menu-scene asynchronously from one of the other scenes.

I don’t recall when I first saw the problem, but at first I didn’t really payed any attention to it, since everything seemed to work just fine.
But as it turns out, everything is not okay, this issue breaks the iPad build.

I was able to pinpoint the script that causes the problem. It’s used to automatically generate a quad with the correct aspect ratio for a given texture to be used as button. (kinda like GUITexture)

using UnityEngine;
using System.Collections;

public class MeshButton : MonoBehaviour {

	[SerializeField]
	private Texture2D m_oTexture;	
	[SerializeField]
	private MeshRenderer m_oRenderer;
	[SerializeField]
	private MeshFilter m_oFilter;
	[SerializeField]
	private BoxCollider m_oCollider;
	
	public Texture2D Texture {get{return m_oTexture;}}
	
	public void Assure() {
		m_oRenderer = gameObject.GetComponent<MeshRenderer>();
		m_oFilter = gameObject.GetComponent<MeshFilter>();
		m_oCollider = gameObject.GetComponent<BoxCollider>();
		
		// Assure renderer
		if(null == m_oRenderer) {
			m_oRenderer = gameObject.AddComponent<MeshRenderer>();
		}
		m_oRenderer.hideFlags = HideFlags.HideInInspector;

		// Assure meshfilter
		if(null == m_oFilter) {
			m_oFilter = gameObject.AddComponent<MeshFilter>();
		}
		m_oFilter.hideFlags = HideFlags.HideInInspector;
		
		// Assure collider
		if(null == m_oCollider) {
			m_oCollider = gameObject.AddComponent<BoxCollider>();
		}
		m_oCollider.hideFlags = 0;
		
		// Assure correct material
		var oMaterial = Application.isPlaying ? m_oRenderer.material : m_oRenderer.sharedMaterial;
		if(null != oMaterial) {
			if(Application.isPlaying) Destroy(oMaterial);
			else DestroyImmediate(oMaterial);
			oMaterial = null;
		}
		if(null == oMaterial) {
			oMaterial = new Material(Shader.Find("Unlit/Transparent"));
			if(Application.isPlaying) m_oRenderer.material = oMaterial;
			else m_oRenderer.sharedMaterial = oMaterial;
		}
		if(Application.isPlaying) m_oRenderer.material.hideFlags = HideFlags.HideInInspector;
		else m_oRenderer.sharedMaterial.hideFlags = HideFlags.HideInInspector;

		// Apply texture
		if(Application.isPlaying) m_oRenderer.material.mainTexture = m_oTexture;
		else m_oRenderer.sharedMaterial.mainTexture = m_oTexture;

		// Assure old mesh is removed
		var oMesh = Application.isPlaying ? m_oFilter.mesh : m_oFilter.sharedMesh;
		if(Application.isPlaying) Destroy(oMesh);
		else DestroyImmediate(oMesh);
		
		// If valid texture, make mesh
		if(null != m_oTexture) {
			
			// Assure mesh
			float nRatio = (float)Texture.width / (float)Texture.height;
			
			float nRatioX = nRatio > 1f ? 1f : nRatio;
			float nRatioY = nRatio < 1f ? 1f : 1f / nRatio;
			
			m_oCollider.size = new Vector3(nRatioX, nRatioY, 0.25f);
			
			float nMinX = -0.5f * nRatioX;
			float nMinY = -0.5f * nRatioY;
			float nMaxX = 0.5f * nRatioX;
			float nMaxY = 0.5f * nRatioY;
			
			oMesh = new Mesh();
			
			var aVertex = new Vector3[] {
				new Vector3(nMinX, nMaxY, 0),
				new Vector3(nMaxX, nMaxY, 0),
				new Vector3(nMaxX, nMinY, 0),
				new Vector3(nMinX, nMinY, 0)
			};
			
			var aUv = new Vector2[] {
				new Vector2(0, 1),
				new Vector2(1, 1),
				new Vector2(1, 0),
				new Vector2(0, 0)
			};
			
			var aIndex = new int[] {
				0, 1, 3,
				1, 2, 3
			};
	
			oMesh.vertices = aVertex;
			oMesh.triangles = aIndex;
			oMesh.uv = aUv;
			
			if(Application.isPlaying) m_oFilter.mesh = oMesh;
			else m_oFilter.sharedMesh = oMesh;
		}
	}
	
	public void SetTexture(Texture2D oTexture) {		
		if(m_oTexture != oTexture) {
			
			m_oTexture = oTexture;
		
			Assure();
		}
	}
}

Somebody else has some experience with this sort problem, or a solution perhaps ?

Don’t know why, but switching to Android and switching back fixed it for me!

FYI, I also ran into this problem.

I had built a custom data editor for our game. It used a lot of reflection and serialization. That’s the short version anyways.

The problem ended up being if I had the editor open while the game was running it would throw several to many of these errors when the game would start:

ms_IDToPointer->find (obj->GetInstanceID ()) == ms_IDToPointer->end ()

I put some early out logic in my data editors OnGUI to not display while the game was running and that took care of the problem.