14
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Unity + Photon + WebGL】マルチプレイヤー対応のバーチャル空間を自作してみた

Last updated at Posted at 2021-08-09

Unityで作ったものをマルチプレイヤー対応のバーチャル空間をウェブで公開してみた。 UnityとPhotonとWebGLを使えばできた。

##動作確認バージョン
Unity 2019.4.22f1

##Photon
Photonにアクセス
https://www.photonengine.com/ja/

アカウント登録して、アプリ新規登録する。

※全世界を対象としてなく日本国内のみでする場合は、リージョンは jp にしたほうが動作は早い。

##Unity
Unityを起動する。

このとき作ったプログラム、アニメーションを使う (カメラ追随以外)
https://qiita.com/tatsuya1970/items/5dea86208951574fcc9c

###PUN2
Asset STOREで、 PUN2 -FREE をダウンロードし、インポートする。
Image from Gyazo

ポップアップが出るので、さきほどのPhotonのウェブサイトで作成したアプリのアプリケーションIDを入力
Image from Gyazo

Photon ServerSetting というのができる。

Image from Gyazo

###アバターの設定
[Resources] フォルダを作成する。
プレイヤー自身のアバターとして表示するゲームオブジェクトのプレハブを作成し、「Resources」フォルダーの中に入れる。
アバターは3つ用意し、後述するスクリプトでは乱数でアバターを選ぶようにした。
Image from Gyazo

アバターなど人型の場合
Avatarのinspectorには
Add Componentから [Photon view]を追加
Image from Gyazo

[Photon Transform View]を追加
Image from Gyazo

[Photon Animator View]を追加
以下設定

disable(同期しない)
discrete(非連続的 = 一定間隔で同期)
continuous(連続的 = 常に同期)

Image from Gyazo


