TKSPのUnity関連ブログ

Unityに関することで書きたいことを書く.

1週間1人で広大なフィールドのRPG風ゲームを作った話(長い)

有料アセットが充実してきたので,長らく敬遠してきたRPGゲームに取り組んでみようと思いました.

f:id:ymtkyorosiku:20171129162040g:plain
© UTJ/UCL

今回はいつも作るような小規模なパズルゲームと違って,広大なエリアを走り回るようなゲームを作ってみました!
途中,これ本当にWebGLで動くのか?となりましたが,案外なんとかなりました.

では,まずはじめにこちらの有料アセットのサンプルシーンを読み込んで動かしてみます.

アニメーションの詰め合わせなのですがサンプルシーンもよくできていて,武器を変えたり,泳いだりすることができます.

しかしながらボタンの連続入力に弱いといった欠陥もありました.
(Unity ver 5.6.3p4,asset download 2017/11/26)

例えば,武器を連続で変えようとすると,前の武器が手元に残ったり,ジャンプを連続ですると,三回くらい飛べてしまったり,水の中から勢いよく飛び出すと,その勢いが空中でもそのまま適用されて,すごく高くまで飛ぶので不自然です(魚か!)

まぁここら辺は「連続入力時に一定時間同じ処理はできない」

//実行して良いか
bool cando=true;
//連続入力を受け付けない時間
float waittime=0.5f;
//何かで呼ばれる(キーが押された時など)
void ホニャホニャ() {
       if(cando){
       cando=false;
       //ジャンプするなどの処理
      ほにゃらら();
      StartCoroutine(wait(wartime));
     }
}
IEnumerator wait(float waiting){
	yield return new WaitForSeconds (waiting);
	cando = true;
}

みたいなことを施したりすればいいのではないでしょうか.

ではデフォルトのキャラクターをUnityちゃんに入れ替えます!
普通に,デフォルトのキャラクターをUnityちゃんのモデルに入れ替えてアニメーションコントローラーと,コンポーネントを同じように設定し,武器などを左手や右手のボーンの階層に移動させるだけです.

デフォルトの武器類を他のモデルに入れ替えます.今回は両手持ちの大剣のみ入れ替えました.モデルはこちらのアセットを使用しております.

ファンタジー系の内装を作るためのモデルが詰まったアセットですが,ポリゴン数削減のため,今回は剣のモデルのみの採用です.
Before 
f:id:ymtkyorosiku:20171129232738p:plain
After
f:id:ymtkyorosiku:20171129232751p:plain

次にこちらのアセットのサンプルシーンを読み込んでみます.

こちらは魔法のエフェクトの詰め合わせです.
先ほどのアニメーションの中に魔法を詠唱するアニメーションが入っていたので,詠唱後,何秒か後にprefab生成すれば魔法が使えるようになります.

プレイヤーの武器や魔法に当たり判定を追加します.効果処理は敵を作ってから考えましょう.


次にこちらのアセットをみてみます.

壁を破壊する機能が欲しくて購入を決めたのですが,如何せんサンプルシーンだけだと使い方がすぐには分からなかったです.
しかし,スクリプトから分割したオブジェクトを生成できるエディタ拡張のようでした.

まず空のオブジェクトにFracturedObjectコンポーネントをアタッチします.
そのあとパラメータを設定します.

壊したいオブジェクトを選択
f:id:ymtkyorosiku:20171128185349p:plain
とりあえずパーツがくっ付きそうな値を無限
f:id:ymtkyorosiku:20171128185355p:plain
あとは壊せるオブジェクト(今回は斧)が当たったらFracturedObjectからExplodeを呼び出す感じで.

//rcはRPGCharacterControllerコンポーネント,左の装備が3なら斧
void OnTriggerEnter(Collider col) {
         if(col.gameObject.tag == "BreakObject"&&rc.leftWeapon==3){
		if (wm.isAttack&&null!=col.gameObject.GetComponentInParent<FracturedObject> ()) {
			col.gameObject.GetComponentInParent<FracturedObject> ().Explode (gameObject.transform.position, 10);
		}
	}
}

壊れた際に崩れたところに張るテクスチャを設定していなかったり,オブジェクトを選択していなかったりすると,生成中にUnityが落ちてしまうので注意!(Unity ver 5.6.3p4,asset download 2017/11/26)

これでオブジェクトが破壊できるようになりました.
f:id:ymtkyorosiku:20171129161142g:plain
あとはプレイヤーにHPなどを設定し,表示します.表示の際にこちらのアセットを使用しました.

追記:ハートマークのテクスチャはこちらのアセットから使用していました.

このような感じになります.
f:id:ymtkyorosiku:20171201011810p:plain


プレイヤーが完成したら,こちらのスライムを使って敵を作成します.

そしたら,こちらのアセットを使ってステージを作成します.今回はWebGL出力のため
処理が軽くなるモデルを使用します.
2017/12/9まで半額だとぉ!半額開始の直前に買ってしまいましたw

そして,このアセットに入っている海の表面がデコボコしていてなんか嫌だったので,こちらのサンプルシーンの海面に切り替えます.

サンプルシーンのものそのまま移植したものをツイートしたら海面の色が濃いと指摘されたので色調を修正しました.


このような感じで.
海面
f:id:ymtkyorosiku:20171201011922p:plain
海中
f:id:ymtkyorosiku:20171201011949p:plain

スカイボックスを設定します.今回はステージを3つ作ったので,これまでにインポートしていた中に入っていたスカイボックスと
下記の二つを使用しました.
ステージ2のスカイボックス

ステージ3のスカイボックス

次に保存機能を作ります.保存にはこちらのアセットを使用します.
Transformも保存できるので,敵のHP情報や自分の位置などを保存する機能を作成します.

