UE4の勉強記録

UE4の勉強の記録です。個人用です。

「Unreal Engine 4.xを使用してRPGを作成する」の足りない部分を作成する Inventory Systemの改善Part5

f:id:kazuhironagai77:20200216205555p:plain

<前文>

前文ではゲームデザインに関係ある話だけ書くように前回から決めたのでコロナウィルスについての私見を述べたかったのですが止めて「宇崎ちゃん」献血ポスターと異世界レビュアーズ打ち切り問題についての私見を述べます。

どちらも最初は問題なかったのにアメリカ人からイチャモン付けられてその結果日本でも大問題になってしまった作品です。

バイリンガルな私が紹介しますが、実はアメリカ人からのイチャモンに対抗する秘策があるんです。勿論英語が出来ないと使えませんが、これ知るだけでアメリカ人からのイチャモンの9割は避ける事が出来る優れものです。

一般的なアメリカ人は世界は3種類の人間で構成されていると信じています。白人、黒人、黄色人種ではありません。羊、狼、羊犬(Sheep dog の日本語訳は牧羊犬ですが、Sheep dogの正しいニュアンスを持っていないので羊犬と直訳しました)です。キリスト教は元々、放牧民の間の宗教から発達したので、何でも羊に例えて説明します。羊は一般人、狼はその一般人を襲うならず者、そして羊犬は狼から羊を守るヒーローです。

この考え方、余りにも単純すぎて色々批判されています。しかし簡単で誰でも理解出来るので結果的にこの理論に基づいてアメリカ人は行動します。

例えば「宇崎ちゃん」献血ポスターにイチャモンつけたアメリカ人は羊犬として行動しています。羊犬の仕事は狼と戦うだけではありません。群れから外れた羊を群れに戻すのも仕事です。つまり道徳という群れから外れたアホな羊(宇崎ちゃんを献血ポスターに使用した事)を群れに戻す。と言う羊犬としての正しい行動をしている訳です。

異世界レビュアーズ打ち切りはCrunchyrollかNetflixか良く知らないですが羊として行動しています。「このアニメを放送したらアメリカ社会から羊ではなく狼と見なされてしまうので放送を中止します。」と

 この考え方の恐ろしい所は狼と認定されたら死ぬまで追い込まれる所です。

日本みたいに「狼カッコイイは。」と言うのはありません。狼は完全に死ぬまで追い込まれます。

絶対に狼と認定されてはいけません。

私が考える狼の条件は、

  1. 一般人(羊)を食い物にしている。
  2. 女、子供を商品として商売している。
  3. 一般社会から追放されている。
  4. 犬を虐める。

などです。一番の具体的な例を挙げると、著作権を持っていないのに侵害されたと訴える会社とか、お金のためだけに働く弁護士とかですが、日本で言えば暴走族のような半グレなんかも入ります。ちなみにアジアで暮らしている白人男性は大体、本国の社会から追放されてるんで、3番に該当するんでそこは必ず突っ込んでおくべきです。

ここで問題もあります。2番の「女、子供を商品として商売している。」ですが「宇崎ちゃん」献血ポスターと異世界レビュアーズがここに該当していると思われてしまった事なんです。しかし現実は絵ですから。「実際に女、子供を商品として商売している。」に該当していると考えるのは、現実と空想の区別の付かない精神のオカシイ人じゃないの?と言う反論は必ず出来ます。

4番の犬を虐めるとは狼に絡めた冗談と思うかもしれませんが、アメリカ人は本当に犬好きです。人間より大切にしています。「あの人犬虐めてました。」と言われたら、一発で狼認定されます。

この秘策を知ったからと言って、いきなりアメリカ人と議論するのはボクシングの試合に飛び入りでチャレンジするようなものですから大変危険です。何処かのネットで匿名で練習して十分自分のものにしてから実践しましょう。この羊、狼、羊犬理論はアメリカ人からのイチャモンと戦うのに必ず使えます。相手を狼であると認定出来れば勝利です。

それでは今週の勉強を始めます。

<本文>

前回の続きをやって行きます。

1.バグの整理

まず、前回直さなかったバグや新しく出て来たバグをまとめます。

  1. 素手を武具にしています。装備を外すボタンを作成して素手を武具から外します。
  2. 装備している武具を売る事が出来ます。
  3. ATKの値をGameCharacterクラスのATKで管理するのかFieldPlayerのSoldierbaseAtkするのか
  4. 武具を売った後に画面に売却した武具の絵がずっと表示されています。
  5. 防具の装備
  6. 装備した時に今より何が強くなるのか不明。
  7. デザインの改善

