Search Unity

Feedback no rename?

Discussion in 'Timeline' started by laurentlavigne, Jan 22, 2020.

  1. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    6,325
    upload_2020-1-21_16-35-47.png
    I'm using this to create quick clip, for example i'm using this as a run cycle
     
    Flavelius likes this.
  2. seant_unity

    seant_unity

    Unity Technologies

    Joined:
    Aug 25, 2015
    Posts:
    1,516
    Unity doesn't permit renaming of SubAssets.

    But, if you go to the animation track, then 'Convert To Clip track', select the clip, you can then rename the associated clip in the inspector. Not ideal - but it is a workaround for exactly this limitation.
     
    laurentlavigne likes this.
  3. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    6,325
    it works but doesn't update the project name immediately, after a few updates i seems

    why doesn't unity permit sub asset renaming?
     
  4. seant_unity

    seant_unity

    Unity Technologies

    Joined:
    Aug 25, 2015
    Posts:
    1,516
    I don't think there is a technical reason for it, I think it's legacy behaviour that likely needs updating. If I'm not mistaken, the main use case for sub-assets were fbx files, where the names were fixed.

    It is possible to do it via script (like the inspector does), and I think there are some user-tools out there to do it.
     
    laurentlavigne likes this.
  5. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    6,325
    Cheers it's fine the way it is, just a habit to get
    The name not updating until reload looks like a glitch though, maybe not your team's job
     
  6. sbinter_levelex

    sbinter_levelex

    Joined:
    Jul 5, 2018
    Posts:
    9
    To tack on here - that behavior to allow for renaming would be incredibly convenient for organizational reasons. We have created a system for sub-asset scriptable objects as data. This allows for several conveniences in keeping track of which assets are related. Using a seemingly random editor window or custom tooling is far less intuitive of a workflow for the non-engineers who use the system than simply renaming the asset is.

    If there really is no technical reason for it, would it be possible for that option to be made available?
     
  7. seant_unity

    seant_unity

    Unity Technologies

    Joined:
    Aug 25, 2015
    Posts:
    1,516
    It seems to be a requested editor feature (https://answers.unity.com/questions/1348379/renaming-child-assets-in-project.html), but I haven't found it on a road map anywhere (which doesn't mean it isn't).

    The post above works around it using the inspector, which works if you have custom types. The following example code - which is condensed for brevity - is a bit closer to what we use in the animation playable asset inspector to change the recorded clip name.

    Code (CSharp):
    1. serializedObject.Update();
    2. var nameProperty = serializedObject.FindProperty("m_Name");
    3. EditorGUI.BeginChangeCheck();
    4. EditorGUILayout.DelayedTextField(nameProperty);
    5. if (EditorGUI.EndChangeCheck())
    6. {
    7.     serializedObject.ApplyModifiedProperties();
    8.     AssetDatabase.SaveAssets();
    9. }
     
  8. sbinter_levelex

    sbinter_levelex

    Joined:
    Jul 5, 2018
    Posts:
    9
    This is mostly fine as a workaround, but the issue as stated above is that the asset won't update immediately. You have to manually go and reimport the asset. Writing in an AssetImport call after SaveAssets doesn't really work either, as it will update the asset but only to the previous (and incorrect) value.

    There is a bit of confusion on the developer end as they're forced to trigger the reimport to see the change.
     
    laurentlavigne likes this.
  9. CDF

    CDF

    Joined:
    Sep 14, 2013
    Posts:
    1,311
    Yep. Unity does not refresh asset names in project view using the above.
    Bug report coming
     
  10. LazloBonin

    LazloBonin

    Joined:
    Mar 6, 2015
    Posts:
    812
    Here's my workaround to get it to refresh the name: remove the subasset, save assets, re-add the subasset, save assets. Nuclear, but seems to work!

    Code (CSharp):
    1. EditorGUI.BeginChangeCheck();
    2.  
    3. var newName = EditorGUILayout.DelayedTextField(subAsset.name);
    4.  
    5. if (EditorGUI.EndChangeCheck())
    6. {
    7.     subAsset.name = newName;
    8.     EditorUtility.SetDirty(subAsset);
    9.  
    10.     if (AssetDatabase.IsSubAsset(subAsset))
    11.     {
    12.         var path = AssetDatabase.GetAssetPath(subAsset);
    13.         var mainAsset = AssetDatabase.LoadMainAssetAtPath(path);
    14.  
    15.         if (mainAsset != null)
    16.         {
    17.             // This works, but it doesn't refresh the project window name instantly:
    18.             // https://forum.unity.com/threads/no-rename.813678/
    19.             //EditorUtility.SetDirty(mainAsset);
    20.             //AssetDatabase.SaveAssetIfDirty(mainAsset);
    21.             //AssetDatabase.ImportAsset(path);
    22.             //AssetDatabase.Refresh();
    23.  
    24.             // This is more nuclear but does work:
    25.             AssetDatabase.RemoveObjectFromAsset(subAsset);
    26.             EditorUtility.SetDirty(mainAsset);
    27.             AssetDatabase.SaveAssetIfDirty(mainAsset);
    28.             AssetDatabase.AddObjectToAsset(subAsset, mainAsset);
    29.             EditorUtility.SetDirty(mainAsset);
    30.             AssetDatabase.SaveAssetIfDirty(mainAsset);
    31.         }
    32.     }
    33. }
    34.  
     
  11. LazloBonin

    LazloBonin

    Joined:
    Mar 6, 2015
    Posts:
    812
    Here it is as a standalone utility method that supports renaming both main assets and sub assets:

    Code (CSharp):
    1. public static void RenameAsset(UnityEngine.Object asset, string newName)
    2. {
    3.     // Check that asset is not null first using your prefered validation method
    4.  
    5.     var assetPath = AssetDatabase.GetAssetPath(asset);
    6.  
    7.     if (AssetDatabase.IsMainAsset(asset))
    8.     {
    9.         AssetDatabase.RenameAsset(assetPath, newName);
    10.     }
    11.     else if (AssetDatabase.IsSubAsset(asset))
    12.     {
    13.         asset.name = newName;
    14.         EditorUtility.SetDirty(asset);
    15.         var mainAsset = AssetDatabase.LoadMainAssetAtPath(assetPath);
    16.  
    17.         AssetDatabase.RemoveObjectFromAsset(asset);
    18.         EditorUtility.SetDirty(mainAsset);
    19.         AssetDatabase.SaveAssetIfDirty(mainAsset);
    20.         AssetDatabase.AddObjectToAsset(asset, mainAsset);
    21.         EditorUtility.SetDirty(mainAsset);
    22.         AssetDatabase.SaveAssetIfDirty(mainAsset);
    23.     }
    24.     else
    25.     {
    26.         throw new Exception("Object is not an asset.");
    27.     }
    28. }
    29.  
     
    Flavelius likes this.
  12. LazloBonin

    LazloBonin

    Joined:
    Mar 6, 2015
    Posts:
    812
    Update: My solution above has a massive issue: by removing and re-adding the sub-asset to the main asset, the fileID for the sub-asset changes in the serialized YAML. The references will appear to be preserved until an assembly reload, but break when the reload occurs.

    I dug deeper and figured that the issue was that ProjectBrowser.ResetViews was not getting called after a sub-asset rename, which is because, I think, EditorApplication.projectChanged does not get called on a sub-asset rename.

    The better solution thus is to manually refresh the project window using reflection, like so:

    Code (CSharp):
    1. public static void RenameAsset(UnityObject asset, string newName)
    2. {
    3.     EnsureArg.IsNotNull(asset);
    4.  
    5.     if (!AssetDatabase.Contains(asset))
    6.     {
    7.         throw new InvalidOperationException("Object is not an asset.");
    8.     }
    9.  
    10.     var assetPath = AssetDatabase.GetAssetPath(asset);
    11.  
    12.     if (AssetDatabase.IsMainAsset(asset))
    13.     {
    14.         AssetDatabase.RenameAsset(assetPath, newName);
    15.     }
    16.     else if (AssetDatabase.IsSubAsset(asset))
    17.     {
    18.         asset.name = newName;
    19.         EditorUtility.SetDirty(asset);
    20.  
    21.         var mainAsset = AssetDatabase.LoadMainAssetAtPath(assetPath);
    22.         EditorUtility.SetDirty(mainAsset);
    23.         AssetDatabase.SaveAssetIfDirty(mainAsset);
    24.  
    25.         var projectBrowserType = typeof(Editor).Assembly.GetType("UnityEditor.ProjectBrowser");
    26.         var resetViewsMethod = projectBrowserType.GetMethod("ResetViews", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
    27.  
    28.         foreach (var window in Resources.FindObjectsOfTypeAll(projectBrowserType))
    29.         {
    30.             resetViewsMethod.Invoke(window, new object[0]);
    31.         }
    32.     }
    33. }
    34.  
     
    BigRifle, Arycama and laurentlavigne like this.
  13. sbsmith

    sbsmith

    Joined:
    Feb 7, 2013
    Posts:
    126
    Thanks @Ludiq! I was trying to make a property drawer do this and couldn't figure out why changing property.serializedObject.targetObject.name wasn't working, even though I was setting it as dirty. I was missing the step of setting the parent object as dirty too. This works! I don't think @seant_unity is around anymore, but I also appreciate the DelayedTextField. I didn't know that existed.