Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by blediract · Mar 24, 2020 at 06:30 PM · assetdeleteguid

GUID removal after deleting a file?

Hello,
I ran into a pretty weird behavior (from my point of view) when trying to check if an asset exists before creating one with the same name.

It works fine the first time the code is executed after opening Unity but if I delete manually the asset file in the Project window, Unity seems to keep the GUID in memory and tells me the asset still exists.


This is the code I made:
if (string.IsNullOrEmpty(AssetDatabase.AssetPathToGUID(_path)))
{
    AssetDatabase.CreateAsset(myObject, _path);
    EditorUtility.FocusProjectWindow();
    Selection.activeObject = myObject;
}
else
{
    Debug.LogError("There is already an asset with this name");
    Debug.Log(AssetDatabase.AssetPathToGUID(_path);
}
After first time I always have the error and an GUID in the console.


I tried AssetDatabase.Refresh() and nothing changed.

AssetDatabase.DeleteAsset(_path) returns false.

AssetDatabase.ImportAsset(_path)" gives me a warning in the console telling me the asset doesn't exist.

But Debug.Log(AssetDatabase.GUIDToAssetPath(AssetDatabase.AssetPathToGUID(_path))) returns my "_path" value... (with the assetname.asset).

So I'm wandering:

  • Is there a way to clear/update the GUID of a project? Because it seems there is a hashtable or something somewhere that still stores the GUID and the path of a deleted .asset file.

  • Am I misunderstanding the use of assets, GUID and asset path?

  • Should I stop right here and use File.Exists of System.IO instead?

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

2 Replies

· Add your reply
  • Sort: 
avatar image
0

Answer by vtclayton · Apr 25, 2020 at 08:20 AM

I sure wish I knew the answer to any of this.


One thing to note that AssetDatabase.DeleteAsset() returns false if the file wasn't there to delete in the first place (... which can be pretty counter-intuitive, but there you go).


If you close Unity and restart it, it will forget about the guid-to-assetPath mapping.


My (sad) guess is that you understand things correctly, and there's an oversight in the API because who would want to check if a thing exists? You can just know that it exists and then check the return value when you delete it. ... I'd be happy to be proved wrong.


Here's a cadre of other things I tried that didn't seem to help (some of these are nonpublic methods you have to invoke via reflection; "results" only verified for 2018.4):

 EditorUtility.UnloadUnusedAssetsImmediate(includeMonoReferenceAsRoots:false);
 EditorUtility.UnloadUnusedAssetsImmediate(includeMonoReferenceAsRoots:true);
 AssetDatabase.ReleaseCachedFileHandles();
 AssetDatabase.SaveAssets();
 AssetDatabase.CloseCachedFiles();
 AssetDatabase.UnregisterAssetFolder();

And this is the Solution I ended up with. It works for deleted folders and a number of other common cases. I'm not 100% sure it works for everything, and I'm somewhat afraid there are going to be false positives... but it's the best I've got (short of quitting and restarting Unity)

 public static bool AssetActuallyExists(string assetPath)
 {
     return !(AssetDatabase.AssetPathToGUID(assetPath) == string.Empty ||
         AssetDatabase.GetMainAssetTypeAtPath(assetPath) != null);
 }

Test Code:

 using NUnit.Framework;
 using System;
 using UnityEditor;
 using UnityEngine;

 namespace WhyWasThisSoDifficult
 {
     [TestFixture]
     public class ExistenceTests
     {
         // Test Utility for creating, copying, and managing different Assets
         private class TestAsset
         {
             public string Path { get; private set; }
             public string DeletedPath
             {
                 get
                 {
                     var fileName = System.IO.Path.GetFileNameWithoutExtension(Path);
                     return Path.Replace(fileName, fileName + "_Deleted");
                 }
             }

             public TestAsset(string path)
             {
                 Path = System.IO.Path.Combine("Assets", path);
                 AssetDatabase.CopyAsset(Path, DeletedPath);
                 AssetDatabase.DeleteAsset(DeletedPath);
             }

             public TestAsset(string path, bool folder)
             {
                 Path = path;

                 AssetDatabase.CreateFolder("Assets", Path);
                 AssetDatabase.CreateFolder("Assets", DeletedPath);

                 Path = System.IO.Path.Combine("Assets", path);

                 AssetDatabase.DeleteAsset(DeletedPath);
             }

             public TestAsset(UnityEngine.Object original, string path)
             {
                 Action<UnityEngine.Object, string> CreateAsset =
                     (obj, p) => AssetDatabase.CreateAsset(obj, p);
                 if(original.GetType() == typeof(GameObject))
                 {
                     CreateAsset = (obj, p) => PrefabUtility.SaveAsPrefabAsset(obj as GameObject, p);
                 }

                 Path = System.IO.Path.Combine("Assets", path);
                 CreateAsset(original, Path);
 
                 UnityEngine.Object clone = UnityEngine.Object.Instantiate(original);
                 CreateAsset(clone, DeletedPath);
 
                 UnityEngine.Object.DestroyImmediate(clone, true);
                 AssetDatabase.DeleteAsset(DeletedPath);
             }

             public bool Exists
             {
                 get
                 {
                     return !(AssetDatabase.AssetPathToGUID(Path) == null ||
                         AssetDatabase.GetMainAssetTypeAtPath(Path) == null);
                 }
             }

             public bool DeletedExists
             {
                 get
                 {
                     return !(AssetDatabase.AssetPathToGUID(DeletedPath) == null ||
                         AssetDatabase.GetMainAssetTypeAtPath(DeletedPath) == null);
                 }
             }
         }

         TestAsset prefab;
         TestAsset folder;
         TestAsset material;
         TestAsset text;
         TestAsset monoScript;
         TestAsset library;

         [OneTimeSetUp]
         public void SetupFixture()
         {
             // This can only really be done once, because AFAIK there's no way to get Unity back to a fresh state without restarting it.

             folder = new TestAsset("Folder", folder: true);
             prefab = new TestAsset(GameObject.CreatePrimitive(PrimitiveType.Cube), "Prefab.prefab");
             material = new TestAsset(new Material(Shader.Find("Standard")), "Material.mat");
             text = new TestAsset(new TextAsset("This is some text"), "Text.txt");
             monoScript = new TestAsset(new MonoScript() { }, "MonoScript.cs");
             library = new TestAsset(@"Packages/Runtime/OculusVR/Plugins/1.47.0/Win64/OVRPlugin.dll");
         }

         [OneTimeTearDown]
         public void TeardownFixture()
         {
             AssetDatabase.DeleteAsset(folder.Path);
             AssetDatabase.DeleteAsset(prefab.Path);
             AssetDatabase.DeleteAsset(material.Path);
             AssetDatabase.DeleteAsset(text.Path);
             AssetDatabase.DeleteAsset(monoScript.Path);
         }

         [Test]
         public void Created_Things_Exist()
         {
             Assert.IsTrue(prefab.Exists, "prefab didn't exist");
             Assert.IsTrue(folder.Exists, "folder didn't exist");
             Assert.IsTrue(material.Exists, "material didn't exist");
             Assert.IsTrue(text.Exists, "text didn't exist");
             Assert.IsTrue(monoScript.Exists, "monoScript didn't exist");
             Assert.IsTrue(library.Exists, "library didn't exist");
         }

         [Test]
         public void Deleted_Things_Dont_Exist()
         {
             Assert.IsFalse(prefab.DeletedExists, "deleted prefab _did_ exist!");
             Assert.IsFalse(folder.DeletedExists, "deleted folder _did_ exist!");
             Assert.IsFalse(material.DeletedExists, "deleted material _did_ exist!");
             Assert.IsFalse(text.DeletedExists, "deleted text _did_ exist!");
             Assert.IsFalse(monoScript.DeletedExists, "deleted monoScript _did_ exist!");
             Assert.IsFalse(library.DeletedExists, "deleted library _did_ exist!");
         }
     }
 }
Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by powerus117 · Oct 26, 2021 at 10:26 AM

I'm probably way too late for this but for future people: I got stuck on the same issue, for me it was related to addressables though and therefor I could not change the actual code that was calling the AssetPathToGUID code. In your case where u can however, u should be able to just specify OnlyExistingAssets option like so:

 AssetDatabase.AssetPathToGUID("Assets/texture.jpg", AssetPathToGUIDOptions.OnlyExistingAssets);

https://docs.unity.cn/2021.2/Documentation/ScriptReference/AssetDatabase.AssetPathToGUID.html

For people having the same issue as I am having, restarting the unity editor doesn't work (even though that is their solution on the unity page). I backed-up the folder that contained the asset that was giving the loading error, then deleted that folder in unity, restart unity, add the folder again, restart unity again (some restarts might not be necessary). This fixed the loading issue for me somehow. Note that this does create new GUIDs in some meta files but you can just revert these and it still works.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

126 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

How do I get a deleted asset back? 5 Answers

What is GUID vs AssetPath? 2 Answers

Asset management with metadata 0 Answers

How to remove an asset package 1 Answer

AssetModificationProcessor OnWillDeleteAsset not called 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges