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);
}
}
}
}
Be First to Comment