拳銃を入手
落とし球ゲームクリアでclearGoodsをtrueにしましたのでroom1に戻ってきた時に景品を用意します。その10で準備した3アイテムの残りである拳銃にしましょう。ArcadeGameクラスに以下追加します。
//ArcadeGameクラス
public GameObject agc;
int countMB;
public GameObject miniBox;//引き出し
public GameObject miniBoxCamera;
public GameObject playerCamera;
void Start()//追加分のみ
{
if (MoveBall.clearGoods){
GameObject gun = GameObject.Find("Gun");
gun.transform.Translate(0.0f, 0.0f, -0.6f);
miniBox.transform.Translate(0.0f, 0.0f, -0.6f);
}
}
public void PushMB()
{
countMB++;
if(countMB % 2 == 1){
miniBoxCamera.SetActive(true);
playerCamera.SetActive(false);
}else{
miniBoxCamera.SetActive(false);
playerCamera.SetActive(true);
}
}
フラグを判定してゲーム機の真ん中の引き出しを動かしています。引き出しをクリックすると中身が分かるアングルに切り替えるPushMBメソッドを作成したので引き出しのイベントに設定。拳銃をクリックしたら取得できます。拳銃は取得状況を保管するためその16で作成したSingletonに加えておきましょう。
拳銃を構える
せっかく拳銃を入手したので、まずはFPSでよくある目の前で構えたように見えるオブジェクトをプレイヤーカメラの子として作成しましょう。それから銃口を向けた先のカーソル用に照準の絵も用意しておきます。これで準備ができたのでその12までに更新したPlayerCameraクラスに以下追加しましょう。
//PlayerCameraクラス_追加のみ記載
[SerializeField]Texture2D cursor;//照準の絵
public static bool gunMode;
public GameObject PGun;//構えたオブジェクト
void Update()
{
if (Input.GetKey(KeyCode.Space))//スペース入力_Gun所持でガンモード
{
GameObject[] items = GameObject.FindGameObjectsWithTag("ItemSlot");
foreach (GameObject i in items)
{
Image images = i.GetComponent<Image>();
if (images.sprite.name.Contains("GunSprite"))
{
gunMode = true;
Cursor.SetCursor(cursor, new Vector2(cursor.width / 2, cursor.height / 2), CursorMode.ForceSoftware);//カーソルを照準に変更_中心に設定
}
}
}
if (Input.GetKey(KeyCode.Return))//リターン入力_デフォルト
{
Cursor.SetCursor(null, Vector2.zero, CursorMode.ForceSoftware);//zeroは左上
PGun.SetActive(false);
gunMode = false;
}
if (gunMode)
{
PGun.SetActive(true);
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);//スクリーン座標
PGun.transform.rotation = Quaternion.LookRotation(ray.direction);//照準に向く
}
}
Input.GetKey(キー)で対応キーを押したらtrueになります。その13で使った処理同様拳銃アイテムを持っていればgunModeになりますのでそれを検知して構えたオブジェクトが出現。構えた向きはScreenPointToRayで検知したマウス位置の点をLookで常に追いかける様にしています。又Cursor.SetCursor(Texture2D, Vector2, cursorMode)を使ってカーソルを用意した照準の絵に変える処理も行ってます。Vector2の位置はデフォルト↖︎では左上なので用意した絵に合わせて中心位置を変更すると違和感がなくなると思います。gunModeからはリターン入力で元に戻るようにしています。
拳銃から弾を発射する
構えた拳銃から弾を撃ってみたいと思います。マズル(レイヤー、Collider設定)・弾(レイヤー、タグ、Collider、Rigidbody設定)をそれぞれ用意しましょう。マズルは発射口になりますので拳銃の先端部分に配置、弾は大きさが調整できたらPrefabにして削除。PlayerCameraクラスに以下追加しましょう。
//PlayerCameraクラス_追加のみ記載
[SerializeField]GameObject bulletPrefab;//弾Prefab
[SerializeField]Transform muzzle;//マズル
[SerializeField]float bulletPower = 800f;
public AudioClip Bang;
AudioSource audioSource;
void Start()
{
audioSource = PGun.GetComponent<AudioSource>();
}
void Update()
{
if (gunMode)
{
if (Input.GetButtonDown("Fire1"))//マウスの左クリックで撃つ
{
audioSource.PlayOneShot(Bang);
Shot();
}
}
}
void Shot()
{//プレハブをマズルの位置回転で発射_2秒で消す
var bulletInstance = Instantiate<GameObject>(bulletPrefab, muzzle.position, muzzle.rotation);
bulletInstance.GetComponent<Rigidbody>().AddForce(bulletInstance.transform.forward * bulletPower);
Destroy(bulletInstance, 2f);
}
左クリックしたらShotメソッド発動。AddForceはRigidbodyで力を加える処理で方向はforwardなので正面=Vector3(0, 0, 1)、bulletPowerで撃ち出してます。弾はそのまま残しておいても良いのですが今回は無限弾仕様なので2秒後に消す事にしましょう。思った方向に飛ばない場合はマズルとプレハブの向きが噛み合っていないのが原因です。位置調整、それでも難しい場合はマズルに空の親オブジェクトを設定するなどして対処してください。
拳銃と照準の重なりをなくす
形上完成しましたが操作してみると照準と拳銃オブジェクトが重なった場合、照準が手前にきてしまうという問題が出てきました。違和感ありすぎなので解消したいと思います。PlayerCameraクラスに以下追加しましょう。
//PlayerCameraクラス_追加のみ記載
void Update()
{
if (gunMode)
{
RaycastHit hit;//レイキャストによる情報を得るための構造体
if (Physics.Raycast(ray, out hit, 1f, LayerMask.GetMask("muzzle")))//範囲1f_マズルのレイヤーに接触
{
Cursor.visible = false;//銃と照準が重なる→照準を見えなくする
}
else
{
Cursor.visible = true;
}
}
}
Physics.Raycastは光線を飛ばして光線上にあるコライダーの情報を取得してboolとして返す処理に用います。本ケースだとマズルが拳銃の先端位置になりますので、まずカメラからマウスの位置(照準)に光線を飛ばす→長さ1fでマズルのコライダーと重なる場合は照準を見えなくする処理を行いました。
以下デモ
その他
発砲する時のクリック処理(ゲーム躯体クリックでシーン移動する処理等)は無効にしておきましょう。
コメント