type mismatch

this results in a list filled with mismatches that go missing on play?
KeyItem derives from Item which derives from scriptableobject, ah and Element also derives from keyitem. all these are Serialized.

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Text.RegularExpressions;

[System.Serializable]
public class Molecule : KeyItem 
{
	public List<Element> moleculeElements = new List<Element>();
	
	public Molecule ()
	{
		moleculeElements = new List<Element>();
	}
	public Molecule (string name)
	{
		ReadMolecule(name);
	}
	private void ReadMolecule (string name)
	{	
	var matches ="([A-Z][a-z]?)";
	string[] output= Regex.Split(name, matches);
	for(int i=1; i<output.Length-1; i+=2)
	{	
		Element element= ScriptableObject.CreateInstance<Element>() as Element;
		element=new Element(output[i]);
		moleculeElements.Add(element);
	}

	}
}

nobody :frowning:
any suggestion is welcome atm… I tried everything i cloud think of and didn’t find any solution on the net… well if i only knew what causes it i could at least do a better search

my script currently

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Text.RegularExpressions;

[System.Serializable]
public class Molecule : KeyItem 
{
	[SerializeField]
	private string _notation;
	[SerializeField]
	private List<Element> _moleculeElements = new List<Element>();
	
	public Molecule ()
	{
		_moleculeElements = new List<Element>();
	}
	public Molecule (string notation)
	{
		this._notation=notation;
		ReadMolecule(_notation);
	}
	
	public string Notation
	{
		get{return _notation;}
		set{_notation = value;}
	}
	public List<Element> MoleculeElements
	{
		get{return _moleculeElements;}
		set{_moleculeElements = value;}
	}
	private void ReadMolecule (string name)
	{	
	var matches ="([A-Z][a-z]?)";
	string[] output= Regex.Split(name, matches);
	for(int i=1; i<output.Length-1; i++)
	{	
		if(System.Char.IsLetter(output[i],0))
		{
			Element element= ScriptableObject.CreateInstance<Element>() as Element;
			element=new Element(output[i]);
			_moleculeElements.Add(element);
		}
		else if(System.Char.IsDigit(output[i],0))
		{
			_moleculeElements[i-2].Amount=int.Parse(output[i]);	
		}
	}

	}
}

it is supposed to read a chemical notation of a molecule and create the proper instances of elements the molecule is made of.
the Elements have a constructor that gets their values from “periodic table”, a class with all functions to get the values needed base on the element symbol.
creating an element as type works fine so i take it that my periodic table and element class work fine,
the _moleculeElements List shows the mismatch for the elements, but they still have the right values if i double click on them to see an element instance…
the only difference with creating an element directly is that all items i make are also created as prefabs via asset database, and the ones that a molecule class makes are not
which is intended… unless if that is the problem…

It’s been a long time but I think were I do that in Unix that would be a 2 to 3 length name but not longer than 3 characters where the first 2 characters are alphabetic, irrespective of case, and the third is blank or any other printable character.

So you are looking for molecular formulas like Na, N, Ag, but not H2O, CO2 or NaClO4?

Just trying to help…not a chemist, haven’t had a class since in it since 1985…

The regex hasn’t an expression to match the 2 in H2O for example.

In Unix I’d match NaClO4 and other molecular formulas like this:

[A-Z][a-z]?|[0-9]+

hey goat,
i use notations like H2O, the reading of the molecule works find i get the elements with their amount back as i want, only the Element instances created in the last for loop malfunction and are in some way not of type Element? or the List says so? or isn’t that what type mismatch means? does it mean there is something wrong with the data in the type?

Oh, sorry. OK.

            _moleculeElements.Add(element);

So line gets data type mismatch.

Should

private string _notation;

be of same type as defined in “Periodic Table” Can you put the error message you get here?

this is the periodic table class

using UnityEngine;

public class PeriodicTable
{
	[SerializeField]
	private Element _thisElement;
	
