AtomicGameEngine
前回の記事はHeliumエンジンっていうのに触れたんですけど、エンジンを実行することもできずに終わってしまうという散々な結果でした。まぁでも、若干勉強にもなったし、楽しかったからよし(笑) 。
今回、新たなゲームエンジンに触れるんですが、UE4ではないです。UE4は一応ビルドも実行も成功したんですけど、一度のビルドに時間がかかりすぎることや、マシンのスペックが追いつけてなかったので、もっと軽量のゲームエンジン探すことにしました。
今回はですね、「Atomic Game Engine」を触っていこうかなと思ってます。もしかしたら、しばらくの付き合いになるかと思います。で、ビルドできずに終わりましたっていう同じ繰り返しにならないように、今回はあらかじめビルドに成功して実行もできてます。Githubのコミット見たら、数分前に新しいコミットがあったり、生きてるプロジェクトは安心感が違いますね。ビルドも一発で通りました!
ゲームエンジンっていう技術の結晶。すごいわくわくする(笑)。
それじゃあ、始める
ビルド手順 は省略。
Build_AtomicEditor.sh
このシェルスクリプトから全ては始まる。
#!/usr/bin/env sh if [ "$(uname)" = "Darwin" ]; then ./Build/Mac/node/node ./Build/Scripts/Bootstrap.js buildeditor "$@" elif [ "$(expr substr $(uname -s) 1 5)" = "Linux" ]; then ./Build/Linux/node/node ./Build/Scripts/Bootstrap.js buildeditor "$@" elif [ "$(expr substr $(uname -s) 1 7)" = "MSYS_NT" ]; then ./Build/Windows/node/node.exe ./Build/Scripts/Bootstrap.js buildeditor "$@" fi
macで動かしてるから、恐らく始めのif文が通るはず。 ちょっといじってみる。
#!/usr/bin/env sh if [ "$(uname)" = "Darwin" ]; then echo "Mac!" #./Build/Mac/node/node ./Build/Scripts/Bootstrap.js buildeditor "$@" elif [ "$(expr substr $(uname -s) 1 5)" = "Linux" ]; then echo "Linux!" #./Build/Linux/node/node ./Build/Scripts/Bootstrap.js buildeditor "$@" elif [ "$(expr substr $(uname -s) 1 7)" = "MSYS_NT" ]; then echo "Windows!" #./Build/Windows/node/node.exe ./Build/Scripts/Bootstrap.js buildeditor "$@" fi
結果
AtomicGameEngine $ ./Build_AtomicEditor.sh Mac!
オーケー
よく見ると、Mac、Linux、Windowsのどれも、node
っていう実行ファイルを実行してる。
で、その引数が、共通して./Build/Scripts/Bootstrap.js
っていうファイル。
javascriptでnodeって聞いたら、Node.js
だよね。
cd ./Build/Mac/node/
して、./node -v
とか./node -help
とかしたら、なんとなく確認できる。
Node.jsがBootstrap.js
を動かしてるわけだな。
あと、/Build/node_modules/
の中にあるのはNode.jsのモジュールだろね。
まさか、こんなところでNode.jsをかじることになるとは思わなかった(笑)。
じゃあ、Bootstrap.js見ていきますかな
Bootstrap.js
console.log()と、process.exit(1)を使いながら動作を追う。
18行目までは、多分パスとか設定してる。
20行目のvar cmd = config._[0];
はコマンドライン引数の受け取りだろう。
22行目から76行目までは実行されてないからとりあえず無視。
で、コマンドライン引数がbuildereditor
だったので、恐らく79行目のif文は通る。
85行目から137行目までも実行されないので無視。選択されてるプラットフォームで不具合があったらメッセージ出して終了するみたいな処理。
大事なのがこれ
83行目var buildTask = jake.Task['build:atomiceditor'];
140行目buildTask.invoke();
invoke
はモジュールの呼び出しだから、jake.Task['build:atomiceditor']
が分かれば次の処理が分かる。
とりあえず、console.log(jake.Task)
実行
{ [Function] super_: { [Function: EventEmitter] EventEmitter: [Circular], usingDomains: false, defaultMaxListeners: 10, init: [Function], listenerCount: [Function] }, getBaseNamespacePath: [Function], getBaseTaskName: [Function], runStatuses: { UNSTARTED: 'unstarted', DONE: 'done', STARTED: 'started' }, 'package:windows_editor': EventEmitter { _currentPrereqIndex: 0, ・ ・ ・ ・
モジュール?関数?毎に折りたたむと下になる
{ [Function] super_: 'package:windows_editor': 'package:mac_editor': 'package:linux_editor': 'build:atomiceditor_phase2': 'build:atomiceditor': 'build:genxcode': 'build:lint_typescript': 'build:precreateScriptBindings': 'build:genAtomicNET': 'build:genscripts': 'build:gendocs': 'build:gendoxygen': 'build:genmdoc': 'build:genexamples': 'build:android_native': 'build:ios_native': 'build:web_player': 'build:atomicnetdocs': 'build:atomicnet': 'build:lint': }
'build:atomiceditor'
ありましたね。
折りたたみを解除するとこんな感じ
'build:atomiceditor': EventEmitter { _currentPrereqIndex: 0, name: 'atomiceditor', prereqs: [], action: [Function], async: true, taskStatus: 'unstarted', fullName: 'build:atomiceditor', description: null, args: [], value: undefined, namespace: { name: 'build', parentNamespace: [Object], childNamespaces: {}, tasks: [Object], rules: {}, path: 'build' }, parallelLimit: 1 },
何もわからん(笑)。
タスクが集められたファイルがあるんだと思うんだけど、、、
プロジェクト内でatomiceditor
で検索すると1622件のヒットで探しようがねぇ。
絞れそうなatomiceditor_phase2
で検索すると、6件のヒット!
その内のファイルのBuild/Scripts/BuildMac.js
を見ると、それっぽいの発見
BuildMac.js
// Builds a standalone Atomic Editor, which can be distributed out of build tree task('atomiceditor', { async: true }, function() { // Always cleanly create the editor target folder host.cleanCreateDir(config.editorAppFolder); // We clean atomicNET here as otherwise platform binaries would be deleted var createDirs = [config.artifactsRoot + "AtomicNET/", buildDir, host.getGenScriptRootDir()]; var removeDirs = [config.artifactsRoot + "Build/Android/", config.artifactsRoot + "Build/IOS/"]; host.setupDirs(!config.noclean, createDirs, removeDirs); process.chdir(buildDir); var cmds = []; // Generate XCode project, AtomicTool binary, and script bindings cmds.push("cmake ../../../ -DATOMIC_DEV_BUILD=0 -G Xcode"); cmds.push("xcodebuild -target GenerateScriptBindings -target AtomicNETNative -configuration " + config["config"] + " -parallelizeTargets -jobs 4") jake.exec(cmds, function() { var rootTask = jake.Task['build:atomiceditor_phase2']; buildTasks.installBuildTasks(rootTask); rootTask.addListener('complete', function () { console.log("\n\nAtomic Editor built to " + config.editorAppFolder + "\n\n"); complete(); }); rootTask.invoke(); }, { printStdout: true, printStderr: true }); });
えーと、
"cmake ../../../ -DATOMIC_DEV_BUILD=0 -G Xcode"
"xcodebuild -target GenerateScriptBindings -target AtomicNETNative -configuration " + config["config"] + " -parallelizeTargets -jobs 4"
が実行された後に、atomiceditor_phase2
がinvokeされるっぽい。
で、atomiceditor_phase2
を見ると、
"xcodebuild -target AtomicEditor -target AtomicPlayer -configuration " + config["config"] + " -parallelizeTargets -jobs 4"
を実行した後に、同じファイルに定義されているcopyAtomicEditor()
とcopyAtomicNET()
が順番に実行されてビルド終了。copyAtomicEditor()とcopyAtomicNET()はビルドしてできたファイルを適切な場所に振り分けてるだけだと思うから特に意識しないでいいだろう。
つまり、
カレントディレクトリがAtomicGameEngine/Artifacts/Build/Mac/
で、
cmake ../../../ -DATOMIC_DEV_BUILD=0 -G Xcode
↓
xcodebuild -target GenerateScriptBindings -target AtomicNETNative -configuration RELEASE
↓
xcodebuild -target AtomicEditor -target AtomicPlayer -configuration RELEASE
の順で実行されて完成。
今回はここまでです!
次回は、cmake理解します。