LoginSignup
4

More than 5 years have passed since last update.

【PUN】ゲーム終了判定

Last updated at Posted at 2017-12-23

Photon Unity Networkの基本機能メモ

【PUN】ログイン
【PUN】アバター生成・同期
【PUN】ゲーム終了判定


  • 誰かのHPが0になったときに、そのプレイヤーに死亡フラグを立てて、ゲームオーバーを表示。
  • 同時に全プレイヤーの死亡状態を取得したい。
  • 各プレイヤーの死亡状態はPhotonNetwork.player.SetCustomPropertiesで設定。
  • カスタムプロパティが変更されたタイミングで、PhotonNetwork.playerListをforeachで回してプレイヤーの死亡状態を確認していく。
  • 死亡者が一人以上存在して、生存者が一人だけなら、その生存者が勝者!ゲーム終了

photon.gif

Avatar.cs
using UnityEngine;
using System.Collections;
using System.Linq;
using UnityEngine.UI;

public class Avatar : Photon.MonoBehaviour {

    [SerializeField] int m_healthPoint = 100;
    [SerializeField] GameObject m_BulletPrefab;
    [SerializeField] GameObject m_DamageEffectPrefab;

    PhotonView m_photonView;

    void Start() {
        m_photonView = GetComponent<PhotonView> ();
        if(m_photonView.isMine) {
            // 初期設定
            SetPlayerName ("Player-Id: " + PhotonNetwork.player.ID);
            SetPlayerDeathState (false);
            SetHealthPoint (m_healthPoint);
        }
    }

    void SetPlayerName(string name) {
        this.gameObject.name = name;
        transform.Find ("NameUI").gameObject.GetComponent<TextMesh> ().text = name;
    }

    void SetHealthPoint(int num) {
        m_healthPoint = num;
        transform.Find ("HealthPointUI").gameObject.GetComponent<TextMesh> ().text = num.ToString();
    }

    // ストリーム同期
    void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info) {
        if (stream.isWriting) {
            // 自分の情報を送る
            string myName = this.gameObject.name;
            int myHealthPoint = m_healthPoint;
            stream.SendNext (myName);
            stream.SendNext (myHealthPoint);
        } else {
            // 他人の情報を受け取る
            string otherName = (string)stream.ReceiveNext();
            int otherHealthPoint = (int)stream.ReceiveNext();
            SetPlayerName (otherName);
            SetHealthPoint (otherHealthPoint);
        }
    }

    // イベント同期
    [PunRPC]
    void Shoot(Vector3 i_pos, Vector3 i_angle) {
        Quaternion rot = Quaternion.Euler (i_angle);
        GameObject bullet = GameObject.Instantiate (m_BulletPrefab ,i_pos ,rot);
        bullet.GetComponent<Rigidbody> ().AddForce (transform.forward * 20, ForceMode.VelocityChange);
        Destroy(bullet, 3);
    }

    void OnTriggerEnter(Collider i_other) {
        if(i_other.tag == "bullet"){
            // ダメージを受ける
            SetHealthPoint (m_healthPoint - 10);
            Instantiate (m_DamageEffectPrefab, transform.position, Quaternion.identity);
            Destroy (i_other.gameObject);

            if(m_healthPoint <= 0){
                if (m_photonView.isMine) {
                    SetPlayerDeathState (true);
                    string text = "You Lose...";
                    DrawResult(text, new Color(0f,0f,1f));
                }
            }
        }
    }

    void Update () {

        if(m_photonView.isMine == false){
            return;
        }

        if (Input.GetKeyDown (KeyCode.Space)) {
            // 自分自身の弾丸でトリガーを引かないようにやや手前から発射
            Vector3 pos = transform.position + transform.forward * 2f;
            Vector3 angle = transform.eulerAngles;
            // 処理が重いのでPhotonViewを付けずに位置と角度を渡す
            m_photonView.RPC ("Shoot", PhotonTargets.AllViaServer, pos, angle);
        }

        // キーボード入力による移動処理
        var v = Input.GetAxis ("Vertical");
        Vector3 velocity = new Vector3 (0, 0, v);
        velocity = transform.TransformDirection (velocity);
        velocity *= 5f;
        transform.localPosition += velocity * Time.fixedDeltaTime;

        // キーボード入力による回転処理
        var h = Input.GetAxis ("Horizontal");
        transform.Rotate (0, h * 3f, 0);
    }

    // ===============================
    // ここから重要
    // ===============================
    public void SetPlayerDeathState( bool isDeath ) {
        var properties  = new ExitGames.Client.Photon.Hashtable();
        properties.Add ("player-id", PhotonNetwork.player.ID);
        properties.Add ("isDeath", isDeath);
        PhotonNetwork.player.SetCustomProperties( properties );
    }

    public void OnPhotonPlayerPropertiesChanged( object[] i_playerAndUpdatedProps ){
        // 全員分回す
        var aliveList = new ArrayList();
        var deathList = new ArrayList();
        foreach(var p in PhotonNetwork.playerList) {
            Debug.Log ("player-id : " + p.CustomProperties["player-id"].ToString() + " - " + "isDeath : " + p.CustomProperties["isDeath"].ToString());
            if ((bool)p.CustomProperties ["isDeath"]) {
                deathList.Add (p);
            } else {
                aliveList.Add (p);
            }
        }
        if(aliveList.Count == 1 && deathList.Count > 0) {
            var winner = (PhotonPlayer)aliveList[0];
            var winnerId = winner.CustomProperties["player-id"];
            if((int)PhotonNetwork.player.ID == (int)winnerId) {
                string text = "プレイヤー" + winnerId.ToString() + " の勝利";
                DrawResult(text, new Color(1f,0f,0f));
            }
        }
    }

    void DrawResult(string text, Color color) {
        Text ResultText = GameObject.Find("ResultText").GetComponent<Text>();
        ResultText.text = text;
        ResultText.color = color;
    }

}

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4