4
1

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 1 year has passed since last update.

【Unity/Photon Voice2】ボイスチャットの実装(ルーム・チャンネルを分けて)

Last updated at Posted at 2022-08-05

はじめに

この記事はUnityでボイスチャットを導入し、なおかつチャンネルを分けたい、例えばAチームはAチームの会話のみ話せ、Bチームの会話は入ってこない、というような実装をします。

サンプルとなるプロジェクトです。
https://github.com/konbraphat51/PhotonVoiceChannelSperated
細かい部分は本記事とは異なりますが、本筋はだいたい同じです。
Photon IDを空欄にしていますので、後述するID2種をご自分で調達して登録してください。

Photon Voiceでは古い記事の実装がうまく通用しなくなったケースがいくらか見られ、この記事もいずれ劣化するかもしれません。この記事は2022年8月の成功例としてご認識ください

Photon Voice 2の導入

こちらのアセットストアから導入してください。
もしPhotonやったことのある方がいれば、PUN2も導入しないといけないのでは?と思うかもしれませんが、Photon voice 2にはPUN2も含まれていますためPUN2を混入しないでください。 公式もそう言ってます。

Photonの登録

Photonはサーバーサービスですので、アプリの登録をしないといけません。
Photonのページからユーザー登録、そしてRealtime、Voiceの2つのアプリを登録してください。

Photonの設定

Unity画面上部のWindow->Photon Unity Networking->Highlight Server SettingsからUnity側のPhoton設定にアクセスできます。
Untitled.png

App ID PUNにRealtimeの方のアプリIDを、
App ID VoiceにVoiceの方のアプリIDをコピペ。
Fixed Regionをjpにするのが定番となっています。

今からやること

本格的な実装に入っていきます。
仕組みとしましては、 まず
・PhotonManager
・VoiceManager
・スピーカー
の三つのオブジェクトがあります。

PunManagerは、最初にサーバーへの接続する役割を担います。

VoiceManagerは画面の前のあなたの声を収録し、それをネットワークを通じて他人のスピーカーへ送り届けます。

スピーカーは、実際に受信した音を発します。ここで注意したいのが、最初(実行する前)スピーカーはいません。プレハブという形にして、PhotonにInstantiateしてもらう形になります。

PunManager

空オブジェクトに、下記のスクリプトをはっつけてください。
大筋の流れは@UpAllNightさんの超分かりやすい記事を参考にさせて頂きました。

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

public class PunManager : MonoBehaviourPunCallbacks
{
    void Start()
    {
        PhotonNetwork.ConnectUsingSettings();
    }

    void OnGUI()
    {
        GUILayout.Label(PhotonNetwork.NetworkClientState.ToString());
    }

    public override void OnConnectedToMaster()
    {
        PhotonNetwork.JoinOrCreateRoom("room", new RoomOptions(), TypedLobby.Default);
    }

    //ルームに入室後に呼び出される
    public override void OnJoinedRoom()
    {
        PhotonNetwork.Instantiate("Speaker", Vector3.zero, Quaternion.identity, 0);
    }
}

これのおかげで、まずサーバーに接続され、Speaker(後述)が生成されます。

スピーカーオブジェクト

空オブジェクトに、Speaker Photon Voice Viewをアタッチしてください。するとAudio Souceも勝手に追加されますが削除しないでください。
下図のような感じで設定していれば大丈夫でしょう。
Untitled.png
これをプレハブにし、プレハブ名を「Speaker」にして
Assets -> Photon -> Resourcesに保存してください。
ここの原理はこちらの記事が超分かりやすいです。

VoiceManager

空オブジェクトに、Photon Voice NetWork Recorderコンポーネントをアタッチしてください。
Untitled.png
こんな感じに設定してみてください。画像はPlayerプレハブになっていますが、Speaker Prefabには先ほど作ったスピーカーをアタッチしてください。
ちなみに筆者はTransmit Enableにチェックを付けていなくて詰んでいました。

第一弾(ルーム分けなし)、完成

これでまず、第一弾完成です。試しにビルドして二つ同時に実行すると、自分のマイクの音が返ってくることがわかると思います。

チャンネル分け機能の実装

所属チームなどによってチャンネルを分け、チームごとに分けたボイスチャットをするまで、あと一息です。
先ほどのVoiceManagerに下記のスクリプトをアタッチしてみてください。

VoiceTeamSwitch.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Photon.Voice.PUN;
using Photon.Voice.Unity;

public class VoiceTeamSwitch : MonoBehaviour
{
    PhotonVoiceNetwork voiceNetwork;
    Recorder recorder;
    // Start is called before the first frame update
    void Start()
    {
        voiceNetwork = GetComponent<PhotonVoiceNetwork>();
        recorder = GetComponent<Recorder>();
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Q))
        {
            byte[] remove = new byte[0];
            byte[] add = new byte[] { 1 };
            //チャンネル変更部分
            voiceNetwork.Client.OpChangeGroups(remove, add);
            recorder.InterestGroup = 1;
            //チャンネル変更部分ここまで
            Debug.Log(1);
        }
        if (Input.GetKeyDown(KeyCode.W))
        {
            byte[] remove = new byte[0];
            byte[] add = new byte[] { 2 };
            voiceNetwork.Client.OpChangeGroups(remove, add);
            recorder.InterestGroup = 2;
            Debug.Log(2);
        }
    }
}

上記のコードで、Qキーを押すとチャンネル1に、Wキーを押すとチャンネル2に切り替えられます。
注意点として、デフォルトはチャンネル0ですが、チャンネル0は「全員」に聞こえるようになっています。よって他チャンネルのボイスを聞こえさせたくない場合は、まずチャンネル0から抜けさせる必要があります。

また、
voiceNetwork.Client.OpChangeGroups(remove, add) は「受信」するチャンネル
recorder.InterestGroup は「送信」するチャンネル
です。
「送信」は1チャンネルのみですが、「受信」に関しては複数チャンネル可能です。
第一引数は抜けるチャンネルを、第二は参加するチャンネルを指定します。
ここにbyte[0]を指定すると、「全チャンネル」から脱退・参加
nullをしているすると「何もしない」になります。

4
1
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
4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?