<前文>
前回、前文を止めて全力でプログラミングをやりましたが結果はあまり変わりませんでした。のでやっぱり前文は書く事にします。
このブログのプロジェクトとは別にプレイすると英語の音素が聞き取れるようになるゲームを開発していますが英語の音素に関して色々な事が分かって来たので書き記して置きます。
<仮説>Short U 音とschwa音は同じ音?<仮説>
Short U 音とは発音記号(IPA)でʌと表される音です。日本語ではウの様なアの様な音に聞こえます。Schwa音は曖昧母音と言われたりする音で発音記号(IPA)はəと書かれたりします。この音は非常に小さい音で、はっきり言うとよく聞き取れない音です。非常に曖昧な音で、あるかないかは分かりますがどんな音かを言ってみてと言われると、ウーン。となってしまう悩ましい音です。See YouのYouをschwa音で発音するとSee Yaになると言われていたり、aboutのaの音がschwa音なので厳密に言えばアの音に近い音なのかもしれませんが実際の会話で聞いてる分にはアの音に近いと言えるほどハッキリは聞こえません。
この二つの音は少なくとも私が理解する限りは全く違う音のはずなのですが、沢山の英語ネイティブのShort U 音とschwa音を録音してまとめた後で比較したら、全く区別がつかないんです。勿論、個人個人でこの二つの音を比較した場合は明確な違いがあるんです。しかし全部合わせてshort Uの音、schwaの音と分けて比較すると全く区別付きません。声が大きくてはっきり発音する人のschwa音はウもしくはアと聞こえます。逆に声が小さくあまりはっきり聞き取れない人のshort U 音はschwa音のように曖昧です。
ここからが私の仮説です。
それで何がこれらの音を区別しているのか考えたら、音量と長さ(後、多分音程)と思ったんです。そしてこれらは個人的には絶対的な基準があったとしても、英語圏全体ではあくまで相対的で単独で抜き出したら区別つかなくなる音じゃないのかと思ったんです。
単独で抜き出したら区別がつかない音、こんなのが存在するなんて日本語を母語とする我々からは想像つきませんよ。アとオの音は似ていますが単独で聞いても区別付きます。もしウとゥみたいな音量の大小だけで区別する別の音が日本語にあったら理解出来たかもしれませんね。
どうですか?
これってあんまり聞かない意見ですよね。しかしこの仮説が正しいかどうか証明する方法があると思います。
IPAの発音記号が読め、かつ英語が母語の人達にその人が考える正しいshort U 音とschwa音を録音してもらいます。これを100人分ぐらい集めます。今度は彼らに被験者に代わってもらってその100のサンプルのshort U 音とschwa音のうちどちらかのみを聞かせて正解を当ててもらいます。つまり一人で100回テストを受ける事になります。
もし100人の日本人がそれぞれアとオの音を録音してその100人が100人分のアとオからどちらか一方だけが発音され、アかオかを当てるテストを受けたらどうなると思いますか?100人全員が100点取りますよね。それでなければ日本語で会話は出来ません。
比較する対象がない状態で、Short U 音とschwa音の区別を英語ネイティブの人達は完璧に出来るのでしょうか?出来なければ、私の仮説、short Uの音とschwaの音は、あくまで相対的な音量と長さ(後、多分音程)の違いで決定される音である。が正しいと証明できると思います。
それでは今週の勉強を始めます。
<本文>
先週は、pure virtual function is …とエラー表示されてエディターがクラッシュする問題を解決しようとしたら以外に難しくて結局解決出来ないで終わりました。
今週は、この問題に集中して解決しようと思います。
ただしずっとこの問題だけ関わっている訳にもいかないので今週、この問題が解けなければ無視して先に進む事にしました。クラッシュするのはUE4C++を書き直してビルドした時の最初の一回だけなので、その一回さえ我慢すれば良い訳ですから。
1.エラーの原因
1. GameModeの自作もう一度
先週、エラーの原因が分からず最初から作成し直す事にしました。新しいプロジェクト(ch4)は自作したGameModeにコードを書き込んでビルドし、UE4エディターからplayをしたらpure virtual function…と言うエラーが表示されクラッシュしました。
あれから色々考えましたが、やはり自作したGameModeに問題があると思います。
ので、また新しいプロジェクトを作成して試してみようと思います。ただし今回はGameModeを最初に自作します。プロジェクト名はch4_1とします。
今回は最初にGameModeを自作しました。親クラスはAGameModeBaseクラスです。名前はRPGGameModeBaseです。
作成したGameModeクラスからBPのGameModeを更に作成し、それをDefault GameModeにセットします。
DefaultPawnClassにThirdPersonCharacterをセットします。
この状態でビルドし、エディターのプレイボタンを押してみます。
クラッシュしませんでした。
うーん。
今度はRPGGameModeBaseクラスにコンストラクターを追加してみます。
先週、この部分を追加した所、pure virtual function…と表示されてクラッシュしました。
これでビルドしてプレイしてみます。
予想に反してクラッシュしませんでした。
コンストラクター内のコードを追加して試しましたが
全く問題なくプレイ出来ました。
うーん。
この結果から考えるとGameModeクラスそのものの問題ではなくGameModeクラス+何か=クラッシュと考えられます。
2. 先週の作業の確認とか
以下に先週行った作業をまとめました。
- UObjectから作成したクラスをFTableRowBaseから派生した構造体に変更
- 1.で作成した構造体を元に、DataTableを作成。
- 敵のモンスターや味方のヒーローの特性を決定するGameCharacterクラスをUObjectクラスから作成
- 3.で作成したGameCharacterクラスにCreateYourHero()関数を追加作成。
- GameModeクラスにRPGGameModeBaseを作成。
- GameInstanceクラスにRPGGameInstanceを作成。
- 6で作成したRPGGameInstanceクラスにコードを追加
- ItemData構造体を2.と同じ方法で作成。
- 8.からDataTable、WeaponsとItemsを作成。
- 3Dモデル, ModularRPGHeroesPolyartをインポート。
- ThirdPersonCharacterのSkeltalMeshとAnimClassを変更。
- RPGGameModeBaseクラスにコンストラクターを追加。->クラッシュ
これらのどれかの作業と自作したGameModeクラスの干渉がエディターのクラッシュを引き起こしていると考えられます。
それで考えたんですが、作業量自体は少ないので一個だけづつ試していこうと思います。
今まで、プログラムを書いていてエラーが起きた時は、間違えている箇所が大体想像出来ました。今回ほど良く分からないエラーは正直、経験した事ありません。何故良く分からないかと言えば情報が少ないからです。ので色々な情報を得るためには一個ずつ試していくのが有効と考えました。
2.1 3D モデルの追加とSlektalMeshとAnimClassの変更、更にFTableRowBaseの追加
先週、一番怪しいのはModularRPGHeroesPolyartかも知れない。と言って終わりました。かなり強くそう思っていたので、ブログを書いた後にこれと自作のゲームモードのコンビネーションを試しました。
結果は全く大丈夫でした。
更に、1.のUObjectから作成したクラスをFTableRowBaseから派生した構造体も追加したのですが、全く大丈夫でした。
この状態で、いくら自作のGameModeにコードを追加してもプレイした後にエディターがクラッシュする事はありませんでした。
ので、1、8、10、11は今回のテストから除外します。
2.2 自作のGameInstanceクラスの追加
以下に示すようにGameInstanceクラスからRPGGameInstanceを作成しました。
なんでUGameInstanceがエラーになっているんでしょうか?多分Flashすれば直るんでしょうが何か気になります。
取りあえずビルドしてみます。
一応確認のため、playもしておきます。
Playを終了したらエディターがクラッシュしました。
Pure virtual function…云々とは出て来ませんが、0xfffffff…にアクセスして云々と書かれている辺り、同じエラーの気がします。
RPGGameModeBaseクラスにコードを追加してテストしてみます。
ビルドしてplayします。
Playを終了してもクラッシュしませんでした。
うーん。
Game Instance Classに作成したRPGGameInstanceクラスから作成したBPクラスをセットします。
これでテストします。
RPGGameModeBaseクラスに追加したコードをはずします。
ビルドしてplayします。
Playを終了したら、
pure virtual function…云々が呼ばれるエラーが起き、エディターがクラッシュしました。
もう一度試してみます。
今度は、RPGGameModeBaseクラスにコードを追加します。
ビルドしてplayします。
Playを終了したらエディターがクラッシュしました。
いきなりですが、エラーの核心に迫って来ましたね。
整理しましょう。
UE4C++のGameMode並びにGameInstanceを作成します。次にそれをマップ上で使用するためにプロジェクトセットでセットします。そして作成したGameModeにC++のコードを追加するとそのたびにplayを終了する時にエディターがクラッシュします。
2.3 もう一度試してみる
また新しいプロジェクトを作成して試してみようと思います。ただし今回はGameInstanceのみ自作します。プロジェクト名はch4_2とします。
まずGameMode並びにGameInstanceを作成します。
それらのBPを作成してProject Settingからセットします。
ビルドします。
エディターからPlayします。
止めます。
エディターがクラッシュしました。
2.4 UE4.24 で試してみる。
今度は新しいプロジェクトを.24で作成して試してみます。何かこのエラーは.25のバグのような気がするからです。プロジェクト名はch4_3とします。
前回と同じようにGameMode並びにGameInstanceを作成します。
それらのBPを作成してProject Settingからセットします。
ビルドします。
エディターからPlayします。
止めます。
全く正常ですね。何にも起きません。
次に、自作のGameModeにコードを追加します。
ビルドします。
エディターからPlayします。
止めます。
全く正常です!
3. Pure Virtual function…のエラーのまとめ
このエラーはUE4の.24でプロジェクトを作成すれば起きない事が分かりました。
もしかしたら自作のGameModeとGameInstanceを両方使用する場合は、絶対しなければならない事があるのかもしれません。もしくは単に.25のバグかもしれません。
しかしUE4の.24でプロジェクトを作成すればこの問題が回避出来るならば、私にとってはそれで充分なのでそうします。
2.4.24での作成
折角ですので、ch4_3をそのまま使用します。
最初ch4のバージョンを4.25から4.24に変換すればいいじゃん。と思ってやったのですが、マップが変換出来ないとか出て来て駄目でした。のでch4_3をベースにして大体はch4のコピーでやっていきます。
1. YourHeroClassInfoクラスの作成
出来ました。コードはch4の丸コピーです。
この構造体からdata tableを作成します。名前はYourHeroClassesです。
ここからそれぞれのデータを打ち込んでいくのですが
今回で三回目になると流石に面倒くさくなります。Ch4のデータを直接インポートする方法を探してみます。
ここにcsvにしてexportする方法が説明されていました。そのcsvをインポートすれば出来そうです。一工程ではないですがまあ良いでしょう。これでやります。
それでdata tableからcsvファイルの作成方法ですが、以下に示すように、右クリック、export as CSVを選択、
で終わりでした。
インポートの仕方はここにありました。
出来ました。
こんな簡単だったのか。もっと早く勉強すれば良かった。
2. GameCharacterクラスの作成
今度はUObjectクラスから敵のモンスターや味方のヒーローの特性を決定するGameCharacterクラスを作成します。
しました。
変数も追加します。
3. GameCharacterクラスのCreateYourHero()関数を実装
はい。これもch4からコピーします。
あれ?
FNameがエラーになっています。今までこんなエラーはなかったはずですが。
このサイトにFNameについての解説がありました。
要するにdereferenceせよ。と言う事です。
うーん。でも今までしなくても出来ていた訳で、良く分からないですね。
ビルドしてみます。
エラーになってしまいました。
試しにdereferenceしてみます。
ビルドします。
うーん。ビルドは成功しました。が良く分からないです。
いや意味は今回の方が良く分かるんですが、今までエラーにならなかったのが良く分からないです。
確認のためにプレイしましたが、クラッシュしませんでした。
4. RPGGameInstanceクラスにコードを追加
Ch4のRPGGameInstanceのコードをそのまま使用します。
ビルドしてプレイします。
エディターは全くの正常でクラッシュする気配すらありません。
実際にGameCharacterクラスが作成されているのか以下のコードでテストします。
出来てますね。
5. ItemData構造体を作成
これもCh4のコードをそのまま使用します。
ビルドすると成功しますが、エディターはクラッシュしました。これもいつもの事ですのでオーケーです。
Ch4を開き
をcsvファイルとしてexportします。
そのcsvファイルをch4_3でインポートします。
出来ましたね。凄い簡単です。
中のデータを確認してみます。
おお!出来てると思ったら
がありません。元のtextureをmigrateするのを忘れていました。
Ch4からmigrateします。
あれ?一個も表示されません。ひょっとして失敗した?
フォルダーを開いたらしっかり入っています。
もしかしたらアセットのデータの管理方法が.25から変わっていてそれ以前のversionだと使用出来ないとか?
Ch2からmigrateしてみます。
うん。出来ましたね。
Imagesの方は要らないので消去します。
出来ないですね。
こいつを残しておくと後で強大な敵になる気がしますが、そん時はまた最初からやり直します。
一応ビルドしてプレイしておきます。クラッシュとかは起きませんでした。
Data tableに絵を追加しました。
6. ModularRPGHeroesPolyartをインポートします。
Ch4からmigrateしても良かったのですが、せっかく.24を使用しているので
ここから直接入れます。
なんと.25も使用出来る様になってました。
アニメーションもch2からインポートします。
パッと見ですが使えそうです。
7. ThirdPersonCharacterのSkeltalMeshとAnimClassを変更します。
変えました。
普通に動いていますがジャンプがオカシイです。
そう言えば何処かでジャンプを直しました。
ここで直していました。
同じように直します。
直りました。
8. RPGGameModeBaseクラスにコンストラクターを追加。
コンストラクターは既に追加していますが、中身を書いていませんでした。ので追加します。
取りあえずこのコードでやります。
DefaultPawnClassの設定をThirdPersonCharacterに戻します。
テストします。
ビルドした後、プレイしましたがクラッシュしません。全く問題ありません。
3.まとめと感想
今週は、先週解けなかったpure virtual function…のエラーの原因を突き止め直しました。正直このエラーは直せると思っていなかったので自分で自分を褒めて上げたいです。しかし実際の予定はまだ大幅に遅れてしまっています。慌ててはいけませんが出来るだけ予定に追い付けるようにします。