	public PeriodicTable (string symbol)
	{
		_thisElement = (Element)ScriptableObject.CreateInstance<Element>();
		_thisElement = new Element(symbol);
		_thisElement.Symbol=symbol;
		//_element.ID=id;
	}
	public PeriodicTable (Element element)
	{
		this._thisElement=element;
		ValenceElectronsBySymbol(element.Symbol);
		AtomicNumberBySymbol(element.Symbol);
	}
	
	public Element ThisElement
	{
		get{return _thisElement;}
		set{_thisElement = value;}
	}
	
	private void ValenceElectronsBySymbol (string symbol)
	{		
		int e=1;
		string[] collums=new string[] {"H","Li","Na","K","Rb","Cs","Fr",
		"-","Be","Mg","Ca","Sr","Ba","Ra","-","B","-","C","Si",
		"-","N","P","As","-","O","S","Se","Te","-","F","Cl",
		"Br","I","At","-","He","Ne","Ar","Kr","Xe","Rn"};
		
		for(var j=0; j<collums.Length; j++)
		{
			if(collums[j]=="-")e++;
			if(symbol==collums[j])
			{
				_thisElement.ValenceElectrons=e;
				_thisElement.NonMetal=true;
			}
		}
		
	}
	private void AtomicNumberBySymbol (string symbol)
	{
		int c=0;
		int r=0;
		string[] collums=new string[] 
		{
			"-","H","Li","Na","K","Rb","Cs","Fr",
			"-","Be","Mg","Ca","Sr","Ba","Ra",
			"-","Sc","Y","La","Ac",
			"-","Ti","Zr","Hf","Rf",
			"-","V","Nb","Ta","Db",
			"-","Cr","Mo","W","Sg",
			"-","Mn","Tc","Re","Bh",
			"-","Fe","Ru","Os","Hs",
			"-","Co","Rh","Ir","Mt",
			"-","Ni","Pd","Pt","Ds",
			"-","Cu","Ag","Au","Rg",
			"-","Zn","Cd","Hg","Cn",
			"-","B","Al","Ga","In","Tl","Uut",
			"-","C","Si","Ge","Sn","Pb","Fl",
			"-","N","P","As","Sb","Bi","Uup",
			"-","O","S","Se","Te","Po","Lv",
			"-","F","Cl","Br","I","At","Uus",
			"-","He","Ne","Ar","Kr","Xe","Rn","Uuo"
		};
		for(int i=0; i<collums.Length; i++)
		{
			if(collums[i]=="-")c++;
			if(symbol==collums[i])Debug.Log (c);
		}
		string[] rows=new string[]
		{
			"-","H","He",
			"-","Li","Be","B","C","N","O","F","Ne",
			"-","Na","Mg","Al","Si","P","S","Cl","Ar",
			"-","K","Ca","Sc","Ti","V","Cr","Mn","Fe","Co","Ni","Cu","Zn","Ga","Ge","As","Se","Br","Kr",
			"-","Rb","Sr","Y","Zr","Nb","Mo","Tc","Ru","Rh","Pd","Ag","Cd","In","Sn","Sb","Te","I","Xe",
			"-","Cs","Ba","La","Ce","Pr","Nd","Pm","Sm","Eu","Gd","Tb","Dy","Ho","Er","Tm","Yb","Lu",
				"Hf","Ta","W","Re","Os","Ir","Pt","Au","Hg","Tl","Pb","Bi","Po","At","Rn",
			"-","Fr","Ra","Ac","Th","Pa","U","Np","Pu","Am","Cm","Bk","Cf","Es","Fm","Md","No","Lr",
				"Rf","Db","Sg","Bh","Hs","Mt","Ds","Rg","Cn","Uut","Fl","Uup","Lv","Uus","Uuo"
		};
		for(int ii=0; ii<collums.Length; ii++)
		{
			if(collums[ii]=="-")r++;
			if(symbol==collums[ii])Debug.Log (r);
		}
		string[] atomNumber=new string[]
		{
			"-","H","He",
			"Li","Be","B","C","N","O","F","Ne",
			"Na","Mg","Al","Si","P","S","Cl","Ar",
			"K","Ca","Sc","Ti","V","Cr","Mn","Fe","Co","Ni","Cu","Zn","Ga","Ge","As","Se","Br","Kr",
			"Rb","Sr","Y","Zr","Nb","Mo","Tc","Ru","Rh","Pd","Ag","Cd","In","Sn","Sb","Te","I","Xe",
			"Cs","Ba","La","Ce","Pr","Nd","Pm","Sm","Eu","Gd","Tb","Dy","Ho","Er","Tm","Yb","Lu",
				"Hf","Ta","W","Re","Os","Ir","Pt","Au","Hg","Tl","Pb","Bi","Po","At","Rn",
			"Fr","Ra","Ac","Th","Pa","U","Np","Pu","Am","Cm","Bk","Cf","Es","Fm","Md","No","Lr",
				"Rf","Db","Sg","Bh","Hs","Mt","Ds","Rg","Cn","Uut","Fl","Uup","Lv","Uus","Uuo"
		};
		for(int n=0; n<atomNumber.Length; n++)
		{
			if(symbol==atomNumber[n])_thisElement.AtomicNumber=n;
		}
	}
	
}

