今回はUnityで銃を撃った時に薬莢を飛ばしてみます。
銃には詳しくないので、どのあたりから薬莢が出てきて、どこへ飛んでいくのかわかりませんが、種類によっても違うみたいです。
詳しく調べてから機能を作成しろよ!
と自分自身に言い聞かせながらてきとうなわたくしはそのまま機能作成に突入するのであった・・・・(謎)
とりあえず、撃ったら薬莢が飛んでいく銃という事に限定しましょう(^_^;)
今回の機能を作成すると、上のような感じになります。
弾のモデルが用意出来なかったので、CapsuleのScaleを調整し、空薬莢として使用しました。
弾の設定と銃に薬莢を飛ばす場所を作成する
上のような弾丸の3Dオブジェクトを用意します。
今回はUnityのCapsuleのScaleを調整して空薬莢にします。
ヒエラルキー上で右クリックから3D Object→Capsuleを選択し名前をBulletとします。
弾丸オブジェクトをシーン上に配置し、弾の大きさの調整をし、AddComponentでRigidbodyをつけます。
銃を撃った時に薬莢に力を加えて飛ばす為です。Use Gravityにチェックを入れ重力も働くようにしておきます。
BulletにはCapsule Colliderがついていて衝突判定として使うのでIs Triggerのチェックは外しておきます。
設定が終わったらAssetsフォルダにドラッグ&ドロップしプレハブ化します。シーン上の弾は削除してかまいません。
これで薬莢の準備が出来ました。
次は銃に薬莢が出てくる場所を設定します。
銃のプレハブをシーン上に配置し、Sliderの子要素に空のゲームオブジェクトを作成して名前をBulletExitPositionにし空薬莢が出てくる位置を作成します。
座標をLocalに変更(重要)し、空薬莢が出ていく方向(青色のZ方向)を調整します。
上のような感じに調整が出来たら、銃のインスペクタでApplyを押し修正をプレハブに反映させます。
反映させたら修正用の銃はヒエラルキー上から削除してください。
銃から空薬莢を飛ばす処理をスクリプトに追加
それでは銃を撃った時に空薬莢を飛ばすスクリプトを作成します。
今までの記事をご覧いただいた方はShotスクリプトを修正します。
そうでない方は銃を撃った時の処理を行うスクリプトを変更してください。
1 2 3 4 5 6 7 | // 空薬莢が出てくるTransform private Transform bulletExitPosition; // 弾のプレハブ [SerializeField] private GameObject bulletPrefab; |
bulletPrefabには薬莢のプレハブ、bulletExitPositionには銃のbulletExitPositionを銃を装備した時に設定します。
銃を撃った時の処理JudgeShotメソッド内に空薬莢の処理を追加します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | // 敵に弾が当たったかどうか public void JudgeShot() { // 弾がなければ弾がない時の効果音を鳴らしreturnで以降の処理をさせない if (myStatus.GetNumberOfBullet() <= 0) { PlaySE(noBulletSE); return; } // 銃のアニメーション gunAnimator.SetTrigger("Shot"); // 空薬莢をインスタンス化し飛ばす var bulletInstance = Instantiate<GameObject>(bulletPrefab, bulletExitPosition.position, equip.transform.rotation); var bulletRigid = bulletInstance.GetComponent<Rigidbody>(); bulletRigid.AddForce(bulletExitPosition.forward * 150f); bulletRigid.AddTorque(Random.insideUnitSphere * 360f); Destroy(bulletInstance, 3f); // 銃の発砲の光を表示 AbleLight(); // 銃の発砲音を鳴らす PlaySE(shotSE); // 弾の数を減らし、戻り値をテキストに設定 bulletText.text = myStatus.SetNumberOfBullet(myStatus.GetNumberOfBullet() - 1).ToString(); Ray ray = new Ray(muzzle.position, muzzle.forward); RaycastHit hitPoint; distance = rayRange; if (Physics.Raycast(ray, out hitPoint, myStatus.GetWeaponStatus().GetWeaponRange(), LayerMask.GetMask("Field"))) { distance = Vector3.Distance(muzzle.position, hitPoint.point); } if (Physics.Raycast(ray, out hitPoint, myStatus.GetWeaponStatus().GetWeaponRange(), LayerMask.GetMask("EnemyHit"))) { if (distance > Vector3.Distance(muzzle.position, hitPoint.point)) { var enemyObj = hitPoint.collider.gameObject.transform.root; if (enemyObj.GetComponent<Enemy>().GetState() != Enemy.EnemyState.Dead) { var enemy = enemyObj.GetComponent<Enemy>(); enemy.TakeDamage(myStatus.GetWeaponStatus().GetShotPower(), hitPoint.point); } } } } |
空薬莢をbulletExitPositionの位置とequip(装備品の親のゲームオブジェクト)の角度でインスタンス化します。
空薬莢のRigidbodyコンポーネントを取得し、exitBulletPositionの向いている方向に力と回転を加えます。
空薬莢は3秒後に消します。
最後に銃の情報を取得しているInitializeGunメソッドに処理を追加します。
1 2 3 4 5 6 7 8 9 10 11 12 | // 銃の情報を取得 public void InitializeGun(GameObject weapon) { raserPointer = weapon.GetComponentInChildren<LineRenderer>(); shotLight = weapon.GetComponentInChildren<Light>(); audioSource = weapon.GetComponentInChildren<AudioSource>(); muzzle = weapon.transform.Find("Muzzle"); gunAnimator = weapon.GetComponent<Animator>(); bulletExitPosition = weapon.transform.Find("Slide/BulletExitPosition"); bulletText.text = myStatus.GetNumberOfBullet().ToString(); } |
装備した武器の子要素からSlide/BulletExitPositionを探してbulletExitPositionに設定します。
これで銃を撃った時に空薬莢を飛ばす処理は完成しました。
Unityの実行ボタンを押して確認してみましょう。
上のように空薬莢が右後ろに飛んで行くようになりました。