I'm writing a custom editor that I want to edit TextAsset contents. What I have right now is a reference to a TextAsset, and what I would love to do is edit textAsset.text, and then call EditorUtility.SetDirty(textAsset) to write the changes to disk. Unfortunately, testAsset.text is readonly. I can't figure out a way to convert from a TextAsset to a system file path, either. Does anyone know how to do this? Any way that I could figure out the local file path of an object selected in the Project panel would be helpful as well.
I was not 100% clear if you were talking about editing the text asset from inside the editor or not. The below information is for modifying files on a run-time build (I did see that your tags included the editor)...
As far as I know the TextAssets are compiled into the same assets files as your other content; which means once the application is deployed it would be compiled into something that looks like this "sharedassets0.assets". There would be no easy way to change the text asset directly without some clever file manipulation.
An easier option would be to maybe store your text assets in another directory local to your project and instead of visually linking them up as assets you would just use the .NET IO API to load the text dynamically and then you could easily save any text changes you needed back to that file. This solution would prevent you from visibly linking them in the editor, but if you needed to assign them in the editor the easiest way would be to just have a string field where you put the file name for the text file and then your application would use that filename when loading your file from code.
For Unity 2022.3, you’ll need a workaround, for example:
public static class TextAssetExtension
{
public static void SetDataInEditor(this TextAsset textAsset, byte[] data)
{
if (textAsset == null)
{
Debug.LogError("TextAsset is null");
return;
}
if (data == null)
{
Debug.LogError("Data is null");
return;
}
var so = new SerializedObject(textAsset);
var bytesProp = so.FindProperty("m_Script"); // internal byte[] of TextAsset
if (bytesProp is not { isArray: true })
{
Debug.LogError("Failed to find m_Script property on TextAsset");
return;
}
// adjust array size
bytesProp.arraySize = data.Length;
// write one byte at a time
for (var i = 0; i < data.Length; ++i)
{
bytesProp.GetArrayElementAtIndex(i).intValue = (sbyte)data[i];
}
so.ApplyModifiedProperties();
}
}
In some situations, you may not want to create a new file just to generate a TextAsset. For example, when writing a ScriptedImporter, you cannot modify the original imported asset file. If you want the import result to include a TextAsset, you need to construct one that does not correspond to a physical file.
Including a TextAsset in the import result has clear benefits compared to embedding raw byte[] data:
TextAsset is read‑only and provides the GetData API, which returns a NativeArray. This allows direct access to the underlying data with fewer memory allocations during loading.