Looking for a way to access the build date (of my own code) as a string in code, if possible. Barring that, some other unique and changing string would be nice.
How would you define the build date of your code, given that each script is re-compiled each time itās edited? The build date for the player itself would be a more reasonable thing to look for, but what value would that have when running in the editor?
What do you need the value for? What are you trying to achieve? There may be a way that makes more sense than using an ill-defined build date.
A build date is an excellent way to tell you when the thing was released to your testers, and is hardly a stretch of a concept. When a bug is identified, a date or code stamp can be helpful.
It looks like Iāll have to adjust a number myself, no biggie, but I like to avoid human error/forgetfulness where possible.
The only way I can think of to automate this is to create your own editor script that builds the player using the BuildPipeline.BuildPlayer function. The script could set a public variable in an object somewhere with the current time just before starting the build process.
What we did in the last company I worked was get the build number from subversion to a file, and read that file at the beginning of the program.
I think you could make something like this using PostBuild scripts to create a file and read it from your scripts (I have not test it, but it appears possible)
You can use a compile-time language to create a string. At least I know that Boo has this.
import UnityEngine
macro build_buildtime_info():
dateString = System.DateTime.Now.ToString()
yield [|
class BuildtimeInfo:
static def DateTimeString() as string:
return "${$(dateString)}"
|]
build_buildtime_info
# # Now you can do this:
# Debug.Log( BuildtimeInfo.DateTimeString() )
You are a life-saver, even 4 years later :). I would never have thought about Boo and what it can do. This still works in the current Unity Engine.
Just put a āBuildtimeInfo.booā file with the above content into āAssets/Pluginsā. You need to do this manually in the OS file explorer, since Unity wont show BOO files anymore.
Then you can use this build time-stamp in C# via:
BuildtimeInfo.DateTimeString()
Pretty sleak.
This works because everything in āAssets/Pluginsā is compiled BEFORE all other stuff so you can access this dynamic class later in the build process.
I like it. Although it is yet another shortcoming of Unity that we have to resort to such hacks to do obvious things.
I use it to create a watermark over debug builds to be sure that the device/WebGL really is using the version I want to test.
I just tried adding this boo script, and it works with no errors in Unity, but VisualStudio complains that āThe name āBuildtimeInfoā does not exist in the current context.ā
I have not worked with Boo files before ā is there any way to get rid of this āerrorā?
a bit late, but try somthing like this:
public class BuildInfo
{
public System.DateTime BuildTime()
{
#if UNITY_EDITOR
BuildTime = System.DateTime.Now;
#else
BuildTime = System.DateTime.Parse(BuildtimeInfo.DateTimeString());
#endif
}
}
Then call:
UnityEngine.Debug.Log("BuildTime: " + BuildInfo.BuildTime());
@dmkmwagner what is BuildtimeInfo? The code you provided doesnāt look valid.
@Krstn BuildtimeInfo was created by the Boo script from steinbitglis from above at build time.
But after Upgrade Unity to the latest 2018.3 the BuildtimeInfo is not created anymore.
Any ideas? Unity seems to stop using the boo script.
One of the changes for 2018.3 was the final removal of the compiler used for UnityScript and Boo.
Thank your for the fast reply.
I have removed the boo script and implement the BuildInfo by another way with C#.
For those who are interested, here are my current solution:
During the pre build procress of unity i create a file with the build time in the StreamingAssets folder.
So the build time can be read from the file later.
There can be stored some other information there too.
example implementation code:
namespace MyAwesomeProject.Build
{
using System;
using System.IO;
using UnityEngine;
public class Info
{
private static Info _instance;
public static Info Instance
{
get
{
if (_instance == null) {
_instance = new Info();
}
return _instance;
}
}
public DateTime BuildTime { get; private set; }
protected Info()
{
byte[] ByteInfo = this.ReadStreamingAsset("BuildInfo");
// file does not exists. set defaults!
if (ByteInfo.Length == 0)
{
BuildTime = DateTime.UtcNow;
return;
}
// else, read the infos from file
using (BinaryReader Reader = new BinaryReader(new MemoryStream(ByteInfo, false))) {
BuildTime = DateTime.FromBinary(Reader.ReadInt64());
}
}
public byte[] ReadStreamingAsset(string path)
{
string filePath = Path.Combine(Application.streamingAssetsPath, path);
// add file prefix
if (Application.platform != RuntimePlatform.Android)
{
filePath = "file://" + filePath;
}
WWW fileContent = new WWW(filePath);
// wait for file was loaded!
while (!fileContent.isDone && string.IsNullOrEmpty(fileContent.error)) { }
return fileContent.bytes;
}
}
#if UNITY_EDITOR
public class AndroidBuildPrepartion : UnityEditor.Build.IPreprocessBuildWithReport
{
public int callbackOrder { get { return 0; } }
public void OnPreprocessBuild(UnityEditor.Build.Reporting.BuildReport report)
{
using (BinaryWriter Writer = new BinaryWriter(File.Open("Assets/StreamingAssets/BuildInfo", FileMode.Create)))
{
Writer.Write(DateTime.UtcNow.ToBinary());
}
}
}
#endif
}
Now you cat read the build time like this:
MyAwesomeProject.Build.Info.Instance.BuildTime
Cool thing and thanks for sharing. Although if you donāt need the file itself only for reading by the game maybe it would be better if you just generate a BuildInfo static class and use that.
Something like this:
Assets/BuildInfo.cs
public static class BuildInfo{public static string BUILD_TIME = "Foobar";}
Assets/Editor/BuildInfoProcessor.cs
using System;
using System.IO;
using System.Text;
using UnityEditor.Build;
using UnityEditor.Build.Reporting;
public class BuildInfoProcessor : IPreprocessBuildWithReport
{
public int callbackOrder { get { return 0; } }
public void OnPreprocessBuild(BuildReport report)
{
StringBuilder sb = new StringBuilder();
sb.Append("public static class BuildInfo");
sb.Append("{");
sb.Append("public static string BUILD_TIME = \"");
sb.Append(DateTime.UtcNow.ToString());
sb.Append("\";");
sb.Append("}");
using(System.IO.StreamWriter file =
new System.IO.StreamWriter(@"Assets/BuildInfo.cs"))
{
file.WriteLine(sb.ToString());
}
}
}
So basically you can refer to this whole thing like BuildInfo.BUILD_TIME; in your code.
The drawback is that every build will overwrite this BuildInfocs file, so the editor runs will be affected by the builds too.
That is a interesting approach @ . Iāll take a look at this later, thank you!
Edit: After a short commemorative break, i think the file is the better solution for me, instead of a dynamical code creation on build time.
Thanks for the solution @dmkmwagner , Awesome work.
I just did not really like the idea of using www to access the file so I made a small modification.
Change it, use it, hate it, burn it, whatever, but maybe another lazy dev comes across it and prefers it as well.
public class Info
{
private static Info _instance;
public static Info Instance
{
get
{
if (_instance == null)
{
_instance = new Info();
}
return _instance;
}
}
public DateTime BuildTime { get; private set; }
public String BuildDate { get; private set; }
protected Info()
{
var txt = (UnityEngine.Resources.Load("BuildDate") as TextAsset);
BuildDate = Loader.sAppVersion = txt.text.Trim();
}
}
#if UNITY_EDITOR
public class AndroidBuildPrepartion : UnityEditor.Build.IPreprocessBuildWithReport
{
public int callbackOrder { get { return 0; } }
public void OnPreprocessBuild(UnityEditor.Build.Reporting.BuildReport report)
{
using (BinaryWriter Writer = new BinaryWriter(File.Open("Assets/Resources/BuildDate.txt", FileMode.OpenOrCreate| FileMode.Truncate)))
{
Writer.Write(DateTime.Now.ToString("dd/MM/yyyy"));
}
}
}
#endif
Hi @ ,
thanks for your reply.
My code is a reduced version. I write some information more in the buildinfo than the time. Thats why there is a binary reader.
I like the idea how you load the information. Iāll check this later and give your idea a try.
Best regards
In my case, I need to put asset refresh code to update changed build date.
What I thought is
- OnPreprocessBuild() called
- Create BuildTime file
- Build <In this phase, builder still point last BuildTime file>
- Update BuildTime file
So I put some update codes and solve problem in my case.
#if UNITY_EDITOR
public class AndroidBuildPrepartion : UnityEditor.Build.IPreprocessBuildWithReport
{
public int callbackOrder { get { return 0; } }
public void OnPreprocessBuild(UnityEditor.Build.Reporting.BuildReport report)
{
using (BinaryWriter Writer = new BinaryWriter(File.Open("Assets/Resources/BuildDate.txt", FileMode.OpenOrCreate| FileMode.Truncate)))
{
Writer.Write(DateTime.Now.ToString("dd/MM/yyyy"));
}
AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate);
}
}
#endif
Since FileMode.OpenOrCreate| FileMode.Truncate did not work for me and was producing error in Unity 2018.4, I replaced it with single line code:
public void OnPreprocessBuild(UnityEditor.Build.Reporting.BuildReport report) {
File.WriteAllText("Assets/Resources/app_build_time.txt", DateTime.Now.ToString("dd/MM/yyyy hh:mm:ss"));
AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate);
}
Isnāt there a simple way of doing this ?
Seems so simple that itās impossible in U3D !
Text myUItext;
myUItext.text = "version: "+#BUILD_DATE;
there seem to be legions of ways with onprebuild, onpostbuild, onwaiticookthepizza, onamnotsureofwhattodo, etcā¦
most (all) are obsolete and thereās no way to find how do versionning ( indeed itās not versionning, i only need the build date ) for built appsā¦
PLEASE light my candle !
I cannot believe this cannot be done simply in unity ![]()
regards !
EDIT:
People use tu compile gazillion of versions a day⦠itās well known ^^
For my own part⦠1 version a day is okay ! therefore the DAY/MONTH/YEAR version string
is okay for meā¦
Then this thought comes to me: WHY IS THIS SO IMPOSSIBLE ???
Is it too simple ?