これくらいでしょうか?

それでは、直していきましょう。

2.ATKの値をGameCharacterクラスのATKで管理するのかFieldPlayerSoldierbaseAtkするのか?

順番が前後しますが、これをしっかり把握しないと、他の部分を変更するのに大変な事になりますので、これからやります。

レベルブループリントに以下のコードを組んで、GameCharacterクラスのATKとFieldPlayerのSoldierbaseAtkを画面上にプリント出来る様にします。

f:id:kazuhironagai77:20200216205734p:plain

ゲームを開始します。

f:id:kazuhironagai77:20200216205757p:plain

開始直後の値です。

武器屋で短剣(小)を買いました。

f:id:kazuhironagai77:20200216205817p:plain

値は変化していません。

短剣(小)を装備しました。

f:id:kazuhironagai77:20200216205836p:plain

GameCharacterクラスのATKの値が15、SoldierBaseATKの値が5に変化しました。

これを見ると、SoldierBaseAtkはキャラクターの基礎ATKをキャラクターが武器を装備している間、保持しておくみたいですね。

武器を外しました。と言っても、武器を外すのボタンはまだ作成していないので、素手を装備しました。

f:id:kazuhironagai77:20200216205902p:plain

あれ、攻撃力が3になってしまいました。

兵士の初期攻撃力は5です。

f:id:kazuhironagai77:20200216205933p:plain

バグってますね。

f:id:kazuhironagai77:20200216210004p:plain

素手のATKが0でなく-2になってました。直します。

f:id:kazuhironagai77:20200216210027p:plain

もう一度最初からやり直します。

f:id:kazuhironagai77:20200216210047p:plain

短剣(小)を装備します。

f:id:kazuhironagai77:20200216210114p:plain

素手を装備します。

f:id:kazuhironagai77:20200216210135p:plain

今度は大丈夫みたいです。

これで、大体GameCharacterクラスのATKとFieldPlayerのSoldierbaseAtkが分かりました。武器を装備した場合のATKをGameCharacterクラスのATKが表し、武器を外した場合のATKをFieldPlayerのSoldierbaseAtkが保持しています。

レベルが上がった場合の例も確認しておきましょう。

確かレベルが上がるとATKが2倍になるはずです。

現在、レベル1で、短剣(大)を装備しています。

f:id:kazuhironagai77:20200216210214p:plain

ATKが1だけ上がりました。

f:id:kazuhironagai77:20200216210238p:plain

レベルが上がった場合のコードを探したら、UE4C++のゲームモード内にありました。

f:id:kazuhironagai77:20200216210333p:plain

レベルが上昇した場合、GameInstance内のPartyMemberのそれぞれのパラメーターの値を上げています。

となると、レベルが上がるとATKが2倍になるのは間違いで、ATKなどのすべてのパラメーターが1だけ上昇する。が正しいようです。

しかしGameCharacterクラスのATKだけ挙げても、武器を外した時にFieldPlayerのSoldierbaseAtkに戻してしまうので意味ないですよね。

これって設計ミスですね。

直します。

BPの値をUE4C++からアクセスしないといけないか。やり方分からないですね。調べます。

ここに載ってました。

f:id:kazuhironagai77:20200216210420p:plain

これによると、まずBPクラスとそのクラスからのインスタンスへのリファレンスが必要だそうです。

うーん。BPのインスタンスにアクセス出来たら普通に、その変数にもアクセス出来そうですが?

f:id:kazuhironagai77:20200216210449p:plain

こうして、

f:id:kazuhironagai77:20200216210506p:plain

これで、FieldPlayerの変数にアクセス出来るのでは?

良く考えたら、SoldierbaseAtkはRPGCharacterの変数じゃなくて、RPGCharacterの派生BPクラス、FieldPlayerの変数なんですね。となるとアクセスするにはCastしないといけないので、

f:id:kazuhironagai77:20200216210558p:plain

どうやってBPクラスのFiledPlayerをUE4C++にincludeするのでしょう。

分かりません。

もう少し調べたら出来そうですが、それよりもBPから呼べるC++関数をこのクラス内に作成して、その実装をBP内で行う方が簡単な気がしてきました。こっちでやってみます。

BlueprintImplementableEventを使用すれば出来るみたいですね。昔勉強した記憶では、_implementationを関数名の後に着けた気がします。

ここにやり方が書いてありました。

_implementationは使用していませんね。うーん。

取りあえず上記のやり方に従って作成してみます。

f:id:kazuhironagai77:20200216210634p:plain

レベルが上がった時に呼ぶ事にします。

f:id:kazuhironagai77:20200216210653p:plain

ビルドしてGameModeクラスのBPからTestBPIEvent()を呼び出します。

f:id:kazuhironagai77:20200216210744p:plain

テストします。

f:id:kazuhironagai77:20200216210801p:plain

呼ばれているみたいです。

レベルが上がった時に、FieldPlayerのSoldierbaseAtkが1上がるようにします。

f:id:kazuhironagai77:20200216210819p:plain

テストします。

レベルが上がったらSoldierbaseAtkが6になりました。

f:id:kazuhironagai77:20200216210842p:plain

更に装備を外しても、ATKは6になっています。

f:id:kazuhironagai77:20200216210901p:plain

出来ちゃったみたいでこれでOKにします。

3.素手を武具にしています。装備を外すボタンを作成して素手を武具から外します。

まず、ボタンを作成します。

f:id:kazuhironagai77:20200216211003p:plain

次にボタンを実装します。

しかし何を実装すればいいのかが分かっていませんので、weaponウィジェットのBP内で装備画面で武器のボタンを押した時のコードを見て参考にします。

f:id:kazuhironagai77:20200216211023p:plain

まず、fieldPlayerの変数、SoldierWeaponに武器の名前を保持させます。

f:id:kazuhironagai77:20200216211040p:plain

次に、fieldPlayer のSoldierbaseAtkと武器のATKの足した値をGameCharacterクラスのATK変数の値に入れます。

f:id:kazuhironagai77:20200216211343p:plain

最後に、fieldPlayer のSoldierWeaponEquipped変数をtrueに変更します。

f:id:kazuhironagai77:20200216211424p:plain

どうやら、やっているのはこの3つだけみたいですね。ではこれを参考に武器を外すボタンを実装します。

f:id:kazuhironagai77:20200216211445p:plain

しました。

話は全然変わりますが、

f:id:kazuhironagai77:20200216211511p:plain

このノードを繋ぐ線を綺麗に並べる点、今までrerouteと打って加えていたのですが、

f:id:kazuhironagai77:20200216211532p:plain

線上でマウスの左ボタンをダブルクリックすれば出来る事を知りました。

テストします。

f:id:kazuhironagai77:20200216211620p:plain

短剣(小)を装備しています。はずすボタンを押します。

f:id:kazuhironagai77:20200216211645p:plain

短剣(小)が外れました。戦闘力も素手の状態の5になっています。

今度は短剣(大)を装備しました。

f:id:kazuhironagai77:20200216211720p:plain

はずすボタンを押します。

f:id:kazuhironagai77:20200216211739p:plain

外れました。

大丈夫みたいです。

最後に素手をデータテーブルから消しました。

f:id:kazuhironagai77:20200216211759p:plain

4.装備している武具を売る事が出来ます。

うーん。装備している武器は売れない様にしましょう。

色々考えたんですが、以下の方法で作成しました。

まず、WeaponウェジェットをduplicateしてWeaponEquippedと名付けます。

f:id:kazuhironagai77:20200216211826p:plain

特に機能は要らないので、

f:id:kazuhironagai77:20200216211844p:plain

f:id:kazuhironagai77:20200216211852p:plain

全部外してしまいます。

WeaponShopSellウェジェットを開き、装備品の名前が現在装備している武器と同じ場合は、最初の一回目に限り、WeaponウェジェットでなくWeaponEquippedウェジェットでボタンを作成します。

f:id:kazuhironagai77:20200216211936p:plain

これで装備している武器は売れなくなったはずです。

テストします。

今、短剣(小)を装備しています。

f:id:kazuhironagai77:20200216212013p:plain

短剣(小)は2振り持っていますが、一個は売る事が出来ません。赤いボタンをクリックすると、

f:id:kazuhironagai77:20200216212036p:plain

となるだけです。

しかし赤くないボタンの短剣(小)をクリックした場合は、

f:id:kazuhironagai77:20200216212106p:plain

普通に売れました。

更に、装備を外してから武器屋に戻ると、

f:id:kazuhironagai77:20200216212144p:plain

色が変わって今まで装備していた武器も売れる様になります。

f:id:kazuhironagai77:20200216212215p:plain

出来ました。

5.武具を売った後に画面に売却した武具の絵がずっと表示されています。

WeaponウェジェットのOnClickedイベントにWeaponImageUMGをターゲットにしたRemoveFromParentを追加します。

f:id:kazuhironagai77:20200216212235p:plain

これで武具の絵が消えるはずです。

f:id:kazuhironagai77:20200216212254p:plain

武具を装備した後ですが、武具の絵は消えています。

同様に武具を売った後も、武具の絵は消えました。

6.防具の装備

防具の装備のやり方は武器の装備をそのまま繰り返せば出来るはずです。

Weaponウェジェットが何をやっているのか分かり易くするために、Blueprintのノードを整理しました。

f:id:kazuhironagai77:20200216212339p:plain

次にfieldPlayerにSoldierArmer変数とsoldierbaseDef変数を追加しました。

f:id:kazuhironagai77:20200216212417p:plain

Pause_Equipmentウィジェットの防具の表示欄にコードをバインドしました。

f:id:kazuhironagai77:20200216212442p:plain

f:id:kazuhironagai77:20200216212451p:plain

今度は、Weapon内のOnClickEventで武器の装備の部分を真似て、防具の装備の部分を追加しました。

f:id:kazuhironagai77:20200216212521p:plain

f:id:kazuhironagai77:20200216212530p:plain

この中でfieldPlayer のSoldierWeaponEquippedノードの役割が分かりません。調べます。

f:id:kazuhironagai77:20200216212549p:plain

fieldPlayer のSoldierWeaponEquippedノードの一つ目の役割が見つかりました。Weaponウィジェットが作成されるたびに、SoldierWeaponEquippedがTrueかどうかをチェックします。もしfalseである場合は、FieldPlayerの変数SoldierbaseAtkにGameCharacterクラスのATK変数の値をコピーします。

これって正直、このボタンを作成する時にすべき内容じゃないですよね。しかもボタンを作成するたびに毎回行っています。後でもっとマシな場所に移しましょう。

f:id:kazuhironagai77:20200216212711p:plain

fieldPlayer のSoldierArmorEquippedノードを使用してTrueかどうかをチェックします。もしfalseである場合は、FieldPlayerの変数SoldierbaseDefにGameCharacterクラスのDEF変数の値をコピーします。

兎に角動くのが最優先ですので、今回は、ATKと全く同じ方法を採用しました。

それではテストしてみます。

f:id:kazuhironagai77:20200216212748p:plain

うーん。装備されませんね。コードを見直します。

一か所間違いがありましたので直しました。

f:id:kazuhironagai77:20200216212822p:plain

もう一度テストします。

f:id:kazuhironagai77:20200216212838p:plain

今度は装備できました。防御力も上がっています。

防具の名前がちょっと嫌ですね。木の盾(小)にしましょう。

f:id:kazuhironagai77:20200216212900p:plain

f:id:kazuhironagai77:20200216212917p:plain

更に防具を変えても正常に作動している事が確認出来ました。

ここからは、武器のバグを直した時と同じはずです。ので、

  1. ワープした時に防具が装備してない事になる。
  2. レベルが上がった時に、ベースのDEFが上がらない。
  3. 装備しているのにその防具が売れる。
  4. はずすボタンで防具を外せるようにする。

こんなもんでしょうか?では直していきます。

6.1 ワープした時に防具が装備してない事になる。

まず、確認します。

木の盾を装備します。

f:id:kazuhironagai77:20200216213008p:plain

ワープします。

f:id:kazuhironagai77:20200216213032p:plain

見事に外れてますね。

直します。

と言ってもどう直せばいいのか分からないので、武器の場合を見てみます。

テレポートのためにマップを開いたとき、

f:id:kazuhironagai77:20200216213102p:plain

GameInstanceにあるItemData、WeaponData、SoldierWeaponData、SoldierWeaponEquippedData、そしてSolderBaseATKDataにFieldPlayerの変数である、ArrayItem、ArrayWeapons、SoldierWeapon、SoldierWeaponEquipped、そしてSoldierbaseAtkの値をコピーしています。

f:id:kazuhironagai77:20200216213136p:plain

新しいレベルに移ってFieldPlayerを再生する時は、逆パターンを行っています。

分かってしまえば簡単ですね。

f:id:kazuhironagai77:20200216213215p:plain

まず、FieldPlayer内に新しく作成した変数、soldierArmor, soldierbaseDef, そしてsoldierArmorEquippedに対応する変数をMyRPGGameInstanceBP内に作成します。

f:id:kazuhironagai77:20200216213231p:plain

作りました。

武器の時と同じようにします。

f:id:kazuhironagai77:20200216213254p:plain

f:id:kazuhironagai77:20200216213301p:plain

テストします。

f:id:kazuhironagai77:20200216213320p:plain

木の盾(小)を装備してワープします。

f:id:kazuhironagai77:20200216213337p:plain

ワープした後でも木の盾(小)を装備していますね。

出来ました。

6.2レベルが上がった時にベースのDEFが上がらない

レベル1の状態を以下に示します。

f:id:kazuhironagai77:20200216213436p:plain

レベル2の状態を以下に示します。

f:id:kazuhironagai77:20200216213453p:plain

DEFは1上昇していますが、SoldierBaseDEFはレベル1の時と変わっていません。

これでは、防具を外した時に、レベルアップで上昇した分が消えてしまいます。

直します。

先程作成した、TestBPIEventの実装部にSoldierBaseDEFの値に1を足すコードを追加します。

f:id:kazuhironagai77:20200216213516p:plain

以上です。

テストします。

レベル2の状態を以下に示します。

f:id:kazuhironagai77:20200216213543p:plain

DEFは1上昇してSoldierBaseDEFも1上昇しています。

6.3 装備しているのにその防具が売れる。

これは武器の所でやったのと同じですね。

f:id:kazuhironagai77:20200216213606p:plain

WeaponShopSellウィジェットの変数EquippedArmorCheckedのみ新しく作成して残りは武器でやったのと全く同じです。

テストします。

短剣(小)と木の盾(小)を装備したまま売ろうとしました。

f:id:kazuhironagai77:20200216213625p:plain

売れませんね。

防具の装備を外す事はまだ出来ないので防具を外したら売れるのかのテストはまだ出来ません。

6.4 外すボタンで防具を外せるようにする。

Pause_Equipmentウィジェットの外すボタンを押した時の実証に装備している防具を外す実装をしました。

f:id:kazuhironagai77:20200216213708p:plain

テストします。

f:id:kazuhironagai77:20200216213738p:plain

外すボタンを押します。

f:id:kazuhironagai77:20200216213758p:plain

外れました。

因みに外れた武具は武器屋で売る事も出来ました。

一応これで防具の部分のバグの直しが終わりましたね。

7.装備した時に今より何が強くなるのか不明

以下に示すように武器や防具の性能値が見えるようにします。

f:id:kazuhironagai77:20200216213825p:plain

出来ました。

f:id:kazuhironagai77:20200216213844p:plain

テストします。

f:id:kazuhironagai77:20200216213905p:plain

出来てますね。

8.デザインの改善

ポーズ画面です。

f:id:kazuhironagai77:20200216213928p:plain

字が読みづらい以外はそんなに悪くないと思っています。これはそのままにします。

道具袋ボタンをクリックします。

f:id:kazuhironagai77:20200216214030p:plain

うーん。

f:id:kazuhironagai77:20200216214049p:plain

取りあえず色を変え、テキストの位置を直しました。フォントとボタンの形状は変えるべきでしょうね。

先に装備品を考えます。

f:id:kazuhironagai77:20200216214122p:plain

テキストの位置が全体的にずれていますね。後バックグランドの画面が微妙にずれています。その辺から直します。

f:id:kazuhironagai77:20200216214138p:plain

前よりはマシになりました。こっからどうするかですね。

試しに装備品を追加してみましたが。それでも寂しいですね。

f:id:kazuhironagai77:20200216214155p:plain

マウスのカーソルを武器ボタンに重ねて武器の性能を表示させます。

f:id:kazuhironagai77:20200216214210p:plain

これでちょっとはマシな感じですか。

後ろにイラストを追加してみました。

f:id:kazuhironagai77:20200216214225p:plain

装備品があるとこんな感じになります。

f:id:kazuhironagai77:20200216214241p:plain

うーん。いいかもしれませんね。

f:id:kazuhironagai77:20200216214258p:plain

取りあえずこれで一週間考えてみます。

まとめと感想

何故か今回は結構疲れました。

装備した武具は3Dモデルに表示したいです。どうすればいいのでしょうか?

まだまだバグはあるかもしれませんが、そろそろ戦闘システムの改善を行いたいです。