lundi 18 septembre 2017

Unity custom editor when motify byteArray field it can not save with reflection whitout SerializedProperty,

I need some feature in my custom class, like intValue ,stringValue, floatValue and so on. But i don’t define many field for save only one data everytime. So i want to use byte[]. I know it not safe,but i need. I try to test below. This is my Class:

using UnityEngine;
using System.Collections;
using System;
public class Test : MonoBehaviour {
    [SerializeField]
    private CustomData _data;
}

[System.Serializable]
public class CustomData
{
    public byte[] bytes;

    public static byte[] GetByte(int i)
    {
        return BitConverter.GetBytes(i);
    }
    public static int ToInt(byte[] bytes)
    {
        return BitConverter.ToInt32(bytes,0);
    }
}

And this is it editor class:

using UnityEngine;
using System.Collections;
using UnityEditor;
using System.Reflection;

[CustomEditor(typeof(Test))]
public class TestEditor : Editor {

    private SerializedProperty _data;
    private SerializedProperty _bytes;

    private FieldInfo _entryField;
    private void OnEnable()
    {
        _data = serializedObject.FindProperty("_data");
        _bytes = _data.FindPropertyRelative("bytes");

        _entryField = typeof(Test).GetField("_data", BindingFlags.NonPublic | BindingFlags.Instance);
    }
    public override void OnInspectorGUI()
    {
        serializedObject.Update();
        //I use one size of array to save one byte
        //---- This is so slow, because it assgin with iteration,if not int but custom data(some big data like more than 200 size of byte array)----
        //int intSize = sizeof(int);
        //if (_bytes.arraySize != intSize)
        //    _bytes.arraySize = intSize;

        //byte[] intSrcBytes = new byte[intSize];
        //for (int i = 0; i < intSize; ++i)
        //    intSrcBytes[i] = (byte)_bytes.GetArrayElementAtIndex(i).intValue;

        //int result= EditorGUILayout.IntField(CustomData.ToInt(intSrcBytes));

        //byte[] intEndBytes = CustomData.GetByte(result);
        //for (int i = 0; i < intSize; ++i)
        //    _bytes.GetArrayElementAtIndex(i).intValue = intEndBytes[i];
        //------------------------------------------------------------------
        //---- This is fast.I get the bytes with reflection. ----
        CustomData data = _entryField.GetValue(target) as CustomData;
        byte[] intFastSrcBytes = data.bytes;
        int resultOfFastSrc = EditorGUILayout.IntField(CustomData.ToInt(intFastSrcBytes));
        data.bytes= CustomData.GetByte(resultOfFastSrc);
        _entryField.SetValue(target, data);
        //--------------------------------------------------------
        serializedObject.ApplyModifiedProperties();
    }

}

At First, i use SerializedProperty to byte[] and byte[] to SerializedProperty at part of annotation.I test it with type of int. Result is fine.But when i use this way to test a custom data of more than 200 size. It so slow.Because it iteration all element from SerializedProperty to byte[] and iteration all element from byte[] to SerializedProperty. Result in slow at Editor on Windows.

And Second. I want to get byte[] directly with reflection. It very good when i get byte[]. But the problem is when i SetValue. I see when i change value with keyboard,and GUI of IntField content in Inspector is changed too. But Editor not display i can go to save this change( not appear "*" any where ). In other word, Editor not think it have been modified. So now i close and restart Unity. My changed content not save. Test show me another, if i do any can save opertion,such as i click the SetActive check box of gameobject at Inspector, it appear "*" ,and i save,then i close an restart Unity,previours changed content will be save.

I need the way of Second.the Problem is when i setValue,but not appear any save tip,i can not to save.I how to solve it,or have other esay solution ?





Aucun commentaire:

Enregistrer un commentaire