Problem with FileUtil.MoveFileOrDirectory and material

I want to move assets from a folder to another through editor script. Consider this sample code:

FileUtil.MoveFileOrDirectory("Assets/ZZZ1", "Assets/ZZZ2");
AssetDatabase.Refresh();

It renames the folder ZZZ1 to ZZZ2. It normally has no problem but if the folder contains a material, the editor console shows an exception:

This seems to be related more specifically to that custom editor code that goes along with that terrain shader addon you’re using. It seems to be doing something that is locking access to the material in-between processing, likely some sort of onvalidate function. Try it with just a regular Standard shader material and see if it still happens.

1 Like

Thanks for the answer. I did it with a new material and happened again. Only materials have this problem. Shaders and textures move just fine. Even materials are moved. The problem is it outputs an error in console and clears material properties. The InstanceId of the material remains the same. I know nothing is going on with the terrain extension because I created it. Anyone could test these two lines in a clear project and the result would be the same. It seems like a bug to me. The version is 5.4.2.f1.

Yeah, confirmed the issue on 2017.1.1p3. I can send in an error report project properly setup to reproduce it if you haven’t done so yet.

1 Like

Found a solution to the issue, and Unity actually gave a warning in a fresh project that tipped me off to it. When moving a folder that has assets in it, you need to move/rename the .meta file as well, so your code should look like:

FileUtil.MoveFileOrDirectory("Assets/ZZZ1", "Assets/ZZZ2");
FileUtil.MoveFileOrDirectory("Assets/ZZZ1.meta", "Assets/ZZZ2.meta");
AssetDatabase.Refresh();

Ideally you could make a wrapping method for this that does that for you automatically.

Thanks for testing it. That would be very nice if you send a report for it.

Oh Thank you very much. Yes that’s a great idea.

After further testing, this isn’t actually a bug really, it’s just improper file moving. Using FileUtil is like renaming a folder outside of Unity, and if you do that without renaming the .meta file as well, that can screw things up in general.
What you actually want to use is "AssetDatabase.MoveAsset(from, to);'. Even though it says “asset”, it actually works on folders as well, and will throw no errors when used the first way you intended.

2 Likes

This is fantastic. Before FileUtil I used MoveAsset to move each file individually. It did move the files but I could not remove the original folder. It gave me every kind of headache because of the async nature of MoveAssets. Moving folders with MoveAsset is working perfect and unity documentation fails to mention that. Nice catch and thank you very much for finding such a painless solution.

I’ve made a Feedback suggestion about it if you’d like to vote on it:
https://feedback.unity3d.com/suggestions/update-assetdatabase-dot-moveasset-description-to-accurately-reflect-functionality

1 Like

Sure. Thank you for getting into trouble. That can save a lot of time for other people.