武器や攻撃範囲の強化・武器の売買ができるお店システムの作り方

unity タワーディフェンスゲームの作り方

Unityの本格ゲーム制作講座はこちら
【30日間の全額返金保証付き】

前回(第8回)では、プレイヤーによる弓の配置と、UI画面を作り始めました。

前回の記事↓

プレイヤーの管理処理の作成 HPやゴールドの表示・弓矢のレベルアップ処理の作成
前回は弓(Bow)と矢(Arrow)を作成し、敵(Enemy)に攻撃できるようになりました。 前回の記事↓ 今回はプレイヤー(Player)を作成し、弓矢の配置やUI(HPなど)の表示をやっていきます。 プレイヤー(P...

今回はさらにUI画面を作り込み、弓オブジェクトのレベルや制作コスト・売却コスト等をやっていきます。

弓レベルの追加・コスト

まず弓のアップグレードが出来るように、弓にLVや、アップグレードコスト設定していきます。

スクリプト入れるためのフォルダ Assets/Scripts を第1回で作ってあると思いますので、今までに作成した各種スクリプトも都度Assets/Scriptsに移動しておきましょう。
それでは Assets/Scripts/Bowスクリプトを修正していきましょう。
  • 弓LV
  • LVに応じた攻撃範囲
  • LVに応じた攻撃速度
  • LVに応じたパワーアップコスト
  • LVに応じた売却額

を追加していきます。

順に説明していきましょう。

弓LVはメンバ変数 lv 宣言し、1にしておきます。

次にLvに応じた攻撃範囲用のプロパティ(ShotRange)を作成しています。

これはエクスプレッションボディ(expression-bodied)という書き方です。
= ではなく、 =>なので注意です。
ShotRange を参照する度に =>の右辺の式が処理されるイメージで考えておくと分かりやすいです。今回はlvが上がれば上がるほど攻撃範囲を広げたいので 1 + lv * 0.5f という計算式にしました。

Lvに応じた攻撃速度のプロパティ(ShotInterval)は次のようにしました。

lvが上がれば上がるほど攻撃速度は速くしたい(値を小さくしたい)ので Mathf.Pow 関数を使っています。
これは、第一引数 の値を 第二引数回乗算してくれます。すなわち0.9fをlv乗するという事です。

パワーアップコスト(Cost)はレベルアップさせるたびに高くさせたいので、100 * 1.5fのlv乗 を指定しています。

売却額(Price)はパワーアップコストの半分にしておきます。

そして、攻撃範囲や攻撃速度が今までは固定の数値でしたが、それぞれ ShotRange と ShotIntervalに差し替えているのが次の箇所になります。

保存をしてUnityEditorで挙動を確認してエラー等無いことを確認しておきましょう。

なお、今までの違いとしては若干攻撃範囲が狭くなり、攻撃速度が速くなっているはずです。

選択中の弓UI

既に配置をした弓をクリックすることで、内部的には選択状態(Player の selectBow に 選択した弓(Bow)が入る)になっていますが、画面上ではそれが分かりません。

選択中のBowの情報表示と、レベルアップや売却が行えるUIを作っていきたいと思います。

前回 PlayerStatusUI オブジェクトを作りました(Canvas/Iamge/)

これを複製(CTRL+D)して、PlayerStatusUI (1) を BowStatusUIと名前を変更し、同じく複製されているPlayerStatusUIは削除(右クリックしてRemoveComponent)します。
位置も重なってしまっているので Pos Yを下に下げます。 -260ぐらいが適当です。

選択中の弓に対するUIとしては

  • LV情報の表示
  • LVUPボタン
  • 売却ボタン

が必要になります。

子要素もそのまま複製されるため Text(HP)と Text(Gold)が BowStatusUI の子要素としてあるので、それぞれ下図のように修正します。

LvUpボタン

では、次にボタンオブジェクトを追加します。

HierarchyビューのBowStatusUIを右クリックして、UI→Buttonを選択します。

Buttonオブジェクトが作成されるので

  • 名前:Button(LVUP)
  • Source Image:tile

に変更します。

このButtonオブジェクトは最初から階層構造になっていて、Buttonの子要素にはTextがあります。Inspectorで設定していきます。

  • Font : Assets/Fonts/ShigotoMemogaki-Regular-1-01
  • Text : –
  • Font Style: BOLD
  • Font Size:40

次に位置・幅を修正します。
SceneビューのモードをRectToolに変更し(ショートカットキー:CTRL+T)

Button(LVUP)の幅と位置を調整しましょう。(間違って、Button(LVUP)の子要素のText(LVUP) を選択しないように気を付けましょう。)

今作った Button(LVUP) を複製(CTRL+D)し、さらに下に並べます。

名前は Button(SELL) としておきます。

BowStatusUI

では、選択したBowの情報をUIに反映させるスクリプトを用意します。

BowStatusUI に AddComponent→New Script → BowStatusUI として、BowStatusUIスクリプトを作成し、下記のように編集します。

は無いと、UIのコンポーネントが扱えないため必要となります。

次に

は、上から順に

  • どのPlayerの情報を表示するか(Inspectorで設定)
  • Player.selectBowのLV情報を表示するためのText(Inspectorで設定)
  • Player.selectBowのLVUPに必要なGOLD情報を表示するためのText(Inspectorで設定)
  • Player.selectBowの売却で取得出来るGOLD情報を表示するためのText(Inspectorで設定)

になります。

そして、

Update関数は毎フレーム呼ばれるので、その中でそれぞれのTextにPlayerが持っているselectBowの情報をセットしています。(Bowを選択していない状態の場合は全て – にします)

では、スクリプトの修正を保存し、UnityEditorで変数をInspectorで指定していきます。

プレイボタンを押し、エラーが出ないことを確認してください。

Buttonにイベントの登録

選択したBowオブジェクトのLvUp金額、売却金額がボタンのTextに表示されるようにはなっていますが、実際にボタンを押した時(OnClick)の処理は指定していないため、ボタンを押してもまだ何も起きません。

Button(LVUP) をクリックしたときには、選択中の弓(Bow)のレベルアップ処理がしたいです。これはタワーディフェンス講座 8/10で既に用意してありますね。 Player スクリプトの LevelUpBow()でした。

では、それをInspectorで指定していきます。

Button(LVUP)をHierarchyで選択します。
次にInspectorで、Button コンポーネントの下の方に On Click() という項目がありますので、+を押すことで、どのScript(Object)どの関数(Function) を呼ぶかが指定できます。

None (Object) となっている箇所にはHierarchyビューから PlayerオブジェクトをドラッグアンドドロップしNo Function となっている箇所はドロップダウンになっていますので Player → LevelUpBow () を選択します。

これで、Button(LVUP)ボタンをクリックしたら、PlayerのLevelUpBow() が呼ばれるようになりました。

では復習として同じように、Button(SELL)ボタンもクリックしたら、PlayerのSellBow() を呼ぶように設定してみましょう

設定を終えたらこのような状態になるはずです(この画像ではRect Transformは折りたたんであります)

設定できたら、プレイボタンを押して、実際にレベルアップや売却が出来るか試してみましょう。

ボタンが反応しているようではありますが、

  • 弓のLVが上がっていない(攻撃が強くなってはいない)
  • 売却金額が表示金額と一致していない

という問題がありますね。

これはボタンクリックから呼び出されるPlayerスクリプトがまだ未完成・弓(Bow)スクリプトにLVの概念が無い状態で作成したままの状態・だからです。

Playerスクリプトの修正

では、Playerスクリプトを修正していきます。

Playerスクリプトの LevelUpBow関数は以下のように、レベルアップに必要な金額が固定値(150)と書いてしまっています。
また、TODOコメント で、弓のレベルアップをする と書いてあるだけで、弓のレベルは上がっていません。

今回Bowスクリプトには、lvというレベルを示す変数を用意しましたし、レベルアップに必要な金額をCost というプロパティも用意したので、それらを使用して以下のように修正します。

同じく売却金額が表示金額と一致しないのは SellBow関数に、売却金額が固定値(50)と書いてしまっているからです。

これも今回Bowスクリプトに追加した、Priceというレベルに応じて変化するプロパティを用意したので、それを使用して以下のように修正します。

TODOコメントは「未来の自分への警告」です。
TODOコメントが残っている。ということはそのゲーム・スクリプトが未完成である。という事です。逆に修正をしたらTODOコメントは消す、または正しいコメントに修正しましょう。
非常に細かい事ですが、それがバグややり残しを減らす事につながります。
Playerスクリプトの修正後は以下のようになります。

変更を保存してUnityEditorで再生をし不具合が修正されているか確認してみましょう。

攻撃範囲の表示

大分それらしくなってきましたが、

  • やっぱりどの弓を選択しているかわからない
  • 弓の攻撃範囲がわからない

という問題があります。これを一気に解決するために「選択中の弓の攻撃範囲を表示する」ようにしましょう。

攻撃範囲なので ShotRange オブジェクトを作成していきましょう。

Hierarchyビューに、新規オブジェクト(CTRL+SHIFT+N)を作成し、新規ScriptもAddComponentしておきます(いつもの流れですね)

  • 名前:ShotRange
  • スクリプト名:ShotRange

次に攻撃範囲の画像として、Assets/Images/effect_blastLargeを使います。

このeffect_blastLargeHierarchyビューの先ほど作ったShotRangeオブジェクトの子要素になるようにドラッグアンドドロップし。

この子要素として配置されたeffect_blastLarge

  • Order in Layer を 20
  • Color を 黄色の半透明

にしておきます。

ShotRangeスクリプトの修正

次にShotRangeスクリプトを以下のように修正します。

メンバ変数

選択中の弓の攻撃範囲を表示する が目的ですから、どの弓を選択しているか、を持っているPlayerが必要になります。

また、攻撃範囲の画像を選択中の弓(bow)の位置に移動させることで、攻撃範囲を表示するので、画像(SpriteRenderer)も必要になります。

Update関数

そしてUpdate関数で、選択中の弓(player.selectBow)がある場合は、攻撃範囲画像(rangeRenderer)を攻撃範囲分(player.selectBow.shotRange)分広げ(ただし、Bowが持っている攻撃範囲は『半径』なので、2倍します)選択中の弓が中心になるよう移動させて表示。
逆に選択中の弓が無い場合は、攻撃範囲画像は非表示にしています。

Inspectorでセット・確認

では、忘れずにスクリプトを保存し、UnityEditorのInspectorで変数をセットしていきます。

設定が出来たら実際に確認してみましょう。

おさらいと次回予告

今回は弓関連のUIを追加し、レベルアップや売却が実際に出来るようになりました。

次回はついにこのタワーディフェンス講座 も最終回。タイトルやゲームクリア・ゲームオーバーなどの「ゲームループ」部分を主に作って完成させていきます。

次回の記事↓

【ゲームの完成】ゲームループ処理の作成とレベルデザイン
前回(9回)は弓関連のUIを追加し、レベルアップや売却が実際に出来るようになりました。 前回の記事↓ 今回はついにこのタワーディフェンス講座も最終回。タイトルやゲームクリア・ゲームオーバーなどの「ゲームループ」部分を主に...

Unityの本格ゲーム制作講座はこちら
【30日間の全額返金保証付き】
【必見】無料資料請求でスクエアエニックスのゲーム開発の企画動画が見れる学校アリ
令和時代のゲームクリエイターになるための必須スキルがUnity。未経験からでもUnityを学んでオリジナルゲーム制作&ゲーム会社就職が可能なゲーム専門学校・プログラミングスクールの情報をオンライン&対面形式に分けてまとめました。 無料資料請求でスクエアエニックスのゲーム開発企画の動画もらえるので見てみるといいですよ。
unity タワーディフェンスゲームの作り方
unity入門の森 ゲームの作り方

コメント

  1. サウスケイ より:

    BowStatusUIを作ったタイミングで

    Assets/BowStatusUI.cs(23,40): error CS1061: ‘Player’ does not contain a definition for ‘SelectBow’ and no accessible extension method ‘SelectBow’ accepting a first argument of type ‘Player’ could be found (are you missing a using directive or an assembly reference?)

    とエラーが出てしまいます。どうしたらいいか教えて欲しいです。

    • サウスケイ より:

      BowStatusUIの最初のコード画像で23,24,25行目がSelectBowになっていました。
      それをselectBowに書き換えたところ、実行することができました。

タイトルとURLをコピーしました