Unity 自动添加头注释代码后无法创建新脚本

出现问题的Unity版本为 2022.3.14,正常使用时的Unity版本为 2020.3.25。

代码为:

public class ScriptsInfoRecoder : UnityEditor.AssetModificationProcessor
{
    private static void OnWillCreateAsset(string path)
    {
        path = path.Replace(".meta", "");
        if (path.EndsWith(".cs"))
        {
            string str = File.ReadAllText(path);
            str = str.Replace("#SCRIPTFULLNAME#", Path.GetFileName(path)).Replace(
                              "#CreateTime#", string.Concat(DateTime.Now.Year, "/", DateTime.Now.Month, "/",DateTime.Now.Day, " ", DateTime.Now.Hour, ":", DateTime.Now.Minute, ":", DateTime.Now.Second));
            File.WriteAllText(path, str);
        }
    }
}

报错:

下方是报错的全部内容

FileNotFoundException: Could not find file "D:\Unity Project\UnlimitedMowing\Assets\Program\Scripts\Test.cs"
System.IO.FileStream..ctor (System.String path, System.IO.FileMode mode, System.IO.FileAccess access, System.IO.FileShare share, System.Int32 bufferSize, System.Boolean anonymous, System.IO.FileOptions options) (at <a3b02d6f9b494355b946095ea1f25c54>:0)
System.IO.FileStream..ctor (System.String path, System.IO.FileMode mode, System.IO.FileAccess access, System.IO.FileShare share, System.Int32 bufferSize, System.IO.FileOptions options) (at <a3b02d6f9b494355b946095ea1f25c54>:0)
(wrapper remoting-invoke-with-check) System.IO.FileStream..ctor(string,System.IO.FileMode,System.IO.FileAccess,System.IO.FileShare,int,System.IO.FileOptions)
System.IO.StreamReader..ctor (System.String path, System.Text.Encoding encoding, System.Boolean detectEncodingFromByteOrderMarks, System.Int32 bufferSize) (at <a3b02d6f9b494355b946095ea1f25c54>:0)
System.IO.StreamReader..ctor (System.String path, System.Text.Encoding encoding, System.Boolean detectEncodingFromByteOrderMarks) (at <a3b02d6f9b494355b946095ea1f25c54>:0)
(wrapper remoting-invoke-with-check) System.IO.StreamReader..ctor(string,System.Text.Encoding,bool)
System.IO.File.InternalReadAllText (System.String path, System.Text.Encoding encoding) (at <a3b02d6f9b494355b946095ea1f25c54>:0)
System.IO.File.ReadAllText (System.String path) (at <a3b02d6f9b494355b946095ea1f25c54>:0)
Tool.Common.ScriptsInfoRecoder.OnWillCreateAsset (System.String path) (at Assets/Program/Scripts/Tool/Editor/ScriptsInfoRecoder.cs:21)
System.Reflection.RuntimeMethodInfo.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) (at <a3b02d6f9b494355b946095ea1f25c54>:0)
Rethrow as TargetInvocationException: Exception has been thrown by the target of an invocation.
System.Reflection.RuntimeMethodInfo.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) (at <a3b02d6f9b494355b946095ea1f25c54>:0)
System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[] parameters) (at <a3b02d6f9b494355b946095ea1f25c54>:0)
UnityEditor.AssetModificationProcessorInternal.OnWillCreateAsset (System.String path) (at <227afaeeb5894c00b1d9aa4278f87f8c>:0)
UnityEditor.ProjectWindowUtil.CreateScriptAssetWithContent (System.String pathName, System.String templateContent) (at <227afaeeb5894c00b1d9aa4278f87f8c>:0)
UnityEditor.ProjectWindowUtil.CreateScriptAssetFromTemplate (System.String pathName, System.String resourceFile) (at <227afaeeb5894c00b1d9aa4278f87f8c>:0)
UnityEditor.ProjectWindowCallback.DoCreateScriptAsset.Action (System.Int32 instanceId, System.String pathName, System.String resourceFile) (at <227afaeeb5894c00b1d9aa4278f87f8c>:0)
UnityEditor.ProjectWindowUtil.EndNameEditAction (UnityEditor.ProjectWindowCallback.EndNameEditAction action, System.Int32 instanceId, System.String pathName, System.String resourceFile, System.Boolean accepted) (at <227afaeeb5894c00b1d9aa4278f87f8c>:0)
UnityEditor.CreateAssetUtility.EndNewAssetCreation (System.String name) (at <227afaeeb5894c00b1d9aa4278f87f8c>:0)
UnityEditor.ObjectListArea.RenameEnded () (at <227afaeeb5894c00b1d9aa4278f87f8c>:0)
UnityEditor.ObjectListArea.HandleRenameOverlay () (at <227afaeeb5894c00b1d9aa4278f87f8c>:0)
UnityEditor.ObjectListArea+LocalGroup.DrawItem (UnityEngine.Rect position, UnityEditor.FilteredHierarchy+FilterResult filterItem, UnityEditor.BuiltinResource builtinResource, System.Boolean isFolderBrowsing) (at <227afaeeb5894c00b1d9aa4278f87f8c>:0)
UnityEditor.ObjectListArea+LocalGroup.DrawInternal (System.Int32 beginIndex, System.Int32 endIndex, System.Single yOffset) (at <227afaeeb5894c00b1d9aa4278f87f8c>:0)
UnityEditor.ObjectListArea+Group.Draw (System.Single yOffset, UnityEngine.Vector2 scrollPos, System.Int32& rowsInUse) (at <227afaeeb5894c00b1d9aa4278f87f8c>:0)
UnityEditor.ObjectListArea.HandleListArea () (at <227afaeeb5894c00b1d9aa4278f87f8c>:0)
UnityEditor.ObjectListArea.OnGUI (UnityEngine.Rect position, System.Int32 keyboardControlID) (at <227afaeeb5894c00b1d9aa4278f87f8c>:0)
UnityEditor.ProjectBrowser.OnGUI () (at <227afaeeb5894c00b1d9aa4278f87f8c>:0)
UnityEditor.HostView.InvokeOnGUI (UnityEngine.Rect onGUIPosition) (at <227afaeeb5894c00b1d9aa4278f87f8c>:0)
UnityEditor.DockArea.DrawView (UnityEngine.Rect dockAreaRect) (at <227afaeeb5894c00b1d9aa4278f87f8c>:0)
UnityEditor.DockArea.OldOnGUI () (at <227afaeeb5894c00b1d9aa4278f87f8c>:0)
UnityEngine.UIElements.IMGUIContainer.DoOnGUI (UnityEngine.Event evt, UnityEngine.Matrix4x4 parentTransform, UnityEngine.Rect clippingRect, System.Boolean isComputingLayout, UnityEngine.Rect layoutSize, System.Action onGUIHandler, System.Boolean canAffectFocus) (at <900dc5ca37fe408984765dccf7e242de>:0)
UnityEngine.UIElements.IMGUIContainer.HandleIMGUIEvent (UnityEngine.Event e, UnityEngine.Matrix4x4 worldTransform, UnityEngine.Rect clippingRect, System.Action onGUIHandler, System.Boolean canAffectFocus) (at <900dc5ca37fe408984765dccf7e242de>:0)
UnityEngine.UIElements.IMGUIContainer.HandleIMGUIEvent (UnityEngine.Event e, System.Action onGUIHandler, System.Boolean canAffectFocus) (at <900dc5ca37fe408984765dccf7e242de>:0)
UnityEngine.UIElements.IMGUIContainer.HandleIMGUIEvent (UnityEngine.Event e, System.Boolean canAffectFocus) (at <900dc5ca37fe408984765dccf7e242de>:0)
UnityEngine.UIElements.IMGUIContainer.SendEventToIMGUIRaw (UnityEngine.UIElements.EventBase evt, System.Boolean canAffectFocus, System.Boolean verifyBounds) (at <900dc5ca37fe408984765dccf7e242de>:0)
UnityEngine.UIElements.IMGUIContainer.SendEventToIMGUI (UnityEngine.UIElements.EventBase evt, System.Boolean canAffectFocus, System.Boolean verifyBounds) (at <900dc5ca37fe408984765dccf7e242de>:0)
UnityEngine.UIElements.KeyboardEventDispatchingStrategy.DispatchEvent (UnityEngine.UIElements.EventBase evt, UnityEngine.UIElements.IPanel panel) (at <900dc5ca37fe408984765dccf7e242de>:0)
UnityEngine.UIElements.EventDispatcher.ApplyDispatchingStrategies (UnityEngine.UIElements.EventBase evt, UnityEngine.UIElements.IPanel panel, System.Boolean imguiEventIsInitiallyUsed) (at <900dc5ca37fe408984765dccf7e242de>:0)
UnityEngine.UIElements.EventDispatcher.ProcessEvent (UnityEngine.UIElements.EventBase evt, UnityEngine.UIElements.IPanel panel) (at <900dc5ca37fe408984765dccf7e242de>:0)
UnityEngine.UIElements.EventDispatcher.Dispatch (UnityEngine.UIElements.EventBase evt, UnityEngine.UIElements.IPanel panel, UnityEngine.UIElements.DispatchMode dispatchMode) (at <900dc5ca37fe408984765dccf7e242de>:0)
UnityEngine.UIElements.BaseVisualElementPanel.SendEvent (UnityEngine.UIElements.EventBase e, UnityEngine.UIElements.DispatchMode dispatchMode) (at <900dc5ca37fe408984765dccf7e242de>:0)
UnityEngine.UIElements.UIElementsUtility.DoDispatch (UnityEngine.UIElements.BaseVisualElementPanel panel) (at <900dc5ca37fe408984765dccf7e242de>:0)
UnityEngine.UIElements.UIElementsUtility.UnityEngine.UIElements.IUIElementsUtility.ProcessEvent (System.Int32 instanceID, System.IntPtr nativeEventPtr, System.Boolean& eventHandled) (at <900dc5ca37fe408984765dccf7e242de>:0)
UnityEngine.UIElements.UIEventRegistration.ProcessEvent (System.Int32 instanceID, System.IntPtr nativeEventPtr) (at <900dc5ca37fe408984765dccf7e242de>:0)
UnityEngine.UIElements.UIEventRegistration+<>c.<.cctor>b__1_2 (System.Int32 i, System.IntPtr ptr) (at <900dc5ca37fe408984765dccf7e242de>:0)
UnityEngine.GUIUtility.ProcessEvent (System.Int32 instanceID, System.IntPtr nativeEventPtr, System.Boolean& result) (at <ab3b53da78e948c59742f9e43eb67ec6>:0)

脚本中的第23行是 string str = File.ReadAllText(path) ,故问题就出现在此。

解决方案:

使用 UniTask,这个插件是我非常喜欢的一个插件,谁用谁知道。修改代码:

private static void OnWillCreateAsset(string path)
{
    path = path.Replace(".meta", "");
    if (path.EndsWith(".cs"))
    {
        ChangeFileContent(path);
    }
}

static async void ChangeFileContent(string path)
{
    await UniTask.Yield();
    string str = File.ReadAllText(path);
    str = str.Replace("#SCRIPTFULLNAME#", Path.GetFileName(path)).Replace(
                      "#CreateTime#", string.Concat(DateTime.Now.Year, "/", DateTime.Now.Month, "/",DateTime.Now.Day, " ", DateTime.Now.Hour, ":", DateTime.Now.Minute, ":", DateTime.Now.Second));
    File.WriteAllText(path, str);
}

结论:

猜测是使用【OnWillCreateAsset】时该文件还没有被创建,而 File.ReadAllText 需要读取到文件故而报错。使用一帧延迟就是表示创建后再对该文件的查找。

请注意:editor下不能执行真正的协程。

如果有小伙伴有其他实现的方法,欢迎在下方评论

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值