Hello,
I have many files with extensions that I renamed to .inf that still kind of ‘tie up’ my development time (I guess because of the amount of files), so, I added a ‘~’ to the end of my folder, but now, when I use Resource.Load(), those files aren’t recognized. I would like for Unity to not compile these files WHILE, at the same time, allow Resource.Load() to use them, and then when I publish my project, those files get published into my project. How would I do this?
What do you mean with “compile”? I guess you’re not talking about source code, but assets?
I assume you just want to by-pass Unity’s import pipeline for these type assets?! If that’s the case, you might want to take a look at StreamingAssets. Resources.Load won’t work with StreamingAssets, but if you by-pass the import pipeline, Unity can’t load any of those assets anyway. Files in StreamingAssets can be loaded using the System.IO API for example.
Yes. If my .inf files contain custom data that is not of any programming language, there would be no point IN them compiling or taking up unnecessary development time IF it is not code that should effect my program. What command would I use to load streaming assets, and when the project publishes can those files be accessed the same way?
You don’t need to put a ‘~’ at the end of the filenames if your file extension was .inf. If Unity doesn’t recognise the file extension then it won’t do anything with the file. So just put the files in your Resources directory and use Resources.Load.
edit: actually my bad, Unity does still seem to attempt to reimport the file. But it seems a lot faster when it doesn’t know what the file is.
How do I do that? What is a post-build process? Wouldn’t that cause me to have to wait a very long time every time I run my program, instead of during development?
You use the PostProcessBuild attribute to write a method that is called after the build has finished. There’s more info here. For example:
using UnityEngine;
using UnityEditor;
using UnityEditor.Callbacks;
public class MyBuildPostprocessor
{
[PostProcessBuild]
public static void OnPostprocessBuild(BuildTarget target, string pathToBuiltProject)
{
Debug.Log( pathToBuiltProject );
}
}
If there is a way to copy large amounts of files into my build, and I am dealing with over 31,000 files in a folder with the ‘~’ in front of it, wouldn’t I have to wait about 5 or 10 minutes every time I would like my program to run?
I guess that depends on a few things - the speed of your hard disk and the size of the files in particular. But Unity would be doing that anyway if you weren’t doing it yourself.
You can speed up the process a bit by doing some simple checks to determine if the files should be copied. For example, for a given file, if the file already exists in the destination directory and its timestamp is the same or newer than the file in the project directory, you don’t have to copy the file.
It would be nice if there was a way to not ignore certain folders while not having any changes of data in any files in these folders cause Unity to have to update any meta data, and just use those files for opening and reading purposes. Then, when the project gets published is when the data in those files get ‘considered’ (IF it is important to pass that data along to the published version). It would save development time. Perhaps (upon the developer’s request), he/she could have Unity set up so that files in those folders would have Unity make up the meta data file only on the files that are wanted to be opened upon demand (if Resource.Load() and other file opening commands look to the meta data files for its data collection), which MAY slow down the program at runtime, but not during development time, and then deletes itself when the program stops running. Isn’t that a good idea for the next version of Unity or for a patch?
Unity can’t be everything to everyone. It doesn’t sound like it would be a high priority issue unfortunately, and it can be solved easily by writing a build post-processor.
I have never wrote a ‘build post-processor program’ before, and am unfamiliar about how to construct the coding in order to do such an operation. Is that a program that ‘tells’ Unity how to handle the meta data before it writes the meta files, or what files to pay attention to? If the files in the ‘~’ folder are ‘ignored’, CAN a post-processor program still work with those files?.. and how would I write the code to ‘un-ignore’ them, and then ‘re-ignore’ them when I stop my program from running?.. and wouldn’t that cost a lot of processor time?
No a build post-processor is a method that runs after your build has finished being created. So if you kick off a standalone Windows player build of your game from the build settings menu (or even from the command-line), when that finishes, your post-processor method is run. Then you can do whatever else you need to do to (e.g. copy files around). It’s pretty easy. I wrote an example for you here (I haven’t tested it though!).
edit: and in case the gist disappears here’s the code itself:
using UnityEngine;
using UnityEditor;
using UnityEditor.Callbacks;
using System;
using System.IO;
public static class CopyFilesBuildPostProcessor
{
private const string PathToCopy = "PathToFiles";
[PostProcessBuild]
public static void OnPostProcessBuild(BuildTarget target, string pathToBuiltProject)
{
// Copy all files from the Unity Assets/{PathToCopy} directory to a directory
// called {PathToCopy} under the build's output directory.
var sourceFullPath = Path.Combine(Application.dataPath, PathToCopy);
var destinationFullPath = Path.Combine(pathToBuiltProject, PathToCopy);
CopyFiles(sourceFullPath, destinationFullPath);
}
private static void CopyFiles(string source, string destination)
{
var files = Directory.GetFiles(source);
foreach (var sourceFile in files)
{
// Get just the filename for the file, so we can determine whether the file
// exists in the destination.
var filename = Path.GetFileName(sourceFile);
var destinationFile = Path.Combine(destination, filename);
var exists = File.Exists(destinationFile);
var doCopy = !exists; // If the file doesn't exist, we definitely need to copy it!
if (exists)
{
// If the file exists at the destination and the source has been modified more
// recently than the destination file, we will copy the source file again.
var sourceTimestamp = File.GetLastWriteTime(sourceFile);
var destinationTimestamp = File.GetLastWriteTime(destinationFile);
doCopy = sourceTimestamp > destinationTimestamp;
}
if (doCopy)
{
try
{
File.Copy(sourceFile, destinationFile);
}
catch (Exception e)
{
Debug.Log("Failed to copy file: " + e.Message);
}
}
}
}
}
I had an interesting solution. The function that is set up to read the files uses Resource.Load(), but I used File.ReadAllText() and noticed that the ‘~’ is a bad symbol, BUT Unity also ignores files that have .tmp as extensions, SO, I got rid of the ‘~’ in my folder and renamed all my .inf extensions to .tmp and changed all the references to open .tmp. Then, I used an ‘if’ statement for a variable named ‘isDeveloping’ (to determine weather or not to use Resources.Load(), or File.ReadAllText()), and before I publish everything, I can change the extensions from .tmp to .txt (since TextAssets through Resources.Load() need to have .txt extensions, and the argument that gets passed to Resources.Load() must not have the extension in them).