1

I'm encountering the "Parent directory is not in asset database" error when using AssetDatabase.MoveAsset in a Unity Editor script. This happens even though I've implemented the following steps to create the parent directory:

  1. Folder Creation: Using Directory.CreateDirectory or unity methods based on AssetDatabase.CreateFolder.
  2. Asset Import: Calling AssetDatabase.ImportAsset with the ImportAssetOptions.ImportRecursive flag.
  3. AssetDatabase Refresh: Using AssetDatabase.Refresh explicitly in various places in my code.

Code Example (Illustrative):

 public class AssetData
    {
        public string Path { get; private set; }
        public string Name { get; private set; }
        public string SuggestedPath { get; private set; }
        public string FileExtension
        {
            get { return System.IO.Path.GetExtension(Path).ToLower(); }
        }
        public bool IsModified { get; set; } = false;

        public AssetData(string path, string name, string suggestedPath)
        {
            Path = path;
            Name = name;
            SuggestedPath = suggestedPath;
        }
        
    }
using System;
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEngine;

[ExecuteInEditMode]
public class AssetProcesser : MonoBehaviour
{
    private Queue<AssetData> m_assetsToProcess;

    public void CorrectAssets(List<AssetData> assets)
    {
        m_assetsToProcess = new Queue<AssetData>(assets);
        EditorApplication.update += ProcessAssetCorrectionQueue;
        AssetDatabase.StartAssetEditing();
    }

    private void ProcessAssetCorrectionQueue()
    {
        if (m_assetsToProcess.Count == 0)
        {
            FinishAssetCorrection();
            return;
        }

        try
        {
            foreach (AssetData asset in m_assetsToProcess)
            {
                ProcessAsset(asset);
            }
        }
        finally
        {
            AssetDatabase.StopAssetEditing();
        }
    }

    private void ProcessAsset(AssetData asset)
    {
        string guid = AssetDatabase.AssetPathToGUID(asset.Path);
        string currentPath = AssetDatabase.GUIDToAssetPath(guid);
        string newPath = asset.SuggestedPath;

        string newParentDirectory = Path.GetDirectoryName(newPath);
        CreateFolderIfNeeded(newParentDirectory);
        ImportFolderRecursive(newParentDirectory);
        AssetDatabase.Refresh(ImportAssetOptions.ImportRecursive);

        string
            error = AssetDatabase.MoveAsset(currentPath,
                newPath); // Error I am getting : Parent directory is not in asset database

        if (!string.IsNullOrEmpty(error))
        {
            ToolsLogs.LogError($"Failed to rename asset {asset.Path}: {error}");
        }

        AssetDatabase.ImportAsset(newPath, ImportAssetOptions.ImportRecursive);
    }

    private static void CreateFolderIfNeeded(string folderPath)
    {
        if (!folderPath.StartsWith("Assets/"))
        {
            ToolsLogs.LogError("Invalid path. Path must be within the Assets folder.");
            return;
        }

        string[] folders = folderPath.Substring("Assets/".Length).Split('/');
        string currentPath = "Assets";

        if (!AssetDatabase.IsValidFolder(folderPath))
        {
            try
            {
                for (int i = 0; i < folders.Length; i++)
                {
                    string folderName = folders[i];
                    currentPath = Path.Combine(currentPath, folderName);

                    if (AssetDatabase.IsValidFolder(currentPath))
                    {
                        continue;
                    }

                    string createdFolderGuid = AssetDatabase.CreateFolder(Path.GetDirectoryName(currentPath),
                        Path.GetFileName(currentPath));

                    if (!string.IsNullOrEmpty(createdFolderGuid))
                    {
                        AssetDatabase.ImportAsset(currentPath, ImportAssetOptions.ImportRecursive);
                        Debug.Log($"Created folder: {createdFolderGuid}");
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.LogError($"Error creating directory: {ex.Message}");
            }
        }
    }

    private static void ImportFolderRecursive(string folderPath)
    {
        AssetDatabase.ImportAsset(folderPath,
            ImportAssetOptions.ImportRecursive | ImportAssetOptions.ForceSynchronousImport);
    }

    private void FinishAssetCorrection()
    {
        EditorUtility.ClearProgressBar();
        EditorApplication.update -= ProcessAssetCorrectionQueue;
        AssetDatabase.Refresh();
    }
}

Environment: Unity Version: [2021.3.15f1] Operating System: [macOS]

Things I've Tried:

  • Debugging with Logging: Verified that the folder exists on the file system but is still not recognized by the Asset Database.
  • Forced Delays: Increased delays and experimented with coroutines.
  • Alternative Folder Creation Methods: Tried variations in folder creation logic.

Questions:

  1. What are the common reasons why the Asset Database might not immediately recognize a newly created directory?
  2. Are there more effective ways to force synchronization between the file system and the Asset Database?
  3. Could there be other parts of my asset processing script interfering with folder recognition?

Additional Notes:

  1. I'm open to exploring the possibility of issues with meta files if the more common solutions don't resolve the problem.
  2. This script runs exclusively within the Unity Editor and is not part of any runtime/build behaviour. The provided code example is a simplified representation of my actual codebase.

Thank you in advance for any insights or suggestions!

1
  • id question what is the path at that point cos if its trying to put it at the same level as assets for example, this would seem a reasonable error Commented Mar 30, 2024 at 15:13

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.