前回は、Photonサーバーにログインし、
ゲームに参加してくるプレイヤーを実装することができました。
本記事では、ゲーム要素である
「シューティング」を実装していきたいと思います。
具体的な内容は、
①マウスクリックで、Ray(光線)を放つ
②相手の当たり判定を処理し、ネットワークを通じて相手にダメージを与える
③体力が0になったらゲームオーバー
という、盛りだくさん!
それでは参ります!
1.シューティングの実装
1-1.Rayを使って当たり判定を得る(Shoot.cs)
実装したいシューティングは、
マウスクリックによって、
画面の中心を打つ(光線を放ち、当たり判定を得る)、というモノです。
これはScriptだけで、おおかた完結します。
「PlayerPrefab」に新たなC#Script「Shoot」を作成し、アタッチしましょう。
スクリプトの内容は次の通り。
using System.Collections; using System.Collections.Generic; using UnityEngine; using Photon.Pun; public class Shoot : MonoBehaviour { [SerializeField] Camera fpsCamera; // Update is called once per frame void Update() { if(Input.GetMouseButtonDown(0)) //左クリックした場合 { RaycastHit _hit; //Rayが衝突した情報を宣言 Ray ray = fpsCamera.ViewportPointToRay(new Vector3(0.5f, 0.5f)); //カメラから画面中心に向けて飛ばすRayを定義 if(Physics.Raycast(ray, out _hit,100)) //Rayが何かオブジェクトに衝突した場合 { Debug.Log(_hit.collider.gameObject.name); //衝突したオブジェクトの名前を出力 if(_hit.collider.gameObject.CompareTag("Player") &&!_hit.collider.gameObject.GetComponent<PhotonView>().IsMine) //衝突したオブジェクトにPlayerタグ付けがあり、なおかつそれが自分のプレイヤーでない場合 { //_hit.collider.gameObject.GetComponent<PhotonView>().RPC("TakeDamage", RpcTarget.AllBuffered, 10f); //RPCを介して、相手オブジェクトのメソッドを呼ぶ(10fというfloat値を渡す) } } } } }
一気に記述しましたが・・・
(25行目の"TakeDamage"を含む行を、今はコメントアウトしておいてください)
マウスの左クリックを行ったときに、
カメラから視界の中心(0.5f、0.5f)にめがけて放たれるRay(光線)を、
シューティングに利用します。
colliderへの当たり判定で、Playerタグの是非で
ただのオブジェクトとプレイヤーを判別して、処理させます。
なので、ここでPlayerPrefabのTagを「Player」に設定します。
そして、「Player」Tag自分でなかった、
”TakeDamage”メソッドを呼ばせます(コメントアウト部分)。
これは、1-3で使っていきます。
1-2.照準の作成
視界の中心に放つ光線を銃撃に使うことにしました。
その位置がわかるように、画面に照準を作成します。
PlayerPrefabのPlayerUIの配下に、
Image(CrossHairImageと名付ける)を作成します。
このとき、自動で新しくCanvasも作成されるので、ScreenCanvasと名付けます。
ScreenCanvasの「UI Scale Mode」を「Scale With Screen Size」にして、
「Reference Resolution」を「1920×1080」にします。
CrossHairImageのInspectorは次のようにします。
PosXYZ:全て0
Width15、Height15
SourceImage:Knob(丸)
Color:やや透明度のある橙色
ここで一度ゲーム(LauncerSceneから)を実行してみて、
Shoot.csに「Debug.Log(....」として記載したように、
照準をオブジェクトに合わせ、左クリックしたとき、
オブジェクトの名前がConsoleに出力されるか確認してみましょう。
1-3.被弾処理の作成(TakingDamage.cs)
相手プレイヤーを撃ったときの処理を作成していきます。
PlayerPrefabに「TakingDamage」という名のC#Scriptを新たに作成し、アタッチします。
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using Photon.Pun; public class TakingDamage : MonoBehaviourPunCallbacks { [SerializeField] Image hpBar; //Inspectorから紐づけ private float hp; //更新されるHPを宣言 public float startHp = 100; //HPの最大値 // Start is called before the first frame update void Start() { hp = startHp; //HPの初期値を最大にする hpBar.fillAmount = hp / startHp; //fillAmount用に0~1の値に変換して代入 } [PunRPC] public void TakeDamage(float _damage) //Playerへの当たり判定から呼び出されるメソッド { hp -= _damage; hpBar.fillAmount = hp / startHp; //fillAmountを更新 if(hp <= 0f) //hpが0以下になったら・・・ { } } }
前回の記事で作成したPlayerUIのHPに連動させ、
被弾してダメージを受けたら、HPBarが減るようにしています。
”TakeDamage”は、同ルーム内にいる他プレイヤーのメソッドにアクセスする処理なので、RPC(Remote Procedure Calls)の属性を適用しています。
「float _damage」は10fが渡されるので、一度の被弾でHPが10減ります。
Scriptができたら、Inspector上のTakingDamageコンポーネントに、
HPBarImageの紐づけを行い、
また、「Shoot.cs」の25行目のコメントアウトを解除します。
ゲームをBuild&Runで動作を確認してみましょう。
複数のウィンドウでWebGLを立ち上げ、
相手プレイヤーを出現させて、照準を合わせてクリック!
HPが減れば実装成功です。
さて、HPが0になったらどうしますか?
「TakingDamage.cs」で、
HPが0以下になったときに行う処理を空白にしていましたね。
次は、
HPがなくなってゲームオーバーになる処理を
実装する方法を解説していきます!