用途
如制作一些配置工具等。
工具窗口说明
窗口内展示若干字段、2个按钮:一个执行功能、一个关闭窗口。
可继承ScriptableWizard来实现。
示例:
public class SaveCurMomentTools : ScriptableWizard
{
private const string Title = "存储当前时刻";
[SerializeField]
private TextAsset _textAsset;
[MenuItem("Fan的工具/存储当前时刻")]
private static void Init()
{
DisplayWizard<SaveCurMomentTools>(Title, "关闭", "执行");
}
private void OnWizardUpdate()
{
Debug.Log($"{Title} 窗口的内容发生了变化!");
}
private void OnWizardOtherButton()
{
SaveMoment();
}
private void OnWizardCreate()
{
Debug.Log("关闭窗口:" + Title);
}
private void SaveMoment()
{
Debug.Log("存储当前时刻");
}
弹出提示窗口
用途
如点击按钮后,执行失败或成功了,需弹窗告知玩家。
实现
private void ShowTipsWnd(string title, string tips)
{
UnityEditor.EditorUtility.DisplayDialog(title, tips, "好的");
}
编辑器模式下的延迟调用
用途
如执行功能是修改某个ScriptableObject文件,若此时Inspector窗口中正展示该文件,在修改保存后立刻弹窗提示时,不能看到该文件内的数据发生了变化(点击按钮关闭弹窗后才能看到数据变化了)。
因此成功执行后,可以等待一会儿再在弹出成功执行的提示窗口。
实现
private void ShowTipsWnd(string title, string tips, float delaySeconds = 0f)
{
if (delaySeconds > 0)
{
System.Func<Task> func = async () =>
{
await Task.Delay(System.TimeSpan.FromSeconds(delaySeconds));
ShowTipsWnd(title, tips);
};
func();
}
else
{
ShowTipsWnd(title, tips);
}
}
async、await、Task
async:会返回一个Task表示异步操作的完成情况。
await运算符可暂停其所属的async方法的执行,直到它修饰的操作执行完成,才继续往下执行。
Task:对ThreadPool进行了封装改进,使我们能更有效地通过代码控制线程的执行顺序、延续、取消等。
ThreadPool:基于线程,目的是减少创建线程的数量和管理线程的成本。无法控制线程执行顺序,不能获取线程取消、异常、完成的通知。
异步方法:一个方法被调用时立即返回,获取一个线程来执行该方法内部的业务,调用者无需等该方法执行完毕才继续执行后续内容。
可以将一些不需要立即使用执行产生的结果,比较耗时的任务设为异步执行。
将csv文件作为TextAsset资源读取
读取所有内容到字符串中
var str = textAsset.text;
读取每行,换行符"\r\n",剔除空白行
var rowContent = str.Split("\r\n", System.StringSplitOptions.RemoveEmptyEntries);
读取每行内的每个元素,csv间隔符',',剔除空白内容(根据实际需求)
var elements = rowContent.Split(',', System.StringSplitOptions.RemoveEmptyEntries);
修改并存储TextAsset文件
private void SetTextAsset(TextAsset textAsset, string str)
{
// 若path不存在则创建->写入->关闭;若存在则打开->覆盖->关闭。
File.WriteAllText(AssetDatabase.GetAssetPath(textAsset), str);
AssetDatabase.Refresh();
}
编辑器模式下修改某文件后,将修改内容保存到磁盘中
例如修改了某个ScriptableObject文件,需保存它。
private void Save(UnityEngine.Object obj)
{
EditorUtility.SetDirty(obj);
UnityEditor.AssetDatabase.SaveAssets();
}
例子:存储当前时刻
在一个TextAsset文件中,存储每次执行本功能时的时刻。
SaveCurMomentTools.cs
using System.Collections;
using System.Collections.Generic;
using System.Threading.Tasks;
using UnityEngine;
using UnityEditor;
using System.IO;
public class SaveCurMomentTools : ScriptableWizard
{
private const string Title = "存储当前时刻";
[SerializeField]
private TextAsset _textAsset;
[MenuItem("Fan的工具/存储当前时刻")]
private static void Init()
{
DisplayWizard<SaveCurMomentTools>(Title, "关闭", "执行");
}
private void OnWizardUpdate()
{
Debug.Log($"{Title} 窗口的内容发生了变化!");
}
private void OnWizardOtherButton()
{
SaveMoment();
}
private void OnWizardCreate()
{
Debug.Log("关闭窗口:" + Title);
}
private void SaveMoment()
{
if (_textAsset == null)
{
ShowTipsWnd("失败", "请配置正确的TextAsset!");
}
else
{
// 显示当前已存储的内容
var curCnt = ShowMomentStorageContent(_textAsset);
// 读取已存储的内容
var dataStr = _textAsset.text;
// 存储当前时刻
var curMoment = System.DateTime.Now.ToString();
var newStr = (curCnt == 0 ? string.Empty : "\r\n") + curCnt.ToString() + "," + curMoment;
dataStr += newStr;
SetTextAsset(_textAsset, dataStr);
// ShowTipsWnd("成功", "将当前时刻存储到了文件中,请查看确认。", 0.1f);
}
}
private void ShowTipsWnd(string title, string tips, float delaySeconds = 0f)
{
if (delaySeconds > 0)
{
System.Func<Task> func = async () =>
{
await Task.Delay(System.TimeSpan.FromSeconds(delaySeconds));
ShowTipsWnd(title, tips);
};
func();
}
else
{
ShowTipsWnd(title, tips);
}
}
private void ShowTipsWnd(string title, string tips)
{
UnityEditor.EditorUtility.DisplayDialog(title, tips, "好的");
}
private int ShowMomentStorageContent(TextAsset textAsset)
{
int curCnt = 0;
foreach (var content in textAsset.text.Split("\r\n", System.StringSplitOptions.RemoveEmptyEntries))
{
var c = content.Split(',', System.StringSplitOptions.RemoveEmptyEntries);
if (int.TryParse(c[0], out int index))
{
string curMoment = c[1];
Debug.Log(index + ":" + curMoment);
curCnt++;
}
}
return curCnt;
}
private void SetTextAsset(TextAsset textAsset, string str)
{
// 若path不存在则创建->写入->关闭;若存在则打开->覆盖->关闭。
File.WriteAllText(AssetDatabase.GetAssetPath(textAsset), str);
// Save(textAsset);
AssetDatabase.Refresh();
}
private void Save(UnityEngine.Object obj)
{
EditorUtility.SetDirty(obj);
UnityEditor.AssetDatabase.SaveAssets();
}
}
网友评论