この記事はLumberyard Advent Calendar 2017の25日目の記事です。
Lumberyard Advent Calendar 2017 - Qiita
環境
Lumberyard 1.12.0.0
参考資料
プレイヤーが移動するまでは下記2つを追ってもらえれば同じようなのができます!
【Lumberyard】Script Canvas入門 - ユーセンブログ
Script Canvas Tutorials - Lumberyard
空のレベルの作成
ScriptCanvasに入る前に適当にレベルを作成しておきます。
プロジェクトは新規作成したものでも、既存のものでも問題ありません。
新規プロジェクト作成方法はこちら
papersloth.hatenablog.com
もし、Defaultで作成できなかったという時はEmptyも試してみてください。
プレイヤーの作成
続いてPlayerを作成していきましょう。
Entitiy OutlinerかViewport上で右クリックして
Create entity
名前を変更したいので、Entity OutlinerかEntity Inspectorから
名前をPlayerに変更
このままだと空のEntityなので、見た目を追加します。
Entity InspectorからAdd Compoenent
RenderingカテゴリのMeshを追加
まだ見た目がないので、設定していきましょう。
MeshComponentのMesh assetを選択
Engine > EngineAssets > Objects > Default.cgfを選択
この時に面、頂点、LOD、マテリアルの情報とプレビューが表示されるのは見やすいですね。
とりあえずプレイヤーの見た目は一旦これで終了です。
ですが、このままだと何も起こらないので次は物理を追加しましょう。
再びAdd Componentから
Physics > Rigid Body Physicsを追加しました。
Unityユーザーには馴染みがあるかもしれませんね。
次に入力を取れるようにします。
このあたりはtachi1427さんの解説と重複している箇所があるため
読み飛ばしていただいても問題ありません。
【Lumberyard】Script Canvas入門 - ユーセンブログ
Lumberyardでは空のEntityでは入力の取得ができない仕組みになっています。
Add Componentから Gameplay > Input
入力の設定ファイルを作成します。
Input to event binding内にアーケードコントローラーみたいなボタンを押します。
するとAsset Editor Windowが開くので、
File > New > Input bindingを選択します。
(ProjectName) > inputbinding内に
player.inputbindingsを追加しました。
作成するとこんな感じになります。
もし、反映されていなければ
File > Openから探して開きましょう。
続いて入力イベントを登録していきます。
Input Event Groupの+ボタンを押下します。
MoveX(左右)とMoveY(前後)を登録しました。
LumberyardはZ-upなので、Yが前後になりますね。
続いてMoveX, MoveYにそれぞれどのキーを割り当てるかを登録していきます。
Event Generators > +
Inputクラス作成のダイアログが出るのでOKを押します。
するとEvent Generatorに登録され
Input Device TypeやInput Nameが設定可能になりました。
とりあえずは前後移動のWSキーを登録しました。
左右移動のADキーも同様に追加します。
全て追加したらFile > Saveを選択して保存します。
作成はされましたが、登録はされていないので登録します。
Playerを選択してInput > Input to event bindingsに作成したplayer.inputbindingsを追加します。
一旦はこれでプレイヤー周りのコンポーネントの追加、作成は完了です。
いよいよScript Canvasに入っていきます。
Playerの処理の追加
さぁ、ようやくScript Canvasの記述です。
先ずはScript Canvasを開きましょう。
Tools > Script Canvas(PREVIEW)です。
Script Canvasを開いたらFile > New ScriptかCtrl + Nで新規作成します
一旦ここで保存します。
File > Save(Ctrl + S)かFile > Save as...(Ctrl + Shift + S)です。
Lumberyard/1.12.0.0/dev/(ProjectName)/ScriptCanvasにPlayerController.scriptcanvasで保存しました。
早速処理を書いていきましょう。
操作はUE4のBlueprintを触ったことがある人は入りやすいかもしれません。
先ずは入力の取得から。
Script Canvas上で右クリックし、inputと入力すると下記のようになります。
Input Handlerを選択しましょう。
MoveXとMoveYとLogを下図のように繋いで先ずは入力が取れているか確認します。
playerを選択してAdd ComponentでScript Canvasを追加します。
Script Canvas Assetの参照も追加します。
先程作成したplayercontroller.scriptcanvasを割り当てたら
実行してWASDキーを押下して、WDで1.0、ASで-1.0が出力されることを確認します。
入力が取れていることが確認できたら移動処理を書きます。
移動にはMove Entityノードを使います。
Sourceは移動ターゲット
Directionは移動方向ですね。
ですが、InputのValueとMoveEntityのDirectionは接続できません。
Number型とVector3型でScript Canvasでは自動でキャストしてくれないからですね。
Constructノードを使ってNumberからVector3を生成します。
同様にMoveYも組んでみると上下左右に移動できると思います。
ノードの複製はCtrl + Dで行えます。
これで動かしてみるとすごく高速移動します
続いて速度の補正を加えることにします。
Multiplyノードで0.1をかけ、1/10の速度にします。
どちらも同じ値なのでとりあえず変数にまとめちゃいます。
Create Variable > Numberで作成します。
Speedという名前で保存しました。
これで1/10の速度で動いてだいぶいい感じになりました。
カメラの追加
動画を見ての通り、カメラ処理がないのでカメラを追加していきます。
先ずはカメラの作成から。
Create Entityして、Camera Componentをつけるだけ!
ですが、これだと動かしてもカメラの位置が変わらないので
Playerの子にすることで追従します。
この辺はUnityと同じですね。
また、位置も調整して少し斜め後ろから見下ろすようにしました。
動かすと分かりますが、少し酔いますね。
カメラの追従を緩やかにする。
このままでもカメラは追従しますが、動きが早いと酔ってしまうので緩やかにする追従するようにします。
UnityだとVector3.MoveTowards, UE4だとVInterpToでサクッと実装できますが
Lumberyardでそれに該当する関数が見つけられなかったので、自作していきます。
CameraRig Componentを活用すればもっと楽に実装できる気もします。
CameraにScript Canvasを追加し、新規にCamera Managerという名前で追加しました。
Camera側でPlayerを参照するには
Playerを選択した状態でReference Selected Entityを選択します。
UE4のLevel BlueprintでLevel上のActorを取得する時と同じようなイメージですね。
先ずはCameraとPlayerの距離ベクトルをDistanceという変数を作成し、保存します。
On Graph StartノードはUnityでいうStart, UE4でいうBeginPlayです。
次は長いので、小分けに説明していきます。
OnTickノードはUnityでいうUpdate, UE4でいうTickです。
InterpSpeed, Offsetという変数を作成しました。
InterpSpeedで追従の速度を調整することになります。
次にPlayerの位置に先程のプレイヤーからカメラの距離を加算します。
この値をカメラの座標にセットすると親子階層にした時と同様に固定距離でべったり貼り付くカメラになりますね。
計算がもう少しだけ続きます。
Playerにカメラとの距離を加算した値からカメラの位置を引きます。
その値に先程求めたOffsetを掛けます。
最後にその値をカメラ座標に足してやれば完成です。
全体像が見えるように折り返して写しました。
中でやってる計算はUE4のVInterpToの簡素なバージョンです。
また、このままでは正常に動作しないため
CameraをPlayerの子階層から外しておきましょう。
計算が多いのはノードエディタと相性が悪いため、LuaかC++で書いた方がいいですね。
関数の作成方法や独自のノードの作成方法が分かればリファクタリングしたいところです。
とりあえず動きとしてはよくなってきました。
弾を撃つ
続いて攻撃処理を作っていきます。
移動できて、弾が撃てて敵が倒せればゲームが作れそうですよね。
先ずは弾となるEntityを作成します。
Create Entityをし、Projectileと命名しました。
Meshを追加し、SampleProject > Objects > default > primitive_sphereを使用します。
サイズも大きいので、Scaleを0.2にしておきます。
次にコリジョンを追加します。
Add Component > Rigid Body Physics, Primitive Colliderを追加します。
Primitive ColliderのAdd Required Componentから
Sphere Shapeを選択します。
Primitive ColliderのSource Typeにはmat_defaultを設定します。
続いて弾の移動処理を追加します。
ProjectileにScript Canvasを追加して、Projectileという名前のScript Canvasを追加しました。
処理は開始時にY軸方向に100倍した値を速度として渡しています。
因みにこのY軸の値は必ずしも1.0ではありません。
最後に弾の消滅処理を書きます。
DelayとDestroyを使うわけですが、Script Canvasは少しおもしろい書き方ができます。
削除は下図の形でつなぎます。
Delayで3秒後に自身をDestroyします。
Script Canvasでは1つのOutピンから複数の入力ピンにつなげることができます。
UE4ではSequenceノードがその役割を果たしていますね。
弾の処理に関しては一旦これで終了です。
弾をSliceとして登録する。
スライスと動的スライス - Lumberyard
SliceとはUnityでいうところのPrefabです。
UE4ではClass Blueprintが近いですね。
Lumberyard/1.12.0.0/dev/(ProjectName)/slicesに保存しました。
Sliceとして保存するとEntity Outliner上で青く表示されます。
ドキュメントを読めば書いてあるのですがこのスライスは実行時に生成ができません。
そのため、動的スライスとして登録します。
先程作成したSliceをAsset Browser上から探し、右クリックでSet Dynamic Sliceを選択します。
これで動的スライス(DynamicSlice)として登録され、実行時の生成が可能になりました。
実行して、弾が無事に飛んでいくことを確認すれば、Entitiy OutlinerからProjectileを削除します。
プレイヤーから弾を撃つ
弾が登録できたので、次はプレイヤーから撃ちます。
Player EntityにSpawnerを追加します。
Dynamic Sliceに先程登録したProjectileを設定します。
次に発射ボタンの登録を行います。
player.inputbindingsを開き、Fire Eventとしてマウスの左ボタンを追加しました。
この時、保存を忘れないようにしましょう。
PlayerControllerのScript Canvasを開き、先ずはログで入力の確認。
左クリックで-1が出力されれば入力が取得できています。
弾の発射処理はこれだけです。
SpawnがSelfになっていることに違和感を感じた方もいるかもしれませんが、
これはSpawnerに登録されているDynamic SliceをSpawnするという意味なのでこれで問題ありません。
ちょっと見た目を変えたりしておしまい。
まとめ
なんとなくゲームを作る雰囲気が見えてきたでしょうか。
幾つかやり残したことがあって次回の課題としたいと思います。
・カメラの回転
カメラ追従にこったりせずにこっちを実装すればよかったと今更思います。
・エフェクトの発生
弾を撃つ時、弾を当てた時のマズルフラッシュと爆発エフェクト
・サウンドの再生
発射音、ヒット音の再生
・敵の追加
AIを作るには時間が足りないのですが、当たり判定の解説用に作ればよかったところです。
・UIの作成
Hit Pointや制限時間などなど
・キャラクターのアニメーション
これに関しては資料というかサンプルが豊富なので、なんとかなりそうです。
1.12からシステムが変わったようなので、時間を作って解析したいところ。
・Levelの遷移
Level遷移は少し資料を探すのが大変そうで難しいかなと思っている点です。
Forumを探したら意外と直ぐに見つかる気もします。
一先ずゲームを完成させた!というにはまだまだ解説する要素が足りなかったですね。
ですが、Lumberyardは2018年で大きく変わるようですので、本当に楽しみです。
来年のAdvent Calendarをもっともっと盛り上げていければと思います。
最後までお付き合いいただき、ありがとうございました!