前回は、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がなくなってゲームオーバーになる処理を
実装する方法を解説していきます!
