Chapter.14「武器変更を実装する」https://gameshi.info/wp-content/uploads/2019/01/bandicam-2019-01-25-01-16-21-187.mp414.武器変更を実装する武器の変更システムに思ったよりも時間を食いましたですよ。強化のシステムはいったん延期して、最後に優先度を再検討しませふ。クラスの構成について武器変更はPlayerShootingクラスに実装していきます。本当は別クラスに武器の特性等を実装していくべきと思うのですが、やってみたらどの変数をどこに置いてどこから呼び出して......の切り分けに混乱しまったく実装が進まなかったので諦めました。問題意識としては持っているが能力が追い付かない、ってかんじでふ。どんな武器を実装するか今回は「どんな敵を実装するか」から考え、その敵への対抗手段として武器種を用意する、というアプローチをとります。「バリアを張っており一撃では倒せない敵」に対して、「バリアを貫通し一撃で倒すことのできる武器」を用意するといった具合に。各武器にはデメリットを必ず用意します。ほかの武器の長所を裏返したデメリットを付与することで使えない武器(死に武器)が存在しにくくなります。先の貫通武器であれば「ただし連射が効かない」といったように。今回は以下の三つの武器(敵)を用意することにしました。三種類の武器を、キー1,2,3を押すことで切り替えられるようにします。切り替えには既定の時間がかかり即時の切り替えはできなくします。3));}}ChangeWeaponメソッドの追加Invokeでは引数を渡すことができないのでcoroutineを使うことにしました。HUDのアイコンを変えたり、残弾数表示の区切りを変えたり、発射レートの値を変えたりしています。true)の場合分けを行い、それぞれ処理を追加してます。//Rayの始点(マズル固定)と方向(一定範囲内でランダム)をnumRayの数だけ設定。直前に出てたものの中断と新たに表示gunParticles.Stop();gunParticles.Play();//Rayの始点(マズル固定)と方向(一定範囲内でランダム)をnumRayの数だけ設定。maxAmmo;}拡散能力を付与するRayを配列化して、ランダムな前方に複数射出するようにしています。この時、射線の数だけLineRendererを付与したオブジェクトが必要となるため、gunLine変数も同様に配列として宣言し、GunBarrelEndオブジェクトにぶら下げた射線用のオブジェクトからLineRendererを取得しています。貫通能力を付与するPhysics.Raycastはぶつかった最初のオブジェクトの情報しか取得しないため、スナイパーライフル装備時はPhysics.RaycastAllを使って、Rayがぶつかったすべてのオブジェクトの情報を取得しています。この時、Enemy以外にもぶつかっているので、EnemyHealthを取得できずTakeDamageを実行しようとしてもNullエラーが出ることがありました。めんどくさがらずEnemyHealthがNullだった場合の分岐を設けなければいけませんでした。Reloadメソッドの改修Changeメソッドと同様の理由でcoroutineを使うことにしました。false;}クラス設計について冒頭にも書きましたが勉強不足を実感してます。あまりにもメンテ性が悪すぎる......。この記事を書くためにコードを読み返すのが苦痛すぎました。雰囲気でここまでやってきましたが、体系的な勉強を始める必要がありそうです。Chapter.13「敵に射撃がヒットした時、ノックバックする」13.敵に射撃がヒットした時、ノックバックする今回の実装は大きく2つ。本当は1つでもよいのだが、よりコンセプトをとがらせるため追加の実装を行う。予定調和にせず緊張感を保たせたいRayが敵にヒットした時、Rayの方向に敵を移動させるヒットした時の処理に、Rigidbody.AddForce(shootRay.direction)を追加すれば実装できると思っていたが、試してみたところAddForceが効いている感じがない。公式リファレンスを確認してみると、NavMeshAgentを付与したキャラクターを動かしたいときには、NavMeshAgent.velocityを使えとのこと。それを踏まえてもう一度。PlayerShootingクラスをいじっているが、EnemyMovementクラスに新たなメソッドを用意してもいいかもしれない。武器種によってノックバック距離を変えるならPlayerShootingくらす、エネミーによるならEnemyMovementクラスに書くのがよいのだろうが、両方でやりたい場合はどうしたらいいだろうか。今は分からないので棚上げにして、実装を進めよう(EnemyMovementクラスに記述して、PlayerShootingクラスから調整用の引数を渡して実行、が正解な気がする)。nbPower;}(略)}挙動はこんな感じ。ノックバックの距離と角度にランダム性を持たせる上まで出来ていればそう難しくない。距離はnbPowerの取る値をランダム化させれば良いし、角度もshootRay.directionのxとzの値に少しランダム値を±させてやればよい。nbPower;}(略)}これで実装できたのがコチラ。値の幅は調整の余地があるけども、ランダムでノックバックするようになりました。触ってみた感触もしかしたらランダムいらないかも。思ったより違和感がある。値の調整でも違和感が拭い去れなければ削除しよう。資源の管理はこのゲームの面白さに据えないので。オートリロードは設けない。俺のリロードは革命(レボリューション)なので。リロード中射撃できない時間を設ける。マグチェンジではとうてい味わえない緊張感と高揚を戦闘にもたらすので。完成形はこんな感じ弾数制限&リロードの基本を実装PlayerShooting.csをいじるよ。maxAmmo;}ミスった点として、Shoot()実行前の残弾数をチェックするタイミングがあります。if(左クリックされたら(略)){Shoot()}という風に、最初に判定してreturnで抜けてしまったところ、残弾が0になった瞬間Update内のすべてのメソッドが効かなくなりました。ifの一塊だけ抜けて、Update内の次の関数に行ってほしかったんですが、残弾数の判定⇒0なのでUpdateメソッド自体を抜ける⇒次フレームで再度Updateメソッド実行⇒...の無限ループしちゃいました。リロードタイムを設けるリロードボタン(Rキー)を押してn秒後にReload()メソッドを実行するようにします。reloadTime);}(略)}これでリロード中は射撃ができないようになりました。リロードタイムがこんなにも息吹を......!![追記]嘘です。この実装だとリロード中も射撃できます。残弾数のUI表示3枚のスプライトを重ね、FillAmountを使って表現します。実際に用意した画像ファイルは4枚、一番上の外枠と、内枠の区切りを示す一本の黒い線とで2枚に分けました。バランス調整や、別の武器の実装で装填数の異なるUIを作るとき、応用が利くようにしたかったためです。等間隔になるようなPosition設定がめんどいので、1枚で書いてもそんなに手間が変わらないかも。HUDCanvas下にImageオブジェクトを4つ追加してそれぞれ画像ファイルを設置。UI)にするのを忘れずに。PlayerShootingスクリプトで制御する必要があるのは真ん中の黄色いスプライトのみです。1.0f;}ついでに、武器変更機能を見越して、装備中の武器がわかるようなHUDも追加しました。リロード中の表現グラフィックでやろうと思ったんですが、AssetStoreに無料でいい感じのオーディオ素材があったのでそちらで実装してみます。();}リロードタイム3秒で丁度SEの長さとあってますが、今後のバランス調整を経てズレてきた場合は、SEの長さを調整する必要が出てきそうです。これでリロード周りの実装は終わりです。次回はノックバックを実装しますよ~それとタイトル名決めました。