- Home /
Creating an texture asset in editor script
Hi Guys,
I wanted to experiment with creating a png from the AssetPreview image and saving it to a folder in my project then creating a component and point it to that texture as an editor extension. Sounds simple but for some reason, even if I edit the permissions of the target folder I get
UnauthorizedAccessException: Access to the path 'Assets/Space Station/Textures/Previews' is denied.
System.IO.FileStream..ctor (System.String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, Boolean anonymous, FileOptions options) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.IO/FileStream.cs:259)
System.IO.FileStream..ctor (System.String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize)
(wrapper remoting-invoke-with-check) System.IO.FileStream:.ctor (string,System.IO.FileMode,System.IO.FileAccess,System.IO.FileShare,int)
System.IO.File.Create (System.String path, Int32 bufferSize) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.IO/File.cs:135)
System.IO.File.Create (System.String path) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.IO/File.cs:130)
System.IO.File.WriteAllBytes (System.String path, System.Byte[] bytes) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.IO/File.cs:594)
DeepspaceUtilities.CreatePreview () (at Assets/Space Station/Scripts/Editor/DeepspaceUtilities.cs:29)
Here is the code, it can be useful but this I/O error has got me stumped!
public class DeepspaceUtilities : ScriptableObject
{
private const string previewPath = "Assets/Space Station/Textures/Previews";
[MenuItem("Deepspace/Create Preview...")]
static void CreatePreview()
{
var transforms = Selection.GetTransforms (SelectionMode.TopLevel);
if (transforms.Length > 0)
{
for(int i = 0; i < transforms.Length; i++)
{
var t = transforms[i];
if (t.GetComponent<PreviewProvider>() == null
&& EditorUtility.DisplayDialog("Create Preview?",
string.Format("Do you want to create and add a preview component to {0}", t),
"Create", "Cancel"))
{
var prev = AssetPreview.GetAssetPreview(t.gameObject);
if (prev != null)
{
string path = previewPath +string.Format("/{0}.png", t.gameObject.name);
File.WriteAllBytes(previewPath, prev.EncodeToPNG ());
Hawk.Log("Created asset at {0}", path);
var provider = t.gameObject.AddComponent<PreviewProvider>();
provider.preview = (Texture2D)AssetDatabase.LoadAssetAtPath(path, typeof(Texture2D));
}
}
}
}
}
}
You are using system.io directly which is not unity specific. Also you are using a relative path. But relative to what? It seems the path does not exist. Try testing with a known path like your desktop. If you want the assets folder I think you can get the assets path with Application.dataPath.
Dave I think you right, it's actually pretty obvious.
Answer by Gizmoi · Sep 09, 2014 at 07:58 AM
Might be easier to use UnityEditor.AssetDatabase.CreateAsset rather than WriteAllBytes
Answer by morbidcamel · Sep 10, 2014 at 02:34 AM
OK Dave you're right - here's the solution... I'm posting it here in case someone wants to make a preview of their assets quickly to use in the game gui for example...
private const string previewPath = "Space Station/Textures/Previews";
[MenuItem("Deepspace/Create Preview...")]
static void CreatePreview()
{
var transforms = Selection.GetTransforms (SelectionMode.TopLevel);
if (transforms.Length > 0)
{
for(int i = 0; i < transforms.Length; i++)
{
var t = transforms[i];
if (t.GetComponent<PreviewProvider>() == null
&& EditorUtility.DisplayDialog("Create Preview?",
string.Format("Do you want to create and add a preview component to {0}", t),
"Create", "Cancel"))
{
var prev = AssetPreview.GetAssetPreview(t.gameObject);
if (prev != null)
{
string path = Path.Combine(Application.dataPath, string.Format("{0}/{1}.png", previewPath, t.gameObject.name));
Hawk.Log("Creating asset at {0}", path);
File.WriteAllBytes(path, prev.EncodeToPNG ());
var provider = t.gameObject.AddComponent<PreviewProvider>();
provider.preview = (Texture2D)AssetDatabase.LoadAssetAtPath("Assets/"+path, typeof(Texture2D));
}
}
}
}
}