Search Unity

Updating renamed bound elements.

Discussion in 'UI Toolkit' started by broots, Aug 11, 2020.

  1. broots

    broots

    Joined:
    Dec 20, 2019
    Posts:
    54
    Heya, I'm having trouble getting bound elements to update their name, nothing I do seems to matter.

    I threw together a script to do... well basically anything I could think of to get the name to update, however it will not update the name until I close the window and open it again, despite the asset being successfully renamed in the editor.


    Code (CSharp):
    1.             renamer.RegisterCallback<BlurEvent>(evnt =>
    2.             {
    3.                 if (property.objectReferenceValue)
    4.                 {
    5.                     AssetDatabase.RenameAsset(AssetDatabase.GetAssetPath(property.objectReferenceValue), renamer.value);
    6.                     AssetDatabase.Refresh();
    7.                     AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(property.objectReferenceValue));
    8.                     AssetDatabase.SaveAssets();
    9.                     property.objectReferenceValue.name = renamer.value;
    10.                     property.serializedObject.ApplyModifiedProperties();
    11.                     property.serializedObject.Update();
    12.                     scriptableObjectField.MarkDirtyRepaint();
    13.                     rootElement.MarkDirtyRepaint();
    14.                 }
    15.             });
    (Full code if it's helpful https://hatebin.com/frrlrhdmod )

    Thanks for your time.
     
    Last edited: Aug 11, 2020
  2. uDamian

    uDamian

    Unity Technologies

    Joined:
    Dec 11, 2017
    Posts:
    1,231
    Since the actual value of "property" does not change, the bound ObjectField is not updated. We seem to not be tracking the "name" when we check for changes in our bindings code.

    A couple of things to note:
    1. verify that the asset reference you get back from your ImportAsset() is still the exact same instance (via instanceId) as your current property.objectReferenceValue
    2. all the MarkDirtyRepaint(), Update() and ApplyModifiedProperties() calls are redundant, because you haven't actually changed the serializedObject in any way. You've changed a property on an object the serializedObject is referencing (one step removed)
    3. try just changing the name on the objectReferenceValue without the re-import and asset db change
    4. worst case, call Unbind() and Bind() on the container element containing your object PropertyFields (or ObjectFields)
     
  3. broots

    broots

    Joined:
    Dec 20, 2019
    Posts:
    54
    Thanks for the reply, here's what I've found.

    1.
    Code (CSharp):
    1.                     AssetDatabase.RenameAsset(AssetDatabase.GetAssetPath(property.objectReferenceValue), renamer.value);
    2.                     AssetDatabase.Refresh();
    3.                     AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(property.objectReferenceValue));
    4.                     AssetDatabase.SaveAssets();
    5.                    
    6.                     property.objectReferenceValue.name = renamer.value;
    7.                     Debug.Log(property.objectReferenceValue.GetInstanceID());
    8.  
    The reference id's do match up after the rename (In my case, my instance ID was -2770 and the renamed asset still had an instance ID of -2770)

    2.
    Good to know, I'll remove these. Was essentially just trying things at random ;p.

    3.

    Just doing
    Code (CSharp):
    1. property.objectReferenceValue.name = renamer.value;
    Behaves essentially the same way, except of course the asset file's name stays the same. It does reflect the name change in the property, but only after clicking on a different object and letting the inspector rebuild.

    4.
    Bind and unbind also behave the same way, using these as trials they behave exactly the same as above.

    Code (CSharp):
    1.                     AssetDatabase.RenameAsset(AssetDatabase.GetAssetPath(property.objectReferenceValue), renamer.value);
    2.                     AssetDatabase.Refresh();
    3.                     AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(property.objectReferenceValue));
    4.                     AssetDatabase.SaveAssets();
    5.                     property.objectReferenceValue.name = renamer.value;
    6.                     scriptableObjectField.Unbind();
    7.                     scriptableObjectField.BindProperty(property);
    or


    Code (CSharp):
    1.                    
    2.                     property.objectReferenceValue.name = renamer.value;
    3.                     scriptableObjectField.Unbind();
    4.                     scriptableObjectField.BindProperty(property);
    I've even tried forcing CreatePropertyGUI to run again, but it still does not update
    Code (CSharp):
    1.                     property.objectReferenceValue.name = renamer.value;
    2.                     rootElement = CreatePropertyGUI(property);
    Silly issue but it's sure not an easy fix!

    Thanks again for your time =]
     
  4. KevinCastejon

    KevinCastejon

    Joined:
    Aug 10, 2021
    Posts:
    108
    I got this working by simply changing the name first then calling SaveAssets() and finally calling RenameAssets()+Refresh()