<前文>
今週も思いついた事をダラダラ書いて行きます。
1.英語の音素を教えない理由
私にとって英語と言えばアメリカ人がしゃべる言葉です。のでイギリス人の英語との違いは精々、関西弁と標準語ぐらいの違いと思っていました。今作成中の英語学習ゲームで、今週はERの音とARの音の違いについて調べてたのですが、ERとARの発音記号(IPA)はɜːとɑːとすっかり信じていたのですが、それはイギリス式の発音の場合でアメリカ式の発音はɝとɑɹ(単語による)になるそうです。ERの音は英語の発音において最も重要な音だと個人的には思っていますが、イギリス式の発音では存在しないと聞いて本当にびっくりしました。
英語の発音の学習において長年疑問だったのが日本語の五十音のように最初に全部の音を教えない事でした。これって教えないんじゃなくて教えられなかったんですね。アメリカ人はイギリス式の発音は良く分からないし、逆もしかりですし。更に日本人に教えるためには日本語の発音にも精通している必要がありますし。よくアメリカ人の英語の先生が日本人の生徒にseeとsheの違いを一生懸命教えようとしますが、日本語でもスィーとシーは全然違う音だとは知らないんでしょうね。よく子供が、欲しい(標準語)をホスィィイ(方言)と発音しているのを聞いて日本人はSとShの音が区別ついていないと勘違いしたんでしょうね。子供だって「静かにして、シー。」と言うのを「静かにして、スィー。」と言ったら大笑いしますよ。だから日本語でもスィーとシーは全然違う音です。
それを日本人の生徒が「先生違います。」と言うべきだったのに、先生が言っているのだから、きっと日本人はs とshの音の区別がついていないんだ。と更に勘違いしたんでしょうね。そのままボタンの掛け違いをしたまま50年以上、突っ走って来たんでしょうね。それで英語を1年以上勉強しても英語がしゃべれないし、更に聞き取れない人を大量生産しているんでしょうね。話は変わりますが、この先生と言う日本語に対応する英語はProfessor やdoctor(博士、Ph.D.の方)が正しいと思うんですよ。それで所謂英語の先生は、先生じゃないんですよ。ただの人。だから間違える事もあるし、その間違いを生徒から指摘されるのも当然有り得るレベルの能力しか有していないんですよ。
2.C-何とかについての考察2
こんなにc-何とかに世の中が影響されるとは思ってもいませんでした。個人的には夏までには収束すると予測していました。だから他人からアドバイスを求められると「決して日々の仕事や学業を疎かにしないように。聖書に書かれているような終末論的な世界が来ると期待して刹那的な行動を取ったり、そこまでは行かなくても、今日やらなくてはいけない事を今日と同じ明日がこない事を理由にサボったりしないようにしましょう。そのような行動は決して貴方の明日が良くなる結果に結びつきはしません。」と言っていました。
今も基本的にこの考え方は変わっていませんが、ひょっとするとあるイギリスの予測にあるように最悪まで行く可能性もある気がして来ました。これは極めて悲観的な予測で現実的ではありませんが、ちょっと考えてみます。現在、日本の人口における65歳以上の割合は、大体30%です。これらの人が全員罹患してしかも医療崩壊していて適切な治療が受けられない場合、その2割が亡くなられると思われます。すると30%の2割ですから全人口の6%ですね。うーん。言っては何ですが、全人口の6%ぐらいの人がいなくなったぐらいで国家が崩壊するわけはありませんね。
これが20代から50代の社会を支える年齢層の6%だったら、国家が崩壊する可能性もあるかもしれません。しかしその層は感染したとしても死ぬ事はないでしょう。医療崩壊して全く治療が受けられなくても20%が亡くなるとは考えられません。亡くなるのは精々2%ぐらいでしょう。今でも保健所で検査して貰えなくて家で薬飲んで寝ているだけの人は結構いるわけでその人達の2割が亡くなっているとは思えません。となると特定の職業の人の死亡率が極端に高くならない限り国家が崩壊するような事態は起きないと思います。
ここで、特定の職業の人と言いましたが、レジ打ちのように直ぐに変えの効く職業はどんどん変わりが入れるのでこの中には含まれません。医者やインフラを支えるエンジニアのように一朝一夕で成れない職業の事です。医者!ああ。医療従事者の感染率と死亡率は結構問題かもしれませんね。もし全ての医療従事者が感染してその内の10%が亡くなるようならば、結構国家が崩壊するかもしれませんね。特に医師の方は高齢者でも現役の方が多いので10%が亡くなる事態も絶対ないとは限りません。
これを防ぐためには病院がこのc-何とかに感染している可能性のある人は診察しなければ良い―言い方が悪かったです―このc-何とかに感染している可能性のある人が行く専用の診察所が有れば良い訳です。なるほど!これが武漢などで見られた野戦病院だったんですね。この病院に入ったら生きて出てこれない噂があると聞いた時私は一笑に付していました。しかしこの野戦病院の目的が、国家の安定の観点から一般の医療の崩壊を防ぐためなら、中の患者が治ろうが死のうが同じわけです。直すのは大変ですが死ぬのはほっとけば良い訳ですから…。
ただ日本でc-何とかに感染した人ためだけの野戦病院が作れるのかと言うと難しいかもしれません。更に地元の病院がc-何とかに感染している可能性のある人は診察しないと言うのはもっと難しいと思います。となると医療崩壊からの国家崩壊も0でないかもしれませんね。
<本文>
前回はGameCharacterクラスが実際に作成されているかを確認した所までやりました。
1.キャラクターの持ち物をGameInsatanceクラスの変数に保持させる
今週はGameInstanceクラスにこのキャラクターが保持しているアイテムや武具を保持する変数、更に装備している武器と防具を保持する変数を作成します。
1.ItemesDataの作成
Ch2のItemsDataを見ましたが、教科書のサンプルからは結構改良してましたがそのまま使用出来そうです。取りあえずは全く同じ物を作成します。
UObjectから作成しFTableRowBaseに変えてビルドしたら何をやってもずっとエラーになってしまいました。
以下に示すようにUSTRUCT()、struct、そしてGENERATED_USTRUCT_BODY()に変更した途端エラーが出なくなり正常に作動するようになりました。
これが原因だったのでしょうか?
後学のためにもう一回試してみます。
TestDataTableクラスをUObjectから作成します。
以下に示すようなコードが書かれています。
以下のようにコードを書き替えました。
ビルドします。
普通にビルド出来ました。
と思ったらUE4エディターがクラッシュしました。
UE4エディターが再起動しました。
問題なく動いています。
何か、何度もやっているようですが、これが正しいFTableRowBaseからの派生クラスの作成方法のようです。
問題が解決したので、ItemsDataの変数などを以下に示すように追加しました。
このクラスから派生したBPデータテーブルであるItemsとWeaponsも同様に作成します。
教科書のサンプルとほとんど同じなので作り方やデータについては省略します。
2.キャラクターが所持しているアイテムなどのデータを保持する変数をGameInstanceクラスに作成する。
作成しなければならない変数は以下に示した物です。
ItemDataはキャラクターが所有しているアイテムのデータを保持する変数です。Items変数にこのデータを保持させます。
同様に、WeaponsDataはWeaponsに、SoldierWeaponsDataはWeaponEquipped、SoldierArmorDataはArmorEquipped、SoldierWeaponEquippedDataはIsWeaponEquipped、そしてSoldierArmorEquippedDataはIsArmorEquippedがそれぞれデータを保持します。
最後のSoldierBaseATKDataとSoldierBaseDefDataはMainCharacter内のパラメーターが同様のデータを保持しているはずです。
ビルドしてみます。
成功したのでこのまま先に進みます。
ここに更に、ワープする前のマップ上の座標を保持する変数が必要ですが、それはBPで作成しても良いと思います。
2.Player Pawnの作成
このまま、my Combat Engineを作成しても良かったのですが、そうするとアイテムや武器を保持したまま別のマップに移動しているかのチェックが出来ません。そのチェックをするためには道具屋や武器屋を先に作成する必要があります。そのために教科書を読み直してみたら、最初にPlayer Pawnを作成していました。
正直、教科書で作成したPlayer Pawnのカメラ位置は快適ではなく、敢えてもう一度作成する価値はないと思っています。ただし単にもう一度作成し直すのではなく、改良して使用し易いようにするのならもう一度作成してもいいかなと思っています。
うーん。止めます。
UE4の付属のPlayer Pawnの方が操作もしやすいしカメラワークも見易いです。戦闘画面にワープした場合に別のPlayer Pawnを作成するかもしれませんが、今回はUE4付属のPlayer Pawnを使用する事にします。
ただし、キャラのメッシュは交換します。
1.Player Pawnのメッシュの交換
このやり方を忘れてしまいました。一番、手っ取り早いのは、ch2で作成したデータをそのままインポートする方法だと思いますが兎に角やり方を忘れてしまったので、まず自分が書いたブログを読み直してみます。
ここにやり方が書かれていました。
本来ならch2からインポートして終わりにすべきなのでしょうが、本当にやり方を忘れてしまったので、自分の書いたブログを元にしてもう一度やり直します。
以下に示すようにThirdPersonCharacterのSkeletal MeshをApprenticeSKに変えます。
2.Player PawnのAnimクラスのインポート
ん。ひょっとするとこのAnim Classに指定されているクラスをインポートすれば全て解決なのでは?
試してみます。
インポート出来たのでテストします。
その通りでした。
出来ました。
3.教科書の内容の確認
一応、Player Pawnについて教科書で説明していると個所をもう一度読み直して確認します。
GameModeのコンストラクター内で上記の指定をしていました。これをやります。というか何でこれを今まで指定しないのにThirdPersonCharacterがPlayer Pawnに選ばれているんでしょうか?
まずARPGGameModeBaseのコンストラクター内に以下のコードを追加します。
ビルドします。
成功したのでテストします。
UE4エディターがクラッシュしました。
再起動したら普通に動きました。
これってthirdPearsonCharacterを静的に配置していたんですね。それでDefaultPawnClassで指定しなくてもこのthirdPearsonCharacterのインスタンスがPlayer Pawnに選ばれたんでしょうか?
試しに新しいレベルを作成してそのgamemodeをARPGGameModeBase から派生して作成したRPGGaemModeBPに指定します。
レベル上にはthirdPearsonCharacterは配置しません。これでplayします。
普通にthirdPearsonCharacterがPlayer Pawnに選ばれました。
今度はARPGGameModeBaseのコンストラクター内でのDefaultPawnClassの指定をコメントアウトします。
更にDefaultPawnClassの指定をdefaultpawnに変更します。
これで試してみます。
エラーになってUE4エディターがクラッシュしました。
なるほど。結構分かって来ました。
DefaultPawnと指定されている場合は、静的に配置されたthirdPearsonCharacterがPlayer Pawnに選ばれるみたいです。
断定するためには更なるテストが必要ですが、教科書もこれ以上の説明はありませんし、この辺でDefaultPawnClassについての調査は止めておきます。
3.Enemy の作成
教科書を見ると、作成の順番が、敵の作成、Combat engineの作成、そして道具、武器の作成になっています。それじゃ敵から作って行きます。
教科書の設計を簡単にまとめると以下に示した図のようになります。
簡単に説明すると敵でも味方でもキャラクターを作成する時は、GameCharacterクラスのコンストラクターで作成します。ただし敵のモンスターを作成する時はEnemy Infoから作成したデータテーブルEnemiesを使用して作成しますが、味方のキャラクターを作成する時はCharacterInfoから作成されたデータテーブルとCharacterClassInfoから作成されたデータテーブルの両方を使用して作成します。
非常に混乱させられるのがEnemy Infoに指定されているデータの種類はCharacterClassInfoに指定されているデータに対応しているのに名称はCharacter Infoと対応している所です。更に言えばCharacterInfoが何故必要なのかが良く分からないです。
ので以下のように設計を変更します。
ここで言うCharacter Classのクラスは職業的なクラスを指していると考えられるので、敵の職業に対応する種族を名前に入れようと思いましたが、それよりモンスターの方が分かり易いと考えEnemy Monster Infoと名付けました。
1. Enemy Monster Infoの作成
Enemy Monster Infoを作成していきます。
もう騙されません。
以下のように直します。
ビルドします。
成功しますが、UE4エディターがクラッシュします。
UE4エディターを再起動します。
もう一度ビルドします。
今度は何の問題もなく成功します。
パラメーターは以下のようにしました。
魔法をどのように管理するか考えていませんでした。これは後から考えます。
それ以外はこれで良いはずです。
2. Enemy Monsterの作成
以下のように作成しました。
このEnemy Monster元のEnemy Monster Infoのパラメーターを変更すると記入したデータが全部消えてしまうんですが、何か保存する手段はないんでしょうか?
エクセルで元のデータを管理しておけば何とかなるかもしれませんね。この辺も後で考えます。
3. GameCharacterクラス内に敵のモンスターを生み出す関数を作成する。
以下に示すように作成しました。
因みに、キャラクターを作成する関数名も、
上記のような名前に変更しました。
4. 作成した関数、CreateEnemyMonster()をテストする。
この関数が正しく作用するかテストしようと思ったら、前に作成したCreateMainCharacter()関数を呼び出しているRPGGameInstanceクラス内のinit()関数をどこからも呼び出していない事に気が付きました。教科書のサンプルの場合、RPGGameModeのBeginPlay()関数から呼び出しています。
呼び出してはいないはずなのにplayボタンを押すと、init()関数が呼ばれています。実際init()関数が呼ばれる事で作成されるMainCharacterのパラメーターの値を読み取る事が出来ます。
???となっています。
ちょっとこの辺で今週は一端止めて来週もう一度考えながら今週作成した部分を復習します。
4.感想とまとめ
今週は、すっきり進んでいたと思ったら、結構分からない部分が出て来たので、一端中止して、その分からない部分を来週もう一度考える事にしました。良く分からない部分を以下にまとめておきます。
1.キャラクターのジャンプ
作成している時には、上手くスクリーンショットがとれなかったので書かなかったのですが、ジャンプされるとモーションがかなりオカシイです。
2.DefaultPawnClassについて
Player Pawnの作成の説明で大体合っていると勝手に納得していたのですが、以下に示すように最初から作成されていたGameModeクラスのコンストラクターでDefaultPawnClassが指定されていました。
これを考えていなかったです。もう一度、DefaultPawnClassの指定について、GameModeクラスのコンストラクターでDefaultPawnClassが指定されてる事実を考慮して考えてみます。後来週は必ず仮説を確認するためのテストも行います。
3.Init()関数の呼び出し
私の理解している範囲では、どこからも呼び出されていないはずなのにplayを押して瞬間に呼ばれています。この謎も解明します。
4. PureVirtualFunctionを呼び出している(おまけ?)
Playを終了した時に、PureVirtualFunctionを呼び出しているという警告が2回ぐらい表示されました。いつも出るわけではないので、もしかしたら偶々かもしれませんが来週もこの警告が見られたらこの原因も解明します。