ゲーム化!tomo_manaのブログ

ゲーム化!tomo-manaのブログ

Unityでゲームを作る方法について紹介しています

Unity学習#18 (Unity 2019.4.1f1) アイテムとステータス

今回はリストにアイテムを表示させるに先立って、アイテムとステータスを定義します。

ステータス

アイテムはステータスを増強するものと捉えて、先にステータスを定義します。

項目

第11課で、ゲームの駆け引きを生む最低限の要素として、以下の3要素を挙げていました。
●体力(消費の対象)
●削る力(消費の単位)・・・攻撃力
●削る速さ(消費行動の優先度)・・・速度

体力は消費の対象なので、最大値と現在値を定義します。

次に、体力、攻撃力、速度の値域を決めるために、最小値と最小値について考えます。

最小値

●体力の最大値=0:存在できない→0になってはいけない
●体力の現在値=0:生きられない→ゲームオーバー
●攻撃=0:生き抜けない
●速度=0:動けない(自力で生き抜けない)

いずれも最小値は致命的です。駆け引きに必要な最低限の要素なので、どれかが欠けても駆け引きが成り立たなくなります。そのため、通常は体力の現在値は 0 を許容(ゲームオーバー)として、攻撃力と速度は 0 を避けるか、0 でも何らかの行動が取れるように補正をかけると思われます。これは一人旅か仲間がいるかによって変わるため、ゲームバランスの要素も含まれます。

今の段階では、攻撃力と速度が最小値を取れなくするような制限はかけないものとします。体力の最大値は、0 を取らないようにする必要があります。

最大値

●体力の最大値=無限大:回復が持つ効果が大きい
●体力の現在値=無限大:死なない
●攻撃力=無限大:敵なし
●速度=無限大:システムによる

最大値を考えるにあたって、まず駆け引きが成り立たなくなる(無敵)領域について考えました。最大値は自分だけでなく対決する相手のステータスとのバランスになります。何を最大とするのかはとても重要そうです。

データの最大値と表示の最大値

無限大(無敵)というのはあり得ないとして、最大値にはゲームプレイヤーから見える表示上の最大値(10進数)と、ゲームプレイヤーからは見えないデータ上の最大値(2進数)の、2つの制限があります。
たとえば体力の表示欄に4桁の制限を付けたら最大値は9999ですが、データ上は2進数のため、9999以上の値となる最小値として、16384(2の14乗) が最大値になります。

今はfloatやdoubleなどの浮動小数点計算が普通に使われており、気にすることもないのかもしれませんが、演算が今より遅かった頃は、データの最大値はゲーム機に搭載するCPUのレジスタ幅も考慮していたと思います。例えばファミコンは8bit CPUのため、できるだけ2の8乗まで(0-255)の値になるようにするか、2の16乗まで(0-65535)の値になるように、値域を設定していたと思います。

また、後述する保存領域の制限も大きかったと思います。

保存容量による制限

ステータス情報は、プログラムとは別の不揮発領域に保存する必要があります。最近は不揮発領域が増えたり、データのクラウド化も進んだので、一つのゲームが不揮発領域を占有するよりかは、スマートフォンやパソコンの一枠を間借りするか、ゲーム機のメモリの一部を間借りすることがほとんどかと思います。それでも、他のアプリなどと不揮発領域(リソース)を共有するため、少ない容量で管理できることに越したことはありません。

オフラインで行うゲームで、プログラムもステータス情報も同じ不揮発媒体(メモリなど)に保存する場合は、画像やテクスチャの方がよっぽど大容量でしょう。オンラインゲームで、サーバ上でステータスを管理する場合、ステータス情報は頻繁にやり取りされるため、データ幅を小さくするために、容量の検討は価値があるかもしれません。

厳密には、保存容量をバイト単位にしない場合は、データの送受信の度にデータを圧縮・解凍する処理時間とのトレードオフになります。それも、3Dのレンダリング処理に比べたら、気にするほどでも無いでしょう・・・

いろいろ考えましたが、とりあえず最大値はゲームバランス重視で決めれば良いと思いました。今の段階では、仮で容量を決めます。

最大値と最小値の差

これはどちらかというとゲームバランスの観点になります。取りうる値が大きいことは振れ幅が大きいことを意味します。値が大きくなると成長を感じやすい反面、強い状態と弱い状態との差が激しく、成長して強くなりすぎる(難易度が下がる)などのデメリットもあるかもしれません。

ただ、駆け引きの点では、値そのものの大きさよりも、対立する相手の平均的な攻撃力とプレイヤーキャラクターの体力との比率の方が重要かもしれません。たとえば、体力が9999あっても、敵の平均的な攻撃が1000近いとすれば、体力が999あって、敵の平均的な攻撃が100近いのと変わりませんし、むしろ値が大きい方が分解能が大きくなります。これは、いずれ駆け引きについて考えるときに、考えることにします。

アイテム

アイテムの効果

アイテムの効果は、ステータスに一定の強化または弱化を一定時間与えるもの(付与)と、体力の現在値を回復または減らすもの(回復)があります。対立する相手に効果を及ぼすものは、駆け引きについて考える時に考えたいと思います。

要素

ステータスを一定時間の間強化または弱化するアイテムの効果を記述するには、以下の要素が必要そうです。

●対象となるステータス
●効果時間
●値(プラスとマイナス)
●値の単位(絶対値、パーセンテージ)
●何回使えるか(摩耗)

付与の例

たとえば、付与について、「ほうれんそう=5分間、攻撃力を20%UP」 だった場合、以下のようになります。

パラメータ
対象となるステータス 攻撃力
効果時間 5分間
+20
値の単位
何回使えるか 1
回復の例

回復についても考えてみます。たとえば、「パン=体力の現在値を30だけ回復する」場合、以下のようになります。

