‫ですから､ 私たちのタワーに近づくと､ デバッグ用の球体を描いているのがわかります｡ これは､ fire関数を呼び出していることを証明しており､
‫2秒ごとにそうしているのです｡
‫今はそれに加えて､ この機能だけを呼び出している｡
‫もし私が射程圏内にいても､ ここに戻ってくれば､ デバッグ用の球を描いていないことに気がつくはずです｡
‫そのため､ 距離の確認も兼ねています｡
‫そして､ 十分に近づくと､ ほら､ デバッグ用の球体が描かれるんです｡
‫こんにちは､ お帰りなさい｡
‫すでにfire関数を作成し､ それをtankクラスで使用しています｡ これはfireアクションマッピングにバインドしているからです｡
‫しかし､ これをtowerクラスで再利用したいとも思っています｡
‫さて､ タワークラスではユーザー入力を使うのではなく､ タイマーを使うことにします｡
‫towerクラスのタイマーを作成し､ タイマーがfire関数を呼び出せるようにします｡
‫たびたび､ fire関数を呼び出す間隔を指定した秒数を設定するんだ｡
‫そこで､ fire関数がtowerクラスで頻繁に呼ばれるようにしたいので､ ここでタイマーの話をする必要があります｡
‫Unreal Engine には､ F Timer Manager と呼ばれるクラスを使ってタイマーを設定する機能があります｡
‫ワールド内のタイマーを管理するワールドタイマーマネージャーが存在します｡
‫さて､ このワールドタイマーマネージャーには､ セットタイマーという関数があり､ セットタイマーは､ タイマーハンドルなどのいくつかの入力を受け取ります｡
‫タイママネージャが管理する特定のタイマへのハンドルである｡
‫これにより､ マネージャーは複数のタイマーを持つことができ､ タイマーハンドルをそのタイマーの名前またはIDのようなものとして使用することで､
‫それぞれのタイマー情報にアクセスすることができます｡
‫F タイマーハンドル型のオブジェクトである｡
‫そこで､ タイマーハンドルを作成し､ これをセットタイマー関数に渡します｡
‫タイマーを設定するには､ 実際に何かを行う前に待つべき時間や速度など､
‫他の入力も必要です｡
‫これで､ コールバック関数に何か書き込まれることになります｡
‫関数を作成し､ この関数をタイマーにバインドして､ タイマーが十分な時間を経過した時点で､ コールバック関数が呼び出されるようにします（具体的には､
‫タイマーの速度）｡
‫タイマーのためにいくつかのものが必要なことがわかりましたので､ これらをtowerクラスに配置します｡
‫それでは､ Tower H に入り､ この Tower H ファイルにいくつかのプライベート変数を追加してみましょう｡
‫そこで､ 射程距離のすぐ下に､ タイマーハンドルが必要になります｡
‫つまり､ これはFタイマーハンドルで､ 単純にファイアレートタイマーハンドルと呼べばいいわけです｡
‫そして､ 浮き上がるような火力も必要です｡
‫これをファイアレートと呼ぶことにして､ 2点Fに初期化することができます｡
‫こうすることで､ コールバック関数が実際に呼ばれるまでに2秒の待ち時間ができます｡
‫そして､ コールバック関数といえば､ 実は1つ必要なんです｡
‫そこで､ void関数を作って､ このcheck fire conditionを呼び出すことができるようにします｡
‫つまり､ タイマーのハンドルを持っていて､ タイマーをセットして走り出したら､
‫実際に関数が呼ばれるまでに2秒待つ必要があります｡
‫これは､ タワーがfire関数を呼び出せるかどうかを確認するためで､ fireが呼び出されることを確認するための条件をいくつか配置できます｡
‫これでファイヤーコンディション関数が宣言されました｡
‫タワーCPPに入り､ ここで関数を定義できるように､ 定義する必要があるのです｡
‫これはbegin playの下に置くので､ 関数本体と､ 関数名の直前にタワークラス名を付けます｡
‫さて､ これで関数ができましたが､ 実際にはタイマーをセットして､ その時間が経過したときに関数が呼び出されるようにする必要があります｡
‫そして､ ここにタイマーをセットしてプレイを開始すると､ ゲームの最初から走り始めることができます｡
‫そこで､ ワールドタイマーマネージャーについて触れましたが､ これにはGet World Timer Managerという関数でアクセスすることができます｡
‫World Timer Managerを取得し､ F Timer Managerオブジェクトを返します｡
‫そして､ その型を使うので､ Fタイマー・マネージャー用のヘッダー・ファイルをインクルードする必要があります｡
‫これは単純に timer manager h をインクルードしたものです｡
‫そして､ このクラスに属する機能の一部も見ることができます｡
‫F timer managerに属する様々な機能に興味があれば､ これらをスクロールしてください｡
‫このヘッダーファイルは､ towerの一番上､ 他のインクルードのすぐ下にあります｡
‫このヘッダーファイルが含まれたことで､ ワールドタイマーマネージャーにアクセスできるようになり､
‫注目すべきはset timerという関数です｡
‫ここで､ get world timer managerは単にF timer managerを返すだけで､ ポインタを返すわけではありません｡
‫だから､ ドットを代わりに使うんだ｡
‫矢印で､ セットタイマーを呼び出します｡
‫現在､ set timerにはいくつかのバージョンや関数のオーバーロードがあります｡
‫現在､ 対のコードにはこのポップアップがあり､ それぞれのオーバーロードを調べて､ この関数のさまざまなバージョンを確認することができるようになっています｡
‫そして､ 私が最初に興味を持ったバージョンは､ Fタイマーハンドルを取り､ Tower Hで宣言したファイアレートタイマーハンドルを使用するつもりです｡
‫さて､ この関数のオーバーロードの次のパラメータは､ bind axis や bind action と同じようにユーザークラスとします｡
‫これは､ 私たちが作業しているクラスで､ この関数をバインドしているところです｡
‫次に､ 先ほど作成したコールバック関数が､ Aタワーチェックの発火条件となります｡
‫ここで､ operatorのアドレスが必要なのは､ set timerが関数のアドレスを取るからです｡
‫次のパラメータは float で､ これはコールバックが呼び出されるまでの時間を表します｡
‫それが､ 私たちの火災発生率になるのです｡
‫そして､ 最後のパラメータは､ このタイマーがループするかどうかを指定するブール値です｡
‫さて､ 2秒ごとにコールバック関数が呼ばれるようにしたいので､ このタイマーをループさせたい｡
‫だから､ 私は真と言うことにしています｡
‫もし､ 偽のまま通過したら､ 2秒が経過してしまう｡
‫私たちの関数が呼び出され､ それで終わりです｡
‫しかし､ ループするように設定しているので､ 2秒後に関数が呼ばれ､ その後タイマーが再開し､
‫さらに2秒後に関数が再び呼ばれ､ ゲームが終わるまでループし続けることになります｡
‫これで､ タイマーにバインドされた関数ができ､ 2秒ごとに呼び出されるように設定されました｡
‫そこで､ タイマーを関数にバインドして､ 2秒ごとに呼び出すことにしました｡
‫しかし､ この関数が実際に呼び出されていることを､ 何らかの形で証明､ 確認したいのです｡
‫では､ towerクラスで挑戦してみましょう｡ 新しいコールバック関数で､ 火の状態をチェックします｡
‫戦車が射撃範囲にあることを確認する｡
‫タワーからタンクまでの距離を確認するんですね｡
‫そして､ この方法はすでにtick関数で行っているので､ わかっています｡
‫そのため､ tick関数を見て､ これがどのように行われるかを確認し､
‫自分自身に思い出させる必要があるかもしれません｡
‫なるほど｡
‫そこで､ Tower CPに戻り､ この距離をどうやって取得したかを思い出すために､ ティック機能までスクロールして､
‫射撃範囲にあるかどうかを確認します｡
‫あとは､ このコードを再利用して､ 火災の状態をチェックするだけです｡
‫しかし､ まずはこれが動作していることを確認し､ タンクポインタが有効であることを確認しましょう｡
‫そこで､ ここでそれを行い､ ファイアコンディションを確認することにします｡
‫もしタンクが有効なら､ 次にできることはその距離を求めることです｡
‫これはfベクトルdist関数で計算されたこの値です｡
‫そこで､ これをチェックファイアの状態で下に置いてみることにします｡
‫さて､ 次に行うのは､ 距離が射程距離以下かどうかを確認することです｡
‫だから､ ここでやるんだ｡
‫距離が発射範囲以下かどうかを言い､ そうであれば､ 単純に発射関数を呼び出せばいいのです｡
‫だから､ ファイヤーを呼ぶ､ それだけでいいんです｡
‫では､ これをコンパイルしてエディタに戻り､ 再生ボタンを押して射程距離に入ってみましょう｡
‫そして､ タワーはバレルの先端にデバッグ用の球体を描いているので､ その発射関数が呼び出され､
‫タンクと同じようにタワーでも動作していることがわかりますね｡
‫だから､ これはすごいことなんです｡
‫これは､ タイマーが動作していること､ コールバック関数が2秒ごとに呼び出されていることを証明しています｡
‫さて､ このfire関数は2秒ごとに呼び出され､ fireの状態をチェックするようになっています｡
‫このように､ 範囲内にあるかどうかを確認する機能がありますが､ これとまったく同じことをtick関数で行っています｡
‫だから､ これはリファクタリングの絶好の機会なんです｡
‫戦車との距離が近いかどうかをブール値で返すような関数を作ればいいんです｡
‫では､ このままさっさとリファクタリングして､ ブルリターン関数にしてしまいましょう｡
‫そこで､ ここTower Hでは､ プライベート関数を作成してみましょう｡
‫これはboolを返すので､ 火の範囲内と言うことになります｡
‫さて､ これは単純なゲームで､ 私たちのタワーは戦車としか射程に入りません｡
‫もし､ このゲームがもっと複雑で､ 塔が距離を確認するようなものがあれば､
‫もう少し違う名前にするかもしれませんが､ 単純に射程内と呼べばいいのです｡
‫そして､ 私がこれから行うのは､ このTowerに実装することです｡
‫それでは､ 関数本体を作ってみましょう｡
‫関数名を修正する前のタワーが必要になりそうです｡
‫そして､ ここで行うのは､ 基本的にこれと同じ距離の確認です｡
‫そこで､ まずtankが有効かどうかをifチェックで確認します｡
‫もしそうなら､ この距離を取得できますので､ この行をコピーして､
‫ここにローカルな距離フロートを作成し､ その距離と射程を単純にチェックします｡
‫この関数は､ 値trueを返すことができる｡
‫そして､ 範囲内であればtrueを返す関数を呼び出すことができるようになりました｡
‫さて､ このif文のreturn trueの行を打つとすぐに､ この関数は戻ってきます｡
‫機能から飛び出す｡
‫そのため､ このif文以降のものは実行されません｡
‫というのも､ もしreturn trueに到達してしまうと､ 実際にはreturn
‫falseの行に到達することができないからです｡
‫単純に早く関数を終了させます｡
‫しかし､ もし範囲内でなければ､ もしここでの距離チェックが失敗したら､ return trueを打つことはできない｡
‫そして､ 関数の最後に到達し､ falseを返します｡
‫この関数は､ 範囲内かどうかによって真か偽を返すので､ 2つの関数で繰り返しコードを使用する代わりに､
‫この関数を使用することができます｡
‫ですから､ 例えばこのカチカチという音で､ 砲塔を回転させる前に射程距離に入っているかどうかを1回確認するだけでいいんです｡
‫そこで､ 「もし射程範囲内なら」といって､ これがtrueを返したら射程範囲内なので､ タレットの回転を呼び出すことができます｡
‫そこで､ if文の中にそれを入れておきます｡
‫そして今､ このコードはすべて不要なので､ 単純に削除すればいいのです｡
‫そして今､ これは以前よりずっときれいに見えます｡
‫そして､ ここに降りてきて､ 火の状態を確認し､ 同じことをすればいいのです｡
‫このようなことをしなくても､ 単純に射程範囲内かどうかを確認すればいいのです｡
‫そして､ もしもの時は､ 火を呼べばいいだけです｡
‫これで､ すべてのコードをin fire range関数で行われるチェックにリファクタリングすることができました｡
‫では､ もう一度コンパイルして､ すべてが期待通りに動作することを確認するために､ 実際にプレイテストしてみましょう｡
‫では､ さっそく再生ボタンを押して､ 射撃範囲に入りましょう｡
‫もちろん､ 火災の範囲内であり､ 正常に作動しています｡
‫要約すると､ タイマーを作り､ 2秒ごとにtowerクラスのfire関数を呼び出しているわけです｡
‫今度はTankが範囲内にいるかどうかも確認しています｡
‫つまり､ 戦車が射撃距離内にいる場合のみ､ 2秒ごとに射撃関数を呼び出しているのです｡
‫そして､ その距離チェックを2つの機能で使い分けていることも確認できました｡
‫そこで､ これを独自の関数にリファクタリングし､ 単純にこれを呼び出して範囲内かどうかをチェックするようにしたのです｡
‫これで､ towerクラスでfire関数が呼び出されるようになったわけです｡
‫次に､ fire機能で実際に弾丸を発射させます｡
‫ということで､ 次の動画でその辺をお話します｡
‫また､ お会いしましょう｡