Load binary data from the resources folder [duplicate] - unity3d

I have am developing a HoloLens project that needs to reference .txt files. I have the files stored in Unity's 'Resources' folder and have them working perfectly fine (when run via Unity):
string basePath = Application.dataPath;
string metadataPath = String.Format(#"\Resources\...\metadata.txt", list);
// If metadata exists, set title and introduction strings.
if (File.Exists(basePath + metadataPath))
{
using (StreamReader sr = new StreamReader(new FileStream(basePath + metadataPath, FileMode.Open)))
{
...
}
}
However, when building the program for HoloLens deployment, I am able to run the code but it doesn't work. None of the resources show up and when examining the HoloLens Visual Studio solution (created by selecting build in Unity), I don't even see a resources or assets folder. I am wondering if I am doing something wrong or if there was a special way to deal with such resources.
Also with image and sound files...
foreach (string str in im)
{
spriteList.Add(Resources.Load<Sprite>(str));
}
The string 'str' is valid; it works absolutely fine with Unity. However, again, it's not loading anything when running through the HoloLens.

You can't read the Resources directory with the StreamReader or the File class. You must use Resources.Load.
1.The path is relative to any Resources folder inside the Assets folder of your project.
2.Do not include the file extension names such as .txt, .png, .mp3 in the path parameter.
3.Use forward slashes instead of back slashes when you have another folder inside the Resources folder. backslashes won't work.
Text files:
TextAsset txtAsset = (TextAsset)Resources.Load("textfile", typeof(TextAsset));
string tileFile = txtAsset.text;
Supported TextAsset formats:
txt .html .htm .xml .bytes .json .csv .yaml .fnt
Sound files:
AudioClip audio = Resources.Load("soundFile", typeof(AudioClip)) as AudioClip;
Image files:
Texture2D texture = Resources.Load("textureFile", typeof(Texture2D)) as Texture2D;
Sprites - Single:
Image with Texture Type set to Sprite (2D and UI) and
Image with Sprite Mode set to Single.
Sprite sprite = Resources.Load("spriteFile", typeof(Sprite)) as Sprite;
Sprites - Multiple:
Image with Texture Type set to Sprite (2D and UI) and
Image with Sprite Mode set to Multiple.
Sprite[] sprite = Resources.LoadAll<Sprite>("spriteFile") as Sprite[];
Video files (Unity >= 5.6):
VideoClip video = Resources.Load("videoFile", typeof(VideoClip)) as VideoClip;
GameObject Prefab:
GameObject prefab = Resources.Load("shipPrefab", typeof(GameObject)) as GameObject;
3D Mesh (such as FBX files)
Mesh model = Resources.Load("yourModelFileName", typeof(Mesh)) as Mesh;
3D Mesh (from GameObject Prefab)
MeshFilter modelFromGameObject = Resources.Load("yourGameObject", typeof(MeshFilter)) as MeshFilter;
Mesh loadedMesh = modelFromGameObject.sharedMesh; //Or design.mesh
3D Model (as GameObject)
GameObject loadedObj = Resources.Load("yourGameObject") as GameObject;
//MeshFilter meshFilter = loadedObj.GetComponent<MeshFilter>();
//Mesh loadedMesh = meshFilter.sharedMesh;
GameObject object1 = Instantiate(loadedObj) as GameObject;
Accessing files in a sub-folder:
For example, if you have a shoot.mp3 file which is in a sub-folder called "Sound" that is placed in the Resources folder, you use the forward slash:
AudioClip audio = Resources.Load("Sound/shoot", typeof(AudioClip)) as AudioClip;
Asynchronous Loading:
IEnumerator loadFromResourcesFolder()
{
//Request data to be loaded
ResourceRequest loadAsync = Resources.LoadAsync("shipPrefab", typeof(GameObject));
//Wait till we are done loading
while (!loadAsync.isDone)
{
Debug.Log("Load Progress: " + loadAsync.progress);
yield return null;
}
//Get the loaded data
GameObject prefab = loadAsync.asset as GameObject;
}
To use: StartCoroutine(loadFromResourcesFolder());

If you want to load text file from resource please do not specify file extension
just simply follow the below given code
private void Start()
{
TextAsset t = Resources.Load<TextAsset>("textFileName");
List<string> lines = new List<string>(t.text.Split('\n'));
foreach (string line in lines)
{
Debug.Log(line);
}
}
debug.Log can print all the data that are available in text file

You can try to store your text files in streamingsasset folder. It works fine in my project

Related

Alternative to AssetDatabase.LoadAssetAtPath for any path?

Currently I am using the following piece of code to load Textures from image files.
Texture my_pic = (Texture) AssetDatabase.LoadAssetAtPath(path, typeof(Texture));
Unfortunately this method doesn't work if the target path isn't in the Asset/ folder. I was wondering how I would load an image, given some absolute path of the form
/Users/Alan/SomeFolder/SomePic.png
(note that I am currently writing a custom Unity editor plugin by extending EditorWindow if that matters)
AssetDatabase is an Editor-only class.
Furthermore, it can only read assets in the /Assets directory (you know, the ones that are known to the asset database).
If you want to read any file on the file system, you need to use the System.IO classes.
Here is some code that will open a unity file dialog, and load the selected texture into a material of the attached object.
string path = EditorUtility.OpenFilePanel("Load an image", "", "png");
if (string.IsNullOrEmpty(path)) {
return;
}
// Load the images bytes from file (this is a synchronous call!)
byte[] bytes = null;
try {
bytes = System.IO.File.ReadAllBytes(path);
} catch (System.Exception e) {
Debug.LogError(e.Message);
return;
}
// Load the bytes into a Unity Texture2D
Texture2D _tex = new Texture2D(2,2);
_tex.LoadImage(bytes);
// Apply this texture to the object
Renderer r = (target as Component).gameObject.GetComponent<Renderer>();
if (r != null) {
r.material.SetTexture("_MainTex", _tex);
}
The last part, just for demonstration, will work only on a script derived from Editor because it uses target to find the attached renderer. It's up to you to decide what to do with the texture in your EditorWindow script.
Also, remember to explicitly call DestroyImmediate on your texture when you no longer need it, as you may end up with a memory leak in your editor code.
You can use UnityWebRequestTexture
var www = UnityWebRequestTexture.GetTexture("file:///Users/Alan/SomeFolder/SomePic.png");
www.SendWebRequest();
while(!www.isDone)
continue;
var texture = DownloadHandlerTexture.GetContent(www);

Can you export sliced sprites (PNG images) in Unity?

So I have a Sprite 2d and UI in unity. (Png image) That contains many small images like buttons. So I slice them and I can use them individualy in unity. But the thing is that I want to export each of the png Images that I got while slicing them for another use. So can I do that? And have them as separate pngs?
And what I want is these Images:
To export them in my (lets say) desktop as individual pngs.
Thank you!
I had a need for this too, I ended up solving it with a simple editor script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
public class ExportSubSprites : Editor {
[MenuItem("Assets/Export Sub-Sprites")]
public static void DoExportSubSprites() {
var folder = EditorUtility.OpenFolderPanel("Export subsprites into what folder?", "", "");
foreach (var obj in Selection.objects) {
var sprite = obj as Sprite;
if (sprite == null) continue;
var extracted = ExtractAndName(sprite);
SaveSubSprite(extracted, folder);
}
}
[MenuItem("Assets/Export Sub-Sprites", true)]
private static bool CanExportSubSprites()
{
return Selection.activeObject is Sprite;
}
// Since a sprite may exist anywhere on a tex2d, this will crop out the sprite's claimed region and return a new, cropped, tex2d.
private static Texture2D ExtractAndName(Sprite sprite) {
var output = new Texture2D((int)sprite.rect.width, (int)sprite.rect.height);
var r = sprite.textureRect;
var pixels = sprite.texture.GetPixels((int)r.x, (int)r.y, (int)r.width, (int)r.height);
output.SetPixels(pixels);
output.Apply();
output.name = sprite.texture.name + " " + sprite.name;
return output;
}
private static void SaveSubSprite(Texture2D tex, string saveToDirectory) {
if (!System.IO.Directory.Exists(saveToDirectory)) System.IO.Directory.CreateDirectory(saveToDirectory);
System.IO.File.WriteAllBytes(System.IO.Path.Combine(saveToDirectory, tex.name + ".png"), tex.EncodeToPNG());
}
}
First, drop this into a script file named EditorSubSprites.cs and make sure that it resides in an Editor folder. If you have no editor folder you can simply create at /Assets/Editor/
To use, expand a texture asset's sprites, and select as many of the sprites as you wish to export. Right-click and select "Export SubSprites".
Use Photoshop, Crop it, a Lot of Cut and Paste is going to happen save as PNG.
Import it to unity inside the folder, i like your designs. Also Watch Brackeys Tutorial on Youtube, https://www.youtube.com/user/Brackeys , he save me from my school years.
(edit : i recommend Photoshop because its the only thing i know.)

JSONReaderException when deploying on hololens [duplicate]

I have am developing a HoloLens project that needs to reference .txt files. I have the files stored in Unity's 'Resources' folder and have them working perfectly fine (when run via Unity):
string basePath = Application.dataPath;
string metadataPath = String.Format(#"\Resources\...\metadata.txt", list);
// If metadata exists, set title and introduction strings.
if (File.Exists(basePath + metadataPath))
{
using (StreamReader sr = new StreamReader(new FileStream(basePath + metadataPath, FileMode.Open)))
{
...
}
}
However, when building the program for HoloLens deployment, I am able to run the code but it doesn't work. None of the resources show up and when examining the HoloLens Visual Studio solution (created by selecting build in Unity), I don't even see a resources or assets folder. I am wondering if I am doing something wrong or if there was a special way to deal with such resources.
Also with image and sound files...
foreach (string str in im)
{
spriteList.Add(Resources.Load<Sprite>(str));
}
The string 'str' is valid; it works absolutely fine with Unity. However, again, it's not loading anything when running through the HoloLens.
You can't read the Resources directory with the StreamReader or the File class. You must use Resources.Load.
1.The path is relative to any Resources folder inside the Assets folder of your project.
2.Do not include the file extension names such as .txt, .png, .mp3 in the path parameter.
3.Use forward slashes instead of back slashes when you have another folder inside the Resources folder. backslashes won't work.
Text files:
TextAsset txtAsset = (TextAsset)Resources.Load("textfile", typeof(TextAsset));
string tileFile = txtAsset.text;
Supported TextAsset formats:
txt .html .htm .xml .bytes .json .csv .yaml .fnt
Sound files:
AudioClip audio = Resources.Load("soundFile", typeof(AudioClip)) as AudioClip;
Image files:
Texture2D texture = Resources.Load("textureFile", typeof(Texture2D)) as Texture2D;
Sprites - Single:
Image with Texture Type set to Sprite (2D and UI) and
Image with Sprite Mode set to Single.
Sprite sprite = Resources.Load("spriteFile", typeof(Sprite)) as Sprite;
Sprites - Multiple:
Image with Texture Type set to Sprite (2D and UI) and
Image with Sprite Mode set to Multiple.
Sprite[] sprite = Resources.LoadAll<Sprite>("spriteFile") as Sprite[];
Video files (Unity >= 5.6):
VideoClip video = Resources.Load("videoFile", typeof(VideoClip)) as VideoClip;
GameObject Prefab:
GameObject prefab = Resources.Load("shipPrefab", typeof(GameObject)) as GameObject;
3D Mesh (such as FBX files)
Mesh model = Resources.Load("yourModelFileName", typeof(Mesh)) as Mesh;
3D Mesh (from GameObject Prefab)
MeshFilter modelFromGameObject = Resources.Load("yourGameObject", typeof(MeshFilter)) as MeshFilter;
Mesh loadedMesh = modelFromGameObject.sharedMesh; //Or design.mesh
3D Model (as GameObject)
GameObject loadedObj = Resources.Load("yourGameObject") as GameObject;
//MeshFilter meshFilter = loadedObj.GetComponent<MeshFilter>();
//Mesh loadedMesh = meshFilter.sharedMesh;
GameObject object1 = Instantiate(loadedObj) as GameObject;
Accessing files in a sub-folder:
For example, if you have a shoot.mp3 file which is in a sub-folder called "Sound" that is placed in the Resources folder, you use the forward slash:
AudioClip audio = Resources.Load("Sound/shoot", typeof(AudioClip)) as AudioClip;
Asynchronous Loading:
IEnumerator loadFromResourcesFolder()
{
//Request data to be loaded
ResourceRequest loadAsync = Resources.LoadAsync("shipPrefab", typeof(GameObject));
//Wait till we are done loading
while (!loadAsync.isDone)
{
Debug.Log("Load Progress: " + loadAsync.progress);
yield return null;
}
//Get the loaded data
GameObject prefab = loadAsync.asset as GameObject;
}
To use: StartCoroutine(loadFromResourcesFolder());
If you want to load text file from resource please do not specify file extension
just simply follow the below given code
private void Start()
{
TextAsset t = Resources.Load<TextAsset>("textFileName");
List<string> lines = new List<string>(t.text.Split('\n'));
foreach (string line in lines)
{
Debug.Log(line);
}
}
debug.Log can print all the data that are available in text file
You can try to store your text files in streamingsasset folder. It works fine in my project

Imaged loaded via new WWW doesn't display in a build, but it does in the player

I'm loading a .jpeg file in at runtime from disk, it works absolutely fine in the player but when I build the project the texture being loaded in via WWW doesn't display - no errors. It suggests a format issue, but like I said it renders as expected in the player:
Unit doc: https://docs.unity3d.com/ScriptReference/WWW.LoadImageIntoTexture.html
private IEnumerator SetMaterialImage(string path)
{
Texture2D tex;
tex = new Texture2D(4, 4, TextureFormat.RGB24, false, true);
WWW www = new WWW(path);
if (!string.IsNullOrEmpty(www.error))
{
Debug.Log("ERROR REDNERING IMAGE --- " + www.error);
}
while (!www.isDone) yield return null;
if (www.isDone)
{
Debug.Log("WWW,ISDONE = TRUE");
Shader shader = Shader.Find("Standard");
www.LoadImageIntoTexture(tex);
GetComponent<Renderer>().material.mainTexture = tex;
GetComponent<Renderer>().material.shader = shader;
}
}
Edit: please don't suggest the Resources folder - this particular application must load from disk
I was unable to locate any Unity documentation that explains why this scenario differed between Player and Build, however I was able to confirm that:
GetComponent<Renderer>().material.mainTexture = tex;
Renderer>().material.shader = shader;
Should have been declared in the opposite order:
Renderer>().material.shader = shader;
GetComponent<Renderer>().material.mainTexture = tex;
Edit: Credit #Programmer 'The reason that code work in the Editor is because the Editor remembers which Shader or Texture is assigned to a material. So, when you change the shader, it uses the old texture'

How to create .anim file from .fbx file in Unity?

I am new in using Unity. In my game, models and animations are exported from 3DMAX as .fbx files, animations are clipped in Unity, but there's no .anim files generated, I need separated .anim files because the following code will not work even I have clipped animation "run":
var clip = animation["run"];
Can someone help me? thanks in advance.
I finally found the answer, pressing CTRL+D on animation clip in .fbx file will create a separate .anim file, what a strange operation!
I wrote a script to do this easily
using System.IO;
using UnityEditor;
using UnityEngine;
public class AnimationExtractor: MonoBehaviour
{
[MenuItem("Assets/Extract Animation")]
private static void ExtractAnimation()
{
foreach (var obj in Selection.objects)
{
var fbx = AssetDatabase.GetAssetPath(obj);
var directory = Path.GetDirectoryName(fbx);
CreateAnim(fbx, directory);
}
}
static void CreateAnim(string fbx, string target)
{
var fileName = Path.GetFileNameWithoutExtension(fbx);
var filePath = $"{target}/{fileName}.anim";
AnimationClip src = AssetDatabase.LoadAssetAtPath<AnimationClip>(fbx);
AnimationClip temp = new AnimationClip();
EditorUtility.CopySerialized(src, temp);
AssetDatabase.CreateAsset(temp, filePath);
AssetDatabase.SaveAssets();
}
}
You have to set the animations up in the importing. Select the .fbx model in Unity and go to Animations tab. There you have to define the clips. The .anim files will be generated under the model.
If you do not see the clips inside the animations tab, change the "Animation Type" under Rig to Legacy.