Przyznam się, że zabawa w portowanie silnika do nowych technologii sprawia mi całkiem niezłą frajdę.
Pewnie dlatego, że jest to takie proste 😉
Dorzucimy więc dzisiaj wisienkę na tort i spróbujemy wyrenderować nasz loch w silniku Unity3D.
Originalnie, przy portowaniu do CLR, miałem w planie pokazać rezultat właśnie w Unity3D.
Jednakże, okazało się, że wymaga to trochę więcej dłubania niż myślałem.
Ale teraz wracamy z nowym narzędziem:
Arcadia
Arcadia jest mostem łączącym Clojure z Unity3D.
W tej chwili jest to dopiero wersja Alpha, ale podstawowe funkcjonalności już są.
Mamy tutaj REPL z kontekstem silnika, kompilacje kodu Clojure do ClojureCLR i ładowanie do Unity3D.
Potrzebujemy zainstalować sobie Ruby (skrypt do REPL jest w ruby).
Potem wystarczy pobrać Arcadie i wrzucić do folderu z assetami.
Arcadia & Windows
Tym razem jednak nie ma tak łatwo jak wcześniej. Mimo, iż zespół developerski Arcadii załatwił za nas większość problemów z ładowaniem skryptów i samego clojure runtime, to jednak troszeczkę trzeba coś pozmieniać.
W pliku Arcadia\Editor\Initialization.cs zmieniamy:
[MenuItem ("Arcadia/Initialization/Update Clojure Load Path")] public static void SetClojureLoadPath() { try { Debug.Log("Setting Load Path..."); string clojureDllFolder = GetClojureDllFolder(); Environment.SetEnvironmentVariable("CLOJURE_LOAD_PATH", Path.GetFullPath(VariadicCombine(clojureDllFolder, "..", "Compiled")) + ";" + Path.GetFullPath(VariadicCombine(clojureDllFolder, "..", "Source")) + ";" + Path.GetFullPath(Application.dataPath) + ";" + Path.GetFullPath(VariadicCombine(clojureDllFolder, "..", "Libraries"))); } catch(InvalidOperationException e) { throw new SystemException("Error Loading Arcadia! Arcadia expects exactly one Arcadia folder (a folder with Clojure.dll in it)"); } Debug.Log("Load Path is " + Environment.GetEnvironmentVariable("CLOJURE_LOAD_PATH")); }
Zamieniamy “:” na “;” – autorzy zakładają, że mamy system Unixowy więc trzeba zmienić to na wersję windowsową.
RL-Engine & Unity3D
Ok, teraz zostało wrzucić nasz kod w Clojure do Arcadii i napisać mały skrypt w C#:
class DungeonGenerator : MonoBehaviour { public GameObject Wall; public GameObject Door; public GameObject Floor; void Start() { GenerateDungeon(); } public void GenerateDungeon() { IFn require = Clojure.var("clojure.core", "require"); require.invoke(Clojure.read("rl-engine.dungeon-generator")); var genratorFactory = Clojure.var("rl-engine.dungeon-generator", "get-generator"); var generator = genratorFactory.invoke("bsp") as IFn; var map = generator.invoke(20, 20); var arrayConverter = Clojure.var("clojure.core", "into-array"); var vectors = arrayConverter.invoke(map) as PersistentVector[]; var arrays = vectors.Select(x => x.Cast<long>().Select<long, int>(Convert.ToInt32).ToArray()).ToArray(); for(int i = 0; i < arrays.Length; i++) { for(int j = 0; j < arrays[i].Length; j++) { GameObject prefab = null; var value = arrays[i][j]; if(value == 0) prefab = Floor; if(value == 1) prefab = Wall; if(value == 2) prefab = Door; Instantiate(prefab, new Vector3(i,j,0), Quaternion.identity); } } } }
Po tym wszystkim powinniśmy dostać coś takiego:
Niceee!
Be First to Comment