とても使いやすいのでオススメです.保存機能自作する場合プラットフォーム切り替えたら動かなかったりするしね.
今まで面倒だけど自作していましたが,これがあればもう安心です.

タイトル画面を作成します.
テンプレートをインポートし,プレハブを配置して,LoadGameボタンを追加します.このテンプレートには音量調整機能も付いているのでオススメです!

iTweenで動きをつけます.Twitterなどでよく目にするため,初めて利用してみたのですが,とても使いやすかったです.

そしたら画像のようになるので,音楽設定などを施し,UIのテクスチャを変更していきます.
f:id:ymtkyorosiku:20171129160337p:plain

使用したスカイボックスはこちらになります.

カメラを2つ使用し,スカイボックスでアセットの中に入っていた適当な画像と組み合わせました.

ボタンにはファンタジー風のこちらのアイコンを使用しました.

タイトルが完成したら,Unityちゃんのジャンプ音などを設定します.SEにはこちらを使わせていただきました.

武器のSEを設定します.こちらを使用しました.

BGMを設定します.こちらを使用しました.

隠し要素としてモブキャラを追加します.今回はただの飾りです.せっかく購入したので.敵のAIを超簡略化して,ただ移動するだけのスクリプトを作りアタッチします.


解き放て!
f:id:ymtkyorosiku:20171130014613g:plain

さて,最後に,終了処理を作成していきます.これは簡単で,HPが0になったらゲームオーバー.スライムを300体倒したらゲームクリアです!
曲はいつもの魔王魂様からお借りしております.

とりあえず定番の回復アイテムを導入.一回のみ使える回復アイテムをあちこちに配置します.保存機構がめちゃくちゃだよぉ.バグが出ないことを祈る.
アイテムのモデルは次のものを使用.

ここまできたらもう一度保存機構を見直しします.連続タッチでの再読み込みを防いだり,保存されているか確認したり,GL出力して動くことを確認したりですね.


さて,今回も約1週間ほどかけてゲームを作りましたが,予想よりも大規模なゲームとなりました.有料アセットを使用したおかげでそこそこのゲームになったのではないかなと思います.そして何より,作っていてとても楽しかった!アセットの使い方の勉強にもなりました.

そして,このくらいの規模だとオブジェクトの管理がとても大変になりました.そのため,管理をするためにこちらのエディタを導入しています.

今回はシーンを4つも使用しているのと,アセットを入れすぎた結果,中身が多すぎてめちゃくちゃになってしまったので,複数のエディタ拡張を用いて自分が分かりやすいようにしました.

まず,過去に開いたシーンをすぐに開くことのできるこちらを導入します.
保存機能の確認のためなどにシーンを行ったり来たりでしたので結構助かりました.

また,オブジェクト管理をするためにオブジェクトに付箋を貼り付けることができるアセットと

お気に入り登録をできるようになるアセットを導入して,大事なオブジェクトをすぐ発見できるようにしました.

そして,こんだけ大量にアセットがあると移動の際にミスってしまうのでカットアンドペーストができるようになるエディタ拡張も導入します.

プレイヤーのコンポーネントがずれていて整理がしたい場合などに入れ替えが楽になるアセットも導入して使っています.今回は1つのオブジェクトにコンポーネントが10個とかざらにあります.

コンポーネントと同じく,今度は配列の場所を入れ替えたいときにはこちらの並べ替えアセットが役に立ちます.

さて,保存関係がめちゃくちゃになってしまうのでタイトルに戻るが今回は使えなくなりました.(ベット処理作るのが面倒だったため)
そのためApplication.Quit()試してみたのですが,こちらはうまく動きませんでした.しかし,調べてみたらApplication.OpenURL("about:blank");という関数を発見しました.こちらはWebGLで使用すると,呼ばれたタイミングでゲーム画面を真っ白にして強制終了することができるようになります.しかし,URLの移動はないので,自分でリロードをするように促す何かが必要かもしれません.


さて,長くなりましたが,今回はRPG風ゲームをWebGLで作ることに挑戦しました!

やってみると色々と処理することが多く,わずか1週間ではかなりきつかったという印象です.
しかし予想よりも大規模なゲームになってしまい,自分でも驚いています.

今回は学校の授業が休みの日があったため,捗りました.
深夜までTwitterに進捗あげてるのがその証拠.

初めて使うアセットが大量にあり,仕様変更や,使い方の勉強など,するべきことは沢山ありましたが有料アセットの力を実感しました.

一番衝撃だったのはエディタ拡張でしたね.フリーのものでも,なんで今まで使っていなかったんだろうといった感じでした.

そして,RPG Character Mecanim というじゃじゃ馬がいましたが,こちらもスクリプトを改変して,思った通りに動いてくれたらつい楽しくなって徹夜してしまいました.

反省点として,マップが広すぎて前に進んでいるのに進んでいる感覚になれなかったり,暇な時間が長くなってしまったことですね.なんか乗り物や,ワープの魔法などを作った方がいいような気がしました.

また,敵の種類を増やしたり,行動パターンを追加したり,数を増やしたりイベントを追加したり(街に入ると音楽が変わる等)と凝ろうと思えばどこまでもできてしまいそうで終わりが見えなくなったので,とりあえず一区切りついたこの状態で投稿しました.(もともと有料アセットの使い方を習うために作ったので)
SEやボイスを追加したりスライム全部倒したらボスを出現させたり,色々とやりたいことが多すぎます.


最後に,一番見て欲しいのは雷魔法や氷魔法かもしれません.
狙った通りにスライムに当てるのが楽しいです.
f:id:ymtkyorosiku:20171130020145g:plain

スライムハンティング! | 無料ゲーム投稿サイト unityroom - Unityのゲームをアップロードして公開しよう

UnityRoomで公開しているので是非遊んでみてください!