もちろん、RigidBodyとCollidar は忘れずに。 ヒト型は不安定なのでFreeze Rotation のXYZにチェック [![Image from Gyazo](https://i.gyazo.com/7ba364d3ca41400c5597311194440998.png)](https://gyazo.com/7ba364d3ca41400c5597311194440998)
今まで述べてきたInspectorをまとめると、 [![Image from Gyazo](https://i.gyazo.com/7b1fda47a47bae15e5ec658ffe5f6742.png)](https://gyazo.com/7b1fda47a47bae15e5ec658ffe5f6742)
なお、inspector と関係ないが、Hierarchy にデフォルトで存在する Main Camera は絶対に消さないこと。 ※スクリプト上で各参加者を追随するカメラとして利用するため

##スクリプト

空のオブジェクトを作り、そこに以下のコードをアタッチ

PhotonController.cs
using Photon.Pun;
using Photon.Realtime;
using UnityEngine;

public class PhotonController : MonoBehaviourPunCallbacks
{
    private void Start()
    {
        // PhotonServerSettingsの設定内容を使ってマスターサーバーへ接続する
        PhotonNetwork.ConnectUsingSettings();
    }

    // マスターサーバーへの接続が成功した時に呼ばれるコールバック
    public override void OnConnectedToMaster()
    {
        // "Room"という名前のルームに参加する(ルームが存在しなければ作成して参加する)
        PhotonNetwork.JoinOrCreateRoom("Room", new RoomOptions(), TypedLobby.Default);
    }

    // ゲームサーバーへの接続が成功した時に呼ばれるコールバック
    public override void OnJoinedRoom()
    {
        //何番目の入室者か? 1から順番通り採番される。退室者がいた場合の法則は未確認
        //今回使わないけど、今後何かで必要そうなので備忘録としてここに残してます。
        int num = PhotonNetwork.CurrentRoom.PlayerCount;

        //自身のアバターはランダムで決定
        //今回のアバター3体で、名をAvatar1,Avatar2,Awatar3とし、Resources フォルダに入れておく
        string avatarName="";
        int _ranNum = Random.Range(1, 4);
        avatarName = "Avatar" + _ranNum;
        
        // ランダムな座標に自身のアバター(ネットワークオブジェクト)を生成する
        var position = new Vector3(Random.Range(-10f, 10f), Random.Range(10f, 0f), Random.Range(-10f, 10f));
        GameObject avatar = PhotonNetwork.Instantiate(avatarName, position, Quaternion.identity);

        var camera = GameObject.Find("MainCamera");

        camera.transform.parent = avatar.transform;
        //camera.transform.position = avatar.transform.position;

        var pos = avatar.transform.position;

        camera.transform.position = new Vector3(pos.x , pos.y+1.0f, pos.z);


    }
}



アバターのスクリプト Walk.cs の public class Walk : MonoBehaviourを public class Walk : MonoBehaviourPunCallbacks に変更

Update()関数に
if (photonView.IsMine)
を追加。

これで、自分のオブジョクトとその他オブジョクトの切り分けができる。

Walk.cs
using UnityEngine;
using System.Collections;
using Photon.Pun;
using Photon.Realtime;

public class Walk : MonoBehaviourPunCallbacks
{

    private Animator animator;
    // Use this for initialization
    void Start()
    {
        animator = GetComponent<Animator>();
    }

    // Update is called once per frame
    void Update()
    {
        if (photonView.IsMine)
        {

            if (Input.GetKey("up"))
            {
                transform.position += transform.forward * 0.02f;
                animator.SetBool("is_walking", true);
            }
            else if (Input.GetKey("down"))
            {
                transform.position -= transform.forward * 0.02f;
                animator.SetBool("is_walking", true);
            }
            else
            {
                animator.SetBool("is_walking", false);
            }
            if (Input.GetKey("right"))
            {
                transform.Rotate(0, 1.0f, 0);
            }
            if (Input.GetKey("left"))
            {
                transform.Rotate(0, -1.0f, 0);
            }
        }
    }

}

##ビルド
WebGLでやってみる

Image from Gyazo

インストールする必要があるので、クリック

モジュールを追加
Image from Gyazo

再度ビルド!

HTMLファイルなどウェブサイト公開に必要なファイルができる。
Image from Gyazo

いろいろなやり方があるが、
私は、できたものをそのまま、契約しているレンタルサーバーにFTPでファイル転送。(使用ソフトはCyberduck)

完了!!

##プレイヤー名
2021.8.11追記

このままでは、どれが誰のアバターなのか判別がつかないので、アバターの頭上にプレイヤー名を表示してみました。
プレファブのアバターをクリックして、空のオブジェクトを追加(この画像では名前を NameDisplay)

inspector に TextMesh Pro を追加すると、いろんなものが付いてくる。

Image from Gyazo

NameDisplay オブジェクトに、以下のスクリプトをアタッチする

AvatarNameDisplay.cs
using Photon.Pun;
using TMPro;

// MonoBehaviourPunCallbacksを継承して、photonViewプロパティを使えるようにする
public class AvatarNameDisplay : MonoBehaviourPunCallbacks
{
    private void Start() {
        var nameLabel = GetComponent<TextMeshPro>();
        // プレイヤー名とプレイヤーIDを表示する
        nameLabel.text = $"{photonView.Owner.NickName}({photonView.OwnerActorNr})";
    }
}

テキストの位置調整
Image from Gyazo

PhtonContoroller.cs の private void Start() に Player名設定のコードを追加

PhtonContoroller.cs
private void Start()
    {
        // プレイヤー自身の名前を"Player"に設定する
        PhotonNetwork.NickName = "Player";

        // PhotonServerSettingsの設定内容を使ってマスターサーバーへ接続する
        PhotonNetwork.ConnectUsingSettings();
    }

できた!

でも、手前側が裏になってしまいますww

236884580_4247686941946474_6227506079556874046_n.jpeg


##参考サイト

14
9
0

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
14
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?