Exemplo n.º 1
0
        public static byte[] PackToBytes(GameObject[] objects, UABConfig config = null, List <ISerializer> serializers = null)
        {
            var package        = Builder.Pack(objects, config, serializers);
            var dataSerialized = UABSerializer.SerializeValueType(package);
            var zipped         = Zipper.ZipString(dataSerialized);

            return(zipped);
        }
        public UABField Pack(string fieldName, System.Type fieldType, object value, List <ISerializer> serializers)
        {
            var uField = new UABField();

            uField.name      = fieldName;
            uField.fieldType = FieldType.ValueType;

            if (value == null || (value is Object && (value as Object) == null))
            {
                uField.data = null;
                return(uField);
            }

            if ((value is Object) == false)
            {
                for (int i = 0; i < serializers.Count; ++i)
                {
                    var s = serializers[i];
                    if ((s is IBinarySerializer) == false && s.IsValid(value) == true)
                    {
                        s.Serialize(this, uField, ref value, serializers);
                        return(uField);
                    }
                }
            }

            var type = fieldType;

            if (value.IsArray() == true)
            {
                // array
                uField.fieldType = FieldType.ArrayType;
            }
            else if (
                (type.IsClass == true || type.IsValueType == true) &&
                type.IsSerializable == true &&
                type.IsSimpleType() == false &&
                type.IsEnum == false)
            {
                // nested

                uField.fieldType = FieldType.NestedType;
                uField.fields    = this.Serialize(value, serializers);
            }
            else if (
                type.IsSimpleType() == true ||
                type.IsValueType == true ||
                type.IsEnum == true)
            {
                // value type
                uField.fieldType = FieldType.ValueType;
            }
            else
            {
                // ref type
                uField.fieldType = FieldType.ReferenceType;

                if (UAB.Builder.IsBinary(this.currentBundleName, value as Object) == true)
                {
                    // binary type
                    uField.fieldType = FieldType.BinaryType;
                }
            }

            if (uField.fieldType == FieldType.ValueType)
            {
                var found = false;
                for (int i = 0; i < serializers.Count; ++i)
                {
                    if (serializers[i].IsValid(value) == true)
                    {
                        serializers[i].Serialize(this, uField, ref value, serializers);
                        found = true;
                        break;
                    }
                }

                if (found == false)
                {
                    // no custom serializator was found - use default
                    uField.serializatorId = "-1";
                    if (value is string)
                    {
                        uField.data = (string)value;
                    }
                    else
                    {
                        uField.data = UABSerializer.SerializeValueType(value);
                    }
                }
            }
            else if (uField.fieldType == FieldType.ReferenceType)
            {
                //Debug.Log("Pack ref type: " + value);

                this.RegisterReferencePack(uField, value);
            }
            else if (uField.fieldType == FieldType.BinaryType)
            {
                this.RegisterBinaryPack(uField, value);
            }
            else if (uField.fieldType == FieldType.ArrayType)
            {
                var count      = 0;
                var enumerator = ((IEnumerable)value).GetEnumerator();
                while (enumerator.MoveNext() == true)
                {
                    ++count;
                }

                //Debug.Log("Pack arr type: " + count);
                if (count > 0)
                {
                    enumerator.Reset();
                    uField.fields = new UABField[count];
                    count         = 0;
                    while (enumerator.MoveNext() == true)
                    {
                        var element = enumerator.Current;
                        uField.fields[count] = (element == null ? null : this.Pack(null, element.GetType(), element, serializers));
                        ++count;
                    }
                }
            }

            return(uField);
        }
        public void BuildReferences(Transform root)
        {
            var list = this.tempReferencesPack;

            for (int i = 0; i < list.Count; ++i)
            {
                var uField = list[i].uField;
                var value  = list[i].value;

                var isObjectNull   = (value as UnityEngine.Object) == null;
                var instanceId     = Builder.GetInstanceID(value).ToString();
                var isLocal        = (isObjectNull == false ? Builder.GetRoot(value) == root : true);
                var isGameObject   = (value is GameObject);
                var postInstanceId = string.Empty;

                //Debug.Log(Builder.GetRoot(value) + " :: " + root);

                var resultInstanceId = string.Empty;

                if (isLocal == false && isObjectNull == false)
                {
                    // Add resource link
                                        #if UNITY_EDITOR
                    var source    = value as Object;
                    var assetPath = UnityEditor.AssetDatabase.GetAssetPath(source);

                    instanceId = UnityEditor.AssetDatabase.AssetPathToGUID(assetPath);

                    if (assetPath.StartsWith("Assets/") == false)
                    {
                        // Unity default resource
                        instanceId = "_" + value.GetType().FullName + "." + (value as Object).name;
                    }
                    else
                    {
                        var obj = UnityEditor.AssetDatabase.LoadAssetAtPath <Object>(assetPath);
                        if (obj != source)
                        {
                            if (obj is GameObject)
                            {
                                // Object is storing inside
                                // Finding local asset path
                                postInstanceId = ME.UAB.Extensions.EditorUtilities.GetLocalIdentfierInFile(source).ToString();
                            }
                            else
                            {
                                var allObjects   = UnityEditor.AssetDatabase.LoadAllAssetsAtPath(assetPath);
                                var objectInside = allObjects.FirstOrDefault(x => x.name == source.name);
                                if (objectInside != null)
                                {
                                    var index = System.Array.IndexOf(allObjects, objectInside);
                                    if (index >= 0)
                                    {
                                        instanceId     = string.Format("{0}_{1}", UnityEditor.AssetDatabase.AssetPathToGUID(assetPath), index);
                                        postInstanceId = "inner";
                                    }
                                    else
                                    {
                                        throw new UnityException(string.Format("Object with the name `{0}` was not found in `{1}`. Package cannot be processed.", objectInside.name, assetPath));
                                    }
                                }
                                else
                                {
                                    throw new UnityException(string.Format("Object was not found in `{0}`. Package cannot be processed.", assetPath));
                                }
                            }
                        }
                        else
                        {
                            postInstanceId = "root";
                        }
                    }

                    var localPath   = this.config.UAB_RESOURCES_PATH;
                    var projectPath = "Assets/" + localPath;

                    {                     // Creating `Resources` directory
                        var path = Application.dataPath + "/" + localPath;
                        if (System.IO.Directory.Exists(path) == false)
                        {
                            System.IO.Directory.CreateDirectory(path);
                            UnityEditor.AssetDatabase.ImportAsset(projectPath);
                        }
                    }

                    {                     // Creating asset by GUID
                        var guid = instanceId + "_" + postInstanceId;
                        var name = guid + ".asset";

                        ObjectReference reference = null;
                        var             fullPath  = projectPath + "/" + name;
                        if (System.IO.File.Exists(fullPath) == false)
                        {
                            reference = ME.UAB.Extensions.EditorUtilities.CreateAsset <ObjectReference>(name, projectPath);
                        }
                        else
                        {
                            reference = UnityEditor.AssetDatabase.LoadAssetAtPath <ObjectReference>(fullPath);
                        }

                        reference.reference = source;
                        UnityEditor.EditorUtility.SetDirty(reference);
                    }
                                        #endif

                    resultInstanceId = string.Format("{0}_{1}", instanceId, postInstanceId);
                }
                else
                {
                    if (isGameObject == true)
                    {
                        var go = (value as GameObject);
                        instanceId = Builder.GetInstanceID(go == null ? null : go.transform).ToString();
                    }

                    resultInstanceId = instanceId;
                }

                uField.serializatorId = "-2";
                uField.data           = UABSerializer.SerializeValueType(new UABReference()
                {
                    instanceId = resultInstanceId, isLocal = isLocal, isGameObject = isGameObject
                });
            }

            list.Clear();
        }
        public void BuildBinaries(ref UABBinaryHeader[] headers, ref UABBinaryData[] data, List <ISerializer> serializers)
        {
            var binData = ListPool <UABBinaryData> .Get();

            var binHeaders = ListPool <UABBinaryHeader> .Get();

            var list = this.tempBinariesPack;

            for (int i = 0; i < list.Count; ++i)
            {
                var uField = list[i].uField;
                var value  = list[i].value;

                var headerId = string.Empty;
                var found    = false;

                                #if UNITY_EDITOR
                var instanceId = UnityEditor.AssetDatabase.AssetPathToGUID(UnityEditor.AssetDatabase.GetAssetPath(value as Object));

                for (int j = 0; j < serializers.Count; ++j)
                {
                    if (serializers[j].IsValid(value) == true)
                    {
                        if (binData.Any(x => x.instanceId == instanceId) == false)
                        {
                            var f = new UABField();
                            serializers[j].Serialize(null, f, ref value, serializers);
                            binData.Add(new UABBinaryData()
                            {
                                instanceId = instanceId, data = f.data
                            });
                        }

                        var field = new UABField();
                        serializers[j].Serialize(this, field, ref value, serializers);

                        var header = new UABBinaryHeader()
                        {
                            binDataInstanceId = instanceId
                        };
                        header.instanceId = header.GetHashCode().ToString();
                        header.field      = field;

                        headerId = header.instanceId;

                        if (binHeaders.Any(x => x.instanceId == header.instanceId) == false)
                        {
                            binHeaders.Add(header);
                        }

                        found = true;

                        break;
                    }
                }
                                #endif

                uField.serializatorId = "-3";
                uField.data           = UABSerializer.SerializeValueType(new UABBinary()
                {
                    instanceId = headerId
                });

                if (found == false)
                {
                    throw new UnityException(string.Format("Binary Serializer was not found for type `{0}`. Package cannot be processed.", value.GetType().ToString()));
                }
            }
            list.Clear();

            data = binData.ToArray();
            ListPool <UABBinaryData> .Release(binData);

            headers = binHeaders.ToArray();
            ListPool <UABBinaryHeader> .Release(binHeaders);
        }