/// <summary> /// Set GIF data /// </summary> /// <param name="gifBytes">GIF byte data</param> /// <param name="gifData">ref GIF data</param> /// <param name="debugLog">Debug log flag</param> /// <returns>Result</returns> private static bool SetGifData(byte[] gifBytes, ref GifData gifData, bool debugLog) { if (debugLog) { Debug.Log("SetGifData Start."); } if (gifBytes == null || gifBytes.Length <= 0) { Debug.LogError("bytes is nothing."); return(false); } int byteIndex = 0; if (SetGifHeader(gifBytes, ref byteIndex, ref gifData) == false) { Debug.LogError("GIF header set error."); return(false); } if (SetGifBlock(gifBytes, ref byteIndex, ref gifData) == false) { Debug.LogError("GIF block set error."); return(false); } if (debugLog) { gifData.Dump(); Debug.Log("SetGifData Finish."); } return(true); }
/// <summary> /// Restores the material values /// </summary> /// <param name="m">Material</param> /// <param name="values">Set of values</param> public void SetValues(Material m, IEnumerable <StoredValue> values) { foreach (var v in values) { switch (v.property.type) { case MaterialProperty.PropertyType.Color: m.SetColor(v.property.name, (Color)v.value[0]); break; case MaterialProperty.PropertyType.Float: m.SetFloat(v.property.name, (float)v.value[0]); break; case MaterialProperty.PropertyType.Range: m.SetFloat(v.property.name, (float)v.value[0]); break; case MaterialProperty.PropertyType.TexEnv: m.SetTexture(v.property.name, (Texture)v.value[0]); m.SetTextureOffset(v.property.name, (Vector2)v.value[1]); m.SetTextureScale(v.property.name, (Vector2)v.value[2]); break; case MaterialProperty.PropertyType.Vector: m.SetVector(v.property.name, (Vector4)v.value[0]); break; default: Debug.LogError("Unsupported type: " + v.property.type.ToString()); break; } } }
/// <summary> /// Get GIF texture list (This is a possibility of lock up) /// </summary> /// <param name="bytes">GIF file byte data</param> /// <param name="loopCount">out Animation loop count</param> /// <param name="width">out GIF image width (px)</param> /// <param name="height">out GIF image height (px)</param> /// <param name="filterMode">Textures filter mode</param> /// <param name="wrapMode">Textures wrap mode</param> /// <param name="debugLog">Debug Log Flag</param> /// <returns>GIF texture list</returns> public static List <GifTexture> GetTextureList(byte[] bytes, out int loopCount, out int width, out int height, FilterMode filterMode = FilterMode.Bilinear, TextureWrapMode wrapMode = TextureWrapMode.Clamp, bool debugLog = false) { loopCount = -1; width = 0; height = 0; // Set GIF data var gifData = new GifData(); if (SetGifData(bytes, ref gifData, debugLog) == false) { Debug.LogError("GIF file data set error."); return(null); } // Decode to textures from GIF data var gifTexList = new List <GifTexture>(); if (DecodeTexture(gifData, gifTexList, filterMode, wrapMode) == false) { Debug.LogError("GIF texture decode error."); return(null); } loopCount = gifData.appEx.loopCount; width = gifData.logicalScreenWidth; height = gifData.logicalScreenHeight; return(gifTexList); }
// Writes mesh to an array of bytes. public static byte[] WriteMesh(Mesh mesh, bool saveTangents) { if (mesh == null) { Debug.LogError("No mesh given!"); return(null); } var verts = mesh.vertices; var normals = mesh.normals; var tangents = mesh.tangents; var uvs = mesh.uv; var tris = mesh.triangles; // figure out vertex format byte format = 1; if (normals.Length > 0) { format |= 2; } if (saveTangents && tangents.Length > 0) { format |= 4; } if (uvs.Length > 0) { format |= 8; } var stream = new MemoryStream(); var buf = new BinaryWriter(stream); // write header var vertCount = (ushort)verts.Length; var triCount = (ushort)(tris.Length / 3); buf.Write(vertCount); buf.Write(triCount); buf.Write(format); // vertex components WriteVector3Array16Bit(verts, buf); WriteVector3ArrayBytes(normals, buf); if (saveTangents) { WriteVector4ArrayBytes(tangents, buf); } WriteVector2Array16Bit(uvs, buf); // triangle indices foreach (var idx in tris) { var idx16 = (ushort)idx; buf.Write(idx16); } buf.Close(); return(stream.ToArray()); }
/// <summary> /// Set texture pixel row /// </summary> private static void SetTexturePixelRow(Texture2D tex, int y, ImageBlock imgBlock, byte[] decodedData, ref int dataIndex, List <byte[]> colorTable, Color32?bgColor, int transparentIndex, bool useBeforeTex) { // Row no (0~) int row = tex.height - 1 - y; for (int x = 0; x < tex.width; x++) { // Line no (0~) int line = x; // Out of image blocks if (row < imgBlock.imageTopPosition || row >= imgBlock.imageTopPosition + imgBlock.imageHeight || line < imgBlock.imageLeftPosition || line >= imgBlock.imageLeftPosition + imgBlock.imageWidth) { if (useBeforeTex == false && bgColor != null) { tex.SetPixel(x, y, bgColor.Value); } continue; } // Out of decoded data if (dataIndex >= decodedData.Length) { tex.SetPixel(x, y, Color.black); // Debug.LogError ("dataIndex exceeded the size of decodedData. dataIndex:" + dataIndex + " decodedData.Length:" + decodedData.Length + " y:" + y + " x:" + x); dataIndex++; continue; } // Get pixel color from color table byte colorIndex = decodedData[dataIndex]; if (colorTable == null || colorTable.Count <= colorIndex) { Debug.LogError("colorIndex exceeded the size of colorTable. colorTable.Count:" + colorTable.Count + " colorIndex:" + colorIndex); dataIndex++; continue; } byte[] rgb = colorTable[colorIndex]; // Set alpha byte alpha = transparentIndex >= 0 && transparentIndex == colorIndex ? (byte)0 : (byte)255; if (alpha != 0 || useBeforeTex == false) { Color32 col = new Color32(rgb[0], rgb[1], rgb[2], alpha); tex.SetPixel(x, y, col); } dataIndex++; } }
/// <summary> /// Get GIF texture list Coroutine (Avoid lock up but more slow) /// </summary> /// <param name="mb">MonoBehaviour to start the coroutine</param> /// <param name="bytes">GIF file byte data</param> /// <param name="cb">Callback method(param is GIF texture list, Animation loop count, GIF image width (px), GIF image height (px))</param> /// <param name="filterMode">Textures filter mode</param> /// <param name="wrapMode">Textures wrap mode</param> /// <param name="debugLog">Debug Log Flag</param> /// <returns>IEnumerator</returns> public static IEnumerator GetTextureListCoroutine(MonoBehaviour mb, byte[] bytes, Action <List <GifTexture>, int, int, int> cb, FilterMode filterMode = FilterMode.Bilinear, TextureWrapMode wrapMode = TextureWrapMode.Clamp, bool debugLog = false) { int loopCount = -1; int width = 0; int height = 0; // Set GIF data var gifData = new GifData(); if (SetGifData(bytes, ref gifData, debugLog) == false) { Debug.LogError("GIF file data set error."); if (cb != null) { cb(null, loopCount, width, height); } yield break; } // avoid lock up yield return(0); // Decode to textures from GIF data List <GifTexture> gifTexList = null; yield return(mb.StartCoroutine(UniGif.DecodeTextureCoroutine(gifData, gtList => { gifTexList = gtList; }, filterMode, wrapMode))); if (gifTexList == null) { Debug.LogError("GIF texture decode error."); if (cb != null) { cb(null, loopCount, width, height); } yield break; } loopCount = gifData.appEx.loopCount; width = gifData.logicalScreenWidth; height = gifData.logicalScreenHeight; if (cb != null) { cb(gifTexList, loopCount, width, height); } }
/// <summary> /// Gets the values given a material /// </summary> /// <param name="m">The material</param> /// <returns>A StoredValue containing value and type information</returns> public List <StoredValue> GetValues(Material m) { var list = GetShaderProperties(m); var output = new List <StoredValue>(); foreach (var p in list) { var o = new StoredValue { property = p }; output.Add(o); switch (p.type) { case MaterialProperty.PropertyType.Color: o.value = new object[1]; o.value[0] = m.GetColor(p.name); break; case MaterialProperty.PropertyType.Float: o.value = new object[1]; o.value[0] = m.GetFloat(p.name); break; case MaterialProperty.PropertyType.Range: o.value = new object[1]; o.value[0] = m.GetFloat(p.name); break; case MaterialProperty.PropertyType.TexEnv: o.value = new object[3]; o.value[0] = m.GetTexture(p.name); o.value[1] = m.GetTextureOffset(p.name); o.value[2] = m.GetTextureScale(p.name); break; case MaterialProperty.PropertyType.Vector: o.value = new object[1]; o.value[0] = m.GetVector(p.name); break; default: Debug.LogError("Unsupported type: " + p.type.ToString()); break; } } return(output); }
/// <summary> /// Convert BitArray to int /// </summary> /// <returns>Converted int</returns> public static int ToNumeral(this BitArray array) { if (array == null) { Debug.LogError("array is nothing."); return(0); } if (array.Length > 32) { Debug.LogError("must be at most 32 bits long."); return(0); } var result = new int[1]; array.CopyTo(result, 0); return(result[0]); }
private static bool SetGifHeader(byte[] gifBytes, ref int byteIndex, ref GifData gifData) { // Signature(3 Bytes) // 0x47 0x49 0x46 (GIF) if (gifBytes[0] != 'G' || gifBytes[1] != 'I' || gifBytes[2] != 'F') { Debug.LogError("This is not GIF image."); return(false); } gifData.sig0 = gifBytes[0]; gifData.sig1 = gifBytes[1]; gifData.sig2 = gifBytes[2]; // Version(3 Bytes) // 0x38 0x37 0x61 (87a) or 0x38 0x39 0x61 (89a) if ((gifBytes[3] != '8' || gifBytes[4] != '7' || gifBytes[5] != 'a') && (gifBytes[3] != '8' || gifBytes[4] != '9' || gifBytes[5] != 'a')) { Debug.LogError("GIF version error.\nSupported only GIF87a or GIF89a."); return(false); } gifData.ver0 = gifBytes[3]; gifData.ver1 = gifBytes[4]; gifData.ver2 = gifBytes[5]; // Logical Screen Width(2 Bytes) gifData.logicalScreenWidth = BitConverter.ToUInt16(gifBytes, 6); // Logical Screen Height(2 Bytes) gifData.logicalScreenHeight = BitConverter.ToUInt16(gifBytes, 8); // 1 Byte { // Global Color Table Flag(1 Bit) gifData.globalColorTableFlag = (gifBytes[10] & 128) == 128; // 0b10000000 // Color Resolution(3 Bits) switch (gifBytes[10] & 112) { case 112: // 0b01110000 gifData.colorResolution = 8; break; case 96: // 0b01100000 gifData.colorResolution = 7; break; case 80: // 0b01010000 gifData.colorResolution = 6; break; case 64: // 0b01000000 gifData.colorResolution = 5; break; case 48: // 0b00110000 gifData.colorResolution = 4; break; case 32: // 0b00100000 gifData.colorResolution = 3; break; case 16: // 0b00010000 gifData.colorResolution = 2; break; default: gifData.colorResolution = 1; break; } // Sort Flag(1 Bit) gifData.sortFlag = (gifBytes[10] & 8) == 8; // 0b00001000 // Size of Global Color Table(3 Bits) int val = (gifBytes[10] & 7) + 1; gifData.sizeOfGlobalColorTable = (int)Math.Pow(2, val); } // Background Color Index(1 Byte) gifData.bgColorIndex = gifBytes[11]; // Pixel Aspect Ratio(1 Byte) gifData.pixelAspectRatio = gifBytes[12]; byteIndex = 13; if (gifData.globalColorTableFlag) { // Global Color Table(0~255×3 Bytes) gifData.globalColorTable = new List <byte[]>(); for (int i = byteIndex; i < byteIndex + (gifData.sizeOfGlobalColorTable * 3); i += 3) { gifData.globalColorTable.Add(new byte[] { gifBytes[i], gifBytes[i + 1], gifBytes[i + 2] }); } byteIndex = byteIndex + (gifData.sizeOfGlobalColorTable * 3); } return(true); }
private static bool SetGifBlock(byte[] gifBytes, ref int byteIndex, ref GifData gifData) { try { int lastIndex = 0; while (true) { int nowIndex = byteIndex; if (gifBytes[nowIndex] == 0x2c) { // Image Block(0x2c) SetImageBlock(gifBytes, ref byteIndex, ref gifData); } else if (gifBytes[nowIndex] == 0x21) { // Extension switch (gifBytes[nowIndex + 1]) { case 0xf9: // Graphic Control Extension(0x21 0xf9) SetGraphicControlExtension(gifBytes, ref byteIndex, ref gifData); break; case 0xfe: // Comment Extension(0x21 0xfe) SetCommentExtension(gifBytes, ref byteIndex, ref gifData); break; case 0x01: // Plain Text Extension(0x21 0x01) SetPlainTextExtension(gifBytes, ref byteIndex, ref gifData); break; case 0xff: // Application Extension(0x21 0xff) SetApplicationExtension(gifBytes, ref byteIndex, ref gifData); break; default: break; } } else if (gifBytes[nowIndex] == 0x3b) { // Trailer(1 Byte) gifData.trailer = gifBytes[byteIndex]; byteIndex++; break; } if (lastIndex == nowIndex) { Debug.LogError("Infinite loop error."); return(false); } lastIndex = nowIndex; } } catch (Exception ex) { Debug.LogError(ex.Message); return(false); } return(true); }
public IEnumerator Load(int numberOfFrames, float timeScale = 0) { if (Data == null) { Debug.LogWarning("There was a problem loading Object Data!"); } ++loadingCount; //var oldFixedTime = Time.fixedDeltaTime; //if (Application.isPlaying) // Time.fixedDeltaTime = 9; //Need to wait while the base level is prepared, it takes 2 frames while (numberOfFrames-- > 0) { yield return(new WaitForEndOfFrame()); } if (LevelSerializer.ShouldCollect && timeScale == 0) { GC.Collect(); } LevelSerializer.RaiseProgress("Initializing", 0); if (Data != null && Data.rootObject != null) { Debug.Log(Data.StoredObjectNames.Any(sn => sn.Name == Data.rootObject) ? "Located " + Data.rootObject : "Not found " + Data.rootObject); } //Check if we should be deleting missing items if (!DontDelete) { //First step is to remove any items that should not exist according to the saved scene if (Data != null) { foreach (var go in UniqueIdentifier.AllIdentifiers.Where(n => Data.StoredObjectNames.All(sn => sn.Name != n.Id)).ToList()) { try { var cancel = false; OnDestroyObject(go.gameObject, ref cancel); if (!cancel) { Destroy(go.gameObject); } } catch (Exception e) { Debug.LogWarning("Problem destroying object " + go.name + " " + e.ToString()); } } } } var flaggedObjects = new List <UniqueIdentifier>(); if (Data != null) { flaggedObjects.AddRange(Data.StoredObjectNames.Select(c => UniqueIdentifier.GetByName(c.Name)).Where(c => c != null).Select(c => c.GetComponent <UniqueIdentifier>())); } LevelSerializer.RaiseProgress("Initializing", 0.25f); var position = new Vector3(0, 2000, 2000); //Next we need to instantiate any items that are needed by the stored scene if (Data != null) { foreach (var sto in Data.StoredObjectNames.Where(c => UniqueIdentifier.GetByName(c.Name) == null)) { try { if (sto.createEmptyObject || sto.ClassId == null || !LevelSerializer.AllPrefabs.ContainsKey(sto.ClassId)) { sto.GameObject = new GameObject("CreatedObject"); sto.GameObject.transform.position = position; var emptyObjectMarker = sto.GameObject.AddComponent <EmptyObjectIdentifier>(); sto.GameObject.AddComponent <StoreMesh>(); emptyObjectMarker.IsDeserializing = true; emptyObjectMarker.Id = sto.Name; if (emptyObjectMarker.Id == Data.rootObject) { Debug.Log("Set the root object on an empty"); } flaggedObjects.Add(emptyObjectMarker); } else { var pf = LevelSerializer.AllPrefabs[sto.ClassId]; var cancel = false; CreateGameObject(pf, ref cancel); if (cancel) { Debug.LogWarning("Cancelled"); continue; } var uis = pf.GetComponentsInChildren <UniqueIdentifier>(); foreach (var ui in uis) { ui.IsDeserializing = true; } sto.GameObject = Instantiate(pf, position, Quaternion.identity) as GameObject; sto.GameObject.GetComponent <UniqueIdentifier>().Id = sto.Name; if (sto.GameObject.GetComponent <UniqueIdentifier>().Id == Data.rootObject) { Debug.Log("Set the root object on a prefab"); } foreach (var ui in uis) { ui.IsDeserializing = false; } flaggedObjects.AddRange(sto.GameObject.GetComponentsInChildren <UniqueIdentifier>()); } position += Vector3.right * 50; sto.GameObject.GetComponent <UniqueIdentifier>().Id = sto.Name; sto.GameObject.name = sto.GameObjectName; if (sto.ChildIds.Count > 0) { var list = sto.GameObject.GetComponentsInChildren <UniqueIdentifier>().ToList(); for (var i = 0; i < list.Count && i < sto.ChildIds.Count; i++) { list[i].Id = sto.ChildIds[i]; } } if (sto.Children.Count > 0) { var list = LevelSerializer.GetComponentsInChildrenWithClause(sto.GameObject); _indexDictionary.Clear(); foreach (var c in list) { if (!sto.Children.ContainsKey(c.ClassId)) { continue; } if (!_indexDictionary.ContainsKey(c.ClassId)) { _indexDictionary[c.ClassId] = 0; } c.Id = sto.Children[c.ClassId][_indexDictionary[c.ClassId]]; _indexDictionary[c.ClassId] = _indexDictionary[c.ClassId] + 1; } } } catch (Exception e) { Debug.LogError(e); Debug.LogWarning("Problem creating an object " + sto.GameObjectName + " with classID " + sto.ClassId + " " + e); } } } var loadedGameObjects = new HashSet <GameObject>(); LevelSerializer.RaiseProgress("Initializing", 0.75f); if (Data != null) { foreach (var so in Data.StoredObjectNames) { var go = UniqueIdentifier.GetByName(so.Name); if (go != null) { loadedGameObjects.Add(go); if (so.Components != null && so.Components.Count > 0) { var all = go.GetComponents <Component>().Where(c => !typeof(UniqueIdentifier).IsAssignableFrom(c.GetType())).ToList(); foreach (var comp in all) { if (!so.Components.ContainsKey(comp.GetType().FullName)) { if (Application.isPlaying) { Destroy(comp); } else { DestroyImmediate(comp); } } } } SetActive(go, so.Active); if (so.setExtraData) { go.layer = so.layer; go.tag = so.tag; } } else { Debug.LogError("Could not find " + so.GameObjectName + " " + so.Name); } } } LevelSerializer.RaiseProgress("Initializing", 0.85f); if (Data != null && rootObject != null) { if (UniqueIdentifier.GetByName(Data.rootObject) == null) { Debug.Log("No root object has been configured"); } } foreach (var go in Data.StoredObjectNames.Where(c => !string.IsNullOrEmpty(c.ParentName))) { var parent = UniqueIdentifier.GetByName(go.ParentName); var item = UniqueIdentifier.GetByName(go.Name); if (item != null && parent != null) { item.SetParent(parent); } } LevelSerializer.RaiseProgress("Initializing", 1f); var currentProgress = 0; UnitySerializer.FinalProcess process; if (Data != null) { using (new UnitySerializer.SerializationSplitScope()) { using (new UnitySerializer.SerializationScope()) { //Now we restore the data for the items foreach (var item in Data.StoredItems.GroupBy(i => i.Name, (name, cps) => new { Name = name, Components = cps.Where(cp => cp.Name == name).GroupBy(cp => cp.Type, (type, components) => new { Type = type, List = components.ToList() }).ToList() })) { Debug.LogFormat("\n*****************\n{0}\n********START**********\n", item.Name); var go = UniqueIdentifier.GetByName(item.Name); if (go == null) { Debug.LogWarning(item.Name + " was null"); continue; } foreach (var cp in item.Components) { try { LevelSerializer.RaiseProgress("Loading", (float)++currentProgress / (float)Data.StoredItems.Count); var type = UnitySerializer.GetTypeEx(cp.Type); if (type == null) { continue; } Last = go; var cancel = false; LoadData(go, ref cancel); LoadComponent(go, type.Name, ref cancel); if (cancel) { continue; } Debug.LogFormat("<{0}>\n", type.FullName); var list = go.GetComponents(type).Where(c => c.GetType() == type).ToList(); //Make sure the lists are the same length while (list.Count > cp.List.Count) { DestroyImmediate(list.Last()); list.Remove(list.Last()); } if (type == typeof(NavMeshAgent)) { var cp1 = cp; var item1 = item; Action perform = () => { var comp = cp1; var tp = type; var tname = item1.Name; UnitySerializer.AddFinalAction(() => { var g = UniqueIdentifier.GetByName(tname); var nlist = g.GetComponents(tp).Where(c => c.GetType() == tp).ToList(); while (nlist.Count < comp.List.Count) { try { nlist.Add(g.AddComponent(tp)); } catch { } } list = list.Where(l => l != null).ToList(); //Now deserialize the items back in for (var i = 0; i < nlist.Count; i++) { if (LevelSerializer.CustomSerializers.ContainsKey(tp)) { LevelSerializer.CustomSerializers[tp].Deserialize((byte[])comp.List[i].Data, nlist[i]); } else { UnitySerializer.DeserializeInto(comp.List[i].Data, nlist[i]); } LoadedComponent(nlist[i]); } }); }; perform(); } else { while (list.Count < cp.List.Count) { try { Debug.Log("Adding component of type " + type.ToString()); // Try to resolve [RequireComponent] attributes by iteratively adding the components that // don't have any requirements first var requirements = new List <Type>() { type }; bool updated = false; do { int before = requirements.Count(); var r = requirements.SelectMany(it => it.GetCustomAttributes(typeof(RequireComponent), true). Select(itm => new[] { ((RequireComponent)itm).m_Type0, ((RequireComponent)itm).m_Type1, ((RequireComponent)itm).m_Type2 }).SelectMany(itm => itm).Where(itm => itm != null).Distinct()).ToList(); requirements.AddRange(r.Where(a => !requirements.Contains(a))); updated = before != requirements.Count(); } while (updated); requirements.RemoveAt(0); foreach (var req in requirements) { go.AddComponent(UnitySerializer.GetTypeEx(item.Components.FirstOrDefault(a => req.IsAssignableFrom(UnitySerializer.GetTypeEx(a.Type))).Type)); } list.Add(go.AddComponent(type)); } catch { } } list = list.Where(l => l != null).ToList(); //Now deserialize the items back in for (var i = 0; i < list.Count; i++) { Debug.Log(string.Format("Deserializing {0} for {1}", type.Name, go.GetFullName())); if (LevelSerializer.CustomSerializers.ContainsKey(type)) { LevelSerializer.CustomSerializers[type].Deserialize(cp.List[i].Data, list[i]); } else { UnitySerializer.DeserializeInto(cp.List[i].Data, list[i]); } LoadedComponent(list[i]); } } Debug.LogFormat("</{0}>", type.FullName); } catch (Exception e) { Debug.LogWarning("Problem deserializing " + cp.Type + " for " + go.name + " " + e.ToString()); } } Debug.LogFormat("\n*****************\n{0}\n********END**********\n\n", item.Name); } process = UnitySerializer.TakeOwnershipOfFinalization(); } UnitySerializer.RunDeferredActions(process); if (LevelSerializer.ShouldCollect && timeScale == 0) { Resources.UnloadUnusedAssets(); GC.Collect(); } PluginsHelper.Add(Last); UnitySerializer.InformDeserializedObjects(process); //Tell the world that the level has been loaded if (Data != null && Data.rootObject != null) { rootObject = UniqueIdentifier.GetByName(Data.rootObject); } else { rootObject = null; } if (rootObject == null && Data.rootObject != null) { Debug.LogError("Could not find the root object"); Debug.Log(Data.rootObject + " not found " + (!Data.StoredObjectNames.Any(n => n.Name == Data.rootObject) ? "not in the stored names" : "was in the stored names")); } //Flag that we aren't deserializing foreach (var obj in flaggedObjects) { obj.IsDeserializing = false; obj.SendMessage("OnDeserialized", SendMessageOptions.DontRequireReceiver); } LevelSerializer.IsDeserializing = false; _loading = false; RoomManager.loadingRoom = false; whenCompleted(rootObject, loadedGameObjects.ToList()); if (Application.isEditor) { Last.hideFlags = HideFlags.HideAndDontSave; Last.GetComponent <MeshRenderer>().enabled = false; } //Get rid of the current object that is holding this level loader, it was //created solely for the purpose of running this script if (Application.isPlaying) { Destroy(gameObject, 0.1f); } else { DestroyImmediate(gameObject); } } } }