- Home /
Error while using SerializeField and HideInInspector tags
Hello!
Im currently doing some heavy work at the Inspector Interface and Multiple Edition and every now and then I get some problem but nothing that I couldnt solve like this one.
So I needed to serialize a Maskfield, and this post helped me with that. But in order to make this solution work I had to make a CallDefaultInspector call, which displays at the inspector all my public vars, which I dont want to.
My first try was to put a [HideInInspector] tag on those vars, but since Im also serializing them, this caused this very strange error
Invalid iteration - (You need to stop calling Next when it returns false)
After some googling I couldnt find anything usefull related to this, so I just decided to try somethiing else, making then my vars to be private and with the tag [SerializeField], which makes them serializable but doesnt hide them from the Inspector. My next try was to use both tags [HideInInspector, SerializeField] to see how they worked togheter and this gave me the same error I had with the HideInInspector tag alone.
So, what can be done to Serialize a variable while not displaying it at the Inspector?
Why do I need this you ask, well, I have a component with a Mask Field where each field selected works like a bool to show a Vec3 field and I need this to work with the tag [CanEditMultipleObjects].
This is my full Editor Class code:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
namespace SimVR
{
[CanEditMultipleObjects, CustomEditor(typeof(LinkActuator))]
public class LinkActuatorEditor : Editor
{
private LinkActuator _script { get { return target as LinkActuator; }}
int nInfo = 6;
string[] _infoNames = new string[6]{ "Linear Velocity",
"Angular Velocity",
"Linear Acceleration",
"Angular Acceleration",
"Force",
"Torque" };
SerializedProperty _functionsMaskProp;
Editor _functionsMaskEditor;
SerializedProperty _linearVelocityProp;
SerializedProperty _angularVelocityProp;
SerializedProperty _linearAccelerationProp;
SerializedProperty _angularAccelerationProp;
SerializedProperty _forceProp;
SerializedProperty _torqueProp;
SerializedProperty _chosenFunctionsProp;
//SerializedProperty _infoToApplyProp;
void OnEnable()
{
_functionsMaskProp = serializedObject.FindProperty("_functionsMask");
_linearVelocityProp = serializedObject.FindProperty("_linearVelocity");
_angularVelocityProp = serializedObject.FindProperty("_angularVelocity");
_linearAccelerationProp = serializedObject.FindProperty("_linearAcceleration");
_angularAccelerationProp = serializedObject.FindProperty("_angularAcceleration");
_forceProp = serializedObject.FindProperty("_force");
_torqueProp = serializedObject.FindProperty("_torque");
_chosenFunctionsProp = serializedObject.FindProperty("_chosenFunctions");
//_infoToApplyProp = serializedObject.FindProperty("_infoToApply");
}
public override void OnInspectorGUI ()
{
DrawDefaultInspector ();
serializedObject.Update ();
EditorGUILayout.Space ();
EditorGUILayout.Space ();
_chosenFunctionsProp.ClearArray ();
for ( int i = 0; i < _infoNames.Length; i++ )
{
if( (_functionsMaskProp.intValue >> i & 0x1) == 1 )
{
_chosenFunctionsProp.arraySize++;
SerializedProperty elementProperty = _chosenFunctionsProp.GetArrayElementAtIndex( _chosenFunctionsProp.arraySize - 1 );
elementProperty.stringValue = _infoNames[i];
}
}
EditorGUILayout.Space ();
EditorGUI.indentLevel++;
for( int i = 0; i < nInfo; i++ )
{
if( chosenFunctionsContains( _infoNames[i] ) )
{
switch ( i )
{
case 0:
InterfaceEditor.CreateField( _linearVelocityProp, _infoNames[0] );
break;
case 1:
InterfaceEditor.CreateField( _angularVelocityProp, _infoNames[1] );
break;
case 2:
InterfaceEditor.CreateField( _linearAccelerationProp, _infoNames[2] );
break;
case 3:
InterfaceEditor.CreateField( _angularAccelerationProp, _infoNames[3] );
break;
case 4:
InterfaceEditor.CreateField( _forceProp, _infoNames[4] );
break;
case 5:
InterfaceEditor.CreateField( _torqueProp, _infoNames[5] );
break;
}
}
}
EditorGUI.indentLevel--;
EditorGUILayout.Space ();
EditorGUILayout.BeginHorizontal();
GUILayout.Space( 10 );
if( GUILayout.Button ( "Apply" ) )
{
if( !Application.isPlaying )
EditorUtility.DisplayDialog( "Error", "Só é possível aplicar essas funções com a simulação em andamento!", "Ok" );
Debug.Log ( "targets.size: " + targets.Length );
foreach( LinkActuator currLA in targets )
{
if( currLA.getChosenFunctions().Count > 0 )
{
Debug.Log ( "Name: " + currLA.gameObject.transform.parent.name );
Link linkScript = currLA.gameObject.GetComponent<Link>();
for( int i = 0; i < nInfo; i++ )
{
if( chosenFunctionsContains( _infoNames[i], currLA.getChosenFunctions() ) )
{
if ( i == 0 ) { Debug.Log ( "_infoToApply.get( 0 ) ): " + currLA.getInfoToApply( i ) ); linkScript.ApplyLinearVelocity ( currLA.getInfoToApply( i ) ); }
else if ( i == 1 ) linkScript.ApplyAngularVelocity ( currLA.getInfoToApply( i ) );
else if ( i == 2 ) linkScript.ApplyLinearAcceleration ( currLA.getInfoToApply( i ) );
else if ( i == 3 ) linkScript.ApplyAngularAcceleration ( currLA.getInfoToApply( i ) );
else if ( i == 4 ) linkScript.ApplyForce ( currLA.getInfoToApply( i ) );
else if ( i == 5 ) linkScript.ApplyTorque ( currLA.getInfoToApply( i ) );
}
}
}
}
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.Space ();
serializedObject.ApplyModifiedProperties ();
}
bool chosenFunctionsContains( string name, List<string> chosenFunctions )
{
for ( int i = 0; i < chosenFunctions.Count; i++ )
{
if ( name == chosenFunctions[i] )
return true;
}
return false;
}
bool chosenFunctionsContains( string name )
{
for ( int i = 0; i < _chosenFunctionsProp.arraySize; i++ )
{
SerializedProperty elementProperty = _chosenFunctionsProp.GetArrayElementAtIndex( i );
if ( name == elementProperty.stringValue )
return true;
}
return false;
}
}
}
And my full regular class as of now:
using UnityEngine;
using System.Collections.Generic;
namespace SimVR
{
public class LinkActuator : MonoBehaviour
{
[HideInInspector, SerializeField]
private Vector3 _linearVelocity = Vector3.zero;
[HideInInspector, SerializeField]
private Vector3 _angularVelocity = Vector3.zero;
[HideInInspector, SerializeField]
private Vector3 _linearAcceleration = Vector3.zero;
[HideInInspector, SerializeField]
private Vector3 _angularAcceleration = Vector3.zero;
[HideInInspector, SerializeField]
private Vector3 _force = Vector3.zero;
[HideInInspector, SerializeField]
private Vector3 _torque = Vector3.zero;
[HideInInspector, SerializeField]
private List<string> _chosenFunctions = new List<string> ();
[GenericMask("Linear Velocity",
"Angular Velocity",
"Linear Acceleration",
"Angular Acceleration",
"Force",
"Torque")]
public int _functionsMask = 0;
public List<string> getChosenFunctions() { return _chosenFunctions; }
public Vector3 getInfoToApply(int idx)
{
switch ( idx )
{
case 0:
return _linearVelocity;
case 1:
return _angularVelocity;
case 2:
return _linearAcceleration;
case 3:
return _angularAcceleration;
case 4:
return _force;
case 5:
return _torque;
default:
Debug.LogError ( "Parametro de entrada incorreto!" );
return Vector3.zero;
}
}
public void setInfoToApply( Vector3 infoToApply, int idx )
{
switch ( idx )
{
case 0:
_linearVelocity = infoToApply;
break;
case 1:
_angularVelocity = infoToApply;
break;
case 2:
_linearAcceleration = infoToApply;
break;
case 3:
_angularAcceleration = infoToApply;
break;
case 4:
_force = infoToApply;
break;
case 5:
_torque = infoToApply;
break;
default:
Debug.LogError ( "Parametro de entrada incorreto!" );
break;
}
}
public void setInfoToApply( Vector3[] infoToApply )
{
_linearVelocity = infoToApply[0];
_angularVelocity = infoToApply[1];
_linearAcceleration = infoToApply[2];
_angularAcceleration = infoToApply[3];
_force = infoToApply[4];
_torque = infoToApply[5];
}
}
}
What can I do to make it work as intended?
Thank you!