and the Element class:

using UnityEngine;
using System.Collections;

[System.Serializable]
public class Element : KeyItem
{
	[SerializeField]
	private int _atomicNumber;
	[SerializeField]
	private string _symbol;
	[SerializeField]
	private int _valenceElectrons;
	[SerializeField]
	private bool _nonMetal;
	[SerializeField]
	private int _electroNegativity;
	[SerializeField]
	private int _atomicRadius;
	[SerializeField]
	private Color _atomColor;
	[SerializeField]
	private int _capacity;
	
	
	public Element (string symbol)
	{
		this._symbol = symbol;
		new PeriodicTable(this);
	}
	
	#region get/set
	public int AtomicNumber
	{
		get{return _atomicNumber;}
		set{_atomicNumber = value;}
	}
	public string Symbol
	{
		get{return _symbol;}
		set{_symbol = value;}
	}
	public int ValenceElectrons
	{
		get{return _valenceElectrons;}
		set{_valenceElectrons = value;}
	}
	public bool NonMetal
	{
		get{return _nonMetal;}
		set{_nonMetal = value;}
	}
	public int ElectroNegativity
	{
		get{return _electroNegativity;}
		set{_electroNegativity = value;}
	}
	public int AtomicRadius
	{
		get{return _atomicRadius;}
		set{_atomicRadius = value;}
	}
	public Color AtomColor
	{
		get{return _atomColor;}
		set{_atomColor = value;}
	}
	public int Capacity
	{
		get{return _capacity;}
		set{_capacity = value;}
	}
	
	#endregion
}

this is the result:

OK, so I’m trying to learn C# by helping people with questions until I order a C# book (I know C/C++) so if I’m wrong at least the information will be here for others to help you:

a. _thisElement = (Element)ScriptableObject.CreateInstance();

b. Element element= ScriptableObject.CreateInstance() as Element;

and the only thing I can come up is with is the lack of a cast on the later b. code causing the problem, although to me that 1st line of a. code shouldn’t need a cast. These List, Dictionary, and Serialization is in particular very foreign to me and the syntax odd too, but that’s what I’m trying to learn.

i tried both casts manners but that didn’t change anything… :frowning:
only other part involved is this:
ah yes and i know i shouldn’t use a constructor with ScriptableObject will change it to OnEnable() but even if i comment out molecule=new Molecule(notation); I still have mismatch.

