Using Resources Folder in Unity
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());
Searching through all subfolders when using Resources.Load in Unity
There is no way to change the Resouces.Load()
static method functionality, it's Unity Internal. However, you can write your own custom class that does your desired functionality. The code needs to find all the directories inside the Resources
folder and search for the file. Let's call the class ResourcesExtension
public class ResourcesExtension
{
public static string ResourcesPath = Application.dataPath+"/Resources";
public static UnityEngine.Object Load(string resourceName, System.Type systemTypeInstance)
{
string[] directories = Directory.GetDirectories(ResourcesPath,"*",SearchOption.AllDirectories);
foreach (var item in directories)
{
string itemPath = item.Substring(ResourcesPath.Length+1);
UnityEngine.Object result = Resources.Load(itemPath+"\\"+resourceName,systemTypeInstance);
if(result!=null)
return result;
}
return null;
}
}
Then all you need to do is calling the static method.
ResourcesExtension.Load("image", typeof(Texture2D))
adding a path to the resources folder in Unity
Regarding your first question Resource.LoadAssetAtPath
has been deprecated and removed but as noted in the documentation you can use AssetDatabase.LoadAssetAtPath
instead: https://docs.unity3d.com/ScriptReference/AssetDatabase.LoadAssetAtPath.html
So to load a resource using the path your can do:
Texture2D t = (Texture2D)AssetDatabase.LoadAssetAtPath("Assets/Textures/texture.jpg", typeof(Texture2D));
Regarding your second question, I don't see any reliability problem in using the resources folder to store any asset you want to reference using Resources.Load.
Playing AudioClip fetched from Resources folder
- Unity does not support loading mp3 at runtime.
- Unity does not recommend using the
Resources
folder:
Don't use it.
This strong recommendation is made for several reasons:
- Use of the Resources folder makes fine-grained memory management more
difficult Improper use of Resources folders will increase application
startup time and the length of builds- As the number of Resources
folders increases, management of the Assets within those folders
becomes very difficult- The Resources system degrades a project's
ability to deliver custom content to specific platforms and
eliminates the possibility of incremental content upgrades
AssetBundle Variants are Unity's primary tool for adjusting content
on a per-device basis
Check this answer for a solution how to load audio files:
public void LoadSong()
{
StartCoroutine(LoadSongCoroutine());
}
IEnumerator LoadSongCoroutine()
{
string url = string.Format("file://{0}", path);
WWW www = new WWW(url);
yield return www;
song.clip = www.GetAudioClip(false, false);
songName = song.clip.name;
length = song.clip.length;
}
Importing each line from text file from Resources in Unity to list in C#
To begin with Don't use Reources
!
If against Unity's own recommendation you still want to do it for some reason then you have to load that resource using Resources.Load
in your case as a TextAsset
like e.g.
// assuming your path is e.g. "Assets/Resources/Text/AllWords.txt"
var file = Resources.Load<TextAsset>("Text/AllWords");
var content = file.text;
var AllWords = content.Split("\n");
listOfWords = new List<string>(AllWords);
The better approach though would probably be to listen to what Unity recommends and instead of using Resources
at all rather place your file into the Assets/StreamingAssets
folder and access it later via Application.streamingAssetsPath
either using as you did
string[] AllWords = File.ReadAllLines(Path.Combine(Application.streamingAssetsPath, "AllWords.txt");
listOfWords = new List<string>(AllWords);
Or - depending on the platform, e.g. in Android you can't directly access the StreamingAssets
StartCoroutine(LoadWords());
...
private IEnumerator GetRequest()
{
var url = Path.Combine(Application.streamingAssetsPath, "AllWords.txt");
using (var webRequest = UnityWebRequest.Get(url))
{
// Request and wait for result
yield return webRequest.SendWebRequest();
switch (webRequest.result)
{
case UnityWebRequest.Result.Success:
var content = webRequest.downloadHandler.text;
var AllWords = content.Split("\n");
listOfWords = new List<string>(AllWords);
break;
default:
Debug.LogError($"Failed loading file \"{url}\" - {webRequest.error}", this);
break;
}
}
}
You could actually also simply put your file into a "normal" folder like Assets/AllWords.txt
and then directly reference it via the Inspector in a
public TextAsset file;
or
[SerializeField] private TextAsset file;
and then access the content via
var content = file.text;
var AllWords = content.Split("\n");
listOfWords = new List<string>(AllWords);
Unity load files from outside of resources folder
You can't load TextAsset
from an external path(path not in the Unity game). In fact, you can't even load it from a path in the project itself which is not the Resources path which is then loaded with the Resources
API.
One option you have is to use the AssetBundle. Add the TextAsset
to the Assetbundle then you can load the Assetbundle from any path and extract the TextAsset
from it.
If you just want to load any file outside the Unity path, you can do this without TextAsset
. Just use any of the System.IO
API such as File.ReadAllText
an File.ReadAllBytes
. This should be able to load your file.
Related Topics
Json.Net: How to Deserialize Without Using the Default Constructor
Memory Leak Using Streamreader and Xmlserializer
Given a Datetime Object, How to Get an Iso 8601 Date in String Format
How to Read a Text File Reversely With Iterator in C#
How to Fix the Flickering in User Controls
Find and Extract a Number from a String
Capturing Console Output from a .Net Application (C#)
Best Practice to Call Configureawait For All Server-Side Code
Multiple Levels in MVC Custom Routing
How to Evaluate C# Code Dynamically
Remove Duplicates in the List Using Linq
What Do Two Question Marks Together Mean in C#
How to Convert Utf-8 Byte[] to String
Easiest Way to Read from and Write to Files
What Is the Overhead of Creating a New Httpclient Per Call in a Webapi Client