Unity

【Unity】オンラインFPSゲームの作り方#6【シューティングの実装】

本記事内には、アフィリエイトリンクを含む場合があります

前回は、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の配下に、
ImageCrossHairImageと名付ける)を作成します。
このとき、自動で新しく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がなくなってゲームオーバーになる処理
実装する方法を解説していきます!

【Unity】オンラインFPSゲームの作り方#7【ゲームオーバー&リスタートの実装】さて、相手に撃たれて、HPが0になったらどうしましょう? ここでは、”誰に倒されたか”を表示し、 5秒のカウントダウンとともに、...
ABOUT ME
いなも@システマライフハッカー
”仙豆”を開発することを夢見て、健康食品会社で働いていたものの、2016年に出会ったロシアの武術”システマ”こそ、その糸口があると感銘し、勝手にシステマ普及活動を始める。 一方で、クリエイティブなモノ作りが好きで、DX社会で楽しみを見出せる"Unity”を活かして、”スマートかつ快適な暮らし”のヒントを発信している。

COMMENT

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA