UE4の勉強記録

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

「Unreal Engine 4.xを使用してRPGを作成する」の足りない部分を作成する バグ出しの続き

f:id:kazuhironagai77:20210307231748p:plain

<前文>

センシティブな同人アニメ絵とアメリカからの圧力による規制について

アメリカに10年住んでいた関係でアメリカの本当の政治事情に詳しい私が予言しますが、これから同人絵のようなセンシティブなアニメ絵に対してアメリカ政府が日本政府に規制するように圧力をかけて来る事はないです。

これは日本のアニメ、特に深夜アニメはポル〇であると断定し、積極的に規制するよう日本政府に圧力をかけていたアメリカの宗教右派がトランプが失脚した事により権力を失ったからです。

アメリカの宗教右派が、日本の同人アニメの絵を規制しないといけない表向きの理由は、彼らの宗教が欲情する事自体を罪にしているからです。しかしその本当の理由は、宗教とは関係なく、有色人種の男性がちょっとでも白人女性に欲情したら使用人として使えないからです。彼らは元々、農場のオーナーなんです。つまりいっぱいいる小作人や使用人を管理する事が彼らにとっての仕事なんです。昔、中国の後宮で働く男性は、宦官にならなければならなかったですが、それと同じ事をやると世論の批判を浴びるので、心理的、精神的に追い込む事で実質、宦官にして使用人にする訳です。そのために欲情する事自体を罪にしている訳です。

アメリカの宗教右派の連中は、日本人全体を彼らの使用人みたく思っていますから、同人アニメの絵の存在そのものを叩く訳です。

これから4年から8年の間、アメリカの政治を司る左派の連中は、元々都会で働くサラリーマンですので、そんな事を考える人は全くいません。むしろ、宗教右派に対して「日本人を使用人にするよりお前のボスにした方が経営上手く行くんじゃないの。」と言う位の連中です。

だから左派の連中がアメリカの政治の中枢にいる限り、日本の同人アニメの絵を叩く事は考えられません。

ただし左派にも僅かにですが同人絵のようなセンシティブなアニメ絵を規制すべきと考える人はいて、彼らが何かのアクションを取る可能性はあります。しかし絶対数が少ないので大した問題にはならないと思われます。

更にアメリカでも、アニメで育った世代が成人となりつつあります。

彼らの中で同人アニメの絵で生計をたてる人も必ず出て来ます。そうなったら規制どころではないです。マリファナですら自分たちに利益をもたらすなら合法化する国が、同人アニメの絵が自分達の利益になった時、180°今までの意見を変えてくるっと賛成派になるのは目に見えています。

そういう訳で、これから同人絵のようなセンシティブなアニメ絵に対してアメリカ政府が日本政府に規制するように圧力をかけて来る事はないと思われます。

ただし、気を付けないといけないのは、これからナチ関係の書籍は逆に大変厳しい規制が課せられたり、賛同するような意見を書いた作者に信じられない位の厳罰が課せられたりするようになると思われます。

先月の前文で説明した通りGenocideの思想そのものがない日本で、本気でナチズムを信じている人はいません。しかしUFOやオカルト本の影響で軽い気持ちで賛同するような意見を書く人はいます。もし貴方の周りにいたら絶対止めるべきです。絶対に最悪な方に誤解されるからです。

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

<本文>

1.今週の予定

以下の事をやって行きたいと思います。

  • モンスターの歩く速度の設定がアニメーションとAIで全然違う
  • BGMの変更、町や村、モンスターが居る廃墟で別々のBGMにする。
  • BPの整理。RPGGameModeBPを整理します。
    • そこら中でThirdPersonCharacter変数に値をセットしている。過去、EventBeginPlay関数がBPから呼べなかったので毎回呼び出していた。これを直す。
    • 戦闘システムから呼ばれるEventを整理してまとめる。
  • セリフシステムの整理。確認出来るだけで3種類以上の方法でセリフを管理している。これを統一する。
  • 更なるバグだし。せめて1時間はこのゲームで遊んでバグ出しする。(今週は10分だった。)
  • Levelデザイン。

2.アニメーションとAIにおけるモンスターの歩く速度の設定の検証

Monsterが使用しているAIではMonsterの歩く速度を150に指定しています。

f:id:kazuhironagai77:20210307231912p:plain

一方で、Monsterが使用しているアニメーションでは歩くアニメーションは85でセットされています。

f:id:kazuhironagai77:20210307231932p:plain

実際は歩き始めるモーションを100%使用し始める速度が85で、そこからは歩くモーションと走るモーションのブレンドになります。

移動する速度が345を超えると100%走るモーションに変わります。

実際の速度が150の時の移動のモーションを見ると、そんなに不自然ではありません。

f:id:kazuhironagai77:20210307231952p:plain

ここで検証したい事は、この二つの速度は同じ単位なのか?もし同じ単位ならその単位は何なのかについてです。

もう一つ検証したい事は、モンスターが探索している時、微妙に浮いている気がする事です。

f:id:kazuhironagai77:20210307232013p:plain

この辺も直せたら直したいです。

2.1 UE4の速度の単位

それではこれから調べて行きましょう。

まずAIの方ですが、モンスターの移動スピードはMonsterBPのCharacter MovementのMax Walk Speedが担当しています。

f:id:kazuhironagai77:20210307232042p:plain

Character Movement:WalkingのMax Walk Speedの設定をみると600.0にセットされています。

f:id:kazuhironagai77:20210307232104p:plain

この単位を探してみましょう。

UE4 Answer Hubのこのサイトで質問されていました。

f:id:kazuhironagai77:20210307232148p:plain

質問者はUU/Sが単位でdefaultでは1UU が1cmなので㎝/sが単位ではないかと予測しています。ただしソースは見つかっていないと言っています。

まずここでの議論で、当たり前のように使われているUUの意味が分からないです。Defaultの1UUは1㎝とか言っています。

UUの意味を調べます。

どうやらUnreal Unitsの意味らしいです。ただし参考で出て来た資料がUE3の時代のものでした。

その後「UE4ではUUは1cmに設定された。」とか「World Settingsで値を変更出来る」とかの断片的な情報は出て来ましたが、確認までは出来ませんでした。

特に、World Settingの項目は以下に示した様にVRの項にあって、普通のゲームにも使用されるのか不明です。

f:id:kazuhironagai77:20210307232207p:plain

ただ100 cmは1 mなので完全に違うとも言い切れないのが難しい所です。

もしMax Walk Speedの単位がcm/sだとしたら6 m/sです。秒速は感覚的に分かりづらいですが、少し速すぎないでしょうか?

色々調べてみたら、大体、日本の高校生の100m走の平均は14秒だそうです。そうすると100 m ÷14 sで7.14 m/sになります。ので6 m/sが速すぎると言う事はないですね。

何か、cm/sで合っている気がしてきました。

この質問に対してのコメントで、実際にゲーム内で100m走って速度を測った人がいました。20回測って平均は5.9 m/sになったそうです。6 m/sに大変近い値です。となるとcm/sがMax Walk Speedの単位である可能性は高いですね。

所がこの質問に対する回答で、スピードは実際はSecondに負っているのではなくFrame rateに負っているから、単純にSecondには変換できないと主張する人がいました。

確かにFrameに負うのはその通りですが、前にUE4のDelta Timeの違いの影響を測定したら差がなかったです。

どの週のブログで測定したのかは覚えていないですが、今100m走の秒速などを計算するためにエクセル開いたら、その時のデータと図だけ残っていました。

ので図だけ貼っておきます。

f:id:kazuhironagai77:20210307232228p:plain

これらの結果から推測するとMax Walk Speedの単位がcm/sであるのはかなり正しそうです。

100m走をUE4内でやるのは面白そうですね。

これは試してみましょう。

良く見たら一目盛り1mと書かれていました。

f:id:kazuhironagai77:20210307232247p:plain

これは簡単に100mが作れますね。

走って見ました。

f:id:kazuhironagai77:20210307232306p:plain

100m走るのに16.809秒かかりました。

計算すると5.949 m/sでした。20回測定して平均を出します。

f:id:kazuhironagai77:20210307232322p:plain

ほとんど時間が変わらないので3回で中止しました。

結果は約5.95m/sです。

多分同じ結果になるんでしょうが、Animationの方も確認します。

Animationの方は、Animation BPであるSkelSwordAni BPで以下の様に設定されていました。

f:id:kazuhironagai77:20210307232340p:plain

Get Velocityノードが何の値を取り出しているのか分かれば、Max Walk Speedの単位と同じであるかどうかが判明出来ますね。

取りあえずどんな説明しているのか、カーソルをノードに添えてみたら、思いっきり説明されていました。

f:id:kazuhironagai77:20210307232357p:plain

Cm/s、つまりUnreal Units/secondと書かれていました。

図らずもAIで使用しているMax Walk Speedの単位とAnimationで使用しているGet Velocity関数の単位が同じであるだけでなく、Max Walk Speedの所で推測したUnreal Unitsの単位が㎝である事と、その速度を測るために秒を測っている(frameではなく)と言う事までも正しい事も分かりました。

これだけ解れば十分ですね。テストなら満点です。

次に行きましょう。

2.2 探索時、モンスターが微妙に浮いている気がする。

これは単純にCollusionを担当するCapsule ComponentがMonsterのMeshより下に飛び出ているからでしょう。

確認すると僅かにですが確かに飛び出していました。

f:id:kazuhironagai77:20210307232426p:plain

直します。

直しましたが、モンスターの動きを見るとまだオカシイです。

スクリーンショットではうまく伝わらないんですが滑っている感じがします。

f:id:kazuhironagai77:20210307232443p:plain

理由が分かりました。

歩いている歩幅に対して実際に進んでいる距離が短すぎるんです。今の2倍位は進むべきです。

85が歩く速度に設定されていますが、どうなんでしょうか?

調べて見ると成人だと1分間で80m歩く位が普通だそうです。1.34 m/sでした。となると134 cm/sですから、歩くを85にセットしていたのはかなり遅いかもしれません。

SkelSword1Dでモンスターの歩く速度を130に変更しました。

f:id:kazuhironagai77:20210307232502p:plain

前より滑ってる感じは無くなりました。かなり良くなってはいます。完全に滑っていないとは言えませんが、これだけ改善されたら十分と思います。

f:id:kazuhironagai77:20210307232518p:plain

3.BGMの変更、町や村、モンスターが居る廃墟で別々のBGMにする

これはLevel designが完成してからやります。ので今回はスキップします。

 

4.BPの整理。RPGGameModeBPを整理します。

4.1 昔、BPからEvent Begin Play関数が呼べなかったので、event毎にThirdPersonCharacter変数に値をセットしていた。これを直します。

まずAnimation for Victoryにありました。外します。

f:id:kazuhironagai77:20210307232606p:plain

Game Overにもありました。外します。

f:id:kazuhironagai77:20210307232623p:plain

Moving Camera Positionの所です。外します。

f:id:kazuhironagai77:20210307232641p:plain

Event Report Character Level Upの所です。外します。

f:id:kazuhironagai77:20210307232658p:plain

テストします。

モンスターと戦闘して勝利しました。レベルも上がりました。エラーの表示が出たりゲームが中断したりする事もありませんでした。

念のためにモンスターと戦闘して負けてみました。単にゲームオーバーになっただけでした。

外しても何の問題も起きませんね。

4.2 戦闘システムから呼ばれるEventを整理してまとめる。

以下に示したのが現在RPGGameModeBP内にあるEventです。

黄色に囲って在るEventの全てが戦闘に関係しています。

f:id:kazuhironagai77:20210307232731p:plain

これらを整理していきます。

以下の様に整理しました。

戦闘に関係のないEvent Begin PlayとEvent Tick 関数をまとめました。

f:id:kazuhironagai77:20210307232752p:plain

f:id:kazuhironagai77:20210307232800p:plain

戦闘に関するEventは以下の様に整理します。

  • Decisionに関係するEvent
  • Action に関係するEvent
  • 戦闘後のVictoryGameOverなどに関係するEvent
  • それ以外のEvent

Decisionに関係するEventです。

f:id:kazuhironagai77:20210307232833p:plain

f:id:kazuhironagai77:20210307232841p:plain

Actionに関係するEventです。

f:id:kazuhironagai77:20210307232900p:plain

f:id:kazuhironagai77:20210307232909p:plain

戦闘後のVictory、GameOverなどに関係するEventです。

f:id:kazuhironagai77:20210307232928p:plain

f:id:kazuhironagai77:20210307232942p:plain

それ以外の関数で戦闘に使用するものです。

f:id:kazuhironagai77:20210307233001p:plain

f:id:kazuhironagai77:20210307233011p:plain

全部で12個でした。

あれ、2つ足りません。

Confirmed Button Is Clicked EventはDecisionの中にありました。

f:id:kazuhironagai77:20210307233032p:plain

同様にConfirmed Button Is Clicked 2EventはActionの中にありました。

f:id:kazuhironagai77:20210307233048p:plain

雑と言えば雑ですが一応整理出来ました。

5.対話システムの整理。確認出来るだけで3種類の方法でセリフを管理している。これを整理する。

5.1 対話システムの確認

今まで作成した対話システムの確認をします。

5.1.1 NPCとの対話

まず、NPCとの会話です。

全てのNPCとの会話はStructであるNPC_ConversationBaseを元にして作成しています。

f:id:kazuhironagai77:20210307233128p:plain

NPC_ConversationBaseはTestタイプの変数とAnswer Comment ManagementタイプのArrayで構成されています。

f:id:kazuhironagai77:20210307233150p:plain

Answer Comment ManagementはStructです。

f:id:kazuhironagai77:20210307233206p:plain

中身はInteger型であるJumpToCommnetとText型であるAnswerCommnetで構成されています。

f:id:kazuhironagai77:20210307233223p:plain

実際のNPCにおける使用は以下の様になります。

f:id:kazuhironagai77:20210307233239p:plain

内容にはこれ以上は深入りしませんが、会話を管理するには非常に優れたシステムとなっています。

5.1.2 店主との対話

次に店主との対話システムです。これは教科書に書かれていた方法をそのまま使用しています。

まずNPC_ParentというWidgetを作成してこれに全ての対話を保持させます。

f:id:kazuhironagai77:20210307233303p:plain

Text型のarrayを作成してそれぞれの店主に対応したセリフを保持させます。

f:id:kazuhironagai77:20210307233322p:plain

実際の保持されているセリフです。

f:id:kazuhironagai77:20210307233342p:plain

このWidgetクラスから子クラスを作成してその子クラスにそれぞれの店主との会話を担当するWidgetにします。

その子クラスからNPC_Parentにある対話用のarrayにアクセスさせ実際の会話に使用します。(以下の様な方法でアクセスします。)

f:id:kazuhironagai77:20210307233431p:plain

この方法では「5.1.1 NPCとの対話」でやったやり方のように、答えの選択が複数ある場合には対応できませんが、それ以外ではまあまあなシステムです。

例えば全てのセリフをNPC_Parentで管理しているので全てのセリフをチェックしなければならない時はNPC_Parentを見れば良いからです。

Widgetを継承するやり方は3種類位勉強しましたが、ここで採用されているやり方でPackaging まで出来るのか不明です。ちょっと心配です。

5.1.3 戦闘システムにおける報連相

以下の方法で管理されています。

f:id:kazuhironagai77:20210307233454p:plain

この方法の何が最悪であるかと言うと、セリフの一括管理が出来ない事です。更にそれ故に対話の流れがセリフからだけでは分からなくなります。

しかしこのシステムから提供されるセリフは、ユーザーからは絶対に必要なものです。何故からそれはユーザーに対する戦闘における報告、連絡、そして相談を担当しているからです。

それでこの戦闘システムの報連相の機能は一切なくさないで、実装方法とセリフの管理方法だけ変更したいんです。

5.2 戦闘システムにおける報連相の全容を確認する。

この戦闘システムの報連相の機能は一切無くさないで、実装方法とセリフの管理方法だけ変更するためにはどうすればいいでしょうか?

取りあえず最初にする事は全容を把握する事です。

そこから始めます。

まず前節で示した戦闘システムの一番最初に出て来る報連相を見ると、セリフをCombat Window ウィジェットのComment Text Contentにセットしています。

f:id:kazuhironagai77:20210307233519p:plain

Combat Window ウィジェットのComment Text Contentを調べます。

調べようとしたらCombat Window ウィジェットのBPがゴチャゴチャしていたので整理をします。

f:id:kazuhironagai77:20210307233536p:plain

以下に示したように整理しました。

f:id:kazuhironagai77:20210307233553p:plain

戦闘前、戦闘システムのDecisionの状態で実行されるEvents、戦闘システムのActionで実行されるevent、最後に「読みましたボタン」を押した時に実行されるEventです。

最初のブロックである戦闘前ですが、ここではComment Text Content変数は全く使用されていないのでこのブロックは無視します。

f:id:kazuhironagai77:20210307233611p:plain

次のDecisionブロックですが、Decisionで決定すべき、攻撃、魔法、アイテム、そして逃げるの4つの選択をした後にそれぞれ実行するコードが書かれています。

f:id:kazuhironagai77:20210307233626p:plain

f:id:kazuhironagai77:20210307233633p:plain

f:id:kazuhironagai77:20210307233641p:plain

攻撃を選択した場合、Comment Text Content変数に関しては以下のTextが追加されます。

f:id:kazuhironagai77:20210307233658p:plain

魔法を選択した場合、Comment Text Content変数に関しては以下のTextが追加されます。

段々、分かって来ました。このComment Text Content変数はDecision状態のユーザーと敵のモンスターの選択した内容を報告するためのセリフを管理するためのものだったんです。

f:id:kazuhironagai77:20210307233734p:plain

こんどはItemを選択した時です。

魔法を選択した時と全く同じです。

f:id:kazuhironagai77:20210307233806p:plain

逃げるを選択した時です。

逃げるを選択した時はここで、Comment For Execute Action変数にもセリフを追加しています。

f:id:kazuhironagai77:20210307233824p:plain

ここはDecisionで選択された結果に対しての実行なのでActionですべき事をここでやってしまうのは、論理的にオカシイ気がしますが、この辺は後で検討しましょう。

ここまで来てComment Text Content変数に保持されているTextは何時、Combat UI ウィジェットのコメント欄に反映されるのかと思ったら、

f:id:kazuhironagai77:20210307233843p:plain

直ぐに反映される仕組みになっていました。

f:id:kazuhironagai77:20210307233859p:plain

確認のために戦闘してみます。

f:id:kazuhironagai77:20210307233918p:plain

f:id:kazuhironagai77:20210307233927p:plain

攻撃を選択しました。

f:id:kazuhironagai77:20210307233956p:plain

攻撃の対象にゴブリンを選択しました。

f:id:kazuhironagai77:20210307234013p:plain

f:id:kazuhironagai77:20210307234021p:plain

Decisionの状態はここまでで、残りはAcitonの状態のはずです。

一応確認するために次のコメントも見ておきます。

f:id:kazuhironagai77:20210307234040p:plain

はい。Actionの状態です。

兎に角、Comment Text Content変数に保持されているTextは直ぐにCombat UI ウィジェットのコメント欄に反映されている事は確認が取れました。

5.3 Comment Text Content変数と戦闘システムにおける報連相の管理方法のまとめ

まだ「5.2 戦闘システムにおける報連相の全容を確認する。」の途中ですが、ここまで整理して来て戦闘システムにおける報連相の管理方法についてのアイデアが出ました。のでここでまとめておきます。

今までずっとComment Text Content変数が、戦闘システムのセリフを管理しているにもかかわらず、その内容はその場その場で管理しているので、戦闘システムにおけるセリフの全体像が把握出来ないという問題がありました。

今回、その問題を解決すべく大々的に戦闘システムのセリフの整理、検討を始めたのですが、ここに来てComment Text Content変数が戦闘システムのセリフを管理しているのではなく、実際は、どの変数も戦闘システムにおけるセリフは管理していないという事が分かりました。

実際、戦闘システム内の個々のセリフは以下の方法で、その場その場で追加されているだけです。

f:id:kazuhironagai77:20210307234102p:plain

と言う事は、これらのセリフを一括で管理するData SheetもしくはTextのArrayを作成して、そこからこのAppendにセリフをパスするように変更すればいいんです。

そうすれば、戦闘システムのセリフを一括で管理する変数が出来ます。

それを作成しましょう。

5.4 戦闘システムのセリフを一括で管理するData Sheet

NPCのセリフの管理で使用したNPC Conversation Baseを使用して戦闘システムのセリフを一括で管理するData Sheetを作成しましょう。

f:id:kazuhironagai77:20210307234124p:plain

これならどこでどんなセリフをいうのか一発で分かりますし、そのセリフに対しての解答とその解答を選択した結果に対してのセリフの関係性も一瞬で分かります。

試してみましょう。

以下に示した様に最初の部分だけ作成しました。

f:id:kazuhironagai77:20210307234139p:plain

ここからセリフを読み取って戦闘システムのセリフが作成されるようにします。

RPGGameModeBPのBeginPlay関数に以下のコードを追加します。

f:id:kazuhironagai77:20210307234216p:plain

これでCombat Dialogue変数にCombat Dialogue data tableの全ての名前が保持されます。

次にCombat UIウィジェットのEvent Constructに以下のコードを追加します。

f:id:kazuhironagai77:20210307234234p:plain

これでComment Text Comtent変数にCombat Dialogue data tableの最初のセリフである「戦闘が開始されました。」がセットされたはずです。

テストしてみます。

Comment Text Comtent変数に入っていたDefaultを「戦闘が開始されました。」を「Test」に変更します。

f:id:kazuhironagai77:20210307234250p:plain

f:id:kazuhironagai77:20210307234258p:plain

これでCombat Dialogue data tableからセリフが読み込まれた場合は「戦闘が開始されました。」が表示されCombat Dialogue data tableからセリフが読みこまれなかった場合は「Test」が表示されるはずです。

f:id:kazuhironagai77:20210307234318p:plain

「戦闘が開始されました。」が表示されました。

出来ています。

しかし完璧ではありませんでした。

段落が無くなってしまっています。

f:id:kazuhironagai77:20210307234335p:plain

直します。

Combat UIウィジェットのGet Comment Text Box関数を以下に示した様に変更します。

f:id:kazuhironagai77:20210307234351p:plain

これでComment Text Content変数のtextに{nextline}が使用されていた場合、段落に変換されます。

更にCombat Dialogue data tableの最初のセリフである「戦闘が開始されました。」に{nextline}を追加しました。

f:id:kazuhironagai77:20210307234416p:plain

テストします。

f:id:kazuhironagai77:20210307234434p:plain

今度は行替えされて表示されています。

出来ました。

次は以下のセリフの交換になります。

f:id:kazuhironagai77:20210307234450p:plain

ここで気が付いたんですが、Combat Dialogue data tableのセリフが少し間違えていました。

直します。

Playerの操作するキャラとモンスターではNewRow_0のセリフは前半部は同じですが後半は違いました。ので二つに分けました。

f:id:kazuhironagai77:20210307234507p:plain

それでは最初の部分のセリフである「“は次の行動を考えています。」をCombat Dialogue data tableから読み込む事にします。

以下に示した様に改良しました。

f:id:kazuhironagai77:20210307234531p:plain

テストします。

f:id:kazuhironagai77:20210307234551p:plain

出来ています。

今度は「{表示されているボタン(攻撃、逃げるなど)の中から一つ選択してください。}」を変えます。

f:id:kazuhironagai77:20210307234611p:plain

テストします。

f:id:kazuhironagai77:20210307234628p:plain

出来ていますね。

行替えは出来てなかったのでそこだけ直しました。

整理しましたがまだまだスパゲティです。

f:id:kazuhironagai77:20210307234645p:plain

セリフをCombat Dialogue data tableから読み込む部分は関数にしますか。

四角で囲った部分です。

f:id:kazuhironagai77:20210307234704p:plain

関数名はGet Dialogue From Combat Dialogue DTです。

f:id:kazuhironagai77:20210307234720p:plain

かなり見栄えも良くなりました。

他の部分も直していきます。

以下の様に直しました。

Combat Dialogue data tableのセリフは以下の様に成りました。

f:id:kazuhironagai77:20210307234741p:plain

以下に実装部を示します。

f:id:kazuhironagai77:20210307234809p:plain

f:id:kazuhironagai77:20210307234816p:plain

f:id:kazuhironagai77:20210307234825p:plain

f:id:kazuhironagai77:20210307234833p:plain

f:id:kazuhironagai77:20210307234842p:plain

f:id:kazuhironagai77:20210307234859p:plain

f:id:kazuhironagai77:20210307234910p:plain

f:id:kazuhironagai77:20210307234919p:plain

f:id:kazuhironagai77:20210307234927p:plain

f:id:kazuhironagai77:20210307234935p:plain

f:id:kazuhironagai77:20210307234945p:plain

f:id:kazuhironagai77:20210307234955p:plain

f:id:kazuhironagai77:20210307235004p:plain

全ての要素でテストした結果、今までと同じセリフが表示されました。

5.5 Action状態におけるセリフを一括で管理するData Sheet

Comment For Execute Action はCombat UIウィジェット内に作成されたTextタイプの変数です。

調べて見るとEvent Report Begin Execute ActionでPlayerの操作するキャラの場合のみ、それまでComment For Execute Action変数内に足していたセリフをComment Text Content変数に移す事でセリフをCombat UIのコメント欄に表示します。

f:id:kazuhironagai77:20210307235032p:plain

f:id:kazuhironagai77:20210307235039p:plain

f:id:kazuhironagai77:20210307235047p:plain

この変数が管理しているTextも全てData Tableで一括に管理する事にします。

調べたら以下の7か所でのみ使用していました。

f:id:kazuhironagai77:20210307235108p:plain

うーん。思っているより少ないですね。

理由が分かりました。Acition状態でも結構な割合でComment Text Contentが使用されていました。

f:id:kazuhironagai77:20210307235129p:plain

Comment Text Contentに代入されるセリフは全部、Combat Dialogue data tableに移したと思ったんですが、まだ残っていました。これは後で直します。

以下の様にセリフを整理しました。

f:id:kazuhironagai77:20210307235146p:plain

簡単に解説します。

まず(始め)を開きます。

すると以下のような選択肢があります。

f:id:kazuhironagai77:20210307235207p:plain

ここで攻撃を選択したとします。

攻撃のJumpToCommentは1ですので、indexの1にJumpします。

Indexは0から始まるので番号の2がIndexの1に当たります。

f:id:kazuhironagai77:20210307235222p:plain

2の「を攻撃しました{nextline}」を開いて見ます。

f:id:kazuhironagai77:20210307235240p:plain

Answer Choiceに選択がありません。ここで終わりです。

所でAnswerのスペルが間違っていますね。後で直しておきます。

こんな感じでアドベンチャーゲームブックのように全てのセリフが繋がっています。つまりこのData Tableでセリフを一括管理している訳です。

以下に実際の実装を示します。

f:id:kazuhironagai77:20210307235256p:plain

全部載せる意義を感じないので一個だけにします。

テストします。

攻撃、魔法、道具、逃げるのそれぞれの場合で試しましたが特に問題は確認されませんでした。

5.5 Action状態でComment Text Contentに直接追加されるセリフを管理するData Table

Comment Text Content変数に追加すべき残りのセリフを調べると、

  • モンスターのセリフ:1
  • Action時のセリフ:2
  • 戦闘終了後のセリフ:2
  • MPHPの増減に関してのセリフ:4
  • 逃げるを選択した場合に関してのセリフ:2

となって結構バラバラです。

今までのようにこれらのセリフ全てを一つに繋げる事は出来なそうですが、出来るだけ整理します。

f:id:kazuhironagai77:20210307235330p:plain

やっぱり全部のセリフの関係性を繋げるのは不可能ではないですが、今回はパスします。

上二つのData Tableと同じやり方で実装しました。一個だけ例を載せておきます。

f:id:kazuhironagai77:20210307235348p:plain

テストもしました。

Indexで3、番号では4の「は勝利しました。{next line}」は「は勝利しました。{nextline}」が正しかったです。

後、Level Upした時のセリフを忘れていました。

それらを直しました。

5.6 Dialogue System 考察

これで一応、戦闘システムの報連相を担当していた数々のセリフが3つのData Tableにまとめられました。その内2つはそれぞれのセリフの前後関係もはっきり分かりData Tableを見るだけで全体像の把握が出来る仕組みになっています。

最後のData tableはセリフ同士の関係を正しく並べる事が出来なかったので全体像までは分かりません。ただし、今回はやりませんが、これも時間をかけて前の二つのData Tableと組み合わせれば前後関係がはっきり分かる様に作成出来るはずです。

このまとめ方はNPCの対話で発明した方法と全く同じです。

NPCとの対話でも店主との対話だけは教科書で紹介された方法で作成しましたが、勿論、店主との対話も他のNPCと同じ方法で作成する事が出来ます。

つまり、全てのセリフはNPCの対話で作成した形式で書く事が出来るのです。

そしてこのNPCの対話で作成した形式は、一括で全てのセリフを管理出来るだけでなく、セリフの前後関係も会話全体の流れもData Tableを見るだけで理解出来る大変優れた方法です。

NPCの対話で作成した形式を、もっと一般化した言い方をするとアドベンチャーゲームブック形式のまとめ方となります。

これについてはかなり深い考察をする必要があるので「アドベンチャーゲームブック形式によるセリフのまとめ方について」来週考察します。

6.更なるバグだし(1時間はこのゲームで遊ぶ)

先週、10分プレイしただけで大量のバグが見つかってゲームを中断せざるえませんでした。

今週は、1時間はプレイしてバグ出しします。

6.1 兎に角、10分間プレイ

武器屋で武器を買ったら値段が金貨0枚でした。

f:id:kazuhironagai77:20210307235431p:plain

朝になるときにPCが音します。

6.2 モンスターを全部倒す。

2体ほどモンスターを倒した後、隣村の武器屋で最強武器と防具を購入。残りのモンスターはその最強武器で倒した。

所要時間:全部のモンスターを倒すのに、10分程度かかった。

f:id:kazuhironagai77:20210307235452p:plain

見つかったバグ:

  • 勝利のポーズの時に剣が頭に刺さる。
  • モンスターが後ろを向いているとプレイヤーの操作するキャラがすぐ後ろに立っていても気が付かない。

6.3 色々な武器を試す

全部の武器のアニメーションを見てみます。

所要時間:20分程度

見つかったバグ:

弓矢の時、片手剣のモーションになっています。

f:id:kazuhironagai77:20210307235525p:plain

弓と剣のような装備が可能でした。正し、見た目はオカシクない。

f:id:kazuhironagai77:20210307235544p:plain

魔法の杖を装備したら名前が枠からはみ出て表示されました。

f:id:kazuhironagai77:20210307235601p:plain

モーションは両手剣、片手剣、弓、杖など何種類かあった方が良いと思いました。

実際に、以下のアニメーションが提供されているのでそれは可能だと思います。

f:id:kazuhironagai77:20210307235617p:plain

後、結構3D酔いします。1時間プレイしたらきついかもしれません。今週はこれで止めます。

6.4 他に気が付いた事

魔法のeffectが一個しかないのは退屈です。10種類は欲しいです。

7.Levelデザイン

今の所、以下の部分しかありません。

f:id:kazuhironagai77:20210307235655p:plain

因みに作成した地図は以下の様になっています。

f:id:kazuhironagai77:20210307235713p:plain

この地図は結構いい出来ですので、実際のマップも同じに作成するのが良いかもしれません。

ただし、現在ABC、CDEはmap1。JKL、LMNはmap2。そしてYZとXYZはmap3に配置してあります。

この設定は変えたくないです。

ところで、環境でマーケットのフリーを検索すると質の高い完成品があります。

f:id:kazuhironagai77:20210307235731p:plain

これをそのまま使用するのも一つの手であると思います。

普通の箱庭的なゲームのマップのサイズってどれくらいなんでしょうか?

うーん。知らないですね。

やっぱりある程度は自分で作成する事でLevel Designの勉強をすべきですね。

色々考えましたが、このアイデアが一番現実的と思います。

上の地図の海の部分で3分割します。それぞれの陸地を別のマップで作成します。

こんな感じです。

f:id:kazuhironagai77:20210307235749p:plain

ここに今あるmap1、map2、そしてmap3を対応させます。

これで行きましょう。

8.まとめと感想

段々、ジグソーパズルが埋まるような感じでゲームとして成り立つには何をすべきなのかが分かって来ました。

来週は以下の事についてやります。

  • 対話システムとアドベンチャーゲーム本形式によるセリフの整理方法の考察
    • Data Tableを使用する事で、全てのセリフを一括で管理出来る。
    • 全てのセリフの前後関係がData Tableを見るだけで分かる。
  • Game Modeクラスの整理の続き
  • バグの直し
    • 勝利のポーズの時に剣が頭に刺さる。
    • モンスターが後ろを向いているとプレイヤーの操作するキャラがすぐ後ろに立っていても気が付かない。
    • 戦闘時の武器のモーションの追加
    • 魔法の杖を装備したら名前が枠からはみ出て表示されていたのでそれを直す。
    • 魔法のeffectを増やす。
  • Levelデザイン

以上です。