case ItemType.molecule:
						notation = EditorGUILayout.TextField("Chemical Notation : ", notation);
						if(GUILayout.Button("Create Item", GUILayout.Width(150)))
						{
							Molecule molecule=(Molecule)ScriptableObject.CreateInstance<Molecule>();
							molecule.Notation=notation;
							molecule = new Molecule(notation);
							molecule.ItemName=itemName;
							molecule.Description=description;
							molecule.ThisItem=itemObj;
							molecule.Icon="KeyItem";
							itemManager.itemList.Add(molecule);
							index = itemManager.itemList.IndexOf(molecule );
							AssetDatabase.CreateAsset(molecule, "Assets/Items/"+index+"_"+molecule.ItemName+"_molecule.prefab");
							Create(index);
						}
					break;

Sorry, my C# just isn’t there yet.

I’d post the actually last few lines of your Unity console complaining, and with this other information, one of the guys that have done C# in the workplace will come by and help out in the next day or so.

the console trows nothing thats why i have no clue as to where it goes wrong… think I’ll try debug the instance creation as close as possible when i have the time,
thanks for the help

So I added the code to my project and I’m missing the KeyItem (-> Item → ScriptableObject) code to try and learn a bit.

Maybe you should:

Element element= (Element)KeyItem.CreateInstance() as Element;

or it seems you did all the inheritance to do this to me:

Element element= new Element(output*);*
and leave out the first line ScriptableObject line.
I’ll leave it for an expert to come by now.

well i changed this : in the molecule class

var matches ="([A-Z][a-z]?)";
	string[] output= Regex.Split(notation, matches);
	for(int i=1; i<output.Length-1; i+=2)
	{	
		string symbol=output[i];
		string amount=output[i+1].ToString();
		if(amount=="")amount="1";
		Element element= (Element)ScriptableObject.CreateInstance<Element>();
		element=new Element(symbol);
		element.Amount=int.Parse(amount);
		_moleculeElements.Add(element);
		AssetDatabase.CreateAsset(element, "Assets/Items/"+notation+"_"+symbol+"_element.prefab");
		
		
	}

so now it creates a prefab for the instances and now they show up…
but i wanted to wait with the create until i actually needed them. now i will have a couple of 100 prefabs of instances more in my game :frowning:

OK, now I remember some code I have from a friend that acted similar. In this case an array in the Editor Inspector was initialized to size 10 and Unity complained until each of those 10 array elements had a prefab drag dropped into those slots.

I’ll ask tomorrow if anything done in the new package fixed that behavior and relay it to you.

OK, he fixed it by adding a statement like this:

if (array != null)
access reference code complaining about type mismatch at runtime…

hey thanks goat, will look try and let you know if that helped

just tried it like this:

private void ReadMolecule (string notation)
	{	
	var matches ="([A-Z][a-z]?)";
	string[] output= Regex.Split(notation, matches);
	if(output != null)
	{
		for(int i=1; i<output.Length-1; i+=2)
		{	
			string symbol=output[i];
			string amount=output[i+1].ToString();
			if(amount=="")amount="1";
			Element element= (Element)ScriptableObject.CreateInstance<Element>();
			element=new Element(symbol);
			element.Amount=int.Parse(amount);
			_moleculeElements.Add(element);
			//AssetDatabase.CreateAsset(element, "Assets/Items/"+notation+"_"+symbol+"_element.prefab");
		}
			
	}

but then the mismatch is back. I find it a strange solution and don’t really see how it could fix things.
anyway if you want i can send you the itemSystem as package in a pm, maybe you can show me how you/he solved it then?
let me know if you want that…

It’s a old thread and maybe you found your answer, but I encountered the same issue and I start to learn a bit about ScriptableObject and serialization in Unity to find a solution.
I wrote a memorandum on how to avoid this issue and some info on serialization. Maybe someone out there would be interested in how achieve a serialization of a list of custom type and multi-list in Unity so here you are: http://ivanozanchetta.com/gamedev/unity3d/unity-serialization-behind-scriptableobject/
This post is not supposed to be the “holy grail” of serialization, but is the way I found solutions to some issue, so take a read and drop a comment…

1 Like