パラメータ
対象となるステータス 体力の現在値
効果時間 恒久
+30
値の単位 絶対値
何回使えるか 1

回復は、ステータスに不可逆的な影響を与えると考えると、付与ではなく体力の現在値の書き換えです。

時間制限があるかどうか

アイテムは、付与と回復という区分よりも、時間制限の有無に着目して、時間制限あり(付与)となし(書き換え)に分ける方がうまく分類できそうです。

不可逆かどうか

「効果時間が恒久であるものは書き換えとみなす」ことにしようと思ったのですが、実際は無限に長いアイテム効果を与えるものを付与した状態で、アイテム効果を無効化された場合、恒久だけれども付与(不可逆的ではない)、ということもあり得ます。その意味で、恒久には不可逆かどうかが重要になります。

●対象時間: enum{不可逆、恒久、有限時間・・・}

複数の効果

一つのアイテムが複数の効果を持つことも珍しくないと思います。そのため、アイテムはアイテム効果のリストを持ちます。これで、ステータスの強化・弱化を持たないアイテムも将来的に対応できます。

●アイテム→List<アイテム効果>

アイテム効果の付与

アイテム効果の付与は、アイテムごとに効果時間があると思います。ゲームプレイヤーはトータルでプレイヤーキャラクターがどれくらい強化または弱化されているかを気にしますが、システムとしてはどのアイテムの効果があとどのくらいの間付与されているかを気にします。

そのため、ステータスはアイテム効果の付与について、適用中のアイテムとその残時間(または経過時間)のリストを持ちます。

●アイテム効果の付与: マップ<アイテムID, 経過時間>

歩数、あるいはリアルタイム時計の時間経過によって、ゲーム上の時間が経過する毎に、上記リストに追加されたアイテムは、経過時間が加算されます。アイテムが持つすべての効果が時間切れとなった場合、付与リストからそのアイテムが消滅します。(一つのアイテムが複数の効果を持ち、効果ごとに効果時間が定義されているため、このような表現になります)

アイテムの装備

アイテムの使い途として、時間制限付きで付与する以外に、装備することもあります。これはただ持っているだけかもしれないし、選んでいる状態かもしれませんが、プレイヤーキャラクターに対して一定のアイテム効果を発揮します。装備の場合、効果時間よりかは、耐久力(摩耗)を考慮すると思います。
付与と装備の違いは、この耐久の考え方の違いと思われます。付与は消費して時間制限付きの効果を与えます。装備は効果を与えますが、時間制限よりはむしろ使用回数制限(耐久)付きの効果を与えます。似ていますが、時間制限と使用回数制限は分けた方が良さそうです。

武器の例

たとえば、「木の棒=攻撃力+10だが10回で壊れる」場合、以下のようになる。

パラメータ
対象となるステータス 攻撃力
耐久力 10
+10
値の単位 絶対値
防具の例

今は防御力は考慮していませんが、防具についても、似た概念を適用できると思います。
たとえば、「木の盾=体力の最大値+10パーセントだが5回攻撃を受けたら壊れる」場合、以下のようになります。

パラメータ
対象となるステータス 最大HP
耐久力 5
+10
値の単位 パーセント
装備の数

装備できる武器の数は一つとは限りません。二刀流なら2つの武器で攻撃します。また、右手と左手のように部位に分けた時には、部位ごとにアイテムを持ちます。

●武器、防具 = List<アイテムID、使用回数>

武器は攻撃した時、防具は攻撃を受けた時に消費します。盾で攻撃できる時はどうするか悩みますが、その時は別途考えます。

アイテム効果の参照(アイテム辞書)

メニュー用に、アイテム毎に取りうるアクションをまとめます。
●使うことができる
●装備することができる
●捨てることができる(!)
昔のゲームの中には、捨てたら絶対にクリアできなくなるアイテムを捨てられる仕様が存在しているものがありました。捨てられるかどうかは重要です!

アイテム辞書は先ほどのアイテム効果と組み合わせて、以下のリストになります。
⚫︎アイテム辞書 = <List<アイテム効果>, List<bool>>[アイテム数]

アイテムの残数管理

アイテムの保持は、同じアイテムを束ねて表示したり、同じアイテムでも列挙したりすることもあります。持ち物に最大で保持できる数や、入手できる回数に制限を付けたりすることもあります。そのため、保持するアイテムには、数量があります。

順序管理

保持するアイテムは、拾った順に登録するものとします。

保持するアイテム量が少なく、アイテムの種類が少ない間は、アイテムを拾うたびに前方検索でアイテム数を増やせば良いのですが、保持できる量かアイテムの種類かのどちらかでも数が多くなると、前方検索では処理時間が無駄になります。また、数量制限や取得数制限なども加味すると、全部のアイテムの拾い状態を配列で持つ方が効率がいい可能性もあります。全部のアイテムの拾い状態をテーブルで持てば、アイテムの数が多くても、検索時間はいつも最小になります。

●アイテム残数管理 = アイテム数量[アイテム数]

相関図(UMLクラス図)

アイテムとステータスの要件をまとめると以下になります。
●ステータスには「要素」と「最大・最小・値域」という要素がある。
●アイテムはステータスの強化・弱化に特化すると、その効果の及ぼし方には「付与」と「装備」とがある。
●アイテムの「残数管理」がある。
●アイテム効果の参照を行う「アイテム辞書」がある。

(クラス図)

f:id:tomo_mana:20200925001626p:plain
クラス図(ステータスとアイテム)

説明には出てきませんでしたが、キャラクターはあるパーティーに属すると思います(それが一人旅でも)。また、当然アイテムには「アイテム名」があります。

次回やること

メニューにアイテムを表示させて、アイテムを使用できるようにする。