mirror of
https://github.com/Ratstail91/Mementos.git
synced 2025-11-29 02:24:28 +11:00
Committed everything
This commit is contained in:
9
Unity/Alternate Genre Jam/Assets/Ink/Editor/Core.meta
Normal file
9
Unity/Alternate Genre Jam/Assets/Ink/Editor/Core.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: df28596461d414a1b9f56cb406a23a3f
|
||||
folderAsset: yes
|
||||
timeCreated: 1459882215
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ddef5103d5ce1401da019f7df6c472af
|
||||
folderAsset: yes
|
||||
timeCreated: 1459882122
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e277a78690c74451084fbfbedc0507e8
|
||||
folderAsset: yes
|
||||
timeCreated: 1459941651
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,178 @@
|
||||
// Automatically creates JSON files from an ink placed within the Assets/Ink folder.
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System.IO;
|
||||
using Debug = UnityEngine.Debug;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Ink.UnityIntegration {
|
||||
class InkPostProcessor : AssetPostprocessor {
|
||||
// Several assets moved at the same time can cause unity to call OnPostprocessAllAssets several times as a result of moving additional files, or simply due to minor time differences.
|
||||
// This queue tells the compiler which files to recompile after moves have completed.
|
||||
// Not a perfect solution - If Unity doesn't move all the files in the same attempt you can expect some error messages to appear on compile.
|
||||
private static List<string> queuedMovedAssets = new List<string>();
|
||||
public static bool disabled = false;
|
||||
// Recompiles any ink files as a result of an ink file (re)import
|
||||
private static void OnPostprocessAllAssets (string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths) {
|
||||
if(disabled) return;
|
||||
if(deletedAssets.Length > 0) {
|
||||
OnDeleteAssets(deletedAssets);
|
||||
}
|
||||
if(movedAssets.Length > 0) {
|
||||
OnMoveAssets(movedAssets.Except(importedAssets).ToArray());
|
||||
}
|
||||
if(importedAssets.Length > 0) {
|
||||
OnImportAssets(importedAssets);
|
||||
}
|
||||
#if !UNITY_2020_1_OR_NEWER
|
||||
if(InkLibrary.created)
|
||||
#endif
|
||||
InkLibrary.Clean();
|
||||
}
|
||||
|
||||
private static void OnDeleteAssets (string[] deletedAssets) {
|
||||
bool deletedInk = false;
|
||||
foreach (var deletedAssetPath in deletedAssets) {
|
||||
if(InkEditorUtils.IsInkFile(deletedAssetPath)) {
|
||||
deletedInk = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!deletedInk)
|
||||
return;
|
||||
|
||||
// bool alsoDeleteJSON = false;
|
||||
// alsoDeleteJSON = EditorUtility.DisplayDialog("Deleting .ink file", "Also delete the JSON file associated with the deleted .ink file?", "Yes", "No"));
|
||||
List<InkFile> masterFilesAffected = new List<InkFile>();
|
||||
for (int i = InkLibrary.instance.inkLibrary.Count - 1; i >= 0; i--) {
|
||||
if(InkLibrary.instance.inkLibrary [i].inkAsset == null) {
|
||||
if(!InkLibrary.instance.inkLibrary[i].isMaster) {
|
||||
foreach(var masterInkFile in InkLibrary.instance.inkLibrary[i].masterInkFiles) {
|
||||
if(!masterFilesAffected.Contains(masterInkFile))
|
||||
masterFilesAffected.Add(masterInkFile);
|
||||
}
|
||||
}
|
||||
if(InkSettings.instance.handleJSONFilesAutomatically) {
|
||||
var assetPath = AssetDatabase.GetAssetPath(InkLibrary.instance.inkLibrary[i].jsonAsset);
|
||||
if(assetPath != null && assetPath != string.Empty) {
|
||||
AssetDatabase.DeleteAsset(assetPath);
|
||||
}
|
||||
}
|
||||
InkLibrary.RemoveAt(i);
|
||||
}
|
||||
}
|
||||
// After deleting files, we might have broken some include references, so we rebuild them. There's probably a faster way to do this, or we could probably just remove any null references, but this is a bit more robust.
|
||||
foreach(InkFile inkFile in InkLibrary.instance.inkLibrary) {
|
||||
inkFile.FindIncludedFiles();
|
||||
}
|
||||
foreach(InkFile masterFile in masterFilesAffected) {
|
||||
if(InkSettings.instance.compileAutomatically || masterFile.compileAutomatically) {
|
||||
InkCompiler.CompileInk(masterFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnMoveAssets (string[] movedAssets) {
|
||||
if (!InkSettings.instance.handleJSONFilesAutomatically)
|
||||
return;
|
||||
|
||||
List<string> validMovedAssets = new List<string>();
|
||||
for (var i = 0; i < movedAssets.Length; i++) {
|
||||
if(!InkEditorUtils.IsInkFile(movedAssets[i]))
|
||||
continue;
|
||||
validMovedAssets.Add(movedAssets[i]);
|
||||
queuedMovedAssets.Add(movedAssets[i]);
|
||||
|
||||
}
|
||||
// Move compiled JSON files.
|
||||
// This can cause Unity to postprocess assets again.
|
||||
bool assetMoved = false;
|
||||
foreach(var inkFilePath in validMovedAssets) {
|
||||
InkFile inkFile = InkLibrary.GetInkFileWithPath(inkFilePath);
|
||||
if(inkFile == null) continue;
|
||||
if(inkFile.jsonAsset == null) continue;
|
||||
|
||||
string jsonAssetPath = AssetDatabase.GetAssetPath(inkFile.jsonAsset);
|
||||
|
||||
string movedAssetDir = Path.GetDirectoryName(inkFilePath);
|
||||
string movedAssetFile = Path.GetFileName(inkFilePath);
|
||||
string newPath = InkEditorUtils.CombinePaths(movedAssetDir, Path.GetFileNameWithoutExtension(movedAssetFile)) + ".json";
|
||||
AssetDatabase.MoveAsset(jsonAssetPath, newPath);
|
||||
assetMoved = true;
|
||||
}
|
||||
|
||||
// Check if no JSON assets were moved (as a result of none needing to move, or this function being called as a result of JSON files being moved)
|
||||
if(!assetMoved && queuedMovedAssets.Count > 0) {
|
||||
List<InkFile> filesToCompile = new List<InkFile>();
|
||||
|
||||
// Add the old master file to the files to be recompiled
|
||||
foreach(var inkFilePath in queuedMovedAssets) {
|
||||
InkFile inkFile = InkLibrary.GetInkFileWithPath(inkFilePath);
|
||||
if(inkFile == null) continue;
|
||||
foreach(var masterInkFile in inkFile.masterInkFilesIncludingSelf) {
|
||||
if(!filesToCompile.Contains(inkFile))
|
||||
filesToCompile.Add(inkFile);
|
||||
}
|
||||
}
|
||||
|
||||
InkLibrary.RebuildInkFileConnections();
|
||||
|
||||
// Add the new file to be recompiled
|
||||
foreach(var inkFilePath in queuedMovedAssets) {
|
||||
InkFile inkFile = InkLibrary.GetInkFileWithPath(inkFilePath);
|
||||
if(inkFile == null) continue;
|
||||
|
||||
foreach(var masterInkFile in inkFile.masterInkFilesIncludingSelf) {
|
||||
if(!filesToCompile.Contains(inkFile))
|
||||
filesToCompile.Add(inkFile);
|
||||
}
|
||||
}
|
||||
|
||||
queuedMovedAssets.Clear();
|
||||
|
||||
// Compile any ink files that are deemed master files a rebuild
|
||||
foreach(var inkFile in filesToCompile) {
|
||||
if(inkFile.isMaster) {
|
||||
if(InkSettings.instance.compileAutomatically || inkFile.compileAutomatically) {
|
||||
InkCompiler.CompileInk(inkFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnImportAssets (string[] importedAssets) {
|
||||
List<string> importedInkAssets = new List<string>();
|
||||
string inklecateFileLocation = null;
|
||||
foreach (var importedAssetPath in importedAssets) {
|
||||
if(InkEditorUtils.IsInkFile(importedAssetPath))
|
||||
importedInkAssets.Add(importedAssetPath);
|
||||
else if (Path.GetFileName(importedAssetPath) == "inklecate" && Path.GetExtension(importedAssetPath) == "")
|
||||
inklecateFileLocation = importedAssetPath;
|
||||
}
|
||||
if(importedInkAssets.Count > 0)
|
||||
PostprocessInkFiles(importedInkAssets);
|
||||
if(inklecateFileLocation != null)
|
||||
PostprocessInklecate(inklecateFileLocation);
|
||||
}
|
||||
|
||||
private static void PostprocessInklecate (string inklecateFileLocation) {
|
||||
// This should probably only recompile files marked to compile automatically, but it's such a rare case, and one where you probably do want to compile.
|
||||
// To fix, one day!
|
||||
Debug.Log("Inklecate updated. Recompiling all Ink files...");
|
||||
InkEditorUtils.RecompileAll();
|
||||
}
|
||||
|
||||
private static void PostprocessInkFiles (List<string> importedInkAssets) {
|
||||
if(EditorApplication.isPlaying && InkSettings.instance.delayInPlayMode) {
|
||||
foreach(var fileToImport in importedInkAssets) {
|
||||
InkCompiler.AddToPendingCompilationStack(fileToImport);
|
||||
}
|
||||
} else {
|
||||
InkLibrary.CreateOrReadUpdatedInkFiles (importedInkAssets);
|
||||
InkCompiler.CompileInk(InkCompiler.GetUniqueMasterInkFilesToCompile (importedInkAssets).ToArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 45a9c84618e20498993d11d2bb89946e
|
||||
timeCreated: 1459667420
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,684 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using UnityEditorInternal;
|
||||
using System.Diagnostics;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
using Debug = UnityEngine.Debug;
|
||||
|
||||
namespace Ink.UnityIntegration {
|
||||
#if UNITY_2020_1_OR_NEWER
|
||||
[FilePath("Library/InkCompiler.asset", FilePathAttribute.Location.ProjectFolder)]
|
||||
public class InkCompiler : ScriptableSingleton<InkCompiler> {
|
||||
#else
|
||||
public class InkCompiler : ScriptableObject {
|
||||
#endif
|
||||
|
||||
#if !UNITY_2020_1_OR_NEWER
|
||||
public static bool created {
|
||||
get {
|
||||
return (_instance != (UnityEngine.Object) null);
|
||||
}
|
||||
}
|
||||
private static InkCompiler _instance;
|
||||
public static InkCompiler instance {
|
||||
get {
|
||||
if(!created)
|
||||
LoadOrCreateInstance();
|
||||
return _instance;
|
||||
} private set {
|
||||
if(_instance == value) return;
|
||||
_instance = value;
|
||||
}
|
||||
}
|
||||
|
||||
static string absoluteSavePath {
|
||||
get {
|
||||
return System.IO.Path.GetFullPath(System.IO.Path.Combine(System.IO.Directory.GetCurrentDirectory(),"Library","InkCompiler.asset"));
|
||||
}
|
||||
}
|
||||
public static void LoadOrCreateInstance () {
|
||||
InternalEditorUtility.LoadSerializedFileAndForget(absoluteSavePath);
|
||||
if(created) {
|
||||
if(InkEditorUtils.isFirstCompile) {
|
||||
ClearCompilationStacks();
|
||||
}
|
||||
} else {
|
||||
instance = ScriptableObject.CreateInstance<InkCompiler>();
|
||||
instance.hideFlags = HideFlags.HideAndDontSave;
|
||||
}
|
||||
}
|
||||
public void Save (bool saveAsText) {
|
||||
InternalEditorUtility.SaveToSerializedFileAndForget((UnityEngine.Object[]) new InkCompiler[1] {this}, absoluteSavePath, saveAsText);
|
||||
}
|
||||
|
||||
protected InkCompiler () {
|
||||
if (created)
|
||||
Debug.LogError((object) "ScriptableSingleton already exists. Did you query the singleton in a constructor?");
|
||||
else {
|
||||
instance = this;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
public class AssetSaver : UnityEditor.AssetModificationProcessor {
|
||||
static string[] OnWillSaveAssets(string[] paths) {
|
||||
InkCompiler.instance.Save(true);
|
||||
return paths;
|
||||
}
|
||||
}
|
||||
public static void SaveStatic (bool saveAsText) {
|
||||
#if !UNITY_2020_1_OR_NEWER
|
||||
if(!created) return;
|
||||
#endif
|
||||
instance.Save(saveAsText);
|
||||
}
|
||||
|
||||
public static bool compiling {
|
||||
get {
|
||||
return instance.compilationStack.Count > 0;
|
||||
}
|
||||
}
|
||||
public static bool buildBlocked = false;
|
||||
static bool playModeBlocked = false;
|
||||
|
||||
public delegate void OnCompileInkEvent (InkFile inkFile);
|
||||
public static event OnCompileInkEvent OnCompileInk;
|
||||
|
||||
// Track if we've currently locked compilation of Unity C# Scripts
|
||||
public static bool hasLockedUnityCompilation = false;
|
||||
|
||||
private static List<Action> onCompleteActions = new List<Action>();
|
||||
|
||||
|
||||
// If InkSettings' delayInPlayMode option is true, dirty files are added here when they're changed in play mode
|
||||
// This ensures they're remembered when you exit play mode and can be compiled
|
||||
public List<string> pendingCompilationStack = new List<string>();
|
||||
// The state of files currently being compiled.
|
||||
public List<InkCompiler.CompilationStackItem> compilationStack = new List<InkCompiler.CompilationStackItem>();
|
||||
|
||||
|
||||
[Serializable]
|
||||
public class CompilationStackItem {
|
||||
public enum State {
|
||||
// Default state, item is about to be queued for compilation
|
||||
Queued,
|
||||
|
||||
// Item is now owned by the thread pool and being compiled
|
||||
Compiling,
|
||||
|
||||
// Compilation has finished, item to be processed for errors and result handled
|
||||
Complete,
|
||||
}
|
||||
|
||||
public State state = State.Queued;
|
||||
public bool immediate;
|
||||
public InkFile inkFile;
|
||||
public string compiledJson;
|
||||
public string inkAbsoluteFilePath;
|
||||
public string jsonAbsoluteFilePath;
|
||||
public List<InkCompilerLog> logOutput = new List<InkCompilerLog>();
|
||||
public List<string> unhandledErrorOutput = new List<string>();
|
||||
public DateTime startTime;
|
||||
public DateTime endTime;
|
||||
|
||||
public float timeTaken {
|
||||
get {
|
||||
if(state == State.Complete) return (float)(endTime - startTime).TotalSeconds;
|
||||
else return (float)(DateTime.Now - startTime).TotalSeconds;
|
||||
}
|
||||
}
|
||||
|
||||
public CompilationStackItem () {}
|
||||
}
|
||||
|
||||
// This always runs after the InkEditorUtils constructor
|
||||
[InitializeOnLoadMethod]
|
||||
static void OnProjectLoadedInEditor() {
|
||||
#if UNITY_2017_1_OR_NEWER
|
||||
EditorApplication.playModeStateChanged += OnPlayModeChange;
|
||||
#else
|
||||
EditorApplication.playmodeStateChanged += LegacyOnPlayModeChange;
|
||||
#endif
|
||||
EditorApplication.update += Update;
|
||||
// I really don't know if this can fire, since it assumes that it compiled so can't have been locked. But safety first!
|
||||
EditorApplication.UnlockReloadAssemblies();
|
||||
#if UNITY_2019_4_OR_NEWER
|
||||
// This one, on the other hand, seems to actually occur sometimes - presumably because c# compiles at the same time as the ink.
|
||||
if(InkEditorUtils.disallowedAutoRefresh) {
|
||||
InkEditorUtils.disallowedAutoRefresh = false;
|
||||
try {
|
||||
AssetDatabase.AllowAutoRefresh();
|
||||
} catch (Exception e) {
|
||||
Debug.LogWarning("Failed AllowAutoRefresh "+e);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
private static void Update () {
|
||||
#if UNITY_2020_1_OR_NEWER
|
||||
// If we're not compiling but have locked C# compilation then now is the time to reset
|
||||
if (!compiling && hasLockedUnityCompilation) {
|
||||
hasLockedUnityCompilation = false;
|
||||
EditorApplication.UnlockReloadAssemblies();
|
||||
}
|
||||
#else
|
||||
// If we're not compiling but have locked C# compilation then now is the time to reset
|
||||
if ((!InkLibrary.created || !compiling) && hasLockedUnityCompilation) {
|
||||
hasLockedUnityCompilation = false;
|
||||
EditorApplication.UnlockReloadAssemblies();
|
||||
}
|
||||
if(!InkLibrary.created)
|
||||
return;
|
||||
#endif
|
||||
|
||||
if(compiling) {
|
||||
// Check for timeouts, in case of an unhandled bug with this system/the ink compiler!
|
||||
for (int i = instance.compilationStack.Count - 1; i >= 0; i--) {
|
||||
var compilingFile = instance.compilationStack [i];
|
||||
if (compilingFile.state == CompilationStackItem.State.Compiling) {
|
||||
if (compilingFile.timeTaken > InkSettings.instance.compileTimeout) {
|
||||
// TODO - Cancel the thread if it's still going. Not critical, since its kinda fine if it compiles a bit later, but it's not clear.
|
||||
RemoveCompilingFile(i);
|
||||
Debug.LogError("Ink Compiler timed out for "+compilingFile.inkAbsoluteFilePath+".\nCompilation should never take more than a few seconds, but for large projects or slow computers you may want to increase the timeout time in the InkSettings file.\nIf this persists there may be another issue; or else check an ink file exists at this path and try Assets/Recompile Ink, else please report as a bug with the following error log at this address: https://github.com/inkle/ink/issues\nError log:\n"+string.Join("\n",compilingFile.unhandledErrorOutput.ToArray()));
|
||||
TryCompileNextFileInStack();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// When all files have compiled, run the complete function.
|
||||
if(NumFilesInCompilingStackInState(CompilationStackItem.State.Compiling) == 0) {
|
||||
if(NumFilesInCompilingStackInState(CompilationStackItem.State.Queued) == 0) {
|
||||
DelayedComplete();
|
||||
} else {
|
||||
// We used to avoid calling this here in favour of calling it CompileInkThreaded but it seems that it doesn't run when called there, for some reason.
|
||||
// If someone can make this work please let me know!
|
||||
TryCompileNextFileInStack();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// If we're not showing a progress bar in Linux this whole step is superfluous
|
||||
#if !UNITY_EDITOR_LINUX
|
||||
UpdateProgressBar();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void RemoveCompilingFile (int index) {
|
||||
instance.compilationStack.RemoveAt(index);
|
||||
instance.Save(true);
|
||||
// Progress bar prevents delayCall callback from firing in Linux Editor, locking the
|
||||
// compilation until it times out. Let's just not show progress bars in Linux Editor
|
||||
#if !UNITY_EDITOR_LINUX
|
||||
if (instance.compilationStack.Count == 0) EditorUtility.ClearProgressBar();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void UpdateProgressBar () {
|
||||
if(instance.compilationStack.Count == 0) return;
|
||||
int numCompiling = NumFilesInCompilingStackInState(CompilationStackItem.State.Compiling);
|
||||
string message = "Compiling .Ink File "+(instance.compilationStack.Count-numCompiling)+" of "+instance.compilationStack.Count+".";
|
||||
if(playModeBlocked) message += " Will enter play mode when complete.";
|
||||
if(buildBlocked || playModeBlocked || EditorApplication.isPlaying) EditorUtility.DisplayProgressBar("Compiling Ink...", message, GetEstimatedCompilationProgress());
|
||||
else EditorUtility.ClearProgressBar();
|
||||
}
|
||||
|
||||
public static float GetEstimatedCompilationProgress () {
|
||||
if(!compiling) return 1;
|
||||
float progress = 0;
|
||||
foreach (var compilingFile in instance.compilationStack) {
|
||||
if (compilingFile.state == CompilationStackItem.State.Compiling)
|
||||
progress += compilingFile.timeTaken / InkSettings.instance.compileTimeout;
|
||||
if (compilingFile.state == CompilationStackItem.State.Complete)
|
||||
progress += 1;
|
||||
}
|
||||
progress /= instance.compilationStack.Count;
|
||||
return progress;
|
||||
}
|
||||
|
||||
#if UNITY_2017_1_OR_NEWER
|
||||
static void OnPlayModeChange (PlayModeStateChange mode) {
|
||||
if(mode == PlayModeStateChange.EnteredEditMode && instance.pendingCompilationStack.Count > 0)
|
||||
CompilePendingFiles();
|
||||
if(mode == PlayModeStateChange.ExitingEditMode && compiling)
|
||||
BlockPlayMode();
|
||||
if(mode == PlayModeStateChange.EnteredPlayMode && compiling)
|
||||
EnteredPlayModeWhenCompiling();
|
||||
}
|
||||
#else
|
||||
static void LegacyOnPlayModeChange () {
|
||||
if(!EditorApplication.isPlayingOrWillChangePlaymode && EditorApplication.isPlaying && instance.pendingCompilationStack.Count > 0)
|
||||
CompilePendingFiles();
|
||||
if(EditorApplication.isPlayingOrWillChangePlaymode && !EditorApplication.isPlaying && compiling)
|
||||
BlockPlayMode();
|
||||
if(EditorApplication.isPlayingOrWillChangePlaymode && EditorApplication.isPlaying && compiling)
|
||||
EnteredPlayModeWhenCompiling();
|
||||
}
|
||||
#endif
|
||||
|
||||
static void CompilePendingFiles () {
|
||||
InkLibrary.CreateOrReadUpdatedInkFiles (instance.pendingCompilationStack);
|
||||
foreach (var pendingMasterFile in GetUniqueMasterInkFilesToCompile(instance.pendingCompilationStack))
|
||||
InkCompiler.CompileInk(pendingMasterFile);
|
||||
}
|
||||
|
||||
static void BlockPlayMode () {
|
||||
EditorApplication.isPlaying = false;
|
||||
var percentage = String.Format("{0:P0}.", GetEstimatedCompilationProgress());
|
||||
Debug.LogWarning("Delayed entering play mode because Ink is still compiling ("+percentage+"). Will enter play mode on completion.");
|
||||
playModeBlocked = true;
|
||||
}
|
||||
|
||||
static void EnteredPlayModeWhenCompiling () {
|
||||
Debug.LogError("Entered Play Mode while Ink was still compiling! Your story will not be up to date. Recommend exiting and re-entering play mode.\nWe normally delay entering play mode when compiling, so you've found an edge case!");
|
||||
}
|
||||
|
||||
public static void CompileInk (params InkFile[] inkFiles) {
|
||||
CompileInk(inkFiles, false, null);
|
||||
}
|
||||
public static void CompileInk (InkFile[] inkFiles, bool immediate, Action onComplete) {
|
||||
#if UNITY_2019_4_OR_NEWER
|
||||
if(!InkEditorUtils.disallowedAutoRefresh) {
|
||||
InkEditorUtils.disallowedAutoRefresh = true;
|
||||
try {
|
||||
AssetDatabase.DisallowAutoRefresh();
|
||||
} catch (Exception e) {
|
||||
Debug.LogWarning("Failed DisallowAutoRefresh "+e);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
InkLibrary.Validate();
|
||||
if(onComplete != null) onCompleteActions.Add(onComplete);
|
||||
StringBuilder filesCompiledLog = new StringBuilder("Files compiled:");
|
||||
foreach (var inkFile in inkFiles) filesCompiledLog.AppendLine().Append(inkFile.filePath);
|
||||
|
||||
StringBuilder outputLog = new StringBuilder ();
|
||||
outputLog.Append ("Ink compilation started at ");
|
||||
outputLog.AppendLine (DateTime.Now.ToLongTimeString ());
|
||||
outputLog.Append (filesCompiledLog.ToString());
|
||||
Debug.Log(outputLog);
|
||||
|
||||
foreach(var inkFile in inkFiles) {
|
||||
CompileInkInternal (inkFile, immediate);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts a System.Process that compiles a master ink file, creating a playable JSON file that can be parsed by the Ink.Story class
|
||||
/// </summary>
|
||||
/// <param name="inkFile">Ink file.</param>
|
||||
private static void CompileInkInternal (InkFile inkFile, bool immediate) {
|
||||
if(inkFile == null) {
|
||||
Debug.LogError("Tried to compile ink file but input was null.");
|
||||
return;
|
||||
}
|
||||
if(!inkFile.isMaster)
|
||||
Debug.LogWarning("Compiling InkFile which is an include. Any file created is likely to be invalid. Did you mean to call CompileInk on inkFile.master?");
|
||||
|
||||
// If we've not yet locked C# compilation do so now
|
||||
if (!hasLockedUnityCompilation)
|
||||
{
|
||||
hasLockedUnityCompilation = true;
|
||||
EditorApplication.LockReloadAssemblies();
|
||||
}
|
||||
|
||||
RemoveFromPendingCompilationStack(inkFile);
|
||||
if(GetCompilationStackItem(inkFile) != null) {
|
||||
UnityEngine.Debug.LogWarning("Tried compiling ink file, but file is already compiling. "+inkFile.filePath);
|
||||
return;
|
||||
}
|
||||
|
||||
string inputPath = InkEditorUtils.CombinePaths(inkFile.absoluteFolderPath, Path.GetFileName(inkFile.filePath));
|
||||
Debug.Assert(inkFile.absoluteFilePath == inputPath);
|
||||
|
||||
CompilationStackItem pendingFile = new CompilationStackItem
|
||||
{
|
||||
inkFile = InkLibrary.GetInkFileWithAbsolutePath(inputPath),
|
||||
inkAbsoluteFilePath = inputPath,
|
||||
jsonAbsoluteFilePath = inkFile.absoluteJSONPath,
|
||||
state = CompilationStackItem.State.Queued,
|
||||
immediate = immediate
|
||||
};
|
||||
|
||||
AddToCompilationStack(pendingFile);
|
||||
|
||||
TryCompileNextFileInStack();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private static void TryCompileNextFileInStack () {
|
||||
if(!compiling) return;
|
||||
InkCompiler.CompilationStackItem fileToCompile = null;
|
||||
foreach(var x in instance.compilationStack) {
|
||||
if(x.state == CompilationStackItem.State.Compiling) return;
|
||||
if(x.state == CompilationStackItem.State.Queued) {
|
||||
fileToCompile = x;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(fileToCompile != null) {
|
||||
if(fileToCompile.immediate) {
|
||||
CompileInkThreaded(fileToCompile);
|
||||
} else {
|
||||
if(EditorApplication.isCompiling) Debug.LogWarning("Was compiling scripts when ink compilation started! This seems to cause the thread to cancel and complete, but the work isn't done. It may cause a timeout.");
|
||||
ThreadPool.QueueUserWorkItem(CompileInkThreaded, fileToCompile);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
private static void BeginCompilingFile(CompilationStackItem item) {
|
||||
if(item.state != CompilationStackItem.State.Queued) return;
|
||||
item.state = CompilationStackItem.State.Compiling;
|
||||
item.startTime = DateTime.Now;
|
||||
}
|
||||
private static void CompleteCompilingFile(CompilationStackItem item) {
|
||||
if(item.state != CompilationStackItem.State.Compiling) return;
|
||||
item.state = CompilationStackItem.State.Complete;
|
||||
item.endTime = DateTime.Now;
|
||||
if (item.timeTaken > InkSettings.instance.compileTimeout * 0.6f)
|
||||
Debug.LogWarning ("Compilation for "+Path.GetFileName(item.inkFile.filePath)+" took over 60% of the time required to timeout the compiler. Consider increasing the compile timeout on the InkSettings file.");
|
||||
}
|
||||
|
||||
private static void CompileInkThreaded(object itemObj) {
|
||||
CompilationStackItem item = (CompilationStackItem) itemObj;
|
||||
if(item.state == CompilationStackItem.State.Compiling) {
|
||||
Debug.LogWarning("CompileInkThreaded was called on a file that is already compiling! This is most likely a threading bug. Please report this!");
|
||||
return;
|
||||
}
|
||||
BeginCompilingFile(item);
|
||||
|
||||
var inputString = File.ReadAllText(item.inkAbsoluteFilePath);
|
||||
var compiler = new Compiler(inputString, new Compiler.Options
|
||||
{
|
||||
countAllVisits = true,
|
||||
fileHandler = new UnityInkFileHandler(Path.GetDirectoryName(item.inkAbsoluteFilePath)),
|
||||
errorHandler = (string message, ErrorType type) => {
|
||||
InkCompilerLog log;
|
||||
if(InkCompilerLog.TryParse(message, out log)) {
|
||||
if(string.IsNullOrEmpty(log.fileName)) log.fileName = Path.GetFileName(item.inkAbsoluteFilePath);
|
||||
item.logOutput.Add(log);
|
||||
} else {
|
||||
Debug.LogWarning("Couldn't parse log "+message);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
try
|
||||
{
|
||||
var compiledStory = compiler.Compile();
|
||||
if (compiledStory != null)
|
||||
item.compiledJson = compiledStory.ToJson();
|
||||
}
|
||||
catch (SystemException e)
|
||||
{
|
||||
item.unhandledErrorOutput.Add(string.Format(
|
||||
"Ink Compiler threw exception \nError: {0}\n---- Trace ----\n{1}\n--------\n", e.Message,
|
||||
e.StackTrace));
|
||||
}
|
||||
|
||||
CompleteCompilingFile(item);
|
||||
|
||||
// This doesn't seem to execute when called in a thread, and I apparently don't have a bloody clue how threads work.
|
||||
// If someone can make this work, I'd rather that TryCompileNextFileInStack ran directly after CompileInkThreaded finishes.
|
||||
// I couldn't make it work, so I've put TryCompileNextFileInStack in Update instead. Bleh!
|
||||
// TryCompileNextFileInStack();
|
||||
}
|
||||
|
||||
// When all files in stack have been compiled. This is called via update because Process events run in another thread.
|
||||
private static void DelayedComplete () {
|
||||
if(NumFilesInCompilingStackInState(CompilationStackItem.State.Compiling) > 0) {
|
||||
Debug.LogWarning("Delayed, but a file is now compiling! You can ignore this warning.");
|
||||
return;
|
||||
}
|
||||
bool errorsFound = false;
|
||||
StringBuilder filesCompiledLog = new StringBuilder("Files compiled:");
|
||||
|
||||
// Create and import compiled files
|
||||
AssetDatabase.StartAssetEditing();
|
||||
foreach (var compilingFile in instance.compilationStack) {
|
||||
// Complete status is also set when an error occured, in these cases 'compiledJson' will be null so there's no import to process
|
||||
if (compilingFile.compiledJson == null) continue;
|
||||
|
||||
// Write new compiled data to the file system
|
||||
File.WriteAllText(compilingFile.jsonAbsoluteFilePath, compilingFile.compiledJson, Encoding.UTF8);
|
||||
AssetDatabase.ImportAsset(compilingFile.inkFile.jsonPath);
|
||||
}
|
||||
AssetDatabase.StopAssetEditing();
|
||||
|
||||
foreach (var compilingFile in instance.compilationStack) {
|
||||
// Load and store a reference to the compiled file
|
||||
compilingFile.inkFile.FindCompiledJSONAsset();
|
||||
|
||||
filesCompiledLog.AppendLine().Append(compilingFile.inkFile.filePath);
|
||||
filesCompiledLog.Append(string.Format(" ({0}s)", compilingFile.timeTaken));
|
||||
if(compilingFile.unhandledErrorOutput.Count > 0) {
|
||||
filesCompiledLog.Append(" (With unhandled error)");
|
||||
StringBuilder errorLog = new StringBuilder ();
|
||||
errorLog.Append ("Unhandled error(s) occurred compiling Ink file ");
|
||||
errorLog.Append ("'");
|
||||
errorLog.Append (compilingFile.inkFile.filePath);
|
||||
errorLog.Append ("'");
|
||||
errorLog.AppendLine ("! Please report following error(s) as a bug:");
|
||||
foreach (var error in compilingFile.unhandledErrorOutput)
|
||||
errorLog.AppendLine (error);
|
||||
Debug.LogError(errorLog);
|
||||
compilingFile.inkFile.unhandledCompileErrors = compilingFile.unhandledErrorOutput;
|
||||
errorsFound = true;
|
||||
} else {
|
||||
SetOutputLog(compilingFile);
|
||||
bool errorsInEntireStory = false;
|
||||
bool warningsInEntireStory = false;
|
||||
foreach(var inkFile in compilingFile.inkFile.inkFilesInIncludeHierarchy) {
|
||||
if(inkFile.hasErrors) {
|
||||
errorsInEntireStory = true;
|
||||
}
|
||||
if(inkFile.hasWarnings) {
|
||||
warningsInEntireStory = true;
|
||||
}
|
||||
}
|
||||
if(errorsInEntireStory) {
|
||||
filesCompiledLog.Append(" (With error)");
|
||||
errorsFound = true;
|
||||
}
|
||||
if(warningsInEntireStory) {
|
||||
filesCompiledLog.Append(" (With warning)");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
foreach (var compilingFile in instance.compilationStack) {
|
||||
if (OnCompileInk != null) {
|
||||
OnCompileInk (compilingFile.inkFile);
|
||||
}
|
||||
}
|
||||
|
||||
StringBuilder outputLog = new StringBuilder ();
|
||||
if(errorsFound) {
|
||||
outputLog.Append ("Ink compilation completed with errors at ");
|
||||
outputLog.AppendLine (DateTime.Now.ToLongTimeString ());
|
||||
outputLog.Append (filesCompiledLog.ToString());
|
||||
Debug.LogError(outputLog);
|
||||
} else {
|
||||
outputLog.Append ("Ink compilation completed at ");
|
||||
outputLog.AppendLine (DateTime.Now.ToLongTimeString ());
|
||||
outputLog.Append (filesCompiledLog.ToString());
|
||||
Debug.Log(outputLog);
|
||||
}
|
||||
|
||||
ClearCompilationStack();
|
||||
|
||||
#if !UNITY_EDITOR_LINUX
|
||||
EditorUtility.ClearProgressBar();
|
||||
#endif
|
||||
|
||||
#if UNITY_2019_4_OR_NEWER
|
||||
if(InkEditorUtils.disallowedAutoRefresh) {
|
||||
InkEditorUtils.disallowedAutoRefresh = false;
|
||||
try {
|
||||
AssetDatabase.AllowAutoRefresh();
|
||||
} catch (Exception e) {
|
||||
Debug.LogWarning("Failed AllowAutoRefresh "+e);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// This is now allowed, if compiled manually. I've left this code commented out because at some point we might want to track what caused a file to compile.
|
||||
// if(EditorApplication.isPlayingOrWillChangePlaymode && InkSettings.instance.delayInPlayMode) {
|
||||
// Debug.LogError("Ink just finished recompiling while in play mode. This should never happen when InkSettings.instance.delayInPlayMode is true!");
|
||||
// }
|
||||
|
||||
buildBlocked = false;
|
||||
|
||||
if(playModeBlocked) {
|
||||
playModeBlocked = false;
|
||||
if(!errorsFound) {
|
||||
// Delaying gives the editor a frame to clear the progress bar.
|
||||
EditorApplication.delayCall += () => {
|
||||
Debug.Log("Compilation completed, entering play mode.");
|
||||
EditorApplication.isPlaying = true;
|
||||
};
|
||||
} else {
|
||||
Debug.LogWarning("Play mode not entered after ink compilation because ink had errors.");
|
||||
}
|
||||
}
|
||||
|
||||
foreach(var onCompleteAction in onCompleteActions) {
|
||||
if(onCompleteAction != null) onCompleteAction();
|
||||
}
|
||||
onCompleteActions.Clear();
|
||||
}
|
||||
|
||||
|
||||
private static void SetOutputLog (CompilationStackItem pendingFile) {
|
||||
pendingFile.inkFile.errors.Clear();
|
||||
pendingFile.inkFile.warnings.Clear();
|
||||
pendingFile.inkFile.todos.Clear();
|
||||
|
||||
foreach(var childInkFile in pendingFile.inkFile.inkFilesInIncludeHierarchy) {
|
||||
childInkFile.unhandledCompileErrors.Clear();
|
||||
childInkFile.errors.Clear();
|
||||
childInkFile.warnings.Clear();
|
||||
childInkFile.todos.Clear();
|
||||
}
|
||||
|
||||
foreach(var output in pendingFile.logOutput) {
|
||||
if(output.type == ErrorType.Error) {
|
||||
pendingFile.inkFile.errors.Add(output);
|
||||
Debug.LogError("Ink "+output.type+": "+output.content + " (at "+output.fileName+":"+output.lineNumber+")", pendingFile.inkFile.inkAsset);
|
||||
} else if (output.type == ErrorType.Warning) {
|
||||
pendingFile.inkFile.warnings.Add(output);
|
||||
Debug.LogWarning("Ink "+output.type+": "+output.content + " (at "+output.fileName+" "+output.lineNumber+")", pendingFile.inkFile.inkAsset);
|
||||
} else if (output.type == ErrorType.Author) {
|
||||
pendingFile.inkFile.todos.Add(output);
|
||||
if(InkSettings.instance.printInkLogsInConsoleOnCompile)
|
||||
Debug.Log("Ink Log: "+output.content + " (at "+output.fileName+" "+output.lineNumber+")", pendingFile.inkFile.inkAsset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static List<InkFile> GetUniqueMasterInkFilesToCompile (List<string> importedInkAssets) {
|
||||
List<InkFile> masterInkFiles = new List<InkFile>();
|
||||
foreach (var importedAssetPath in importedInkAssets) {
|
||||
foreach(var masterInkFile in GetMasterFilesIncludingInkAssetPath(importedAssetPath)) {
|
||||
if (!masterInkFiles.Contains(masterInkFile) && (InkSettings.instance.compileAutomatically || masterInkFile.compileAutomatically)) {
|
||||
masterInkFiles.Add(masterInkFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
return masterInkFiles;
|
||||
}
|
||||
|
||||
// An ink file might actually have several owners! This should be reflected here.
|
||||
public static IEnumerable<InkFile> GetMasterFilesIncludingInkAssetPath (string importedAssetPath) {
|
||||
InkFile inkFile = InkLibrary.GetInkFileWithPath(importedAssetPath);
|
||||
// Trying to catch a rare (and not especially important) bug that seems to happen occasionally when opening a project
|
||||
// It's probably this - I've noticed it before in another context.
|
||||
Debug.Assert(InkSettings.instance != null, "No ink settings file. This is a bug. For now you should be able to fix this via Assets > Rebuild Ink Library");
|
||||
// I've caught it here before
|
||||
Debug.Assert(inkFile != null, "No internal InkFile reference at path "+importedAssetPath+". This is a bug. For now you can fix this via Assets > Rebuild Ink Library");
|
||||
Debug.Assert(inkFile != null);
|
||||
return inkFile.masterInkFilesIncludingSelf;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public static void AddToCompilationStack (InkCompiler.CompilationStackItem compilationStackItem) {
|
||||
if(!instance.compilationStack.Contains(compilationStackItem)) {
|
||||
instance.compilationStack.Add(compilationStackItem);
|
||||
instance.Save(true);
|
||||
}
|
||||
}
|
||||
|
||||
public static void ClearCompilationStack () {
|
||||
if(instance.compilationStack.Count != 0) {
|
||||
instance.compilationStack.Clear();
|
||||
instance.Save(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void AddToPendingCompilationStack (string filePath) {
|
||||
if(!instance.pendingCompilationStack.Contains(filePath)) {
|
||||
instance.pendingCompilationStack.Add(filePath);
|
||||
instance.Save(true);
|
||||
}
|
||||
}
|
||||
|
||||
public static void RemoveFromPendingCompilationStack (InkFile inkFile) {
|
||||
bool anyChange = false;
|
||||
anyChange = instance.pendingCompilationStack.Remove(inkFile.filePath) || anyChange;
|
||||
foreach(var includeFile in inkFile.inkFilesInIncludeHierarchy) {
|
||||
anyChange = instance.pendingCompilationStack.Remove(includeFile.filePath) || anyChange;
|
||||
}
|
||||
if(anyChange)
|
||||
instance.Save(true);
|
||||
}
|
||||
public static void ClearCompilationStacks () {
|
||||
instance.compilationStack.Clear();
|
||||
instance.pendingCompilationStack.Clear();
|
||||
instance.Save(true);
|
||||
}
|
||||
|
||||
public static int NumFilesInCompilingStackInState (InkCompiler.CompilationStackItem.State state) {
|
||||
int count = 0;
|
||||
foreach(var x in instance.compilationStack) {
|
||||
if(x.state == state)
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
public static List<InkCompiler.CompilationStackItem> FilesInCompilingStackInState (InkCompiler.CompilationStackItem.State state) {
|
||||
List<InkCompiler.CompilationStackItem> items = new List<InkCompiler.CompilationStackItem>();
|
||||
foreach(var x in instance.compilationStack) {
|
||||
if(x.state == state)
|
||||
items.Add(x);
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
public static InkCompiler.CompilationStackItem GetCompilationStackItem (InkFile inkFile) {
|
||||
foreach(var x in instance.compilationStack) {
|
||||
if(x.inkFile == inkFile)
|
||||
return x;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 430cb8f71c23c438cb8b0ce85cc80fa6
|
||||
timeCreated: 1459463931
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,23 @@
|
||||
using Ink;
|
||||
using System.IO;
|
||||
|
||||
// Utility class for the ink compiler, used to work out how to find include files and their contents
|
||||
public class UnityInkFileHandler : IFileHandler {
|
||||
private readonly string rootDirectory;
|
||||
|
||||
public UnityInkFileHandler(string rootDirectory)
|
||||
{
|
||||
this.rootDirectory = rootDirectory;
|
||||
}
|
||||
|
||||
public string ResolveInkFilename(string includeName)
|
||||
{
|
||||
// Convert to Unix style, and then use FileInfo.FullName to parse any ..\
|
||||
return new FileInfo(Path.Combine(rootDirectory, includeName).Replace('\\', '/')).FullName;
|
||||
}
|
||||
|
||||
public string LoadInkFileContents(string fullFilename)
|
||||
{
|
||||
return File.ReadAllText(fullFilename);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2de904d59497c1c47b0792de1a85faf6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c547bc1dd015a497cb998538d42d2340
|
||||
folderAsset: yes
|
||||
timeCreated: 1459878666
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,58 @@
|
||||
using System.Text.RegularExpressions;
|
||||
using Debug = UnityEngine.Debug;
|
||||
|
||||
namespace Ink.UnityIntegration
|
||||
{
|
||||
[System.Serializable]
|
||||
public class InkCompilerLog {
|
||||
public Ink.ErrorType type;
|
||||
public string content;
|
||||
public string fileName;
|
||||
public int lineNumber;
|
||||
|
||||
public InkCompilerLog (Ink.ErrorType type, string content, string fileName, int lineNumber = -1) {
|
||||
this.type = type;
|
||||
this.content = content;
|
||||
this.fileName = fileName;
|
||||
this.lineNumber = lineNumber;
|
||||
}
|
||||
|
||||
public static bool TryParse (string rawLog, out InkCompilerLog log) {
|
||||
var match = _errorRegex.Match(rawLog);
|
||||
if (match.Success) {
|
||||
Ink.ErrorType errorType = Ink.ErrorType.Author;
|
||||
string filename = null;
|
||||
int lineNo = -1;
|
||||
string message = null;
|
||||
|
||||
var errorTypeCapture = match.Groups["errorType"];
|
||||
if( errorTypeCapture != null ) {
|
||||
var errorTypeStr = errorTypeCapture.Value;
|
||||
if(errorTypeStr == "AUTHOR" || errorTypeStr == "TODO") errorType = Ink.ErrorType.Author;
|
||||
else if(errorTypeStr == "WARNING") errorType = Ink.ErrorType.Warning;
|
||||
else if(errorTypeStr == "ERROR") errorType = Ink.ErrorType.Error;
|
||||
else Debug.LogWarning("Could not parse error type from "+errorTypeStr);
|
||||
}
|
||||
|
||||
var filenameCapture = match.Groups["filename"];
|
||||
if (filenameCapture != null)
|
||||
filename = filenameCapture.Value;
|
||||
|
||||
var lineNoCapture = match.Groups["lineNo"];
|
||||
if (lineNoCapture != null)
|
||||
lineNo = int.Parse (lineNoCapture.Value);
|
||||
|
||||
var messageCapture = match.Groups["message"];
|
||||
if (messageCapture != null)
|
||||
message = messageCapture.Value.Trim();
|
||||
log = new InkCompilerLog(errorType, message, filename, lineNo);
|
||||
return true;
|
||||
} else {
|
||||
Debug.LogWarning("Could not parse InkFileLog from log: "+rawLog);
|
||||
log = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
private static Regex _errorRegex = new Regex(@"(?<errorType>ERROR|WARNING|TODO):(?:\s(?:'(?<filename>[^']*)'\s)?line (?<lineNo>\d+):)?(?<message>.*)");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2af758247ca160446b0727c6e91632cc
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,371 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System.IO;
|
||||
using Debug = UnityEngine.Debug;
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Ink.UnityIntegration {
|
||||
// Helper class for ink files that maintains INCLUDE connections between ink files
|
||||
[System.Serializable]
|
||||
public class InkFile {
|
||||
|
||||
public bool compileAutomatically = false;
|
||||
// A reference to the ink file
|
||||
public DefaultAsset inkAsset;
|
||||
|
||||
//specify json destination folder (if None, default to same folder as ink file)
|
||||
public DefaultAsset jsonAssetDirectory;
|
||||
|
||||
// The compiled json file. Use this to start a story.
|
||||
public TextAsset jsonAsset;
|
||||
|
||||
// The file path relative to the Assets folder (Assets/Ink/Story.ink)
|
||||
public string filePath {
|
||||
get {
|
||||
if(inkAsset == null)
|
||||
return null;
|
||||
|
||||
return InkEditorUtils.SanitizePathString(AssetDatabase.GetAssetPath(inkAsset));
|
||||
}
|
||||
}
|
||||
|
||||
// The full file path (C:/Users/Inkle/HeavensVault/Assets/Ink/Story.ink)
|
||||
public string absoluteFilePath {
|
||||
get {
|
||||
if(inkAsset == null)
|
||||
return null;
|
||||
return InkEditorUtils.UnityRelativeToAbsolutePath(filePath);
|
||||
}
|
||||
}
|
||||
|
||||
public string absoluteFolderPath {
|
||||
get {
|
||||
return InkEditorUtils.SanitizePathString(Path.GetDirectoryName(absoluteFilePath));
|
||||
}
|
||||
}
|
||||
|
||||
// The path of any compiled json file. Relative to assets folder.
|
||||
public string jsonPath {
|
||||
get {
|
||||
var _filePath = filePath;
|
||||
Debug.Assert(_filePath != null, "File path for ink file is null! The ink library requires rebuilding.");
|
||||
|
||||
DefaultAsset jsonFolder = jsonAssetDirectory;
|
||||
if (jsonFolder == null) // no path specified for this specific file
|
||||
{
|
||||
if(InkSettings.instance.defaultJsonAssetPath != null)
|
||||
{
|
||||
// use default path in InkSettings
|
||||
jsonFolder = InkSettings.instance.defaultJsonAssetPath;
|
||||
}
|
||||
|
||||
if (jsonFolder == null)
|
||||
{
|
||||
//fallback to same folder as .ink file
|
||||
jsonFolder = AssetDatabase.LoadAssetAtPath<DefaultAsset>(Path.GetDirectoryName(_filePath));
|
||||
}
|
||||
}
|
||||
|
||||
Debug.Assert(jsonFolder != null, "JSON folder not found for ink file at path "+_filePath);
|
||||
|
||||
string jsonPath = AssetDatabase.GetAssetPath(jsonFolder);
|
||||
string strJsonAssetPath = InkEditorUtils.CombinePaths(jsonPath, Path.GetFileNameWithoutExtension(_filePath)) + ".json";
|
||||
return strJsonAssetPath;
|
||||
}
|
||||
}
|
||||
|
||||
public string absoluteJSONPath {
|
||||
get {
|
||||
if(inkAsset == null)
|
||||
return null;
|
||||
return InkEditorUtils.UnityRelativeToAbsolutePath(jsonPath);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Fatal unhandled errors that should be reported as compiler bugs.
|
||||
public List<string> unhandledCompileErrors = new List<string>();
|
||||
public bool hasUnhandledCompileErrors {
|
||||
get {
|
||||
return unhandledCompileErrors.Count > 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Fatal errors caused by errors in the user's ink script.
|
||||
public List<InkCompilerLog> errors = new List<InkCompilerLog>();
|
||||
public bool hasErrors {
|
||||
get {
|
||||
return errors.Count > 0;
|
||||
}
|
||||
}
|
||||
|
||||
public List<InkCompilerLog> warnings = new List<InkCompilerLog>();
|
||||
public bool hasWarnings {
|
||||
get {
|
||||
return warnings.Count > 0;
|
||||
}
|
||||
}
|
||||
|
||||
public List<InkCompilerLog> todos = new List<InkCompilerLog>();
|
||||
public bool hasTodos {
|
||||
get {
|
||||
return todos.Count > 0;
|
||||
}
|
||||
}
|
||||
|
||||
public bool requiresCompile {
|
||||
get {
|
||||
if(!isMaster) return false;
|
||||
return jsonAsset == null || lastEditDate > lastCompileDate || hasUnhandledCompileErrors;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the last compile date of the story.
|
||||
/// </summary>
|
||||
/// <value>The last compile date of the story.</value>
|
||||
public DateTime lastCompileDate {
|
||||
get {
|
||||
if(isMaster) {
|
||||
string fullJSONFilePath = InkEditorUtils.UnityRelativeToAbsolutePath(AssetDatabase.GetAssetPath(jsonAsset));
|
||||
return File.GetLastWriteTime(fullJSONFilePath);
|
||||
} else {
|
||||
return default(DateTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the last edit date of the file.
|
||||
/// </summary>
|
||||
/// <value>The last edit date of the file.</value>
|
||||
public DateTime lastEditDate {
|
||||
get {
|
||||
return File.GetLastWriteTime(absoluteFilePath);
|
||||
}
|
||||
}
|
||||
|
||||
// File that contains this file as an include, if one exists.
|
||||
public List<DefaultAsset> parents;
|
||||
public IEnumerable<InkFile> parentInkFiles {
|
||||
get {
|
||||
if(parents != null && parents.Count != 0) {
|
||||
foreach(var parentInkAsset in parents) {
|
||||
yield return InkLibrary.GetInkFileWithFile(parentInkAsset);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Is this ink file a parent file?
|
||||
public bool isParent {
|
||||
get {
|
||||
return includes.Count > 0;
|
||||
}
|
||||
}
|
||||
|
||||
public List<DefaultAsset> masterInkAssets;
|
||||
public IEnumerable<InkFile> masterInkFiles {
|
||||
get {
|
||||
if(masterInkAssets != null && masterInkAssets.Count != 0) {
|
||||
foreach(var masterInkAsset in masterInkAssets) {
|
||||
yield return InkLibrary.GetInkFileWithFile(masterInkAsset);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public IEnumerable<InkFile> masterInkFilesIncludingSelf {
|
||||
get {
|
||||
if(isMaster) yield return this;
|
||||
else {
|
||||
foreach(var masterInkFile in masterInkFiles) {
|
||||
yield return masterInkFile;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public DefaultAsset masterInkAsset;
|
||||
|
||||
// Is this ink file a master file?
|
||||
public bool isMaster {
|
||||
get {
|
||||
return masterInkAssets == null || masterInkAssets.Count == 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// The files included by this file
|
||||
// We cache the paths of the files to be included for performance, giving us more freedom to refresh the actual includes list without needing to parse all the text.
|
||||
public List<string> includePaths = new List<string>();
|
||||
public List<DefaultAsset> includes = new List<DefaultAsset>();
|
||||
// The InkFiles of the includes of this file
|
||||
public List<InkFile> includesInkFiles {
|
||||
get {
|
||||
List<InkFile> _includesInkFiles = new List<InkFile>();
|
||||
foreach(var child in includes) {
|
||||
if(child == null) {
|
||||
Debug.LogError("Error compiling ink: Ink file include in "+filePath+" is null.", inkAsset);
|
||||
continue;
|
||||
}
|
||||
_includesInkFiles.Add(InkLibrary.GetInkFileWithFile(child));
|
||||
}
|
||||
return _includesInkFiles;
|
||||
}
|
||||
}
|
||||
// The InkFiles in the include hierarchy of this file.
|
||||
public List<InkFile> inkFilesInIncludeHierarchy {
|
||||
get {
|
||||
List<InkFile> _inkFilesInIncludeHierarchy = new List<InkFile>();
|
||||
_inkFilesInIncludeHierarchy.Add(this);
|
||||
foreach(var child in includesInkFiles) {
|
||||
if (child == null)
|
||||
return null;
|
||||
_inkFilesInIncludeHierarchy.AddRange(child.inkFilesInIncludeHierarchy);
|
||||
}
|
||||
return _inkFilesInIncludeHierarchy;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public InkFile (DefaultAsset inkAsset) {
|
||||
Debug.Assert(inkAsset != null);
|
||||
this.inkAsset = inkAsset;
|
||||
|
||||
ParseContent();
|
||||
}
|
||||
|
||||
public void FindCompiledJSONAsset () {
|
||||
Debug.Assert(inkAsset != null);
|
||||
jsonAsset = AssetDatabase.LoadAssetAtPath<TextAsset>(jsonPath);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// public string content;
|
||||
// The contents of the .ink file
|
||||
public string GetFileContents () {
|
||||
if(inkAsset == null) {
|
||||
Debug.LogWarning("Ink file asset is null! Rebuild library using Assets > Rebuild Ink Library");
|
||||
return "";
|
||||
}
|
||||
return File.ReadAllText(absoluteFilePath);
|
||||
}
|
||||
|
||||
public void ParseContent () {
|
||||
includePaths.Clear();
|
||||
includePaths.AddRange(InkIncludeParser.ParseIncludes(GetFileContents()));
|
||||
}
|
||||
|
||||
public void FindIncludedFiles (bool addMissing = false) {
|
||||
includes.Clear();
|
||||
foreach(string includePath in includePaths) {
|
||||
string localIncludePath = InkEditorUtils.CombinePaths(Path.GetDirectoryName(filePath), includePath);
|
||||
// This enables parsing ..\ and the like. Can we use Path.GetFullPath instead?
|
||||
var fullIncludePath = new FileInfo(localIncludePath).FullName;
|
||||
localIncludePath = InkEditorUtils.AbsoluteToUnityRelativePath(fullIncludePath);
|
||||
DefaultAsset includedInkFileAsset = AssetDatabase.LoadAssetAtPath<DefaultAsset>(localIncludePath);
|
||||
if(includedInkFileAsset == null) {
|
||||
Debug.LogError(filePath+ " expected child .ink asset at '"+localIncludePath+"' but file was not found.", inkAsset);
|
||||
} else {
|
||||
InkFile includedInkFile = InkLibrary.GetInkFileWithFile(includedInkFileAsset, addMissing);
|
||||
if(includedInkFile == null) {
|
||||
Debug.LogError(filePath+ " expected child InkFile from .ink asset at '"+localIncludePath+"' but file was not found.", inkAsset);
|
||||
} else if (includedInkFile.includes.Contains(inkAsset)) {
|
||||
Debug.LogError("Circular INCLUDE reference between '"+filePath+"' and '"+includedInkFile.filePath+"'.", inkAsset);
|
||||
} else
|
||||
includes.Add(includedInkFileAsset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class InkIncludeParser {
|
||||
static Regex _includeRegex;
|
||||
static Regex includeRegex {
|
||||
get {
|
||||
if(_includeRegex == null) {
|
||||
_includeRegex = new Regex (@"^\s*INCLUDE\s+([^\r\n]+)\r*$", RegexOptions.Multiline);
|
||||
}
|
||||
return _includeRegex;
|
||||
}
|
||||
}
|
||||
public static IEnumerable<string> ParseIncludes (string inkContents) {
|
||||
return FindIncludes (EliminateComments(inkContents));
|
||||
}
|
||||
|
||||
static string EliminateComments(string inkStr) {
|
||||
var sb = new StringBuilder ();
|
||||
int idx = 0;
|
||||
while(idx < inkStr.Length) {
|
||||
var commentStarterIdx = inkStr.IndexOf ('/', idx);
|
||||
// Final string?
|
||||
if (commentStarterIdx == -1 || commentStarterIdx >= inkStr.Length-2 ) {
|
||||
sb.Append (inkStr.Substring (idx, inkStr.Length - idx));
|
||||
break;
|
||||
}
|
||||
sb.Append (inkStr.Substring (idx, commentStarterIdx - idx));
|
||||
var commentStarter = inkStr.Substring (commentStarterIdx, 2);
|
||||
if (commentStarter == "//" || commentStarter == "/*") {
|
||||
int endOfCommentIdx = -1;
|
||||
// Single line comments
|
||||
if (commentStarter == "//") {
|
||||
endOfCommentIdx = inkStr.IndexOf ('\n', commentStarterIdx);
|
||||
if (endOfCommentIdx == -1)
|
||||
endOfCommentIdx = inkStr.Length;
|
||||
else if (inkStr [endOfCommentIdx - 1] == '\r')
|
||||
endOfCommentIdx = endOfCommentIdx - 1;
|
||||
}
|
||||
// Block comments
|
||||
else if (commentStarter == "/*") {
|
||||
endOfCommentIdx = inkStr.IndexOf ("*/", idx);
|
||||
if (endOfCommentIdx == -1)
|
||||
endOfCommentIdx = inkStr.Length;
|
||||
else
|
||||
endOfCommentIdx += 2;
|
||||
// If there are *any* newlines, we should add one in here,
|
||||
// so that lines are spit up correctly
|
||||
if (inkStr.IndexOf ('\n', commentStarterIdx, endOfCommentIdx - commentStarterIdx) != -1)
|
||||
sb.Append ("\n");
|
||||
}
|
||||
// Skip over comment
|
||||
if (endOfCommentIdx > -1)
|
||||
idx = endOfCommentIdx;
|
||||
}
|
||||
// Normal slash we need, not a comment
|
||||
else {
|
||||
sb.Append ("/");
|
||||
idx = commentStarterIdx + 1;
|
||||
}
|
||||
}
|
||||
return sb.ToString ();
|
||||
}
|
||||
static IEnumerable<string> FindIncludes(string str) {
|
||||
MatchCollection matches = includeRegex.Matches(str);
|
||||
foreach (Match match in matches)
|
||||
{
|
||||
var capture = match.Groups [1].Captures [0];
|
||||
yield return capture.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public override string ToString () {
|
||||
return string.Format ("[InkFile: filePath={0}]", filePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b497ccd4b61cb4fee8b8f0ce86302e83
|
||||
timeCreated: 1459464092
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,475 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using UnityEditorInternal;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Diagnostics;
|
||||
using Debug = UnityEngine.Debug;
|
||||
|
||||
/// <summary>
|
||||
/// Holds a reference to an InkFile object for every .ink file detected in the Assets folder.
|
||||
/// Provides helper functions to easily obtain these files.
|
||||
/// </summary>
|
||||
namespace Ink.UnityIntegration {
|
||||
#if UNITY_2020_1_OR_NEWER
|
||||
[FilePath("Library/InkLibrary.asset", FilePathAttribute.Location.ProjectFolder)]
|
||||
public class InkLibrary : ScriptableSingleton<InkLibrary>, IEnumerable<InkFile> {
|
||||
#else
|
||||
public class InkLibrary : ScriptableObject, IEnumerable<InkFile> {
|
||||
#endif
|
||||
//
|
||||
public static System.Version inkVersionCurrent = new System.Version(1,0,0);
|
||||
public static System.Version unityIntegrationVersionCurrent = new System.Version(1,0,0);
|
||||
|
||||
static string absoluteSavePath {
|
||||
get {
|
||||
return System.IO.Path.GetFullPath(System.IO.Path.Combine(System.IO.Directory.GetCurrentDirectory(),"Library","InkLibrary.asset"));
|
||||
}
|
||||
}
|
||||
|
||||
#if !UNITY_2020_1_OR_NEWER
|
||||
public static bool created {
|
||||
get {
|
||||
// If it's null, there's no InkLibrary loaded
|
||||
return (_instance != (Object) null);
|
||||
}
|
||||
}
|
||||
private static InkLibrary _instance;
|
||||
public static InkLibrary instance {
|
||||
get {
|
||||
if(!created)
|
||||
LoadOrCreateInstance();
|
||||
return _instance;
|
||||
} private set {
|
||||
if(_instance == value) return;
|
||||
_instance = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// This occurs on recompile, creation and load (note that data has not necessarily been loaded at this point!)
|
||||
protected InkLibrary () {
|
||||
if (created)
|
||||
Debug.LogError((object) "ScriptableSingleton already exists. Did you query the singleton in a constructor?");
|
||||
else {
|
||||
instance = this;
|
||||
}
|
||||
}
|
||||
|
||||
public static void LoadOrCreateInstance () {
|
||||
InternalEditorUtility.LoadSerializedFileAndForget(absoluteSavePath);
|
||||
if(created) {
|
||||
if(InkEditorUtils.isFirstCompile) {
|
||||
Validate();
|
||||
}
|
||||
} else {
|
||||
instance = ScriptableObject.CreateInstance<InkLibrary>();
|
||||
instance.hideFlags = HideFlags.HideAndDontSave;
|
||||
Rebuild();
|
||||
instance.Save(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void Save (bool saveAsText) {
|
||||
if(!created) return;
|
||||
InternalEditorUtility.SaveToSerializedFileAndForget((Object[]) new InkLibrary[1] {instance}, absoluteSavePath, saveAsText);
|
||||
}
|
||||
|
||||
static void EnsureCreated () {
|
||||
if(!created) LoadOrCreateInstance();
|
||||
}
|
||||
#endif
|
||||
|
||||
public class AssetSaver : UnityEditor.AssetModificationProcessor {
|
||||
static string[] OnWillSaveAssets(string[] paths) {
|
||||
instance.Save(true);
|
||||
return paths;
|
||||
}
|
||||
}
|
||||
|
||||
public List<InkFile> inkLibrary = new List<InkFile>();
|
||||
Dictionary<DefaultAsset, InkFile> inkLibraryDictionary;
|
||||
|
||||
public int Count {
|
||||
get {
|
||||
return inkLibrary.Count;
|
||||
}
|
||||
}
|
||||
public InkFile this[int key] {
|
||||
get {
|
||||
return inkLibrary[key];
|
||||
} set {
|
||||
inkLibrary[key] = value;
|
||||
}
|
||||
}
|
||||
IEnumerator<InkFile> IEnumerable<InkFile>.GetEnumerator() {
|
||||
return inkLibrary.GetEnumerator();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator() {
|
||||
return inkLibrary.GetEnumerator();
|
||||
}
|
||||
|
||||
void OnValidate () {
|
||||
BuildLookupDictionary();
|
||||
Validate();
|
||||
}
|
||||
// After recompile, the data associated with the object is fetched (or whatever happens to it) by this point.
|
||||
void OnEnable () {
|
||||
// Deletes the persistent version of this asset that we used to use prior to 0.9.71
|
||||
if(!Application.isPlaying && EditorUtility.IsPersistent(this)) {
|
||||
var path = AssetDatabase.GetAssetPath(this);
|
||||
if(!string.IsNullOrEmpty(path)) {
|
||||
#if !UNITY_2020_1_OR_NEWER
|
||||
if(_instance == this) _instance = null;
|
||||
#endif
|
||||
AssetDatabase.DeleteAsset(path);
|
||||
AssetDatabase.Refresh();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void BuildLookupDictionary () {
|
||||
if(instance.inkLibraryDictionary == null) instance.inkLibraryDictionary = new Dictionary<DefaultAsset, InkFile>();
|
||||
else instance.inkLibraryDictionary.Clear();
|
||||
foreach(var inkFile in instance.inkLibrary) {
|
||||
instance.inkLibraryDictionary.Add(inkFile.inkAsset, inkFile);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the library is corrupt and rebuilds if necessary. Returns true if the library was valid
|
||||
/// </summary>
|
||||
public static bool Validate () {
|
||||
if(RequiresRebuild()) {
|
||||
Rebuild();
|
||||
Debug.LogWarning("InkLibrary was invalid and has been rebuilt. This can occur if files are moved/deleted while the editor is closed. You can ignore this warning.");
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the library is corrupt and requires a Rebuild.
|
||||
/// This can happen when asset IDs change, causing the wrong file to be referenced.
|
||||
/// This occassionally occurs from source control.
|
||||
/// This is a fairly performant check.
|
||||
/// </summary>
|
||||
static bool RequiresRebuild () {
|
||||
#if !UNITY_2020_1_OR_NEWER
|
||||
EnsureCreated();
|
||||
#endif
|
||||
foreach(var inkFile in instance.inkLibrary) {
|
||||
if(inkFile == null) {
|
||||
return true;
|
||||
}
|
||||
if(inkFile.inkAsset == null) {
|
||||
return true;
|
||||
}
|
||||
if(!instance.inkLibraryDictionary.ContainsKey(inkFile.inkAsset)) {
|
||||
return true;
|
||||
}
|
||||
if(inkFile.inkAsset == null) {
|
||||
return true;
|
||||
}
|
||||
foreach(var include in inkFile.includes) {
|
||||
if(include == null) {
|
||||
return true;
|
||||
}
|
||||
if(!instance.inkLibraryDictionary.ContainsKey(include)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes and null references in the library
|
||||
/// </summary>
|
||||
public static bool Clean () {
|
||||
bool wasDirty = false;
|
||||
for (int i = instance.Count - 1; i >= 0; i--) {
|
||||
InkFile inkFile = InkLibrary.instance[i];
|
||||
if (inkFile.inkAsset == null) {
|
||||
InkLibrary.RemoveAt(i);
|
||||
wasDirty = true;
|
||||
}
|
||||
}
|
||||
return wasDirty;
|
||||
}
|
||||
|
||||
public static void Add (InkFile inkFile) {
|
||||
instance.inkLibrary.Add(inkFile);
|
||||
SortInkLibrary();
|
||||
instance.inkLibraryDictionary.Add(inkFile.inkAsset, inkFile);
|
||||
}
|
||||
public static void RemoveAt (int index) {
|
||||
var inkFile = instance.inkLibrary[index];
|
||||
instance.inkLibrary.RemoveAt(index);
|
||||
instance.inkLibraryDictionary.Remove(inkFile.inkAsset);
|
||||
}
|
||||
static void SortInkLibrary () {
|
||||
instance.inkLibrary = instance.inkLibrary.OrderBy(x => x.filePath).ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the ink library. Executed whenever an ink file is changed by InkToJSONPostProcessor
|
||||
/// Can be called manually, but incurs a performance cost.
|
||||
/// </summary>
|
||||
public static void Rebuild () {
|
||||
// Disable the asset post processor in case any assetdatabase functions called as a result of this would cause further operations.
|
||||
InkPostProcessor.disabled = true;
|
||||
|
||||
// Remove any old file connections
|
||||
Clean();
|
||||
|
||||
// Reset the asset name
|
||||
instance.name = "Ink Library "+unityIntegrationVersionCurrent.ToString();
|
||||
|
||||
// Add any new file connections (if any are found it replaces the old library entirely)
|
||||
string[] inkFilePaths = GetAllInkFilePaths();
|
||||
bool inkLibraryChanged = false;
|
||||
List<InkFile> newInkLibrary = new List<InkFile>(inkFilePaths.Length);
|
||||
for (int i = 0; i < inkFilePaths.Length; i++) {
|
||||
InkFile inkFile = GetInkFileWithAbsolutePath(inkFilePaths [i]);
|
||||
// If the ink library doesn't have a representation for this file, then make one
|
||||
if(inkFile == null) {
|
||||
inkLibraryChanged = true;
|
||||
string localAssetPath = InkEditorUtils.AbsoluteToUnityRelativePath(inkFilePaths [i]);
|
||||
DefaultAsset inkFileAsset = AssetDatabase.LoadAssetAtPath<DefaultAsset>(localAssetPath);
|
||||
// If the ink file can't be found, it might not yet have been imported. We try to manually import it to fix this.
|
||||
if(inkFileAsset == null) {
|
||||
AssetDatabase.ImportAsset(localAssetPath);
|
||||
inkFileAsset = AssetDatabase.LoadAssetAtPath<DefaultAsset>(localAssetPath);
|
||||
if(inkFileAsset == null) {
|
||||
Debug.LogWarning("Ink File Asset not found at "+localAssetPath+". This can occur if the .meta file has not yet been created. This issue should resolve itself, but if unexpected errors occur, rebuild Ink Library using Assets > Recompile Ink");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
inkFile = new InkFile(inkFileAsset);
|
||||
}
|
||||
newInkLibrary.Add(inkFile);
|
||||
}
|
||||
if(inkLibraryChanged) {
|
||||
instance.inkLibrary = newInkLibrary;
|
||||
SortInkLibrary();
|
||||
}
|
||||
BuildLookupDictionary();
|
||||
|
||||
RebuildInkFileConnections();
|
||||
|
||||
foreach (InkFile inkFile in instance.inkLibrary) inkFile.FindCompiledJSONAsset();
|
||||
instance.Save(true);
|
||||
|
||||
// Re-enable the ink asset post processor
|
||||
InkPostProcessor.disabled = false;
|
||||
Debug.Log("Ink Library was rebuilt.");
|
||||
}
|
||||
|
||||
public static void CreateOrReadUpdatedInkFiles (List<string> importedInkAssets) {
|
||||
foreach (var importedAssetPath in importedInkAssets) {
|
||||
InkFile inkFile = InkLibrary.GetInkFileWithPath(importedAssetPath);
|
||||
if(inkFile == null) {
|
||||
DefaultAsset asset = AssetDatabase.LoadAssetAtPath<DefaultAsset>(importedAssetPath);
|
||||
inkFile = new InkFile(asset);
|
||||
Add(inkFile);
|
||||
} else {
|
||||
inkFile.ParseContent();
|
||||
}
|
||||
}
|
||||
// Now we've updated all the include paths for the ink library we can create master/child references between them.
|
||||
RebuildInkFileConnections();
|
||||
}
|
||||
|
||||
// Finds absolute file paths of all the ink files in Application.dataPath
|
||||
private static string[] GetAllInkFilePaths () {
|
||||
string[] inkFilePaths = Directory.GetFiles(Application.dataPath, "*.ink", SearchOption.AllDirectories);
|
||||
for (int i = 0; i < inkFilePaths.Length; i++) {
|
||||
inkFilePaths [i] = InkEditorUtils.SanitizePathString(inkFilePaths [i]);
|
||||
}
|
||||
return inkFilePaths;
|
||||
}
|
||||
|
||||
// All the master files
|
||||
public static IEnumerable<InkFile> GetMasterInkFiles () {
|
||||
if(instance.inkLibrary == null) yield break;
|
||||
foreach (InkFile inkFile in instance.inkLibrary) {
|
||||
if(inkFile.isMaster)
|
||||
yield return inkFile;
|
||||
}
|
||||
}
|
||||
|
||||
// All the master files which are dirty and are set to compile
|
||||
public static IEnumerable<InkFile> GetFilesRequiringRecompile () {
|
||||
foreach(InkFile inkFile in InkLibrary.GetMasterInkFiles ()) {
|
||||
if(inkFile.requiresCompile && (InkSettings.instance.compileAutomatically || inkFile.compileAutomatically))
|
||||
yield return inkFile;
|
||||
}
|
||||
}
|
||||
|
||||
// All the master files which are set to compile
|
||||
public static IEnumerable<InkFile> FilesCompiledByRecompileAll () {
|
||||
foreach(InkFile inkFile in InkLibrary.GetMasterInkFiles ()) {
|
||||
if(InkSettings.instance.compileAutomatically || inkFile.compileAutomatically)
|
||||
yield return inkFile;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the ink file from the .ink file reference.
|
||||
/// </summary>
|
||||
/// <returns>The ink file with path.</returns>
|
||||
/// <param name="file">File asset.</param>
|
||||
/// <param name="addIfMissing">Adds the file if missing from inkLibrary.</param>
|
||||
public static InkFile GetInkFileWithFile (DefaultAsset file, bool addIfMissing = false) {
|
||||
if(instance.inkLibrary == null) return null;
|
||||
|
||||
if (!file) {
|
||||
Debug.LogError("Can't add null file.");
|
||||
return null;
|
||||
}
|
||||
|
||||
if(instance.inkLibraryDictionary == null) {
|
||||
Debug.LogWarning("GetInkFileWithFile: inkLibraryDictionary was null! This should never occur, but is handled following a user reported bug. If this has never been seen long after 12/08/2020, it can be safely removed");
|
||||
BuildLookupDictionary();
|
||||
}
|
||||
foreach(InkFile inkFile in instance.inkLibrary) {
|
||||
if(inkFile.inkAsset == file) {
|
||||
return inkFile;
|
||||
}
|
||||
}
|
||||
|
||||
if (addIfMissing) {
|
||||
InkFile newFile = new InkFile(file);
|
||||
instance.inkLibrary.Add(newFile);
|
||||
Debug.Log(file + " missing from ink library. Adding it now.");
|
||||
return newFile;
|
||||
}
|
||||
|
||||
System.Text.StringBuilder listOfFiles = new System.Text.StringBuilder();
|
||||
foreach(InkFile inkFile in instance.inkLibrary) {
|
||||
listOfFiles.AppendLine(inkFile.ToString());
|
||||
}
|
||||
Debug.LogWarning (file + " missing from ink library. Please rebuild.\n"+listOfFiles);
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the ink file with path relative to Assets folder, for example: "Assets/Ink/myStory.ink".
|
||||
/// </summary>
|
||||
/// <returns>The ink file with path.</returns>
|
||||
/// <param name="path">Path.</param>
|
||||
public static InkFile GetInkFileWithPath (string path) {
|
||||
if(instance.inkLibrary == null) return null;
|
||||
foreach(InkFile inkFile in instance.inkLibrary) {
|
||||
if(inkFile.filePath == path) {
|
||||
return inkFile;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the ink file with absolute path.
|
||||
/// </summary>
|
||||
/// <returns>The ink file with path.</returns>
|
||||
/// <param name="path">Path.</param>
|
||||
public static InkFile GetInkFileWithAbsolutePath (string absolutePath) {
|
||||
if(instance.inkLibrary == null) return null;
|
||||
foreach(InkFile inkFile in instance.inkLibrary) {
|
||||
if(inkFile.absoluteFilePath == absolutePath) {
|
||||
return inkFile;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Rebuilds which files are master files and the connections between the files.
|
||||
/// </summary>
|
||||
public static void RebuildInkFileConnections () {
|
||||
Queue<InkFile> inkFileQueue = new Queue<InkFile>(instance.inkLibrary);
|
||||
while (inkFileQueue.Count > 0) {
|
||||
InkFile inkFile = inkFileQueue.Dequeue();
|
||||
inkFile.parents = new List<DefaultAsset>();
|
||||
inkFile.masterInkAssets = new List<DefaultAsset>();
|
||||
inkFile.ParseContent();
|
||||
inkFile.FindIncludedFiles(true);
|
||||
|
||||
foreach (InkFile includedInkFile in inkFile.includesInkFiles) {
|
||||
if (!inkFileQueue.Contains(includedInkFile)) {
|
||||
inkFileQueue.Enqueue(includedInkFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We now set the master file for ink files. As a file can be in an include hierarchy, we need to do this in two passes.
|
||||
// First, we set the master file to the file that includes an ink file.
|
||||
foreach (InkFile inkFile in instance.inkLibrary) {
|
||||
if(inkFile.includes.Count == 0)
|
||||
continue;
|
||||
foreach (InkFile otherInkFile in instance.inkLibrary) {
|
||||
if(inkFile == otherInkFile)
|
||||
continue;
|
||||
if(inkFile.includes.Contains(otherInkFile.inkAsset)) {
|
||||
if(!otherInkFile.parents.Contains(inkFile.inkAsset)) {
|
||||
otherInkFile.parents.Add(inkFile.inkAsset);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Next, we create a list of all the files owned by the actual master file, which we obtain by travelling up the parent tree from each file.
|
||||
Dictionary<InkFile, List<InkFile>> masterChildRelationships = new Dictionary<InkFile, List<InkFile>>();
|
||||
foreach (InkFile inkFile in instance.inkLibrary) {
|
||||
foreach(var parentInkFile in inkFile.parentInkFiles) {
|
||||
InkFile lastMasterInkFile = parentInkFile;
|
||||
InkFile masterInkFile = parentInkFile;
|
||||
while (masterInkFile.parents.Count != 0) {
|
||||
// This shouldn't just pick first, but iterate the whole lot!
|
||||
// I didn't feel like writing a recursive algorithm until it's actually needed though - a file included by several parents is already a rare enough case!
|
||||
masterInkFile = masterInkFile.parentInkFiles.First();
|
||||
lastMasterInkFile = masterInkFile;
|
||||
}
|
||||
if(lastMasterInkFile.parents.Count > 1) {
|
||||
Debug.LogError("The ink ownership tree has another master file that is not discovered! This is an oversight of the current implementation. If you requres this feature, please take a look at the comment in the code above - if you solve it let us know and we'll merge it in!");
|
||||
}
|
||||
if(!masterChildRelationships.ContainsKey(masterInkFile)) {
|
||||
masterChildRelationships.Add(masterInkFile, new List<InkFile>());
|
||||
}
|
||||
masterChildRelationships[masterInkFile].Add(inkFile);
|
||||
}
|
||||
|
||||
// if(inkFile.parent == null)
|
||||
// continue;
|
||||
// InkFile parent = inkFile.parentInkFile;
|
||||
// while (parent.metaInfo.parent != null) {
|
||||
// parent = parent.metaInfo.parentInkFile;
|
||||
// }
|
||||
// if(!masterChildRelationships.ContainsKey(parent)) {
|
||||
// masterChildRelationships.Add(parent, new List<InkFile>());
|
||||
// }
|
||||
// masterChildRelationships[parent].Add(inkFile);
|
||||
}
|
||||
// Finally, we set the master file of the children
|
||||
foreach (var inkFileRelationship in masterChildRelationships) {
|
||||
foreach(InkFile childInkFile in inkFileRelationship.Value) {
|
||||
if(!childInkFile.masterInkAssets.Contains(inkFileRelationship.Key.inkAsset)) {
|
||||
childInkFile.masterInkAssets.Add(inkFileRelationship.Key.inkAsset);
|
||||
} else {
|
||||
Debug.LogWarning("Child file already contained master file reference! This is weird!");
|
||||
}
|
||||
if(InkSettings.instance.handleJSONFilesAutomatically && childInkFile.jsonAsset != null) {
|
||||
AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(childInkFile.jsonAsset));
|
||||
childInkFile.jsonAsset = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dc234ab28a32840f5adfb84a075bc023
|
||||
timeCreated: 1485516445
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6188b37f5f5824313b73fb964d1b269e
|
||||
folderAsset: yes
|
||||
timeCreated: 1459878666
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,114 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using Debug = UnityEngine.Debug;
|
||||
|
||||
/// <summary>
|
||||
/// Holds a reference to an InkFile object for every .ink file detected in the Assets folder.
|
||||
/// Provides helper functions to easily obtain these files.
|
||||
/// </summary>
|
||||
namespace Ink.UnityIntegration {
|
||||
#if UNITY_2020_1_OR_NEWER
|
||||
[FilePath("ProjectSettings/InkSettings.asset", FilePathAttribute.Location.ProjectFolder)]
|
||||
public class InkSettings : ScriptableSingleton<InkSettings> {
|
||||
#else
|
||||
public class InkSettings : ScriptableObject {
|
||||
#endif
|
||||
#if !UNITY_2020_1_OR_NEWER
|
||||
public static bool created {
|
||||
get {
|
||||
// If it's null, there's just no InkSettings asset in the project
|
||||
return _instance != null;
|
||||
}
|
||||
}
|
||||
static string absoluteSavePath {
|
||||
get {
|
||||
return System.IO.Path.GetFullPath(System.IO.Path.Combine(Application.dataPath,"..","ProjectSettings","InkSettings.asset"));
|
||||
|
||||
}
|
||||
}
|
||||
public static void SaveStatic (bool saveAsText) {
|
||||
UnityEditorInternal.InternalEditorUtility.SaveToSerializedFileAndForget(new[] { instance }, absoluteSavePath, saveAsText);
|
||||
}
|
||||
public void Save (bool saveAsText) {
|
||||
UnityEditorInternal.InternalEditorUtility.SaveToSerializedFileAndForget((UnityEngine.Object[]) new InkSettings[1] {this}, absoluteSavePath, saveAsText);
|
||||
}
|
||||
|
||||
private static InkSettings _instance;
|
||||
public static InkSettings instance {
|
||||
get {
|
||||
if(_instance == null) {
|
||||
Object[] objects = UnityEditorInternal.InternalEditorUtility.LoadSerializedFileAndForget(absoluteSavePath);
|
||||
if (objects != null && objects.Length > 0) {
|
||||
instance = objects[0] as InkSettings;
|
||||
} else {
|
||||
instance = ScriptableObject.CreateInstance<InkSettings>();
|
||||
instance.Save(true);
|
||||
}
|
||||
}
|
||||
return _instance;
|
||||
} private set {
|
||||
if(_instance == value) return;
|
||||
_instance = value;
|
||||
}
|
||||
}
|
||||
#else
|
||||
public static void SaveStatic (bool saveAsText) {
|
||||
instance.Save(saveAsText);
|
||||
}
|
||||
#endif
|
||||
|
||||
public class AssetSaver : UnityEditor.AssetModificationProcessor {
|
||||
static string[] OnWillSaveAssets(string[] paths) {
|
||||
InkSettings.instance.Save(true);
|
||||
return paths;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public TextAsset templateFile;
|
||||
public string templateFilePath {
|
||||
get {
|
||||
if(templateFile == null) return "";
|
||||
else return AssetDatabase.GetAssetPath(templateFile);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public DefaultAsset defaultJsonAssetPath;
|
||||
|
||||
public bool compileAutomatically = true;
|
||||
public bool delayInPlayMode = true;
|
||||
public bool handleJSONFilesAutomatically = true;
|
||||
|
||||
public int compileTimeout = 30;
|
||||
|
||||
public bool printInkLogsInConsoleOnCompile;
|
||||
|
||||
#if UNITY_EDITOR && !UNITY_2018_1_OR_NEWER
|
||||
[MenuItem("Edit/Project Settings/Ink", false, 500)]
|
||||
public static void SelectFromProjectSettings() {
|
||||
Selection.activeObject = instance;
|
||||
}
|
||||
#elif UNITY_EDITOR && UNITY_2018_1_OR_NEWER
|
||||
public static SerializedObject GetSerializedSettings() {
|
||||
return new SerializedObject(instance);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Deletes the persistent version of this asset that we used to use prior to 0.9.71
|
||||
void OnEnable () {
|
||||
if(!Application.isPlaying && EditorUtility.IsPersistent(this)) {
|
||||
var path = AssetDatabase.GetAssetPath(this);
|
||||
if(!string.IsNullOrEmpty(path)) {
|
||||
#if !UNITY_2020_1_OR_NEWER
|
||||
if(_instance == this) _instance = null;
|
||||
#endif
|
||||
AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(this));
|
||||
AssetDatabase.Refresh();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 983af1b6602bf416b9928d40b37a38bd
|
||||
timeCreated: 1485516445
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,103 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Ink.UnityIntegration {
|
||||
|
||||
[CustomEditor(typeof(InkSettings))]
|
||||
public class InkSettingsEditor : Editor {
|
||||
|
||||
#pragma warning disable
|
||||
protected InkSettings data;
|
||||
|
||||
public void OnEnable() {
|
||||
data = (InkSettings) target;
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI() {
|
||||
serializedObject.Update();
|
||||
|
||||
DrawSettings(serializedObject);
|
||||
|
||||
if(GUI.changed && target != null)
|
||||
EditorUtility.SetDirty(target);
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
|
||||
#if UNITY_2018_1_OR_NEWER
|
||||
[SettingsProvider]
|
||||
public static SettingsProvider CreateInkSettingsProvider() {
|
||||
// First parameter is the path in the Settings window.
|
||||
// Second parameter is the scope of this setting: it only appears in the Project Settings window.
|
||||
var provider = new SettingsProvider("Project/Ink", SettingsScope.Project) {
|
||||
// By default the last token of the path is used as display name if no label is provided.
|
||||
label = "Ink",
|
||||
// Create the SettingsProvider and initialize its drawing (IMGUI) function in place:
|
||||
guiHandler = (searchContext) => {
|
||||
// Drawing the SO makes them disabled, and I have no idea why. Drawing manually until fixed.
|
||||
// var settings = InkSettings.GetSerializedSettings();
|
||||
DrawSettings(InkSettings.instance);
|
||||
},
|
||||
|
||||
// Populate the search keywords to enable smart search filtering and label highlighting:
|
||||
// keywords = new HashSet<string>(new[] { "Number", "Some String" })
|
||||
};
|
||||
return provider;
|
||||
}
|
||||
#endif
|
||||
|
||||
static string versionLabel => string.Format("Ink Unity Integration version "+InkLibrary.unityIntegrationVersionCurrent+"\nInk version "+InkLibrary.inkVersionCurrent+"\nInk story format version "+Ink.Runtime.Story.inkVersionCurrent+"\nInk save format version "+Ink.Runtime.StoryState.kInkSaveStateVersion);
|
||||
static void DrawSettings (InkSettings settings) {
|
||||
var cachedLabelWidth = EditorGUIUtility.labelWidth;
|
||||
EditorGUIUtility.labelWidth = 260;
|
||||
|
||||
EditorGUILayout.HelpBox(versionLabel, MessageType.Info);
|
||||
|
||||
if(settings.templateFile == null) {
|
||||
EditorGUILayout.HelpBox("Template not found. Ink files created via Assets > Create > Ink will be blank.", MessageType.Info);
|
||||
}
|
||||
settings.templateFile = (TextAsset)EditorGUILayout.ObjectField(new GUIContent("Ink Template", "Optional. The default content of files created via Assets > Create > Ink."), settings.templateFile, typeof(TextAsset));
|
||||
settings.defaultJsonAssetPath = (DefaultAsset)EditorGUILayout.ObjectField(new GUIContent("New JSON Path", "By default, story JSON files are placed next to the ink. Drag a folder here to place new JSON files there instead."), settings.defaultJsonAssetPath, typeof(DefaultAsset));
|
||||
settings.compileAutomatically = EditorGUILayout.Toggle(new GUIContent("Compile All Ink Automatically", "When disabled, automatic compilation can be enabled on a per-story basis via the inspector for a master story file. This can be helpful when you have several stories in a single project."), settings.compileAutomatically);
|
||||
settings.delayInPlayMode = EditorGUILayout.Toggle(new GUIContent("Delay compilation if in Play Mode", "When enabled, ink compilation is delayed if in play mode. Files will be compiled on re-entering edit mode."), settings.delayInPlayMode);
|
||||
settings.printInkLogsInConsoleOnCompile = EditorGUILayout.Toggle(new GUIContent("Print ink TODOs in console on compile", "When enabled, ink lines starting with TODO are printed in the console."), settings.printInkLogsInConsoleOnCompile);
|
||||
settings.handleJSONFilesAutomatically = EditorGUILayout.Toggle(new GUIContent("Handle JSON Automatically", "Whether JSON files are moved, renamed and deleted along with their ink files."), settings.handleJSONFilesAutomatically);
|
||||
settings.compileTimeout = EditorGUILayout.IntField(new GUIContent("Compile Timeout", "The max time the compiler will attempt to compile for in case of unhanded errors. You may need to increase this for very large ink projects."), settings.compileTimeout);
|
||||
|
||||
EditorGUIUtility.labelWidth = cachedLabelWidth;
|
||||
|
||||
EditorGUILayout.Separator();
|
||||
if(GUILayout.Button("Show changelog")) {
|
||||
InkUnityIntegrationStartupWindow.ShowWindow();
|
||||
}
|
||||
}
|
||||
static void DrawSettings (SerializedObject settings) {
|
||||
var cachedLabelWidth = EditorGUIUtility.labelWidth;
|
||||
EditorGUIUtility.labelWidth = 260;
|
||||
EditorGUI.BeginChangeCheck();
|
||||
|
||||
EditorGUILayout.HelpBox(versionLabel, MessageType.Info);
|
||||
|
||||
if(settings.FindProperty("templateFile").objectReferenceValue == null) {
|
||||
EditorGUILayout.HelpBox("Template not found. Ink files created via Assets > Create > Ink will be blank.", MessageType.Info);
|
||||
}
|
||||
EditorGUILayout.PropertyField(settings.FindProperty("templateFile"), new GUIContent("Ink Template", "Optional. The default content of files created via Assets > Create > Ink."));
|
||||
EditorGUILayout.PropertyField(settings.FindProperty("defaultJsonAssetPath"), new GUIContent("New JSON Path", "By default, story JSON files are placed next to the ink. Drag a folder here to place new JSON files there instead."));
|
||||
EditorGUILayout.PropertyField(settings.FindProperty("compileAutomatically"), new GUIContent("Compile All Ink Automatically", "When disabled, automatic compilation can be enabled on a per-story basis via the inspector for a master story file. This can be helpful when you have several stories in a single project."));
|
||||
EditorGUILayout.PropertyField(settings.FindProperty("delayInPlayMode"), new GUIContent("Delay compilation if in Play Mode", "When enabled, ink compilation is delayed if in play mode. Files will be compiled on re-entering edit mode."));
|
||||
EditorGUILayout.PropertyField(settings.FindProperty("printInkLogsInConsoleOnCompile"), new GUIContent("Print ink TODOs in console on compile", "When enabled, ink lines starting with TODO are printed in the console."));
|
||||
EditorGUILayout.PropertyField(settings.FindProperty("handleJSONFilesAutomatically"), new GUIContent("Handle JSON Automatically", "Whether JSON files are moved, renamed and deleted along with their ink files."));
|
||||
EditorGUILayout.PropertyField(settings.FindProperty("compileTimeout"), new GUIContent("Compile Timeout", "The max time the compiler will attempt to compile for in case of unhanded errors. You may need to increase this for very large ink projects."));
|
||||
|
||||
if(EditorGUI.EndChangeCheck()) {
|
||||
settings.ApplyModifiedProperties();
|
||||
}
|
||||
EditorGUIUtility.labelWidth = cachedLabelWidth;
|
||||
|
||||
EditorGUILayout.Separator();
|
||||
if(GUILayout.Button("Show changelog")) {
|
||||
InkUnityIntegrationStartupWindow.ShowWindow();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4842c69e8d1f0443d8f4626c65ea356a
|
||||
timeCreated: 1485516445
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,294 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Linq;
|
||||
using Ink.Runtime;
|
||||
using UnityEditor.ProjectWindowCallback;
|
||||
using UnityEditor.Callbacks;
|
||||
using Path = System.IO.Path;
|
||||
|
||||
namespace Ink.UnityIntegration {
|
||||
class CreateInkAssetAction : EndNameEditAction {
|
||||
public override void Action(int instanceId, string pathName, string resourceFile) {
|
||||
var text = "";
|
||||
if(File.Exists(resourceFile)) {
|
||||
StreamReader streamReader = new StreamReader(resourceFile);
|
||||
text = streamReader.ReadToEnd();
|
||||
streamReader.Close();
|
||||
}
|
||||
UnityEngine.Object asset = CreateScriptAsset(pathName, text);
|
||||
ProjectWindowUtil.ShowCreatedAsset(asset);
|
||||
}
|
||||
|
||||
internal static UnityEngine.Object CreateScriptAsset(string pathName, string text) {
|
||||
string fullPath = Path.GetFullPath(pathName);
|
||||
UTF8Encoding encoding = new UTF8Encoding(true, false);
|
||||
bool append = false;
|
||||
StreamWriter streamWriter = new StreamWriter(fullPath, append, encoding);
|
||||
streamWriter.Write(text);
|
||||
streamWriter.Close();
|
||||
AssetDatabase.ImportAsset(pathName);
|
||||
return AssetDatabase.LoadAssetAtPath(pathName, typeof(DefaultAsset));
|
||||
}
|
||||
}
|
||||
|
||||
[InitializeOnLoad]
|
||||
public static class InkEditorUtils {
|
||||
public const string inkFileExtension = ".ink";
|
||||
const string lastCompileTimeKey = "InkIntegrationLastCompileTime";
|
||||
|
||||
|
||||
// When compiling we call AssetDatabase.DisallowAutoRefresh.
|
||||
// We NEED to remember to re-allow it or unity stops registering file changes!
|
||||
// The issue is that you need to pair calls perfectly, and you can't even use a try-catch to get around it.
|
||||
// So - we cache if we've disabled auto refresh here, since this persists across plays.
|
||||
// This does have one issue - this setting is saved even when unity re-opens, but the internal asset refresh state isn't.
|
||||
// We need this to reset on launching the editor.
|
||||
// We currently fix this by setting it false on InkEditorUtils.OnOpenUnityEditor
|
||||
// A potentially better approach is to use playerprefs for this, since it's really nothing to do with the library.
|
||||
public static bool disallowedAutoRefresh {
|
||||
get {
|
||||
if(EditorPrefs.HasKey("InkLibraryDisallowedAutoRefresh"))
|
||||
return EditorPrefs.GetBool("InkLibraryDisallowedAutoRefresh");
|
||||
return false;
|
||||
} set {
|
||||
EditorPrefs.SetBool("InkLibraryDisallowedAutoRefresh", value);
|
||||
}
|
||||
}
|
||||
|
||||
// This should run before any of the other ink integration scripts.
|
||||
static InkEditorUtils () {
|
||||
EnsureFirstLaunchHandled();
|
||||
EditorApplication.wantsToQuit += WantsToQuit;
|
||||
}
|
||||
|
||||
// Save the current EditorApplication.timeSinceStartup so OnOpenUnityEditor is sure to run next time the editor opens.
|
||||
static bool WantsToQuit () {
|
||||
LoadAndSaveLastCompileTime();
|
||||
return true;
|
||||
}
|
||||
public static bool isFirstCompile;
|
||||
static void EnsureFirstLaunchHandled () {
|
||||
float lastCompileTime = LoadAndSaveLastCompileTime();
|
||||
isFirstCompile = EditorApplication.timeSinceStartup < lastCompileTime;
|
||||
if(isFirstCompile)
|
||||
OnOpenUnityEditor();
|
||||
}
|
||||
|
||||
static float LoadAndSaveLastCompileTime () {
|
||||
float lastCompileTime = 0;
|
||||
if(EditorPrefs.HasKey(lastCompileTimeKey))
|
||||
lastCompileTime = EditorPrefs.GetFloat(lastCompileTimeKey);
|
||||
EditorPrefs.SetFloat(lastCompileTimeKey, (float)EditorApplication.timeSinceStartup);
|
||||
return lastCompileTime;
|
||||
}
|
||||
|
||||
static void OnOpenUnityEditor () {
|
||||
disallowedAutoRefresh = false;
|
||||
}
|
||||
|
||||
[MenuItem("Assets/Rebuild Ink Library", false, 200)]
|
||||
public static void RebuildLibrary() {
|
||||
InkLibrary.Rebuild();
|
||||
}
|
||||
|
||||
[MenuItem("Assets/Recompile Ink", false, 201)]
|
||||
public static void RecompileAll() {
|
||||
var filesToRecompile = InkLibrary.FilesCompiledByRecompileAll().ToArray();
|
||||
string logString = filesToRecompile.Any() ?
|
||||
"Recompile All will compile "+string.Join(", ", filesToRecompile.Select(x => Path.GetFileName(x.filePath)).ToArray()) :
|
||||
"No valid ink found. Note that only files with 'Compile Automatic' checked are compiled if not set to compile all files automatically in InkSettings file.";
|
||||
Debug.Log(logString);
|
||||
InkCompiler.CompileInk(filesToRecompile);
|
||||
}
|
||||
|
||||
public static void RecompileAllImmediately() {
|
||||
var filesToRecompile = InkLibrary.FilesCompiledByRecompileAll().ToArray();
|
||||
string logString = filesToRecompile.Any() ?
|
||||
"Recompile All Immediately will compile "+string.Join(", ", filesToRecompile.Select(x => Path.GetFileName(x.filePath)).ToArray()) :
|
||||
"No valid ink found. Note that only files with 'Compile Automatic' checked are compiled if not set to compile all files automatically in InkSettings file.";
|
||||
Debug.Log(logString);
|
||||
InkCompiler.CompileInk(filesToRecompile, true, null);
|
||||
}
|
||||
|
||||
|
||||
[MenuItem("Assets/Create/Ink", false, 120)]
|
||||
public static void CreateNewInkFile () {
|
||||
string fileName = "New Ink.ink";
|
||||
string filePath = AssetDatabase.GenerateUniqueAssetPath(Path.Combine(GetSelectedPathOrFallback(), fileName));
|
||||
CreateNewInkFile(filePath, InkSettings.instance.templateFilePath);
|
||||
}
|
||||
|
||||
public static void CreateNewInkFile (string filePath, string templateFileLocation) {
|
||||
ProjectWindowUtil.StartNameEditingIfProjectWindowExists(0, ScriptableObject.CreateInstance<CreateInkAssetAction>(), filePath, InkBrowserIcons.inkFileIcon, templateFileLocation);
|
||||
}
|
||||
|
||||
private static string GetSelectedPathOrFallback() {
|
||||
string path = "Assets";
|
||||
foreach (UnityEngine.Object obj in Selection.GetFiltered(typeof(UnityEngine.Object), SelectionMode.Assets)) {
|
||||
path = AssetDatabase.GetAssetPath(obj);
|
||||
if (!string.IsNullOrEmpty(path) && File.Exists(path)) {
|
||||
path = Path.GetDirectoryName(path);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
|
||||
|
||||
[MenuItem("Help/Ink/About")]
|
||||
public static void OpenAbout() {
|
||||
Application.OpenURL("https://github.com/inkle/ink#ink");
|
||||
}
|
||||
|
||||
[MenuItem("Help/Ink/Writing Tutorial...")]
|
||||
public static void OpenWritingDocumentation() {
|
||||
Application.OpenURL("https://github.com/inkle/ink/blob/master/Documentation/WritingWithInk.md");
|
||||
}
|
||||
|
||||
[MenuItem("Help/Ink/API Documentation...")]
|
||||
public static void OpenAPIDocumentation() {
|
||||
Application.OpenURL("https://github.com/inkle/ink/blob/master/Documentation/RunningYourInk.md");
|
||||
}
|
||||
|
||||
[MenuItem("Help/Ink/Donate...")]
|
||||
public static void Donate() {
|
||||
Application.OpenURL("https://www.patreon.com/inkle");
|
||||
}
|
||||
|
||||
[PostProcessBuildAttribute(-1)]
|
||||
public static void OnPostprocessBuild(BuildTarget target, string pathToBuiltProject) {
|
||||
if(!Debug.isDebugBuild) {
|
||||
var color = EditorGUIUtility.isProSkin ? "#3498db" : "blue";
|
||||
Debug.Log("<color="+color+">Thanks for using ink, and best of luck with your release!\nIf you're doing well, please help fund the project via Patreon https://www.patreon.com/inkle</color>");
|
||||
}
|
||||
}
|
||||
|
||||
public static TextAsset CreateStoryStateTextFile (string jsonStoryState, string defaultPath = "Assets/Ink", string defaultName = "storyState") {
|
||||
string name = AssetDatabase.GenerateUniqueAssetPath(Path.Combine(defaultPath, defaultName+".json")).Substring(defaultPath.Length+1);
|
||||
string fullPathName = EditorUtility.SaveFilePanel("Save Story State", defaultPath, name, "json");
|
||||
if(fullPathName == "")
|
||||
return null;
|
||||
using (StreamWriter outfile = new StreamWriter(fullPathName)) {
|
||||
outfile.Write(jsonStoryState);
|
||||
}
|
||||
string relativePath = AbsoluteToUnityRelativePath(fullPathName);
|
||||
AssetDatabase.ImportAsset(relativePath);
|
||||
TextAsset textAsset = AssetDatabase.LoadAssetAtPath<TextAsset>(relativePath);
|
||||
return textAsset;
|
||||
}
|
||||
|
||||
public static bool StoryContainsVariables (Story story) {
|
||||
return story.variablesState.GetEnumerator().MoveNext();
|
||||
}
|
||||
|
||||
public static bool CheckStoryIsValid (string storyJSON, out Exception exception) {
|
||||
try {
|
||||
new Story(storyJSON);
|
||||
} catch (Exception ex) {
|
||||
exception = ex;
|
||||
return false;
|
||||
}
|
||||
exception = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool CheckStoryIsValid (string storyJSON, out Story story) {
|
||||
try {
|
||||
story = new Story(storyJSON);
|
||||
} catch {
|
||||
story = null;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool CheckStoryIsValid (string storyJSON, out Exception exception, out Story story) {
|
||||
try {
|
||||
story = new Story(storyJSON);
|
||||
} catch (Exception ex) {
|
||||
exception = ex;
|
||||
story = null;
|
||||
return false;
|
||||
}
|
||||
exception = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool CheckStoryStateIsValid (string storyJSON, string storyStateJSON) {
|
||||
Story story;
|
||||
if(CheckStoryIsValid(storyJSON, out story)) {
|
||||
try {
|
||||
story.state.LoadJson(storyStateJSON);
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Returns a sanitized version of the supplied string by:
|
||||
// - swapping MS Windows-style file separators with Unix/Mac style file separators.
|
||||
// If null is provided, null is returned.
|
||||
public static string SanitizePathString(string path) {
|
||||
if (path == null) {
|
||||
return null;
|
||||
}
|
||||
return path.Replace('\\', '/');
|
||||
}
|
||||
|
||||
// Combines two file paths and returns that path. Unlike C#'s native Paths.Combine, regardless of operating
|
||||
// system this method will always return a path which uses forward slashes ('/' characters) exclusively to ensure
|
||||
// equality checks on path strings return equalities as expected.
|
||||
public static string CombinePaths(string firstPath, string secondPath) {
|
||||
Debug.Assert(firstPath != null);
|
||||
Debug.Assert(secondPath != null);
|
||||
return SanitizePathString(Path.Combine(firstPath, secondPath));
|
||||
}
|
||||
|
||||
public static string AbsoluteToUnityRelativePath(string fullPath) {
|
||||
return SanitizePathString(fullPath.Substring(Application.dataPath.Length-6));
|
||||
}
|
||||
|
||||
public static string UnityRelativeToAbsolutePath(string filePath) {
|
||||
return InkEditorUtils.CombinePaths(Application.dataPath, filePath.Substring(7));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Draws a property field for a story using GUILayout, allowing you to attach stories to the player window for debugging.
|
||||
/// </summary>
|
||||
/// <param name="story">Story.</param>
|
||||
/// <param name="label">Label.</param>
|
||||
public static void DrawStoryPropertyField (Story story, GUIContent label) {
|
||||
Debug.LogWarning("DrawStoryPropertyField has been moved from InkEditorUtils to InkPlayerWindow");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Draws a property field for a story using GUI, allowing you to attach stories to the player window for debugging.
|
||||
/// </summary>
|
||||
/// <param name="position">Position.</param>
|
||||
/// <param name="story">Story.</param>
|
||||
/// <param name="label">Label.</param>
|
||||
public static void DrawStoryPropertyField (Rect position, Story story, GUIContent label) {
|
||||
Debug.LogWarning("DrawStoryPropertyField has been moved from InkEditorUtils to InkPlayerWindow");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks to see if the given path is an ink file or not, regardless of extension.
|
||||
/// </summary>
|
||||
/// <param name="path">The path to check.</param>
|
||||
/// <returns>True if it's an ink file, otherwise false.</returns>
|
||||
public static bool IsInkFile(string path) {
|
||||
string extension = Path.GetExtension(path);
|
||||
if (extension == InkEditorUtils.inkFileExtension) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return String.IsNullOrEmpty(extension) && InkLibrary.instance.inkLibrary.Exists(f => f.filePath == path);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: eeaeb991395be4e9e9ab83197c649ad8
|
||||
timeCreated: 1459944754
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
16
Unity/Alternate Genre Jam/Assets/Ink/Editor/InkEditor.asmdef
Normal file
16
Unity/Alternate Genre Jam/Assets/Ink/Editor/InkEditor.asmdef
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"name": "InkEditor",
|
||||
"references": [
|
||||
"Ink-Libraries"
|
||||
],
|
||||
"optionalUnityReferences": [],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": []
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2047ab7874eb449d78c2b459017aa506
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Unity/Alternate Genre Jam/Assets/Ink/Editor/Tools.meta
Normal file
8
Unity/Alternate Genre Jam/Assets/Ink/Editor/Tools.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a26a7e3f7a600f249af24114621ba554
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 15e2b2aa92f3dff4b9aa6924a01bfd96
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,66 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using UnityEditor.Build;
|
||||
using System.Text;
|
||||
using Ink.UnityIntegration;
|
||||
using System.Linq;
|
||||
#if UNITY_2018_1_OR_NEWER
|
||||
using UnityEditor.Build.Reporting;
|
||||
#endif
|
||||
|
||||
class InkPreBuildValidationCheck :
|
||||
#if UNITY_2018_1_OR_NEWER
|
||||
IPreprocessBuildWithReport
|
||||
#else
|
||||
IPreprocessBuild
|
||||
#endif
|
||||
{
|
||||
public int callbackOrder { get { return 0; } }
|
||||
|
||||
#if UNITY_2018_1_OR_NEWER
|
||||
public void OnPreprocessBuild(BuildReport report) {
|
||||
PreprocessValidationStep();
|
||||
}
|
||||
#else
|
||||
public void OnPreprocessBuild(BuildTarget target, string path) {
|
||||
PreprocessValidationStep();
|
||||
}
|
||||
#endif
|
||||
|
||||
static void PreprocessValidationStep () {
|
||||
AssertNotCompiling();
|
||||
CheckForInvalidFiles();
|
||||
}
|
||||
|
||||
static void AssertNotCompiling () {
|
||||
if(InkCompiler.compiling) {
|
||||
StringBuilder sb = new StringBuilder("Ink is currently compiling!");
|
||||
var errorString = sb.ToString();
|
||||
InkCompiler.buildBlocked = true;
|
||||
if(UnityEditor.EditorUtility.DisplayDialog("Ink Build Error!", errorString, "Ok")) {
|
||||
Debug.LogError(errorString);
|
||||
}
|
||||
}
|
||||
}
|
||||
// When syncronous compilation is allowed we should try to replace this error with a compile.
|
||||
static void CheckForInvalidFiles () {
|
||||
var filesToRecompile = InkLibrary.GetFilesRequiringRecompile();
|
||||
if(filesToRecompile.Any()) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.AppendLine("There are Ink files which should be compiled, but appear not to be. You can resolve this by either:");
|
||||
sb.AppendLine(" - Compiling your files via 'Assets/Recompile Ink'");
|
||||
var resolveStep = " - Disabling 'Compile Automatically' "+(InkSettings.instance.compileAutomatically ? "in your Ink Settings file" : "for each of the files listed below");
|
||||
sb.AppendLine(resolveStep);
|
||||
sb.AppendLine();
|
||||
sb.AppendLine("Files:");
|
||||
var filesAsString = string.Join(", ", filesToRecompile.Select(x => x.filePath).ToArray());
|
||||
sb.AppendLine(filesAsString);
|
||||
var errorString = sb.ToString();
|
||||
if(!UnityEditor.EditorUtility.DisplayDialog("Ink Build Error!", errorString, "Build anyway", "Cancel build")) {
|
||||
Debug.LogError(errorString);
|
||||
} else {
|
||||
Debug.LogWarning(errorString);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 260430d96c5f0aa46a31363984dc9088
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 51bebdd29a127594b90edb5938e78b79
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,184 @@
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
/*
|
||||
* This script allows you to set custom icons for folders in project browser.
|
||||
* Recommended icon sizes - small: 16x16 px, large: 64x64 px;
|
||||
*/
|
||||
|
||||
namespace Ink.UnityIntegration {
|
||||
[InitializeOnLoad]
|
||||
public class InkBrowserIcons {
|
||||
private static bool isRetina {
|
||||
get {
|
||||
float unityVersion = float.Parse(Application.unityVersion.Substring (0, 3));
|
||||
return Application.platform == RuntimePlatform.OSXEditor && unityVersion >= 5.4f;
|
||||
}
|
||||
}
|
||||
private const float largeIconSize = 64f;
|
||||
|
||||
private static Texture2D _inkFileIcon;
|
||||
public static Texture2D inkFileIcon {
|
||||
get {
|
||||
if(_inkFileIcon == null) {
|
||||
if(isRetina) {
|
||||
_inkFileIcon = Resources.Load<Texture2D>("InkFileIcon-retina");
|
||||
} else {
|
||||
_inkFileIcon = Resources.Load<Texture2D>("InkFileIcon");
|
||||
}
|
||||
}
|
||||
return _inkFileIcon;
|
||||
}
|
||||
}
|
||||
private static Texture2D _inkFileIconLarge;
|
||||
public static Texture2D inkFileIconLarge {
|
||||
get {
|
||||
if(_inkFileIconLarge == null) {
|
||||
_inkFileIconLarge = Resources.Load<Texture2D>("InkFileIcon-large");
|
||||
}
|
||||
return _inkFileIconLarge;
|
||||
}
|
||||
}
|
||||
private static Texture2D _errorIcon;
|
||||
public static Texture2D errorIcon {
|
||||
get {
|
||||
if(_errorIcon == null) {
|
||||
_errorIcon = Resources.Load<Texture2D>("InkErrorIcon");
|
||||
}
|
||||
return _errorIcon;
|
||||
}
|
||||
}
|
||||
private static Texture2D _warningIcon;
|
||||
public static Texture2D warningIcon {
|
||||
get {
|
||||
if(_warningIcon == null) {
|
||||
_warningIcon = Resources.Load<Texture2D>("InkWarningIcon");
|
||||
}
|
||||
return _warningIcon;
|
||||
}
|
||||
}
|
||||
private static Texture2D _todoIcon;
|
||||
public static Texture2D todoIcon {
|
||||
get {
|
||||
if(_todoIcon == null) {
|
||||
_todoIcon = Resources.Load<Texture2D>("InkTodoIcon");
|
||||
}
|
||||
return _todoIcon;
|
||||
}
|
||||
}
|
||||
private static Texture2D _manualIcon;
|
||||
public static Texture2D manualIcon {
|
||||
get {
|
||||
if(_manualIcon == null) {
|
||||
_manualIcon = Resources.Load<Texture2D>("InkCompileManualIcon");
|
||||
}
|
||||
return _manualIcon;
|
||||
}
|
||||
}
|
||||
private static Texture2D _childIcon;
|
||||
public static Texture2D childIcon {
|
||||
get {
|
||||
if(_childIcon == null) {
|
||||
_childIcon = Resources.Load<Texture2D>("InkChildIcon");
|
||||
}
|
||||
return _childIcon;
|
||||
}
|
||||
}
|
||||
private static Texture2D _childIconLarge;
|
||||
public static Texture2D childIconLarge {
|
||||
get {
|
||||
if(_childIconLarge == null) {
|
||||
_childIconLarge = Resources.Load<Texture2D>("InkChildIcon-Large");
|
||||
}
|
||||
return _childIconLarge;
|
||||
}
|
||||
}
|
||||
private static Texture2D _unknownFileIcon;
|
||||
public static Texture2D unknownFileIcon {
|
||||
get {
|
||||
if(_unknownFileIcon == null) {
|
||||
_unknownFileIcon = Resources.Load<Texture2D>("InkUnknownFileIcon");
|
||||
}
|
||||
return _unknownFileIcon;
|
||||
}
|
||||
}
|
||||
|
||||
static InkBrowserIcons() {
|
||||
EditorApplication.projectWindowItemOnGUI += OnDrawProjectWindowItem;
|
||||
}
|
||||
|
||||
static void OnDrawProjectWindowItem(string guid, Rect rect) {
|
||||
string path = AssetDatabase.GUIDToAssetPath(guid);
|
||||
if (InkEditorUtils.IsInkFile(path)) {
|
||||
DefaultAsset asset = AssetDatabase.LoadAssetAtPath<DefaultAsset>(path);
|
||||
DrawInkFile(InkLibrary.GetInkFileWithFile(asset), rect);
|
||||
}
|
||||
}
|
||||
|
||||
static void DrawInkFile (InkFile inkFile, Rect rect) {
|
||||
bool isSmall = rect.width > rect.height;
|
||||
if (isSmall) {
|
||||
rect.width = rect.height;
|
||||
} else {
|
||||
rect.height = rect.width;
|
||||
}
|
||||
if (rect.width >= largeIconSize) {
|
||||
DrawLarge(inkFile, rect);
|
||||
} else {
|
||||
DrawSmall(inkFile, rect);
|
||||
}
|
||||
}
|
||||
|
||||
static void DrawLarge (InkFile inkFile, Rect rect) {
|
||||
var offset = (rect.width - largeIconSize) * 0.5f;
|
||||
rect = new Rect(rect.x + offset, rect.y + offset, largeIconSize, largeIconSize);
|
||||
if(inkFileIconLarge != null)
|
||||
GUI.DrawTexture(rect, inkFileIconLarge);
|
||||
|
||||
Rect miniRect = new Rect(rect.center, rect.size * 0.5f);
|
||||
if(inkFile == null) {
|
||||
if(unknownFileIcon != null) {
|
||||
GUI.DrawTexture(miniRect, unknownFileIcon);
|
||||
}
|
||||
} else {
|
||||
if(inkFile.hasErrors && errorIcon != null) {
|
||||
GUI.DrawTexture(miniRect, errorIcon);
|
||||
} else if(inkFile.hasWarnings && warningIcon != null) {
|
||||
GUI.DrawTexture(miniRect, warningIcon);
|
||||
} else if(inkFile.hasTodos && todoIcon != null) {
|
||||
GUI.DrawTexture(miniRect, todoIcon);
|
||||
}
|
||||
if(!inkFile.isMaster && childIcon != null) {
|
||||
GUI.DrawTexture(new Rect(rect.x, rect.y, rect.width * 0.5f, rect.height * 0.5f), childIconLarge);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void DrawSmall (InkFile inkFile, Rect rect) {
|
||||
if(inkFileIcon != null)
|
||||
GUI.DrawTexture(rect, inkFileIcon);
|
||||
|
||||
if(inkFile == null) {
|
||||
if(unknownFileIcon != null) {
|
||||
GUI.DrawTexture(new Rect(rect.x, rect.y, unknownFileIcon.width, unknownFileIcon.height), unknownFileIcon);
|
||||
}
|
||||
} else {
|
||||
if(!InkSettings.instance.compileAutomatically && !inkFile.compileAutomatically && inkFile.isMaster)
|
||||
GUI.DrawTexture(new Rect(rect.x, rect.y + rect.size.y * 0.5f, rect.size.x * 0.5f, rect.size.y * 0.5f), manualIcon);
|
||||
|
||||
Rect miniRect = new Rect(rect.center, rect.size * 0.5f);
|
||||
if(inkFile.hasErrors && errorIcon != null) {
|
||||
GUI.DrawTexture(miniRect, errorIcon);
|
||||
} else if(inkFile.hasWarnings && warningIcon != null) {
|
||||
GUI.DrawTexture(miniRect, warningIcon);
|
||||
} else if(inkFile.hasTodos && todoIcon != null) {
|
||||
GUI.DrawTexture(miniRect, todoIcon);
|
||||
}
|
||||
if(!inkFile.isMaster && childIcon != null) {
|
||||
GUI.DrawTexture(new Rect(rect.x, rect.y, childIcon.width, childIcon.height), childIcon);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 38c650d4ee11f47559699f833d29d4b9
|
||||
timeCreated: 1459341699
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7db532cf76e3b4072a4e7ea2ff88d03e
|
||||
folderAsset: yes
|
||||
timeCreated: 1475576594
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@@ -0,0 +1,57 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f4e541342c07c476094e04dc118fed7b
|
||||
timeCreated: 1463742861
|
||||
licenseType: Store
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
serializedVersion: 2
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
linearTexture: 1
|
||||
correctGamma: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 0
|
||||
cubemapConvolution: 0
|
||||
cubemapConvolutionSteps: 7
|
||||
cubemapConvolutionExponent: 1.5
|
||||
seamlessCubemap: 0
|
||||
textureFormat: -3
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
filterMode: 0
|
||||
aniso: 1
|
||||
mipBias: -1
|
||||
wrapMode: 1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
rGBM: 0
|
||||
compressionQuality: 50
|
||||
allowsAlphaSplitting: 0
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 100
|
||||
alphaIsTransparency: 1
|
||||
textureType: 2
|
||||
buildTargetSettings: []
|
||||
spriteSheet:
|
||||
sprites: []
|
||||
outline: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@@ -0,0 +1,57 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 53256257fd17e4dfda5f08016551019e
|
||||
timeCreated: 1461958426
|
||||
licenseType: Store
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
serializedVersion: 2
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
linearTexture: 1
|
||||
correctGamma: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 0
|
||||
cubemapConvolution: 0
|
||||
cubemapConvolutionSteps: 7
|
||||
cubemapConvolutionExponent: 1.5
|
||||
seamlessCubemap: 0
|
||||
textureFormat: -3
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
filterMode: 0
|
||||
aniso: 1
|
||||
mipBias: -1
|
||||
wrapMode: 1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
rGBM: 0
|
||||
compressionQuality: 50
|
||||
allowsAlphaSplitting: 0
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 100
|
||||
alphaIsTransparency: 1
|
||||
textureType: 2
|
||||
buildTargetSettings: []
|
||||
spriteSheet:
|
||||
sprites: []
|
||||
outline: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@@ -0,0 +1,84 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1e91fdbfb2b154a18b675257bc4d43d9
|
||||
timeCreated: 1485360612
|
||||
licenseType: Store
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
serializedVersion: 4
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
sRGBTexture: 0
|
||||
linearTexture: 1
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: -3
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
filterMode: 0
|
||||
aniso: 1
|
||||
mipBias: -1
|
||||
wrapMode: 1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 100
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 2
|
||||
textureShape: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
- buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
- buildTarget: iPhone
|
||||
maxTextureSize: 2048
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,3 @@
|
||||
Hello world!
|
||||
* Hello back!
|
||||
Nice to hear from you!
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0487be7f554cd45a6916f94d2b6baf50
|
||||
timeCreated: 1462291397
|
||||
licenseType: Store
|
||||
TextScriptImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@@ -0,0 +1,57 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ab12885a47a21456596113fc9233946c
|
||||
timeCreated: 1461099630
|
||||
licenseType: Store
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
serializedVersion: 2
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
linearTexture: 1
|
||||
correctGamma: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 0
|
||||
cubemapConvolution: 0
|
||||
cubemapConvolutionSteps: 7
|
||||
cubemapConvolutionExponent: 1.5
|
||||
seamlessCubemap: 0
|
||||
textureFormat: -3
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
filterMode: 0
|
||||
aniso: 1
|
||||
mipBias: -1
|
||||
wrapMode: 1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
rGBM: 0
|
||||
compressionQuality: 50
|
||||
allowsAlphaSplitting: 0
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 100
|
||||
alphaIsTransparency: 1
|
||||
textureType: 2
|
||||
buildTargetSettings: []
|
||||
spriteSheet:
|
||||
sprites: []
|
||||
outline: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@@ -0,0 +1,57 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 957c8ea47888d42349ae208cffe69c4b
|
||||
timeCreated: 1463734461
|
||||
licenseType: Store
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
serializedVersion: 2
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
linearTexture: 1
|
||||
correctGamma: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 0
|
||||
cubemapConvolution: 0
|
||||
cubemapConvolutionSteps: 7
|
||||
cubemapConvolutionExponent: 1.5
|
||||
seamlessCubemap: 0
|
||||
textureFormat: -3
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
filterMode: 0
|
||||
aniso: 1
|
||||
mipBias: -1
|
||||
wrapMode: 1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
rGBM: 0
|
||||
compressionQuality: 50
|
||||
allowsAlphaSplitting: 0
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 16
|
||||
alphaIsTransparency: 1
|
||||
textureType: 2
|
||||
buildTargetSettings: []
|
||||
spriteSheet:
|
||||
sprites: []
|
||||
outline: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@@ -0,0 +1,57 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bd3c497264be941e3a935055a433bbb9
|
||||
timeCreated: 1459953147
|
||||
licenseType: Store
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
serializedVersion: 2
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
linearTexture: 1
|
||||
correctGamma: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 0
|
||||
cubemapConvolution: 0
|
||||
cubemapConvolutionSteps: 7
|
||||
cubemapConvolutionExponent: 1.5
|
||||
seamlessCubemap: 0
|
||||
textureFormat: -3
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
filterMode: 0
|
||||
aniso: 1
|
||||
mipBias: -1
|
||||
wrapMode: 1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
rGBM: 0
|
||||
compressionQuality: 50
|
||||
allowsAlphaSplitting: 0
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 100
|
||||
alphaIsTransparency: 1
|
||||
textureType: 2
|
||||
buildTargetSettings: []
|
||||
spriteSheet:
|
||||
sprites: []
|
||||
outline: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@@ -0,0 +1,57 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8e6b218461abe4192baeeabfbe7a9ced
|
||||
timeCreated: 1459341708
|
||||
licenseType: Store
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
serializedVersion: 2
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
linearTexture: 1
|
||||
correctGamma: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 0
|
||||
cubemapConvolution: 0
|
||||
cubemapConvolutionSteps: 7
|
||||
cubemapConvolutionExponent: 1.5
|
||||
seamlessCubemap: 0
|
||||
textureFormat: -3
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
filterMode: 0
|
||||
aniso: 1
|
||||
mipBias: -1
|
||||
wrapMode: 1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
rGBM: 0
|
||||
compressionQuality: 50
|
||||
allowsAlphaSplitting: 0
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 16
|
||||
alphaIsTransparency: 1
|
||||
textureType: 2
|
||||
buildTargetSettings: []
|
||||
spriteSheet:
|
||||
sprites: []
|
||||
outline: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@@ -0,0 +1,84 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 73b0b2e787c654227845ff231c5eab5d
|
||||
timeCreated: 1485360612
|
||||
licenseType: Store
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
serializedVersion: 4
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
sRGBTexture: 0
|
||||
linearTexture: 1
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: -3
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
filterMode: 0
|
||||
aniso: 1
|
||||
mipBias: -1
|
||||
wrapMode: 1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 100
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 2
|
||||
textureShape: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
- buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
- buildTarget: iPhone
|
||||
maxTextureSize: 2048
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@@ -0,0 +1,57 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b26518ba7d72a4fd3bc42599f621c839
|
||||
timeCreated: 1462526037
|
||||
licenseType: Store
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
serializedVersion: 2
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
linearTexture: 1
|
||||
correctGamma: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 0
|
||||
cubemapConvolution: 0
|
||||
cubemapConvolutionSteps: 7
|
||||
cubemapConvolutionExponent: 1.5
|
||||
seamlessCubemap: 0
|
||||
textureFormat: -3
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
filterMode: 0
|
||||
aniso: 1
|
||||
mipBias: -1
|
||||
wrapMode: 1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
rGBM: 0
|
||||
compressionQuality: 50
|
||||
allowsAlphaSplitting: 0
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 100
|
||||
alphaIsTransparency: 1
|
||||
textureType: 2
|
||||
buildTargetSettings: []
|
||||
spriteSheet:
|
||||
sprites: []
|
||||
outline: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@@ -0,0 +1,57 @@
|
||||
fileFormatVersion: 2
|
||||
guid: efc1324f6160840a9a4c26231cc2d304
|
||||
timeCreated: 1461099630
|
||||
licenseType: Store
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
serializedVersion: 2
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
linearTexture: 1
|
||||
correctGamma: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 0
|
||||
cubemapConvolution: 0
|
||||
cubemapConvolutionSteps: 7
|
||||
cubemapConvolutionExponent: 1.5
|
||||
seamlessCubemap: 0
|
||||
textureFormat: -3
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
filterMode: 0
|
||||
aniso: 1
|
||||
mipBias: -1
|
||||
wrapMode: 1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
rGBM: 0
|
||||
compressionQuality: 50
|
||||
allowsAlphaSplitting: 0
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 100
|
||||
alphaIsTransparency: 1
|
||||
textureType: 2
|
||||
buildTargetSettings: []
|
||||
spriteSheet:
|
||||
sprites: []
|
||||
outline: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c7ff1896f35a148d8a4c1850f1e8e13d
|
||||
folderAsset: yes
|
||||
timeCreated: 1459934446
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,60 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Ink.UnityIntegration {
|
||||
[CustomEditor(typeof(DefaultAsset), true)]
|
||||
public class DefaultAssetEditor : Editor {
|
||||
|
||||
private DefaultAssetInspector inspector;
|
||||
|
||||
private void OnEnable () {
|
||||
inspector = FindObjectInspector ();
|
||||
if(inspector != null) {
|
||||
inspector.editor = this;
|
||||
inspector.serializedObject = serializedObject;
|
||||
inspector.target = target;
|
||||
inspector.OnEnable();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDisable () {
|
||||
if(inspector != null)
|
||||
inspector.OnDisable();
|
||||
}
|
||||
|
||||
protected override void OnHeaderGUI () {
|
||||
if(inspector != null) {
|
||||
inspector.OnHeaderGUI();
|
||||
}
|
||||
else
|
||||
base.OnHeaderGUI();
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI () {
|
||||
if(inspector != null) {
|
||||
GUI.enabled = true;
|
||||
inspector.OnInspectorGUI();
|
||||
}
|
||||
else
|
||||
base.OnInspectorGUI();
|
||||
}
|
||||
|
||||
private DefaultAssetInspector FindObjectInspector () {
|
||||
var assembly = Assembly.GetExecutingAssembly();
|
||||
var assetPath = AssetDatabase.GetAssetPath(target);
|
||||
foreach(var type in assembly.GetTypes()) {
|
||||
if(type.IsSubclassOf(typeof(DefaultAssetInspector))) {
|
||||
DefaultAssetInspector objectInspector = (DefaultAssetInspector)Activator.CreateInstance(type);
|
||||
if(objectInspector.IsValid(assetPath)) {
|
||||
objectInspector.target = target;
|
||||
return objectInspector;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fe3507ae5d970447197e131c39ac31b6
|
||||
timeCreated: 1464440328
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,19 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
namespace Ink.UnityIntegration {
|
||||
public abstract class DefaultAssetInspector {
|
||||
// Reference to the actual editor we draw to
|
||||
public Editor editor;
|
||||
// Shortcut to the target object
|
||||
public Object target;
|
||||
// Shortcut to the serializedObject
|
||||
public SerializedObject serializedObject;
|
||||
|
||||
public abstract bool IsValid(string assetPath);
|
||||
public virtual void OnEnable () {}
|
||||
public virtual void OnDisable () {}
|
||||
public virtual void OnHeaderGUI () {}
|
||||
public virtual void OnInspectorGUI() {}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7fa6f007190b6408c8aebb32050a3bbe
|
||||
timeCreated: 1470299519
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,418 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditorInternal;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace Ink.UnityIntegration {
|
||||
public class InkInspector : DefaultAssetInspector {
|
||||
|
||||
private InkFile inkFile;
|
||||
private ReorderableList includesFileList;
|
||||
private ReorderableList mastersFileList;
|
||||
private ReorderableList errorList;
|
||||
private ReorderableList warningList;
|
||||
private ReorderableList todosList;
|
||||
private string cachedTrimmedFileContents;
|
||||
private const int maxCharacters = 16000;
|
||||
|
||||
public override bool IsValid(string assetPath) {
|
||||
return Path.GetExtension(assetPath) == InkEditorUtils.inkFileExtension;
|
||||
}
|
||||
|
||||
public override void OnHeaderGUI () {
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.Space(38f);
|
||||
GUILayout.BeginVertical();
|
||||
GUILayout.Space(19f);
|
||||
GUILayout.BeginHorizontal();
|
||||
|
||||
GUILayoutUtility.GetRect(10f, 10f, 16f, 16f, EditorStyles.layerMaskField);
|
||||
GUILayout.FlexibleSpace();
|
||||
|
||||
EditorGUI.BeginDisabledGroup(inkFile == null);
|
||||
if (GUILayout.Button("Open", EditorStyles.miniButton)) {
|
||||
AssetDatabase.OpenAsset(inkFile.inkAsset, 3);
|
||||
GUIUtility.ExitGUI();
|
||||
}
|
||||
EditorGUI.EndDisabledGroup();
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
GUILayout.EndVertical();
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
Rect lastRect = GUILayoutUtility.GetLastRect();
|
||||
Rect rect = new Rect(lastRect.x, lastRect.y, lastRect.width, lastRect.height);
|
||||
Rect iconRect = new Rect(rect.x + 6f, rect.y + 6f, 32f, 32f);
|
||||
GUI.DrawTexture(iconRect, InkBrowserIcons.inkFileIconLarge);
|
||||
Rect childIconRect = new Rect(iconRect.x, iconRect.y, 16f, 16f);
|
||||
if(inkFile == null) {
|
||||
GUI.DrawTexture(childIconRect, InkBrowserIcons.unknownFileIcon, ScaleMode.ScaleToFit);
|
||||
} else if(!inkFile.isMaster) {
|
||||
GUI.DrawTexture(childIconRect, InkBrowserIcons.childIconLarge, ScaleMode.ScaleToFit);
|
||||
}
|
||||
|
||||
Rect titleRect = new Rect(rect.x + 44f, rect.y + 6f, rect.width - 44f - 38f - 4f, 16f);
|
||||
titleRect.yMin -= 2f;
|
||||
titleRect.yMax += 2f;
|
||||
GUI.Label(titleRect, editor.target.name, EditorStyles.largeLabel);
|
||||
}
|
||||
|
||||
public override void OnEnable () {
|
||||
Rebuild();
|
||||
InkCompiler.OnCompileInk += OnCompileInk;
|
||||
}
|
||||
|
||||
public override void OnDisable () {
|
||||
InkCompiler.OnCompileInk -= OnCompileInk;
|
||||
}
|
||||
|
||||
void OnCompileInk (InkFile inkFile) {
|
||||
Rebuild();
|
||||
}
|
||||
|
||||
void Rebuild () {
|
||||
cachedTrimmedFileContents = "";
|
||||
string assetPath = AssetDatabase.GetAssetPath(target);
|
||||
inkFile = InkLibrary.GetInkFileWithPath(assetPath);
|
||||
if(inkFile == null)
|
||||
return;
|
||||
|
||||
if (inkFile.includes.Count > 0) CreateIncludeList ();
|
||||
else includesFileList = null;
|
||||
|
||||
if (inkFile.masterInkAssets.Count > 0) CreateMastersList ();
|
||||
else mastersFileList = null;
|
||||
|
||||
CreateErrorList();
|
||||
CreateWarningList();
|
||||
CreateTodoList();
|
||||
cachedTrimmedFileContents = inkFile.GetFileContents();
|
||||
cachedTrimmedFileContents = cachedTrimmedFileContents.Substring(0, Mathf.Min(cachedTrimmedFileContents.Length, maxCharacters));
|
||||
if(cachedTrimmedFileContents.Length >= maxCharacters)
|
||||
cachedTrimmedFileContents += "...\n\n<...etc...>";
|
||||
}
|
||||
|
||||
void CreateIncludeList () {
|
||||
List<DefaultAsset> includeTextAssets = inkFile.includes;
|
||||
includesFileList = new ReorderableList(includeTextAssets, typeof(DefaultAsset), false, false, false, false);
|
||||
includesFileList.drawHeaderCallback = (Rect rect) => {
|
||||
EditorGUI.LabelField(rect, "Included Files");
|
||||
};
|
||||
includesFileList.drawElementCallback = (Rect rect, int index, bool isActive, bool isFocused) => {
|
||||
DefaultAsset childAssetFile = ((List<DefaultAsset>)includesFileList.list)[index];
|
||||
if(childAssetFile == null) {
|
||||
Debug.LogError("Ink file in include list is null. This should never occur. Use Assets > Recompile Ink to fix this issue.");
|
||||
EditorGUI.LabelField(rect, new GUIContent("Warning: Ink File in include list is null. Use Assets > Recompile Ink to fix this issue."));
|
||||
return;
|
||||
}
|
||||
InkFile childInkFile = InkLibrary.GetInkFileWithFile(childAssetFile);
|
||||
if(childInkFile == null) {
|
||||
Debug.LogError("Ink File for included file "+childAssetFile+" not found. This should never occur. Use Assets > Recompile Ink to fix this issue.");
|
||||
EditorGUI.LabelField(rect, new GUIContent("Warning: Ink File for included file "+childAssetFile+" not found. Use Assets > Recompile Ink to fix this issue."));
|
||||
return;
|
||||
}
|
||||
Rect iconRect = new Rect(rect.x, rect.y, 0, 16);
|
||||
if(childInkFile.hasErrors || childInkFile.hasWarnings) {
|
||||
iconRect.width = 20;
|
||||
}
|
||||
Rect objectFieldRect = new Rect(iconRect.xMax, rect.y, rect.width - iconRect.width - 80, 16);
|
||||
Rect selectRect = new Rect(objectFieldRect.xMax, rect.y, 80, 16);
|
||||
if(childInkFile.hasErrors) {
|
||||
EditorGUI.LabelField(iconRect, new GUIContent(InkBrowserIcons.errorIcon));
|
||||
} else if(childInkFile.hasWarnings) {
|
||||
EditorGUI.LabelField(iconRect, new GUIContent(InkBrowserIcons.warningIcon));
|
||||
}
|
||||
EditorGUI.BeginDisabledGroup(true);
|
||||
EditorGUI.ObjectField(objectFieldRect, childAssetFile, typeof(Object), false);
|
||||
EditorGUI.EndDisabledGroup();
|
||||
if(GUI.Button(selectRect, "Select")) {
|
||||
Selection.activeObject = childAssetFile;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
void CreateMastersList () {
|
||||
List<DefaultAsset> mastersTextAssets = inkFile.masterInkAssets;
|
||||
mastersFileList = new ReorderableList(mastersTextAssets, typeof(DefaultAsset), false, false, false, false);
|
||||
mastersFileList.drawHeaderCallback = (Rect rect) => {
|
||||
EditorGUI.LabelField(rect, "Master Files");
|
||||
};
|
||||
mastersFileList.drawElementCallback = (Rect rect, int index, bool isActive, bool isFocused) => {
|
||||
DefaultAsset masterAssetFile = ((List<DefaultAsset>)mastersFileList.list)[index];
|
||||
if(masterAssetFile == null) {
|
||||
Debug.LogError("Ink file in masters list is null. This should never occur. Use Assets > Recompile Ink to fix this issue.");
|
||||
EditorGUI.LabelField(rect, new GUIContent("Warning: Ink File in masters list is null. Use Assets > Recompile Ink to fix this issue."));
|
||||
return;
|
||||
}
|
||||
InkFile masterInkFile = InkLibrary.GetInkFileWithFile(masterAssetFile);
|
||||
if(masterInkFile == null) {
|
||||
Debug.LogError("Ink File for master file "+masterAssetFile+" not found. This should never occur. Use Assets > Recompile Ink to fix this issue.");
|
||||
EditorGUI.LabelField(rect, new GUIContent("Warning: Ink File for master file "+masterAssetFile+" not found. Use Assets > Recompile Ink to fix this issue."));
|
||||
return;
|
||||
}
|
||||
Rect iconRect = new Rect(rect.x, rect.y, 0, 16);
|
||||
if(masterInkFile.hasErrors || masterInkFile.hasWarnings) {
|
||||
iconRect.width = 20;
|
||||
}
|
||||
Rect objectFieldRect = new Rect(iconRect.xMax, rect.y, rect.width - iconRect.width - 80, 16);
|
||||
Rect selectRect = new Rect(objectFieldRect.xMax, rect.y, 80, 16);
|
||||
if(masterInkFile.hasErrors) {
|
||||
EditorGUI.LabelField(iconRect, new GUIContent(InkBrowserIcons.errorIcon));
|
||||
} else if(masterInkFile.hasWarnings) {
|
||||
EditorGUI.LabelField(iconRect, new GUIContent(InkBrowserIcons.warningIcon));
|
||||
}
|
||||
EditorGUI.BeginDisabledGroup(true);
|
||||
EditorGUI.ObjectField(objectFieldRect, masterAssetFile, typeof(Object), false);
|
||||
EditorGUI.EndDisabledGroup();
|
||||
if(GUI.Button(selectRect, "Select")) {
|
||||
Selection.activeObject = masterAssetFile;
|
||||
}
|
||||
|
||||
|
||||
// foreach(var masterInkFile in inkFile.masterInkFiles) {
|
||||
// EditorGUILayout.BeginHorizontal();
|
||||
// if(masterInkFile.hasErrors) {
|
||||
// GUILayout.Label(new GUIContent(InkBrowserIcons.errorIcon), GUILayout.Width(20));
|
||||
// } else if(masterInkFile.hasWarnings) {
|
||||
// GUILayout.Label(new GUIContent(InkBrowserIcons.warningIcon), GUILayout.Width(20));
|
||||
// }
|
||||
// EditorGUI.BeginDisabledGroup(true);
|
||||
// EditorGUILayout.ObjectField("Master Ink File", masterInkFile.inkAsset, typeof(Object), false);
|
||||
// EditorGUI.EndDisabledGroup();
|
||||
// if(GUILayout.Button("Select", GUILayout.Width(80))) {
|
||||
// Selection.activeObject = masterInkFile.inkAsset;
|
||||
// }
|
||||
// EditorGUILayout.EndHorizontal();
|
||||
// }
|
||||
};
|
||||
}
|
||||
|
||||
void CreateErrorList () {
|
||||
errorList = new ReorderableList(inkFile.errors, typeof(string), false, false, false, false);
|
||||
errorList.elementHeight = 18;
|
||||
errorList.drawHeaderCallback = (Rect rect) => {
|
||||
EditorGUI.LabelField(rect, new GUIContent(InkBrowserIcons.errorIcon), new GUIContent("Errors"));
|
||||
};
|
||||
errorList.drawElementCallback = (Rect rect, int index, bool isActive, bool isFocused) => {
|
||||
Rect labelRect = new Rect(rect.x, rect.y, rect.width - 80, rect.height);
|
||||
Rect buttonRect = new Rect(labelRect.xMax, rect.y, 80, rect.height-2);
|
||||
InkCompilerLog log = ((List<InkCompilerLog>)errorList.list)[index];
|
||||
string label = log.content;
|
||||
GUI.Label(labelRect, label);
|
||||
string openLabel = "Open"+ (log.lineNumber == -1 ? "" : " ("+log.lineNumber+")");
|
||||
if(GUI.Button(buttonRect, openLabel)) {
|
||||
OpenInEditor(inkFile.filePath, log.lineNumber);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
void CreateWarningList () {
|
||||
warningList = new ReorderableList(inkFile.warnings, typeof(string), false, false, false, false);
|
||||
warningList.elementHeight = 18;
|
||||
warningList.drawHeaderCallback = (Rect rect) => {
|
||||
EditorGUI.LabelField(rect, new GUIContent(InkBrowserIcons.warningIcon), new GUIContent("Warnings"));
|
||||
};
|
||||
warningList.drawElementCallback = (Rect rect, int index, bool isActive, bool isFocused) => {
|
||||
Rect labelRect = new Rect(rect.x, rect.y, rect.width - 80, rect.height);
|
||||
Rect buttonRect = new Rect(labelRect.xMax, rect.y, 80, rect.height-2);
|
||||
InkCompilerLog log = ((List<InkCompilerLog>)warningList.list)[index];
|
||||
string label = log.content;
|
||||
GUI.Label(labelRect, label);
|
||||
string openLabel = "Open"+ (log.lineNumber == -1 ? "" : " ("+log.lineNumber+")");
|
||||
if(GUI.Button(buttonRect, openLabel)) {
|
||||
OpenInEditor(inkFile.filePath, log.lineNumber);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
void CreateTodoList () {
|
||||
todosList = new ReorderableList(inkFile.todos, typeof(string), false, false, false, false);
|
||||
todosList.elementHeight = 18;
|
||||
todosList.drawHeaderCallback = (Rect rect) => {
|
||||
EditorGUI.LabelField(rect, "To do");
|
||||
};
|
||||
todosList.drawElementCallback = (Rect rect, int index, bool isActive, bool isFocused) => {
|
||||
Rect labelRect = new Rect(rect.x, rect.y, rect.width - 80, rect.height);
|
||||
Rect buttonRect = new Rect(labelRect.xMax, rect.y, 80, rect.height-2);
|
||||
InkCompilerLog log = ((List<InkCompilerLog>)todosList.list)[index];
|
||||
string label = log.content;
|
||||
GUI.Label(labelRect, label);
|
||||
string openLabel = "Open"+ (log.lineNumber == -1 ? "" : " ("+log.lineNumber+")");
|
||||
if(GUI.Button(buttonRect, openLabel)) {
|
||||
OpenInEditor(inkFile.filePath, log.lineNumber);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
static void OpenInEditor (string filePath, int lineNumber) {
|
||||
#if UNITY_2019_1_OR_NEWER
|
||||
// This function replaces OpenFileAtLineExternal, but I guess it's totally internal and can't be accessed.
|
||||
// CodeEditorUtility.Editor.Current.OpenProject(filePath, lineNumber);
|
||||
#pragma warning disable
|
||||
UnityEditorInternal.InternalEditorUtility.OpenFileAtLineExternal(filePath, lineNumber);
|
||||
#pragma warning restore
|
||||
#else
|
||||
UnityEditorInternal.InternalEditorUtility.OpenFileAtLineExternal(filePath, lineNumber);
|
||||
#endif
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI () {
|
||||
editor.Repaint();
|
||||
serializedObject.Update();
|
||||
if(inkFile == null) {
|
||||
EditorGUILayout.HelpBox("Ink File is not in library.", MessageType.Warning);
|
||||
if(GUILayout.Button("Rebuild Library")) {
|
||||
InkLibrary.Rebuild();
|
||||
Rebuild();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if(InkCompiler.GetCompilationStackItem(inkFile) != null) {
|
||||
EditorGUILayout.HelpBox("File is compiling...", MessageType.Info);
|
||||
return;
|
||||
}
|
||||
|
||||
if(inkFile.isMaster) {
|
||||
DrawMasterFileHeader();
|
||||
DrawEditAndCompileDates(inkFile);
|
||||
if(inkFile.hasUnhandledCompileErrors) {
|
||||
EditorGUILayout.HelpBox("Last compiled failed", MessageType.Error);
|
||||
} if(inkFile.hasErrors) {
|
||||
EditorGUILayout.HelpBox("Last compiled had errors", MessageType.Error);
|
||||
} else if(inkFile.hasWarnings) {
|
||||
EditorGUILayout.HelpBox("Last compile had warnings", MessageType.Warning);
|
||||
} else if(inkFile.jsonAsset == null) {
|
||||
EditorGUILayout.HelpBox("Ink file has not been compiled", MessageType.Warning);
|
||||
}
|
||||
if(inkFile.requiresCompile && GUILayout.Button("Compile")) {
|
||||
InkCompiler.CompileInk(inkFile);
|
||||
}
|
||||
DrawIncludedFiles();
|
||||
|
||||
DrawCompileErrors();
|
||||
DrawErrors();
|
||||
DrawWarnings();
|
||||
DrawTODOList();
|
||||
} else {
|
||||
DrawSubFileHeader();
|
||||
}
|
||||
|
||||
DrawFileContents ();
|
||||
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
|
||||
void DrawMasterFileHeader () {
|
||||
EditorGUILayout.LabelField("Master File", EditorStyles.boldLabel);
|
||||
if(!InkSettings.instance.compileAutomatically) {
|
||||
inkFile.compileAutomatically = EditorGUILayout.Toggle("Compile Automatially", inkFile.compileAutomatically);
|
||||
EditorApplication.RepaintProjectWindow();
|
||||
}
|
||||
EditorGUI.BeginDisabledGroup(true);
|
||||
EditorGUILayout.ObjectField("JSON Asset", inkFile.jsonAsset, typeof(TextAsset), false);
|
||||
EditorGUI.EndDisabledGroup();
|
||||
|
||||
if(inkFile.jsonAsset != null && inkFile.errors.Count == 0 && GUILayout.Button("Play")) {
|
||||
InkPlayerWindow.LoadAndPlay(inkFile.jsonAsset);
|
||||
}
|
||||
|
||||
// if(!checkedStoryForErrors) {
|
||||
// if(GUILayout.Button("Check for errors")) {
|
||||
// GetStoryErrors();
|
||||
// }
|
||||
// } else {
|
||||
// if(exception != null) {
|
||||
// EditorGUILayout.HelpBox("Story is invalid\n"+exception.ToString(), MessageType.Error);
|
||||
// } else {
|
||||
// EditorGUILayout.HelpBox("Story is valid", MessageType.Info);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
void DrawSubFileHeader() {
|
||||
EditorGUILayout.LabelField("Include File", EditorStyles.boldLabel);
|
||||
if(mastersFileList != null && mastersFileList.count > 0) {
|
||||
mastersFileList.DoLayoutList();
|
||||
}
|
||||
}
|
||||
|
||||
void DrawEditAndCompileDates (InkFile masterInkFile) {
|
||||
string editAndCompileDateString = "";
|
||||
DateTime lastEditDate = inkFile.lastEditDate;
|
||||
editAndCompileDateString += "Last edit date "+lastEditDate.ToString();
|
||||
if(masterInkFile.jsonAsset != null) {
|
||||
DateTime lastCompileDate = masterInkFile.lastCompileDate;
|
||||
editAndCompileDateString += "\nLast compile date "+lastCompileDate.ToString();
|
||||
if(lastEditDate > lastCompileDate) {
|
||||
if(EditorApplication.isPlaying && InkSettings.instance.delayInPlayMode) {
|
||||
editAndCompileDateString += "\nWill compile on exiting play mode";
|
||||
EditorGUILayout.HelpBox(editAndCompileDateString, MessageType.Info);
|
||||
} else {
|
||||
EditorGUILayout.HelpBox(editAndCompileDateString, MessageType.Warning);
|
||||
}
|
||||
} else {
|
||||
EditorGUILayout.HelpBox(editAndCompileDateString, MessageType.None);
|
||||
}
|
||||
} else {
|
||||
EditorGUILayout.HelpBox(editAndCompileDateString, MessageType.None);
|
||||
}
|
||||
}
|
||||
|
||||
void DrawIncludedFiles () {
|
||||
if(includesFileList != null && includesFileList.count > 0) {
|
||||
includesFileList.DoLayoutList();
|
||||
}
|
||||
}
|
||||
|
||||
void DrawCompileErrors () {
|
||||
if(inkFile.unhandledCompileErrors.Count == 0)
|
||||
return;
|
||||
EditorGUILayout.BeginVertical(GUI.skin.box);
|
||||
EditorGUILayout.HelpBox("Compiler bug prevented compilation of JSON file. Please help us fix it by reporting this as a bug.", MessageType.Error);
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
if(GUILayout.Button("Report via Github")) {
|
||||
Application.OpenURL("https://github.com/inkle/ink-unity-integration/issues/new");
|
||||
}
|
||||
if(GUILayout.Button("Report via Email")) {
|
||||
Application.OpenURL("mailto:info@inklestudios.com");
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
foreach(string compileError in inkFile.unhandledCompileErrors) {
|
||||
GUILayout.TextArea(compileError);
|
||||
}
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
|
||||
void DrawErrors () {
|
||||
if(errorList != null && errorList.count > 0) {
|
||||
errorList.DoLayoutList();
|
||||
}
|
||||
}
|
||||
|
||||
void DrawWarnings () {
|
||||
if(warningList != null && warningList.count > 0) {
|
||||
warningList.DoLayoutList();
|
||||
}
|
||||
}
|
||||
|
||||
void DrawTODOList () {
|
||||
if(todosList != null && todosList.count > 0) {
|
||||
todosList.DoLayoutList();
|
||||
}
|
||||
}
|
||||
|
||||
void DrawFileContents () {
|
||||
float width = EditorGUIUtility.currentViewWidth-50;
|
||||
float height = EditorStyles.wordWrappedLabel.CalcHeight(new GUIContent(cachedTrimmedFileContents), width);
|
||||
EditorGUILayout.BeginVertical(EditorStyles.textArea);
|
||||
EditorGUILayout.SelectableLabel(cachedTrimmedFileContents, EditorStyles.wordWrappedLabel, GUILayout.ExpandHeight(true), GUILayout.Width(width), GUILayout.Height(height));
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6905e53703af64a70aa6eb42f98b047c
|
||||
timeCreated: 1460011343
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 09e392e872101fd4885d68e71c7ab38b
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,86 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Ink.Runtime;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Ink.UnityIntegration.Debugging {
|
||||
[System.Serializable]
|
||||
public class InkHistoryContentItem {
|
||||
public enum ContentType {
|
||||
PresentedContent,
|
||||
ChooseChoice,
|
||||
PresentedChoice,
|
||||
EvaluateFunction,
|
||||
CompleteEvaluateFunction,
|
||||
ChoosePathString,
|
||||
Warning,
|
||||
Error,
|
||||
DebugNote
|
||||
}
|
||||
|
||||
public string content;
|
||||
public List<string> tags;
|
||||
public ContentType contentType;
|
||||
[SerializeField]
|
||||
JsonDateTime _time;
|
||||
public DateTime time {
|
||||
get {
|
||||
return _time;
|
||||
} private set {
|
||||
_time = value;
|
||||
}
|
||||
}
|
||||
|
||||
InkHistoryContentItem (string text, ContentType contentType) {
|
||||
this.content = text;
|
||||
this.contentType = contentType;
|
||||
this.time = DateTime.Now;
|
||||
}
|
||||
InkHistoryContentItem (string text, List<string> tags, ContentType contentType) {
|
||||
this.content = text;
|
||||
this.tags = tags;
|
||||
this.contentType = contentType;
|
||||
this.time = DateTime.Now;
|
||||
}
|
||||
|
||||
public static InkHistoryContentItem CreateForContent (string choiceText, List<string> tags) {
|
||||
return new InkHistoryContentItem(choiceText, tags, InkHistoryContentItem.ContentType.PresentedContent);
|
||||
}
|
||||
public static InkHistoryContentItem CreateForPresentChoice (Choice choice) {
|
||||
return new InkHistoryContentItem(choice.text.Trim(), InkHistoryContentItem.ContentType.PresentedChoice);
|
||||
}
|
||||
public static InkHistoryContentItem CreateForMakeChoice (Choice choice) {
|
||||
return new InkHistoryContentItem(choice.text.Trim(), InkHistoryContentItem.ContentType.ChooseChoice);
|
||||
}
|
||||
public static InkHistoryContentItem CreateForEvaluateFunction (string choiceText) {
|
||||
return new InkHistoryContentItem(choiceText, InkHistoryContentItem.ContentType.EvaluateFunction);
|
||||
}
|
||||
public static InkHistoryContentItem CreateForCompleteEvaluateFunction (string choiceText) {
|
||||
return new InkHistoryContentItem(choiceText, InkHistoryContentItem.ContentType.CompleteEvaluateFunction);
|
||||
}
|
||||
public static InkHistoryContentItem CreateForChoosePathString (string choiceText) {
|
||||
return new InkHistoryContentItem(choiceText, InkHistoryContentItem.ContentType.ChoosePathString);
|
||||
}
|
||||
public static InkHistoryContentItem CreateForWarning (string choiceText) {
|
||||
return new InkHistoryContentItem(choiceText, InkHistoryContentItem.ContentType.Warning);
|
||||
}
|
||||
public static InkHistoryContentItem CreateForError (string choiceText) {
|
||||
return new InkHistoryContentItem(choiceText, InkHistoryContentItem.ContentType.Error);
|
||||
}
|
||||
public static InkHistoryContentItem CreateForDebugNote (string choiceText) {
|
||||
return new InkHistoryContentItem(choiceText, InkHistoryContentItem.ContentType.DebugNote);
|
||||
}
|
||||
|
||||
struct JsonDateTime {
|
||||
public long value;
|
||||
public static implicit operator DateTime(JsonDateTime jdt) {
|
||||
return DateTime.FromFileTime(jdt.value);
|
||||
}
|
||||
public static implicit operator JsonDateTime(DateTime dt) {
|
||||
JsonDateTime jdt = new JsonDateTime();
|
||||
jdt.value = dt.ToFileTime();
|
||||
return jdt;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9eeba5396eb679a4fbf1e275b4da1b2c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bf969d7f2c98e470c9797844e20b20ee
|
||||
timeCreated: 1459342679
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e6bbfb931dd0d104199fc4542fc5a85d
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,123 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Ink.UnityIntegration {
|
||||
[InitializeOnLoad]
|
||||
public class InkUnityIntegrationStartupWindow : EditorWindow {
|
||||
const string editorPrefsKeyForVersionSeen = "Ink Unity Integration Startup Window Version Confirmed";
|
||||
const int announcementVersion = 2;
|
||||
|
||||
Vector2 scrollPosition;
|
||||
static int announcementVersionPreviouslySeen;
|
||||
|
||||
private static Texture2D _logoIcon;
|
||||
public static Texture2D logoIcon {
|
||||
get {
|
||||
if(_logoIcon == null) {
|
||||
_logoIcon = Resources.Load<Texture2D>("InkLogoIcon");
|
||||
}
|
||||
return _logoIcon;
|
||||
}
|
||||
}
|
||||
|
||||
static InkUnityIntegrationStartupWindow () {
|
||||
UnityEditor.EditorApplication.delayCall += TryCreateWindow;
|
||||
}
|
||||
|
||||
static void TryCreateWindow() {
|
||||
announcementVersionPreviouslySeen = EditorPrefs.GetInt(editorPrefsKeyForVersionSeen, -1);
|
||||
if(announcementVersion != announcementVersionPreviouslySeen) {
|
||||
ShowWindow();
|
||||
}
|
||||
}
|
||||
|
||||
public static void ShowWindow () {
|
||||
InkUnityIntegrationStartupWindow window = EditorWindow.GetWindow(typeof(InkUnityIntegrationStartupWindow), true, "Ink Update "+InkLibrary.unityIntegrationVersionCurrent.ToString(), true) as InkUnityIntegrationStartupWindow;
|
||||
window.minSize = new Vector2(200, 200);
|
||||
var size = new Vector2(520, 320);
|
||||
window.position = new Rect((Screen.currentResolution.width-size.x) * 0.5f, (Screen.currentResolution.height-size.y) * 0.5f, size.x, size.y);
|
||||
EditorPrefs.SetInt(editorPrefsKeyForVersionSeen, announcementVersion);
|
||||
}
|
||||
|
||||
void OnGUI ()
|
||||
{
|
||||
EditorGUILayout.BeginVertical();
|
||||
var areaSize = new Vector2(90,90);
|
||||
GUILayout.BeginArea(new Rect((position.width-areaSize.x)*0.5f, 15, areaSize.x, areaSize.y));
|
||||
EditorGUILayout.BeginVertical();
|
||||
EditorGUILayout.LabelField(new GUIContent(logoIcon), GUILayout.Width(areaSize.x), GUILayout.Height(areaSize.x*((float)logoIcon.height/logoIcon.width)));
|
||||
GUILayout.Space(5);
|
||||
EditorGUILayout.LabelField("Version "+InkLibrary.unityIntegrationVersionCurrent.ToString(), EditorStyles.centeredGreyMiniLabel);
|
||||
EditorGUILayout.LabelField("Ink version "+InkLibrary.inkVersionCurrent.ToString(), EditorStyles.centeredGreyMiniLabel);
|
||||
EditorGUILayout.EndVertical();
|
||||
GUILayout.EndArea();
|
||||
|
||||
GUILayout.Space(20+areaSize.y);
|
||||
|
||||
if(announcementVersionPreviouslySeen == -1) {
|
||||
EditorGUILayout.BeginVertical(GUI.skin.box);
|
||||
EditorGUILayout.LabelField("New to ink?", EditorStyles.boldLabel);
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
|
||||
if (GUILayout.Button("About Ink")) {
|
||||
Application.OpenURL("https://www.inklestudios.com/ink/");
|
||||
}
|
||||
if (GUILayout.Button("❤️Support Us!❤️")) {
|
||||
Application.OpenURL("https://www.patreon.com/inkle");
|
||||
}
|
||||
if (GUILayout.Button("Close")) {
|
||||
Close();
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
{
|
||||
scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition);
|
||||
{
|
||||
// 1.0.0
|
||||
EditorGUILayout.BeginVertical(GUI.skin.box);
|
||||
EditorGUILayout.LabelField("🎉Version 1.0.0🎉:", EditorStyles.boldLabel);
|
||||
EditorGUILayout.LabelField("• Update ink to 1.0.0", EditorStyles.wordWrappedLabel);
|
||||
EditorGUILayout.LabelField("• Ink Editor Window: Allow resizing (some) panels", EditorStyles.wordWrappedLabel);
|
||||
EditorGUILayout.LabelField("• Ink Editor Window: Named content panel ", EditorStyles.wordWrappedLabel);
|
||||
EditorGUILayout.LabelField("• Ink Editor Window: Improved performance for large stories", EditorStyles.wordWrappedLabel);
|
||||
EditorGUILayout.LabelField("• Allow compiling include files that don't have the .ink file extension", EditorStyles.wordWrappedLabel);
|
||||
EditorGUILayout.LabelField("• Remove ability to use a custom inklecate (legacy compiler)", EditorStyles.wordWrappedLabel);
|
||||
EditorGUILayout.LabelField("• Fixes settings menu on 2020+", EditorStyles.wordWrappedLabel);
|
||||
EditorGUILayout.LabelField("• Improved migration from earlier versions", EditorStyles.wordWrappedLabel);
|
||||
EditorGUILayout.LabelField("• Moved persistent compilation tracking code from InkLibrary into InkCompiler", EditorStyles.wordWrappedLabel);
|
||||
EditorGUILayout.LabelField("• Use Unity's new ScriptableSingleton for InkLibrary, InkSettings and InkCompiler on 2020+", EditorStyles.wordWrappedLabel);
|
||||
EditorGUILayout.EndVertical();
|
||||
EditorGUILayout.BeginVertical(GUI.skin.box);
|
||||
// 0.9.71
|
||||
EditorGUILayout.BeginVertical(GUI.skin.box);
|
||||
EditorGUILayout.LabelField("Version 0.9.71:", EditorStyles.boldLabel);
|
||||
EditorGUILayout.LabelField("• Resolves some compilation issues.", EditorStyles.wordWrappedLabel);
|
||||
EditorGUILayout.EndVertical();
|
||||
EditorGUILayout.BeginVertical(GUI.skin.box);
|
||||
// 0.9.60
|
||||
EditorGUILayout.LabelField("Version 0.9.60:", EditorStyles.boldLabel);
|
||||
EditorGUILayout.LabelField("• Moved InkLibrary and InkSettings from Assets into Library and ProjectSettings.", EditorStyles.wordWrappedLabel);
|
||||
EditorGUILayout.LabelField(" ‣ InkLibrary should no longer be tracked in source control.", EditorStyles.wordWrappedLabel);
|
||||
EditorGUILayout.LabelField(" ‣ Changes to InkSettings must be migrated manually.", EditorStyles.wordWrappedLabel);
|
||||
EditorGUILayout.LabelField(" ‣ The InkLibrary and InkSettings files in your project folder should be deleted.", EditorStyles.wordWrappedLabel);
|
||||
EditorGUILayout.LabelField("• Added a divertable list of knots, stitches and other named content to the Ink Editor Window, replacing the Diverts subpanel.", EditorStyles.wordWrappedLabel);
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
|
||||
EditorGUILayout.EndScrollView();
|
||||
}
|
||||
EditorGUILayout.Space();
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c436e11a2a780e14680d25152259eadd
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ed82eefbb606deb49b637f3947d9cfb0
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 6.1 KiB |
@@ -0,0 +1,121 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 09746d3311e36764faa38d0e982f6a2d
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
externalObjects: {}
|
||||
serializedVersion: 9
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
sRGBTexture: 1
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: 1
|
||||
mipBias: -100
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: -1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 2
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 2
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- serializedVersion: 2
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- serializedVersion: 2
|
||||
buildTarget: WebGL
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- serializedVersion: 2
|
||||
buildTarget: Nintendo Switch
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID:
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
spritePackingTag:
|
||||
pSDRemoveMatte: 0
|
||||
pSDShowRemoveMatteOption: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user