public void Load(WWW url, OnSpreedSheetLoaded callback) { if (string.IsNullOrEmpty(config.API_Key)) { Debug.Log("Missing API Key, please enter this in the confie settings"); return; } if (callback != null) { onFinishedLoading += callback; } if (Application.isPlaying) { Task t = new Task(WaitForRequest(url)); } #if UNITY_EDITOR else { EditorCoroutineRunner.StartCoroutine(WaitForRequest(url)); } #endif }
/// <summary> /// Adds the data to the next avaiable space to write it after the startcell /// </summary> /// <param name="search"></param> /// <param name="inputData"></param> /// <param name="callback"></param> public static void Append(GSTU_Search search, ValueRange inputData, UnityAction callback) { StringBuilder sb = new StringBuilder(); sb.Append("https://sheets.googleapis.com/v4/spreadsheets"); sb.Append("/" + search.sheetId); sb.Append("/values"); sb.Append("/" + search.worksheetName + "!" + search.startCell); sb.Append(":append"); sb.Append("?valueInputOption=USER_ENTERED"); sb.Append("&access_token=" + Config.gdr.access_token); string json = JSON.Dump(inputData, EncodeOptions.NoTypeHints); UnityWebRequest request = UnityWebRequest.Post(sb.ToString(), ""); //have to do this cause unitywebrequest post will nto accept json data corrently... byte[] bodyRaw = new UTF8Encoding().GetBytes(json); request.uploadHandler = new UploadHandlerRaw(bodyRaw); request.downloadHandler = new DownloadHandlerBuffer(); if (Application.isPlaying) { new Task(Append(request, callback)); } #if UNITY_EDITOR else { EditorCoroutineRunner.StartCoroutine(Append(request, callback)); } #endif }
/// <summary> /// Writes data to a spreadsheet /// </summary> /// <param name="search"></param> /// <param name="inputData"></param> /// <param name="callback"></param> public static void Write(GSTU_Search search, ValueRange inputData, UnityAction callback) { StringBuilder sb = new StringBuilder(); sb.Append("https://sheets.googleapis.com/v4/spreadsheets"); sb.Append("/" + search.sheetId); sb.Append("/values"); sb.Append("/" + search.worksheetName + "!" + search.startCell + ":" + search.endCell); sb.Append("?valueInputOption=USER_ENTERED"); sb.Append("&access_token=" + Config.gdr.access_token); string json = JSON.Dump(inputData, EncodeOptions.NoTypeHints); byte[] bodyRaw = new UTF8Encoding().GetBytes(json); UnityWebRequest request = UnityWebRequest.Put(sb.ToString(), bodyRaw); if (Application.isPlaying) { new Task(Write(request, callback)); } #if UNITY_EDITOR else { EditorCoroutineRunner.StartCoroutine(Write(request, callback)); } #endif }
/** * @function GenerateTerrain(행성 이름, 구름 구성정보, 구형 생성 Flag) * @brief 구름을 생성한다. */ public void GenerateClouds(string planetName, CloudInfo info, bool isSphere) { if (info == null) { return; } //행성 정보 재구성 var voxelPlanet = InitVoxelPlanet(planetName); var planetInfo = voxelPlanet.GetComponent <VoxelPlanetInfo>(); planetInfo.Init(planetName); planetInfo.isSphere = isSphere; //구름 생성 정보 재구성 planetInfo.cloudInfo = info.DeepCopy(); //구름 오브젝트 초기화 GameObject objClouds = InitPlanetObject(voxelPlanet, "Clouds"); var compClouds = objClouds.AddComponent <VoxelClouds>(); compClouds.planetInfo = planetInfo; //청크 생성 EditorCoroutineRunner.StartEditorCoroutine(compClouds.BuildChunk()); SaveCurrentPlanetInfo(voxelPlanet); }
/// <summary> /// Read a public accessable spreadsheet /// </summary> /// <param name="searchDetails"></param> /// <param name="callback">event that will fire after reading is complete</param> public static void ReadPublicSpreadsheet(GSTU_Search searchDetails, OnSpreedSheetLoaded callback) { if (string.IsNullOrEmpty(Config.API_Key)) { Debug.Log("Missing API Key, please enter this in the confie settings"); return; } StringBuilder sb = new StringBuilder(); sb.Append("https://sheets.googleapis.com/v4/spreadsheets"); sb.Append("/" + searchDetails.sheetId); sb.Append("/values"); sb.Append("/" + searchDetails.worksheetName + "!" + searchDetails.startCell + ":" + searchDetails.endCell); sb.Append("?key=" + Config.API_Key); if (Application.isPlaying) { new Task(Read(new WWW(sb.ToString()), searchDetails.titleColumn, searchDetails.titleRow, callback)); } #if UNITY_EDITOR else { EditorCoroutineRunner.StartCoroutine(Read(new WWW(sb.ToString()), searchDetails.titleColumn, searchDetails.titleRow, callback)); } #endif }
/// <summary> /// Writes a batch update to a spreadsheet /// </summary> /// <param name="search"></param> /// <param name="requestData"></param> /// <param name="callback"></param> public static void WriteBatch(GSTU_Search search, BatchRequestBody requestData, UnityAction callback) { StringBuilder sb = new StringBuilder(); sb.Append("https://sheets.googleapis.com/v4/spreadsheets"); sb.Append("/" + search.sheetId); sb.Append("/values:batchUpdate"); sb.Append("?access_token=" + Config.gdr.access_token); string json = JSON.Dump(requestData, EncodeOptions.NoTypeHints); UnityWebRequest request = UnityWebRequest.Post(sb.ToString(), ""); byte[] bodyRaw = new UTF8Encoding().GetBytes(json); request.uploadHandler = new UploadHandlerRaw(bodyRaw); request.downloadHandler = new DownloadHandlerBuffer(); if (Application.isPlaying) { new Task(WriteBatch(request, callback)); } #if UNITY_EDITOR else { EditorCoroutineRunner.StartCoroutine(WriteBatch(request, callback)); } #endif }
/** * @function GenerateTerrain(행성 이름, 지형 구성정보, 구형 생성 Flag) * @brief 지형을 생성한다. */ public void GenerateTerrain(string planetName, TerrainInfo info, bool isSphere) { if (info == null) { return; } //행성 정보 재구성 var voxelPlanet = InitVoxelPlanet(planetName); var planetInfo = voxelPlanet.GetComponent <VoxelPlanetInfo>(); planetInfo.Init(planetName); planetInfo.isSphere = isSphere; //지형 생성 정보 재구성 planetInfo.terrainInfo = info.DeepCopy(); //지형 오브젝트 초기화 GameObject objTerrain = InitPlanetObject(voxelPlanet, "Terrain"); var compTerrain = objTerrain.AddComponent <VoxelTerrain>(); compTerrain.planetInfo = planetInfo; //청크 생성 EditorCoroutineRunner.StartEditorCoroutine(compTerrain.BuildChunk()); SaveCurrentPlanetInfo(voxelPlanet); }
void OnGUI() { is_toggle = EditorGUILayout.Toggle(is_toggle); if (is_toggle) { EditorCoroutineRunner.StartEditorCoroutine(test()); } }
void Cancel() { if (GUILayout.Button("Cancel")) { EditorCoroutineRunner.StopEditorCoroutine(); builder.Cancel(); } }
static IEnumerator PackAllAssetBundleAsync(bool check) { string srcConfFolder = GetConf(); if (string.IsNullOrEmpty(srcConfFolder)) { yield break; } if (!Directory.Exists(ResourceConst.PkgBundleFolder)) { Directory.CreateDirectory(ResourceConst.PkgBundleFolder); } Clear(); DateTime dt1 = System.DateTime.UtcNow; // 分析场景; yield return(EditorCoroutineRunner.StartEditorCoroutine(DisposeSceneAsync())); DateTime dt2 = System.DateTime.UtcNow; yield return(EditorCoroutineRunner.StartEditorCoroutine(DisposeResourcesFolderAsync())); DateTime dt3 = System.DateTime.UtcNow; Build(); DateTime dt4 = System.DateTime.UtcNow; // 拷贝Conf; PackAssetBundleUtlis.CopyFolder(srcConfFolder, bundleBuildFolder); FileListUtility.BuildFileList(false); DateTime dt5 = System.DateTime.UtcNow; string confFolder = Path.GetFileName(srcConfFolder); PackAssetBundleUtlis.CopyAssetBundle(bundleBuildFolder, ResourceConst.PkgBundleFolder, confFolder); DateTime dt6 = System.DateTime.UtcNow; string info = string.Format("bundle打包完成\n总共{0}个文件\n耗时:{1}分钟\n其中:\n" , _packTools.Count, (dt6 - dt1).TotalMinutes.ToString("f1")); info = string.Format("{0}分析场景资源耗时:{1}秒\n", info, (dt2 - dt1).TotalSeconds.ToString("f1")); info = string.Format("{0}分析Resource资源耗时:{1}秒\n", info, (dt3 - dt2).TotalSeconds.ToString("f1")); info = string.Format("{0}打包AssetBundle耗时:{1}秒\n", info, (dt4 - dt3).TotalSeconds.ToString("f1")); info = string.Format("{0}生成FileList耗时:{1}秒\n", info, (dt5 - dt4).TotalSeconds.ToString("f1")); info = string.Format("{0}拷贝AssetBundle耗时:{1}秒\n", info, (dt6 - dt5).TotalSeconds.ToString("f1")); EditorUtility.DisplayDialog("打包完成", info, "好的"); if (check) { PackAssetBundleUtlis.CheckAllBundles(); } }
public static void DownloadConfig <T>() where T : CsvDataParser, new() { m_parser = new T(); GLDDownloadConfig downloadConfig = LoadDownLoadConfig(); EditorCoroutineRunner.StartEditorCoroutine(DownloadGoogleSheet(downloadConfig)); }
/// <summary> /// 更新服务器资源数据 /// </summary> public void UpdateSkillAction() { string url = string.Format("{0}{1}{2}", ActionEventConfig.SERVER_URL, ActionEventConfig.SERVER_SKILL_ACTION_URL, ActionEventConfig.LIST); //设置正在获取服务器数据 is_get_server_info = true; EditorCoroutineRunner.StartEditorCoroutine(GetServerInfo(url, UpdateSkillActionDone)); }
/// <summary> /// 更新服务器资源数据 /// </summary> public void UpdateClientEffect() { string url = string.Format("{0}{1}{2}", ActionEventConfig.SERVER_URL, ActionEventConfig.SERVER_CLIENT_EFFECT_URL, ActionEventConfig.LIST); //设置正在获取服务器数据 is_get_server_info = true; EditorCoroutineRunner.StartEditorCoroutine(GetServerInfo(url, UpdateClientEffectDone)); }
public static void DemoEditorCoroutines() { // adds a menu item to test the coroutine system. if (!Application.isPlaying) { // lets fire off the demo coroutine with a UI so we can see what its doing. We could also run it without a UI by using EditorCoroutineRunner.StartCoroutine(...) EditorCoroutineRunner.StartCoroutineWithUI(DemoCoroutiune(), "Lotte's Coroutine Demo", true); } }
public void Build() { if (EditorApplication.isPlaying) { EditorApplication.ExecuteMenuItem("Edit/Play"); } AssetDatabase.Refresh(); EditorCoroutineRunner.StartEditorCoroutine(build()); }
/// <summary> /// 打包所有资源 /// </summary> public static void BuildAllAssetBundles() { if (ToolsHelper.IsPlaying()) { return; } ToolsHelper.ClearConsole(); EditorCoroutineRunner.StartEditorCoroutine(_OnBuildAllAssetBundles()); }
void Build() { if (GUILayout.Button("Build")) { PrefabUtility.DisconnectPrefabInstance(builder); Undo.RecordObject(builder, ""); EditorCoroutineRunner.StartEditorCoroutine(IEBuild()); EditorCoroutineRunner.StartEditorCoroutine(ShowProgress()); } }
private void DrawPartScreen() { EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("区域", GUILayout.Width(100))) { DoPartScreen(); EditorCoroutineRunner.StartEditorCoroutine(DoPartScreen()); } EditorGUILayout.EndHorizontal(); GuiUtil.NewLine(); }
/// <summary> /// Reads the spread sheet and callback with the results /// </summary> /// <param name="request"></param> /// <param name="search"></param> /// <param name="containsMergedCells"></param> /// <param name="callback"></param> /// <returns></returns> static IEnumerator Read(UnityWebRequest request, GSTU_Search search, bool containsMergedCells, UnityAction <GstuSpreadSheet> callback) { if (Application.isPlaying) { yield return(new Task(CheckForRefreshToken())); } #if UNITY_EDITOR else { yield return(EditorCoroutineRunner.StartCoroutine(CheckForRefreshToken())); } #endif using (request) { yield return(request.SendWebRequest()); if (string.IsNullOrEmpty(request.downloadHandler.text) || request.downloadHandler.text == "{}") { Debug.LogWarning("Unable to Retreive data from google sheets"); yield break; } ValueRange rawData = JSON.Load(request.downloadHandler.text).Make <ValueRange>(); LoadSheet.rawData = JSON.Load(request.downloadHandler.text).Make <ValueRange>(); GSTU_SpreadsheetResponce responce = new GSTU_SpreadsheetResponce(rawData); //if it contains merged cells then process a second set of json data to know what these cells are if (containsMergedCells) { StringBuilder sb = new StringBuilder(); sb.Append("https://sheets.googleapis.com/v4/spreadsheets"); sb.Append("/" + search.sheetId); sb.Append("?access_token=" + Config.gdr.access_token); UnityWebRequest request2 = UnityWebRequest.Get(sb.ToString()); yield return(request2.SendWebRequest()); SheetsRootObject root = JSON.Load(request2.downloadHandler.text).Make <SheetsRootObject>(); responce.sheetInfo = root.sheets.FirstOrDefault(x => x.properties.title == search.worksheetName); } if (callback != null) { callback(new GstuSpreadSheet(responce, search.titleColumn, search.titleRow)); } } }
protected static IEnumerator CopyData() { startTime = EditorApplication.timeSinceStartup; EditorCoroutineRunner.UpdateUITitle("Import 1/5: Sounds"); EditorCoroutineRunner.UpdateUILabel("Getting Background data"); TraverseNodes(sounds, "sound"); yield return(null); yield return(EditorCoroutineRunner.StartCoroutine(CopyAssets(targetPaths, ImportType.Sound))); targetPaths = new List <ImportAsset>(); EditorCoroutineRunner.UpdateUITitle("Import 2/5: Backgrounds"); EditorCoroutineRunner.UpdateUILabel("Getting Background data"); TraverseNodes(backgrounds, "background"); yield return(null); yield return(EditorCoroutineRunner.StartCoroutine(CopyAssets(targetPaths, ImportType.Background))); targetPaths = new List <ImportAsset>(); EditorCoroutineRunner.UpdateUITitle("Import 3/5: Sprites"); EditorCoroutineRunner.UpdateUILabel("Getting Sprite data"); TraverseNodes(sprites, "sprite"); yield return(null); yield return(EditorCoroutineRunner.StartCoroutine(CopyAssets(targetPaths, ImportType.Sprite))); targetPaths = new List <ImportAsset>(); EditorCoroutineRunner.UpdateUITitle("Import 4/5: Objects"); EditorCoroutineRunner.UpdateUILabel("Getting Object data"); TraverseNodes(objects, "object"); yield return(null); yield return(EditorCoroutineRunner.StartCoroutine(CopyAssets(targetPaths, ImportType.Object))); targetPaths = new List <ImportAsset>(); EditorCoroutineRunner.UpdateUITitle("Import 5/5: Rooms"); EditorCoroutineRunner.UpdateUILabel("Getting Room data"); TraverseNodes(rooms, "room"); yield return(null); yield return(EditorCoroutineRunner.StartCoroutine(CopyAssets(targetPaths, ImportType.Room))); TimeSpan timeSpan = TimeSpan.FromSeconds(EditorApplication.timeSinceStartup - startTime); string timeText = string.Format("{0:D2}:{1:D2}:{2:D2}", timeSpan.Hours, timeSpan.Minutes, timeSpan.Seconds); print("Project Imported! Total Time: <color=#22ffccff></color> " + "<color=#22ee22ff>" + timeText + "</color>"); }
void Package() { isPacking = true; //自动保存设置文件 CreatePackageFile(); //自动增加小版本号 VersionService.SmallVersion++; VersionService.CreateVersionFile(); EditorCoroutineRunner.StartEditorCoroutine(PackageService.Package(relyPackages, bundles, ProessCallback)); }
/// <summary> /// Chekcs for a valid token and if its out of date attempt to refresh it /// </summary> /// <returns></returns> static IEnumerator CheckForRefreshToken() { if (Application.isPlaying) { yield return(new Task(GoogleAuthrisationHelper.CheckForRefreshOfToken())); } #if UNITY_EDITOR else { yield return(EditorCoroutineRunner.StartCoroutine(GoogleAuthrisationHelper.CheckForRefreshOfToken())); } #endif }
/// <summary> /// Child classes should call this once the auth token has been successfully retrieved.</summary> static void NotifyAuthTokenReceived(string authToken) { lock (_notifyAuthTokenLock) { // We're not directly calling _onComplete() here because we're still on HttpListener's async thread. // We need _onComplete() to be called on the main thread, so we store the auth token and set a flag // that will tell us when we should call _onComplete() in the Update() method, which always executes // on the main thread. _authToken = authToken; _shouldNotifyAuthTokenReceived = true; EditorCoroutineRunner.StartCoroutine(CheckForTokenRecieve()); } }
protected static IEnumerator CopyAssets(List <ImportAsset> assetData, ImportType importType) { switch (importType) { case ImportType.Background: for (int i = 0; i < assetData.Count; i++) { EditorCoroutineRunner.UpdateUI("Importing Background: " + assetData[i].targetName, i / (float)assetData.Count); SpriteImporter.ImportSprite(assetData[i]); yield return(null); } break; case ImportType.Object: for (int i = 0; i < assetData.Count; i++) { EditorCoroutineRunner.UpdateUI("Importing Object: " + assetData[i].targetName, i / (float)assetData.Count); ObjectImporter.ImportObject(assetData[i]); yield return(null); } break; case ImportType.Room: for (int i = 0; i < assetData.Count; i++) { EditorCoroutineRunner.UpdateUI("Importing Room: " + assetData[i].targetName, i / (float)assetData.Count); RoomImporter.ImportRoom(assetData[i]); yield return(null); } break; case ImportType.Sound: for (int i = 0; i < assetData.Count; i++) { EditorCoroutineRunner.UpdateUI("Importing Sound: " + assetData[i].targetName, i / (float)assetData.Count); CheckAndCopy(assetData[i]); yield return(null); } break; case ImportType.Sprite: for (int i = 0; i < assetData.Count; i++) { EditorCoroutineRunner.UpdateUI("Importing Sprite: " + assetData[i].targetName, i / (float)assetData.Count); SpriteImporter.ImportSprite(assetData[i]); yield return(null); } break; } }
/// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void Painter() { //返回当前点击的场景游戏物体;选择多个则返回第一个选择的;未选择相应的则返回null Transform CurrentSelect = Selection.activeTransform; //获取当前模型的MeshFilter MeshFilter temp = CurrentSelect.GetComponent <MeshFilter>(); //圓的大小 //笔刷在模型上的正交大小 = float(1-36) * 當前物體x的scale值 * 当前物體的MeshFilter的x大小 / 200 float orthographicSize = (brushSize * CurrentSelect.localScale.x) * (temp.sharedMesh.bounds.size.x / 200); //从材质球中获取Control贴图 MaskTex = (Texture2D)CurrentSelect.gameObject.GetComponent <MeshRenderer>().sharedMaterial.GetTexture("_Control"); //笔刷在模型上的直徑大小 = (int)四捨五入 < float(1-36) * Control贴图寬度 / 100 > brushSizeInPourcent = (int)Mathf.Round((brushSize * MaskTex.width) / 100); //bool ToggleF = false; Event e = Event.current;//检测输入,Event.current当前窗口的事件 //不想让SceneView视图接收鼠标点击选择事件,只希望在Hierarchy视图选择 HandleUtility.AddDefaultControl(0); RaycastHit raycastHit = new RaycastHit(); Ray terrain = HandleUtility.GUIPointToWorldRay(e.mousePosition); //从鼠标位置发射一条射线 if (Physics.Raycast(terrain, out raycastHit, Mathf.Infinity, 1 << LayerMask.NameToLayer("ground"))) //射线检测名为"ground"的层 { Handles.color = new Color(1f, 1f, 0f, 1f); //(滑鼠)控制器的颜色,黃色(R+G) Handles.DrawWireDisc(raycastHit.point, raycastHit.normal, orthographicSize); //根据笔刷大小在鼠标位置显示一个圆 //鼠标点击或按下并拖动进行绘制 if ((e.type == EventType.MouseDrag && e.alt == false && e.control == false && e.shift == false && e.button == 0) || (e.type == EventType.MouseDown && e.shift == false && e.alt == false && e.control == false && e.button == 0 && ToggleF == false)) { //选择绘制的通道 Vector2 pixelUV = raycastHit.textureCoord; //取得raycast點到的 纹理坐标(0~1) EditorCoroutineRunner.StartEditorCoroutine(Draw(pixelUV)); //Draw(pixelUV); ToggleF = true; } } else if (e.type == EventType.Layout && e.alt == false && e.button == 0 && ToggleF == true) { SaveTexture();//绘制结束保存Control贴图 ToggleF = false; } }
static void LoadBundle() { //EditorApplication.isPlaying = true; string bundleFile = Utils.OpenFileLocalPath(new string[] { TARGET_FORMAT }); Debug.Log(bundleFile); if (string.IsNullOrEmpty(bundleFile)) { EditorUtility.DisplayDialog("error", "your selection is error," + "please select the real assetbunldes file", "sure"); } else { EditorCoroutineRunner.StartEditorCoroutine(LoadBundle(bundleFile)); } }
/// <summary> /// Reads information from a spreadsheet /// </summary> /// <param name="search"></param> /// <param name="callback"></param> /// <param name="containsMergedCells"> does the spreadsheet contain merged cells, will attempt to group these by titles</param> public static void Read(GSTU_Search search, UnityAction <GstuSpreadSheet> callback, bool containsMergedCells = false) { UnityWebRequest request = UnityWebRequest.Get(CreateReadRequestURI(search)); if (Application.isPlaying) { new Task(Read(request, search, containsMergedCells, callback)); } #if UNITY_EDITOR else { EditorCoroutineRunner.StartCoroutine(Read(request, search, containsMergedCells, callback)); } #endif }
private static IEnumerator GetCitys() { isGenerateData = true; Map.ProvinceNum = 0; for (int i = mapSizeX; i >= 0; i -= 16) { for (int j = mapSizeY; j >= 0; j -= 16) { if (isGenerateData && MapData.ColorNear(MapData.Map.GetPixel(i, j), MapData.MapColor)) { yield return(EditorCoroutineRunner.StartEditorCoroutine(new Province().GetCityFromPoint(i, j))); } } } }
BuildAssetBundleOptions relyBuildOption; //依赖包打包设置 void CheckAndPackage() { CheckPackage(); if (errorCount == 0) { EditorCoroutineRunner.StartEditorCoroutine(Package()); } else { if (EditorUtility.DisplayDialog("失败", "打包设置有错误,请先修复错误!", "好的", "仍要打包") == false) { EditorCoroutineRunner.StartEditorCoroutine(Package()); } } }
static IEnumerator DemoCoroutiune() { // You can code editor coroutines exactly like you would a normal unity coroutine Debug.Log("Step: 0"); yield return(null); // all the normal return types that work with regular Unity coroutines should work here! for example lets wait for a second Debug.Log("Step: 1"); yield return(new WaitForSeconds(1)); // We can also yeild any type that extends Unitys CustomYieldInstruction class. here we are going to use EditorStatusUpdate. this allows us to yield and update the // editor coroutine UI at the same time! yield return(new EditorStatusUpdate("coroutine is running", 0.2f)); // We can also yield to nested coroutines Debug.Log("Step: 2"); yield return(EditorCoroutineRunner.StartCoroutine(DemoTwo())); EditorCoroutineRunner.UpdateUIProgressBar(0.35f); // we can use the UpdateUI helper methods to update the UI whenever, without yielding a EditorStatusUpdate yield return(DemoTwo()); // it shouldnt matter how we start the nested coroutine, the editor runner can hadle it // we can even yield a WWW object if we want to grab data from the internets! Debug.Log("Step: 3"); // for example, lets as random.org to generate us a list of random numbers and shove it into the console var www = new WWW("https://www.random.org/integers/?num=100&min=1&max=1000&col=1&base=10&col=5&format=plain&rnd=new"); yield return(www); Debug.Log(www.text); EditorCoroutineRunner.UpdateUI("Half way!", 0.5f); yield return(new WaitForSeconds(1)); // Finally lets do a long runnig task and split its updates over many frames to keep the editor responsive Debug.Log("Step: 4"); var test = 1000; yield return(new WaitUntil(() => { test--; EditorCoroutineRunner.UpdateUI("Crunching Numbers: " + test, 0.5f + (((1000 - test) / 1000f) * 0.5f)); return (test <= 0); })); Debug.Log("Done!!"); }