‫なるほど｡
‫そこで､ このビデオでは､ ポンズにデスを実装することを目標としています｡
‫だから､ うちのタワーから2､ 3回殴られたら､ タンクが死んだから消えたとわかるはずです｡
‫そして､ 私の技量が十分であれば､ 1つでも破壊に踏み切れば､ それも消えるのがわかるはずです｡
‫そこで､ この動画では､ これらのポーンに死を実装します｡
‫こんにちは､ お帰りなさい｡
‫今､ すでにポーンに弾丸が当たったときにダメージを与えています｡
‫あとは､ 死後をどうするかですね｡
‫つまり､ 特定のアクターの破壊を処理するための何らかの関数が必要になるのです｡
‫そこで､ ハンドル破壊機能を作ることにします｡
‫また､ アクターダイ関数も必要です｡ これは､ ゲームモードが､ 私たちの世界のアクターが死んだときに何が起こるかを処理できるようにするもので､
‫特定のポーンの健康値がゼロになったときに､ このアクターダイ関数を呼び出すことにします｡
‫では､ このシステムをどのように導入していくのか､ 少しロードマップのようなものをお話ししましょう｡
‫弾丸があり､ それがダメージの適用を呼び出していて､ その結果､ ダメージを受ける関数がヘルスコンポーネントのデリゲートブロードキャストに応答していることが分かっています｡
‫だから､ そこからどうするか考えないといけない｡
‫さて､ 私たちのゲームモードは､ アクターが死んだときに処理する機能を持つことができます｡
‫つまり､ 受けたダメージでは､ 体力が0になるかどうかを確認することができるのです｡
‫そして､ その時点でゲームモード上のアクター死亡関数を呼び出し､ そこからポーンが破壊を処理できるようになります｡
‫つまり､ 最終的には､ 死んだアクターのハンドル破壊関数を呼び出すのは､ ゲームモード次第ということです｡
‫というわけで､ ちょっとしたゲームプランができましたので､ これを実行するためのステップを概説しましょう｡
‫まず､ 破壊処理関数を作成し､ ポーンのいずれかが死んだときに起こるべき機能を処理するために､
‫これをポーンの基底クラスに配置します｡
‫タンクとタワーのクラスにもこれを実装します｡ タンクとタワーは､ それぞれ死んだときに独自の機能を持つからです｡
‫それから､ アクターの死亡関数を作成して､ これをゲームモード・クラスに置き､ そこから破壊処理を呼び出せるようにします｡
‫その後､ ゲームモード上のアクターdied関数でhandle destructionを呼び出し､ ヘルスが0になったらヘルスコンポーネントからアクターdiedを呼び出せるようにします｡
‫では､ まず最初にハンドルの破壊関数を作ってみましょう｡
‫そこで､ このベースポンドHで､ このハンドル破壊機能を追加したいと思います｡
‫さて､ この関数はゲームモードから呼び出す予定です｡ つまり､ パブリック関数である必要があるので､
‫この関数をパブリックセクションに配置することができます｡
‫voidになるので､ ハンドル破壊と言うことになります｡
‫これで､ 入力パラメータを取る必要がなくなりました｡
‫それは単に､ この特定のポーンの破壊を処理することになるのです｡
‫そこで､ この関数をベースとなるpawn CPファイルに実装してみましょう｡ この関数は､ コンストラクタのすぐ下に配置することにします｡
‫そこで､ ハンドル破壊を行い､ 関数名の直前にベースポーンクラス名を配置することにします｡
‫さて､ これはベースポーンに基づくポーンのどれかが死んだときに起こることになります｡
‫そこで､ ハンドルの破壊関数で何をするのか､ ここにto doを配置します｡
‫ここでは､ ポーンが死ぬことに関係する視覚効果､ 聴覚効果をすべて扱いたいと思います｡
‫ですから､ ビジュアルスラッシュ・サウンドエフェクトということにしておいて､ このコースの特殊効果とサウンドのパートに入ったときに､
‫これを忘れずに実装するようにします｡
‫今､ ハンドル破壊がありますが､ タンクとタワーの両クラスにもハンドル破壊の関数を置いて､
‫これらのポーンが死んだときの処理をしたいと思います｡
‫そして､ 最もシンプルな破壊の実装は､ おそらく我々のタワーのために行われるでしょう｡
‫そこで､ Tower Hに入り､ ここにhandle destructionというパブリック関数を追加してみましょう｡
‫そこで､ void handle destructionと言い､ これを実装してtick関数のすぐ下にCPを塔載することにします｡
‫だから､ ここにあるチックはハンドル破壊で､ 関数名の前にちょうどタワーをつけるんだ｡
‫タワーのハンドル破壊関数では､ スーパーバージョンを呼び出して､ ベースポーンのハンドル破壊が呼び出され､
‫タワーが死んだときの視覚効果や音響効果を得られるようにしたいと思います｡
‫だから､ それが呼ばれることを確認するために､ スーパーハンドル破壊と言うことにしているんだ｡
‫そしてその後は､ 単純にタワーを破壊するだけです｡
‫これで､ この仕組みがわかりました｡
‫destroy関数を呼び出すだけで､ タワーの破壊を処理することができます｡
‫これを保存して､ タワーとCPのファイルを閉じると､ 今度はタンククラスにハンドル破壊関数を配置することができます｡
‫そこで､ tankに行き､ tick関数の下にhandle destructionというパブリック関数を宣言してみます｡
‫そして､ Tank CPに行き､ ここのチックのすぐ下にこれを実装します｡ 関数名の前にタンクを付けるのを忘れないようにします｡
‫さて､ タワークラスと同じように､ スーパーハンドルの破壊を呼び出したいと思います｡
‫そうすれば､ その視覚効果や音響効果を得ることができます｡
‫さて､ タンクのほうは､ ちょっと変わったことをします｡
‫戦車を破壊するのではなく､ 隠したい｡
‫そして､ TIC機能を無効化することで､ 世界に存在し､ 私たちが所有することになるのです｡
‫だから､ 今でもカメラからはその景色が見えるんです｡
‫ただ､ 私たちはそれを見ることも動かすこともできないでしょう｡
‫そこで､ 戦車を隠すために､ ゲーム内でset actor hiddenという関数を呼び出し､ booleanを受け取ります｡
‫そして､ もしtrueでパスすれば､ 効果的に戦車を隠すことができます｡
‫あとは､ テロップを無効にしたいのですが､ そのための機能もあります｡
‫セットアクターチックを有効にするというものです｡
‫そして､ このためにfalseを渡すと､ タンクの刻みを無効にすることができます｡
‫これで､ ハンドルの破壊機能は完了です｡
‫そこで､ ハンドルの破壊関数を用意しました｡
‫次のステップは､ ゲームモードでアクターが死ぬ機能を作ることです｡
‫では､ それを実装してみましょう｡
‫ここでは､ Tune Tanksゲームモードで､ アクターdied関数を作成することができます｡
‫そこで､ publicセクションを追加して､ actor died関数を作成します｡
‫これで無効となり､ アクターが死亡したと言うことになります｡
‫そして､ これは単に死んだアクターと呼ばれるアクターポインターを取ることができ､ 今私たちはタンクゲームモードを調整するために死んだアクターを実装することができます｡
‫CP だから､ ここに置いて､ 名前の前にチューンタンクのゲームモードを付けると､ 今度はアクターが死んでしまう機能です｡
‫今度は､ 死んだアクターがタンクかどうかを確認したいのですが､ そのためにはタンク用の変数が必要になります｡
‫そこで､ ゲームモード「チューンドタンク」に話を戻します｡
‫プライベートセクションを作り､ タンク変数を追加してforward declareするつもりです｡
‫そして､ これはAタンクポインタのタイプで､ 単純にこのタンクを呼び出すつもりです｡ そして､ タンクの池のアドレスでこれを初期化する必要があり､
‫そうすれば再生を開始できます｡
‫begin playはprotected関数なので､ ゲームモードではprotectedのままにして､ begin,
‫playをオーバーライドできるようにします｡
‫そこで､ virtual void, begin, play, overrideと言い､ ここではチューンタンク､ ゲームモードで実装できるようにしました｡
‫うん｡
‫だからvoid begin playになるし､ チューンタンク､ ゲームモードのクラス名を使うつもりです｡
‫そして､ まずはスーパービギープレイを呼び出します｡
‫そうすれば､ 親機能を手に入れることができ､ ゲームプレイのスタティックを使ってプレイヤーのポーンを手に入れることができるのです｡
‫そこで､ まずゲームプレイのスタティックを盛り込みますが､ それはすでに見たようにキスマイスラッシュのゲームプレイのスタティックにあります｡
‫そして､ ここで「タンク」を取り出して､ ユースゲームプレイのスタティックの値を割り当てることができます｡
‫ギタリストの椰子｡
‫さて､ これはワールドコンテキストオブジェクトを受け取りますが､
‫これを利用することができます｡
‫jet playerはAポインタを返し､ tankは子クラスであるA tank型であることがわかりました｡
‫そして､ この結果をAタンクポインタに格納したい場合は､ そのAタンククラスにキャストする必要があることがわかりました｡
‫そこでまず､ タンクヘッダーを搭載します｡
‫だから､ タンクHを含むと言いながら､ タンクにキャストするんです｡
‫そこで､ cast to a tankと言いながら､ get player --から返された値をキャストしています｡
‫だから､ ここの括弧の中に入れておく｡
‫そして今度は､ プレイヤーへのポインター--Aタンクポインターの形で--を持つことになります｡
‫では､ タンクができたので､ 死んだアクターがタンクであるかどうかを確認します｡
‫つまり､ デッドアクターがダブルでタンクに等しい場合､ タンクはヌルになる可能性があると言えるのです｡
‫TankがNULLでdead actorがタンクそのものを参照している場合は､ ifチェックに失敗し､ NULLポインタにアクセスしようとはしないので､
‫この内部まで到達することはないからです｡
‫さて､ 死んだアクターが実は戦車だった場合､ 戦車ハンドルの破壊関数を呼び出したいと思います｡
‫そこで､ タンクハンドル破壊と呼ぶことにします｡
‫さて､ ハンドルの破壊関数を呼び出した後､ タンクポッドの入力も無効にしたいので､ タンクを取得して､
‫タンクが継承するdisable inputという組み込み関数を呼び出すことができるようにします｡
‫無効化入力にはAプレイヤーコントローラが必要になりました｡
‫さて､ タンククラスは､ タンクHに来ると､ プレーヤーコントローラのref変数を持っていることがわかります｡
‫参照ではないので､ ポインタになります｡
‫むしろタンクプレーヤーコントローラーと呼びたいくらいです｡
‫では､ 実際に､ このまま名前を変えてみてはどうでしょう？
‫これは､ 開発者が変数に悪い名前をつけてしまったことに気づいたときに､ よくやることです｡
‫そこで､ このコードでは､ これを簡単に行う方法を用意しています｡
‫この変数をハイライトしてF 2キーを押すと､ 名前を変更するように要求されます｡
‫これをタンクプレーヤーコントローラーと呼ぶことにします｡
‫では､ これをご覧ください｡
‫ここではタンクプレーヤーコントローラーと呼ばれています｡
‫タンクCPに行くと､ ここでもリネームされているのがわかります｡
‫だから､ プレイヤー､ コントローラー､ レフなどのインスタンスをいちいち探しに行かなくてもよかったんです｡
‫タンクプレイヤーコントローラーで検索すると､ ここで使われているのはどこも変わっていることがわかりますね｡
‫だから､ リファクタリングのスキルは高いと思いますね｡
‫さて､ ここ「Tune Tanks」のゲームモードでは､ 戦車の入力を無効にする必要がありますが､ これにはプレイヤーコントローラーが必要です｡
‫そこでまず､ if tankと言って戦車のプレイヤーコントローラーが有効であることを確認し､ そのプレイヤーコントローラーにアクセスする必要があります｡
‫しかし､ tankでは､ プレイヤーコントローラの変数がプライベートであることを思い出してください｡
‫さて､ これを公開してパブリックにするか､ この変数に対してパブリックなゲッター関数を作成することができます｡
‫むしろ､ パブリックゲッターを作った方がプログラミング的には良い｡
‫このパブリック・セクションに､ タンク・プレイヤー・コントローラのパブリック・ゲッターを作成することにします｡
‫この関数は､ get tank playerと呼ばれます｡
‫コントローラゲッターは通常､ 変数名の前にgetを付けます｡ また､ この関数はこのクラス内の何かを変更するためのものではなく､
‫プレイヤーコントローラを返すだけなので､ 一般的にコストをかけて作られています｡
‫そこで､ リターンタンク・プレイヤー・コントローラと言うことにして､ それだけを実行することにしました｡
‫戦車のプレイヤーコントローラのパブリックゲッター関数ができたので､ ゲームモード内からここのプレイヤーコントローラにアクセスできるようになりました｡
‫つまり､ if tankが戦車のプレイヤーコントローラーを取得し､ ここでその関数を呼び出すということです｡
‫そして､ この if 文の内部まで到達したら､ プレイヤー・コントローラは有効なので､ この tank disable
‫input の呼び出しをここに移動して､ disabled input にタンクのプレイヤー・コントローラを渡すことができます｡
‫そこで､ ここでもタンクゲット・プレイヤー・コントローラーと呼ぶことにします｡
‫プレイヤーコントローラにアクセスしている間に､ プレイヤーコントローラのbe show mouse
‫cursor Booleanメンバ変数を取って､ これをfalseに設定したいと思います｡
‫そこで､ 入力を無効化し､ マウスカーソルが表示されないようにもしています｡
‫それで､ タンクが死んだときの機能を処理するようになっています｡
‫さて､ 死んだアクターがタンクでない場合､ それがタワークラスのインスタンスであるかどうかを確認したいと思います｡
‫そこで､ ここにelse ifを追加します｡
‫では､ このelseifの条件はどうなるのでしょうか？
‫さて､ 死んだアクターがAタワーに投げられるかどうかを確認したいのですが､ それにはタワーのクラスが必要です｡
‫だから､ タワーも含めて｡
‫そして､ キャスティングに挑む｡
‫そこで､ 角括弧と括弧を取るcastと言うことにします｡
‫そして､ 私たちも鋳造しているものは塔であり､ 鋳造しているものは死んでいるのです｡
‫アクターは死んだアクターをキャストしようとします｡
‫あとは､ このキャストの結果を実際に代入して､ ローカル変数を作成します｡
‫ここでは条件として､ 塔のポインタを言うことができ､ この破壊された塔を呼び出し､ このキャストから返された値を代入することができる｡
‫そうすると､ この破壊されたアクターにアクセスできるようになります｡ これは､ 死んだアクターをタワーにキャストしたものです｡
‫さて､ これが成功したら､ elseifの中まで作ることになります｡
‫そして､ 破壊されたものを取ることができるのです｡
‫タワー､ そして私たちは単にハンドル破壊と呼ぶことができます｡
‫これで､ ゲームモードのアクターが死ぬ関数ができあがりました｡
‫これでステップ2は完了です｡
‫アクター死亡関数を作成し､ ついでにアクター死亡関数でハンドル破壊も呼び出した｡
‫そこで､ 最後のステップとして､ ヘルスがゼロになったときにアクターが死亡したことを呼び出します｡
‫さて､ ゲームモードに存在するこの関数を呼び出すために､ 健康コンポーネントはゲームモードのアドレスを格納する変数を必要とします｡
‫では､ 健康コンポーネントのクラスに入りましょう｡
‫ここにhealthコンポーネントがあります｡ ここでは､ ちょうど一番下にプライベート変数を追加するつもりです｡
‫そして､ これはタイプAのチューンタンクゲームモードのポインタとなり､ これをチューンタンクゲームモードと呼ぶことにします｡
‫ここで､ ヘッダーファイルをインクルードする必要がないように､ これをフォワード宣言して､ ゲームモードにアクセスする必要があります｡
‫では､ 健康部品CPに移動して､ 上にスクロールすると､ ここにbegin play機能がありますが､
‫ここがゲームモードに最適な場所です｡
‫繰り返しになりますが､ コンストラクタに入れるのは早計です｡
‫ゲームモードにアクセスしようとする前に､ ゲームモードが構築され､ 存在することを確認する必要があります｡
‫ここで､ Get Game Modeというゲームプレイスタティクスに関する便利な関数があり､ 現在のゲームモードのベースを返すか､
‫クライアントなどで取得できない場合はnullを返すと書いてあります｡
‫今､ オン・ザ・クライアントでは､ マルチプレイヤーのプログラミングをする必要がありますが､ その心配はありません｡
‫ゲーム用の唯一無二のマシン上で動作しているので､ スクロールダウンして､ ゲームモードのベースがワールドコンテキストオブジェクトを取ることを見てみましょう｡
‫これはあくまで世界の中のオブジェクトであり､ ワールドコンテキストオブジェクトの扱い方はこれまで見てきたとおりです｡
‫これはゲームプレイのstatic hに存在するので､ これをincludeしてみましょう｡
‫そして､ ここのhealth componentsに､ CPがゲームプレイ統計用のincludeを貼り付け､ ここにゲームモードの取得を呼び出し､
‫プレイを開始します｡
‫そこで､ チューンタンク､ ゲームモードと言うことになります｡
‫そして､ それを自分の価値観に設定する｡
‫ゲームプレイ統計は､ ゲームモードとワールドコンテキストオブジェクトを取得します｡
‫これでパスして､ 今度はゲームモードです｡
‫しかし､ ゲームモードを取得すると､ ゲームモードのベースが返され､ それを子クラスのチューンタンクゲームモードに格納しようとしているので､
‫キャストが必要になります｡
‫そうなんです｡
‫そこで､ cast to a tune tanks game modeと言う必要があり､ get game modeから結果をキャストしています｡
‫だから､ そこのカッコの中に入れるんです｡
‫そして､ ゲームモードはチューンタンクを使用しています｡
‫そこで､ そのヘッダーファイルを一番上にインクルードすることにします｡
‫だから､ 含むと言うことです｡
‫Tune Tanksのゲームモード｡
‫そこで､ この健康部品にゲームモードを搭載しています｡
‫ここでダメージテイクに降りて､ ヘルスがゼロになるかどうか確認する準備が整いました｡
‫この場合､ tune tanksのゲームモードポインタを使用して､
‫死んだアクターを渡す関数actor diedを呼び出すことができます｡
‫その場合は､ ゲームモードを使ってアクターが死んだとコールしてください｡
‫ゲームモードへのポインタを持っているので､ まずこのポインタがヌルでないかどうかを確認することを忘れないでください｡
‫そして､ 一旦アクターが死亡したことを呼び出すと､ アクターで渡す必要が出てきます｡
‫死んだ役者で通すのか｡
‫だから､ ビデオを一時停止して､ 今すぐダメージ取得機能にこれを実装してください｡
‫なるほど｡
‫つまり､ すでに健康状態からダメージを引いているわけです｡
‫これで､ その健康値がゼロになったかどうかを確認する準備が整いました｡
‫だから､ 健康状態がゼロF以下であれば､ 電話をかけるのが適切ということになりますね｡
‫ゲームモードが有効かどうかを確認する必要があるため､ 現在アクターは死亡しています｡
‫私はチューンタンクのゲームモードが有効であるかどうかをチェックし､ 確認する場合は､ この中でここに広告を配置することができます｡
‫もしNULLなら､ ここでfalseを返し､ if文の内部には到達しない｡
‫つまり､ if文の内部まで到達すれば､ チューンタンクのゲームモードが有効で､ 体力がゼロになったことになります｡
‫だから､ チューンタンク､ ゲームモードと言えるのです｡
‫そして､ 俳優を死亡とすることができる｡
‫そして､ これには俳優が必要で､ 死んだ俳優がダメージを受けた俳優になることは分かっているのです｡
‫そこで､ 破損したアクターを渡すことにします｡
‫そして､ これをコンパイルして見ることができるようになりました｡
‫コンパイルに成功しました｡
‫では､ エディタに戻りましょう｡
‫そして､ このエディターで､ 死のテストを進めてみてはどうだろう｡
‫自分が壊される前に､ この戦車を何台か壊せるか試してみよう｡
‫それはちょっと大変そうですね｡
‫あ､ 1人いますね｡
‫一人殺したら､ 二人目を手に入れた｡
‫あ､ あと､ 死にました｡
‫だから､ 池に死と破壊を加えたことで､ このゲームがより楽しくなったことがおわかりいただけると思います｡
‫だから､ これはすごいことなんです｡
‫さて､ このビデオではアクターデスを扱いましたが､ このゲームではこれらのクラスの間でかなりの量の相互作用があります｡
‫今､ 死の実装方法は､ 池が単に消えるだけですが､ そのためにまだいくつかのものが必要です｡
‫勝ち負けの条件が必要なのです｡
‫ゲームの勝敗をプレイヤーに示す方法が必要だ｡
‫そして､ その特殊効果も必要です｡
‫音も必要だし､ 爆発音も必要だ｡
‫そういうものは､ すぐにでもやってきますよ｡
‫だから､ おめでとうございます｡
‫あなたはすでに長い道のりを歩んできており､ あと数歩を残すのみです｡
‫次の動画でお会いしましょう｡