Photon RealtimeとPhoton Voice でマルチ通信

# 事前準備
## 新規Unityアプリケーションを作成する
新規アプリケーションを作成して開発を行うための準備を行います。
Unityを起動して、ページ上部にあるNEWを選択してください。


![alt](https://www.evernote.com/l/AgvPDHROjZtKqrfWCE33fQJMK4NbZHzc-Y4B/image.png)

Project name の入力欄に、「photontest」と入力してください。Locationが指定のフォルダ以下になっていることを確認します。3Dを選択した後、「Create project
」を選択し、Projectを作成してください。

![alt](https://www.evernote.com/l/AgtUxJ6EMrJMR72i_9NzqPJUffX5MkGMiS0B/image.png)



## Asset Storeで必要なアセットをインポート
### Unityちゃんのインポート
Asset Storeを起動してください。 以下の画像のようになっていれば、大丈夫です。

![alt](https://www.evernote.com/l/AgtpmhAoR9BLjpflXwZVp7m3M6285mN_YOgB/image.png)

Asset Storeの検索窓に**「Unity-chan」**と打ち込み、虫眼鏡マークをクリックしてください。

![alt](https://www.evernote.com/l/AgumL9zVQxFHWaHgEgkvN4SHY9_9SoLaNcgB/image.png)

下に行くと、今回使用するassetがあるので、クリックしてください。

![alt](https://www.evernote.com/l/AgtxdQWR199CkL1Iv-mOXgboFBr3AgyvnQ0B/image.png)

アセットの個別ページに遷移をしたら、**「ダウンロード」**をクリックします。

![alt](https://www.evernote.com/l/Agv0G6jVpWZIq5KyZzoL1z0JhoAnOmPc89MB/image.png)

「ダウンロード」が「インポート」に変わるので、クリックをします。

![alt](https://www.evernote.com/l/AgsiHJh99WdCOILgMzF7wTi1IYq1dOTaVQcB/image.png)

全てにチェックが入っていることを確認して、importをクリックします。

![alt](https://www.evernote.com/l/AgtDtNRXLdhOm6Gb5toRqazX7zUTXCPsEHMB/image.png)

Projectビューに以下の画像と同じものが追加されていれば大丈夫です。

![alt](https://www.evernote.com/l/AgtlcuJa_h5JUaOWcUtUPBuF8pJ1WZYBTZUB/image.png)


### Photon Voiceのインポート
Asset Storeの検索窓に**「Photon Voice」**と打ち込み、虫眼鏡マークをクリックしてください。

![alt](https://www.evernote.com/l/Agvn_BYG05pN-blnAdRI84KPbovw8mhdxxsB/image.png)

下に行くと、今回使用するassetがあるので、クリックしてください。

![alt](https://www.evernote.com/l/Agv8pd4oxhNK05xZY1OR3hsR5ZbvQjKNGN8B/image.png)

アセットの個別ページに遷移をしたら、**「ダウンロード」**をクリックします。

![alt](https://www.evernote.com/l/AguPU_3XhVJLvpsjgLFZHNvm6QV2N9_An9kB/image.png)

「ダウンロード」が「インポート」に変わるので、クリックをします。

![alt](https://www.evernote.com/l/AguK5hyYtzRBFZQKao9q1fjANEF1f1Ii6QgB/image.png)

全てにチェックが入っていることを確認して、importをクリックします。

![alt](https://www.evernote.com/l/AgvFcvc-oRZL_JHIyOtsRpH2qxERv5Pn9dgB/image.png)

※以下のようなビューが表示されても気にしないでください。

![alt](https://www.evernote.com/l/Aguzm3WOivtClZXDbPhZmqhEfx9mnmw9qUEB/image.png)

Projectビューに以下の画像と同じものが追加されていれば大丈夫です。

![alt](https://www.evernote.com/l/AgtnErQ3pkZKdqFiKqaQ5qa2zCiKXUgqdWoB/image.png)

### 不必要なフォルダを削除
ProjectビューのPUNVoice以下にある、「DemoVoice」は今回は不要なので削除してください。
削除する方法は、右クリック→削除 または ⌘(コマンド)+ｖで可能です。
以下の動画も参考にしてください。

[![https://gyazo.com/7b3e872e4641e95487cdc19acf50e793](https://i.gyazo.com/7b3e872e4641e95487cdc19acf50e793.gif)](https://gyazo.com/7b3e872e4641e95487cdc19acf50e793)


## AppIDの取得
IDを２つメモしていただきます。2つの判別がつかなくならないように注意してください。
###Photon realtimeのAppIDの取得
Photon Realtimeは無料のアカウントを取得するとすぐに利用できます。
アカウントの取得は下記URLからメールアドレスを登録するとできます。
https://www-jp.exitgames.com/ja/Realtime
完了すると、登録したメールアドレスにURLが記載されていますので、そちらを押下し登録を完了してください。

次に、以下のURLに行き、ダッシュボードからRealtimeをクリックしてください。
https://www.photonengine.com/ja/Photon
すると、以下のような画面に行くので、「新しくReaktimeアプリを作成する」をクリックしてください。

![alt](https://www.evernote.com/l/AgsOsMMF2pFC7bY6TPbrHHSr3kA0DcKo3-EB/image.png)

以下のように入力をし、「作成する」を押してください。
アプリケーション名は任意のもので構いません。

![alt](https://www.evernote.com/l/AgtT3vHfCH1DMarhBjZdRnIXdWKOafwPK9MB/image.png)

すると以下のような画面に行くので、IDをメモしておいてください。

![alt](https://www.evernote.com/l/AgtW04J3C4JOaZV_pf-4KpabpHQ5F0jjbi8B/image.png)


###Photon Voiceの取得
以下のURLに行き、ダッシュボードからVoiceをクリックしてください。
https://www.photonengine.com/ja/Photon

![alt](https://www.evernote.com/l/AguEXJw0VUJB4rMXbXQyIuaklh4MMgQE4GcB/image.png)

右下の「新しくVoiceアプリを作成する」をクリックしてください。
すると以下のような画面に行くので、画像を参考に入力してください。
アプリケーション名は任意のもので構いません。

![alt](https://www.evernote.com/l/Agv480G2jBxBkI-QcVxKMx8upnTuuGBt-fYB/image.png)

入力できたら、「作成する」をクリックしてください。
すると以下のような画面に行くので、IDをメモしておいてください。

![alt](https://www.evernote.com/l/AgvVwNFdpqBOb77MavgCH0SBy5x2pnReqQ4B/image.png)

# PUNによる通信
## 開発用のフォルダーを作成
Assets以下に以下の3つのフォルダを作成してください。
・Scenesフォルダ
・Prefabsフォルダ
・Scriptsフォルダ
以下のようになっていれば大丈夫です。

![alt](https://www.evernote.com/l/AguLyXLOVmFHoZREvbyrvDlF4BHFyZf3ABcB/image.png)

## UnityちゃんをPrefab化
Projectビューのunitychanフォルダ内のPrefabsフォルダにある、unitychanプレファブをHierarchyビューにドラッグ＆ドロップしてください。
以下の動画も参考にしてください。

[![https://gyazo.com/dda2489cf62a6e010bb496842311013c](https://i.gyazo.com/dda2489cf62a6e010bb496842311013c.gif)](https://gyazo.com/dda2489cf62a6e010bb496842311013c)

HierarchyビューにあるunitychanをAssets以下のPrefabsフォルダにドラッグ＆ドロップしてください。
以下の動画も参考にしてください。

[![https://gyazo.com/94352ba02ea9eb41b125650be075cfd3](https://i.gyazo.com/94352ba02ea9eb41b125650be075cfd3.gif)](https://gyazo.com/94352ba02ea9eb41b125650be075cfd3)


## シーンを保存
Projectビューにある、UnityChanフォルダ内にあるScenesフォルダの**「Locomotion」**をダブルクリックしてSceneを変えてください。

![alt](https://www.evernote.com/l/AgsQKsQ7-hNNtqFTwlne1B3PFLtTxK76X5wB/image.png)

Hierarchyビューにあるunitychanを削除してください。
以下の様になっていれば大丈夫です。

![alt](https://www.evernote.com/l/Aguf1DY_mj5MAIq_22iPQfdMGKYKvCeX8xYB/image.png)

次にシーンを保存します。左上のファイルから「Save Scene as ...」選択し、シーン名をDemosとしてください。
保存先は、Assets以下のScenesフォルダにしてください。
以下の動画も参考にしてください。

[![https://gyazo.com/b0eb7c8b5dadc3e0f3703f4834c9b21f](https://i.gyazo.com/b0eb7c8b5dadc3e0f3703f4834c9b21f.gif)](https://gyazo.com/b0eb7c8b5dadc3e0f3703f4834c9b21f)

# コンポーネントの追加
Prefab化したunitychanに同期するためのコンポーネントを追加します。
Prefab化したunitychanを選択し、Inspectorビューの「Add Component」から以下の3つのコンポーネントを追加してください。
PhotonView : ゲーム内に必ず１つ必要。メッセージの送信を行う。
Photon Transform View : オブジェクトのTransformを同期するためのコンポーネント
Photon Animator View : オブジェクトのアニメーションを同期するためのコンポーネント

![alt](https://www.evernote.com/l/AgtoEX38ftFFobIvfOdUhavBtxNFHMFZH0MB/image.png)

以上の手順を残りの２つのコンポーネントについても行いましょう。
終了後、以下のようになっていれば大丈夫です。

![alt](https://www.evernote.com/l/Agscgw860GxEpqzsrYa946P9u0Fc11IXVGMB/image.png)

## PhotonViewの設定
Unityちゃんを同期するための手順として、PhotonViewの設定を行います。
現在PhotonViewは以下のようになっていると思います。

![alt](https://www.evernote.com/l/AguO44K7eRBD6a-_RdH-kl74jxudwlueYA0B/image.png)

上から順に説明します。

|言葉| 意味|
|:-----------------:|:------------------:|
| Owner             |アタッチしているゲームオブジェクトを所有する人|
| View ID           | Photon ViewのID番号 |
| Observe option    | 同期の方法(いつ、どのように)   | 
| Observed Components| 同期させたいオブジェクト|

今回は、監視対象(Observed Components)にPhoton Transform ViewとPhoton Animator Viewを追加します。
これは、アタッチするときと同じように、ドラッグ＆ドロップで可能です。以下の動画を参考にしてください。

[![https://gyazo.com/ee7c03820a0d0ce46c0f08dced886532](https://i.gyazo.com/ee7c03820a0d0ce46c0f08dced886532.gif)](https://gyazo.com/ee7c03820a0d0ce46c0f08dced886532)

以上で、Photon Viewの設定は終わりです。

## Photon Transform Viewを設定
Transformコンポーネントのうち同期させたいものにチェックをいれます。
今回は、以下２つにチェックしてください。
・Synchronized Position
・Synchronized Rotation

![alt](https://www.evernote.com/l/Agv0sbgLTCxLqIRH9nDLierYJ4xWlFDe9SYB/image.png)

Synchronized Positionを以下のように設定してください。

|項目|値|
|:-:|:-:|
|Interpolate Option| Lerp|
|Lerp Speed| 3|


### Interpolate Option
補完処理を行うための設定。これにより、オブジェクトの動きが滑らかに同期される。
各オプションの詳細は以下の通りです。
**・Disable**
補完を行いません。こちらに設定すると、同期させたいオブジェクトの動きが滑らかになリません。

**・Fixed Speed**
一定速度でオブジェクトを追従し補完します。
同期させたいオブジェクトの動きが一定のときに有効です。

**・Estimated Speed**
受け取った「直前の座標」と「現在の座標」の差分を現在の速度と仮定してオブジェクトを移動させて補間します。
ゆっくりと加速/減速するオブジェクトに有効です。

**・Synchronize Values**
スクリプトで直接Transformを指定し、これを用いて補完します。
動きの激しいオブジェクトの同期に有効です。

**・Lerp**
線形補完をします。
激しく動くオブジェクトも滑らかに同期できるが、タイムラグが生じる。
選択すると出てくる、Lerp Speedは線形補間を行う速さを表します。

### Extrapolate Option
補外処理。未来の座標を予測してオブジェクトを予め移動させておくことで同期による遅延を低減することができます。
急激に速度が変化したり、予測不能な動きをするオブジェクトには向いていません。

### Draw synchronized position error
ONにするとSceneViewに同期座標が描画されるようになります。


Synchronized Rotationを以下のように設定してください。
|項目|値|
|:--:|:--:|
|Interpolate Option| Lerp|

### Interpolate Option
**・Rotate Towards**
指定速度で補完します。

![alt](https://www.evernote.com/l/Agtc9O529R5Ncrz3kz1TXZJvGmGukuFAiL0B/image.png)

以上で、Photon Transform Viewの設定は終了です。

## Photon Transform Viewの設定
同期するパラメータの設定を行います。
各項目を以下のように設定してください。

|項目|設定値|
|:--:|:--:|
|Speed|Continuous|
|Direction|Continuous|
|Jump|Discrete|
|Rest|Discrete|
|JumpHight|Continuous|
|GravityControl|Continuous|

![alt](https://www.evernote.com/l/AgvYG2_CMUFFXrnQ8v23fcBlrFYy8q6gQ8IB/image.png)

設定値の意味は以下の通りです。
・Disable：同期しない
・Discrete：1秒間に10回のペースで同期を行う
・Continuous：1秒間に10回のペースでの同期は同じです。ただしこちらは毎フレームのパラメータ値を保存し、同期のタイミングでまとめて送信します。受信側では送られてきたパラメータ値を１フレームに１つずつ読み込んで再現します。


## Photon Serverの設定を編集
ProjectビューにあるPhoton Unity Networkingをクリックしてください。
Resourcesフォルダ内にある、PhotonServerSettingsをクリックしてください。

![alt](https://www.evernote.com/l/Agt9UwjM6EhFAq51Cp3e5qQ0z6Xrp_ssu6sB/image.png)

各項目を以下のように設定してください。

|項目|設定値|
|:-:|:-:|
|Hosting|PhotonCloud|
|Region|Jp|
|Appid|先程取得したPUNのID|
|Protocol|Udp|
|Client Settings|Auto-join Lobbyにチェック|

ここで、Appidに入力するidはphotonvoiceのidではなく、**photon realtimeのid**なので注意してください。

## PhotonControllerを作成
HierarchyビューのCreateを選択した後、Create Empty を選択してください。
すると、空のゲームオブジェクトが生成されるので、名前を「PhotonController」にしてください。
以下の動画も参考にしてください。

[![https://gyazo.com/da049444ee7f89b634d9cc24aac80a8e](https://i.gyazo.com/da049444ee7f89b634d9cc24aac80a8e.gif)](https://gyazo.com/da049444ee7f89b634d9cc24aac80a8e)

## スクリプトの作成
ProjectビューのScriptsフォルダを選択した後、右クリックから「Create」→「C# Script」と選択してください。
作成したC#スクリプトの名前をRandomMatchmakerとしてください。
以下のようになっていれば大丈夫です。

![alt](https://www.evernote.com/l/AgvqLD8uGjVBup_FKSjSPfnth1OlDfB8N0sB/image.png)

RandomMatchmaker.csを以下のように編集してください。

```
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class RandomMatchmaker : MonoBehaviour {
	public GameObject photonObject;

	void Start(){
		PhotonNetwork.ConnectUsingSettings("0.1");
	}

	void OnJoinedLobby(){
		PhotonNetwork.JoinRandomRoom();
	}

	void OnPhotonRandomJoinFailed(){
		PhotonNetwork.CreateRoom(null);
	}

	void OnJoinedRoom(){
		PhotonNetwork.Instantiate(
			photonObject.name,
			new Vector3(0f, 1f, 0f),
			Quaternion.identity, 0
		);

		GameObject mainCamera = 
			GameObject.FindWithTag("MainCamera");
		mainCamera.GetComponent<ThirdPersonCamera>().enabled = true;
	}

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

### PhotonNetwork.ConnectUsingSettings(string gameVersion)
エディタで設定するためにPhotonと接続します。
引数のgameVersionとはクライアントのバージョン番号です。ユーザーはゲームバージョンで個々に分断されます。

### OnJoinedLobby()
ロビーに入ったときに呼ばれるメソッド。
今回は、Auto-join Lobbyにチェックを入れているので、ロビーが存在すると自動でロビーに入ります。

### PhotonNetwork.JoinRandomRoom()
現在使われているロビーの、有効なRoomのどれかに入室します。有効なRoomがなければ失敗します。

### OnPhotonRandomJoinFailed()
Roomが存在せず、入室に失敗した時に呼ばれるメソッドです。

### PhotonNetwork.CreateRoom(string roomName)
Roomを作成するメソッドです。同一名のRoomがすでに存在している場合は失敗します。マスターサーバでのみ呼び出し可能。
固有のルーム名を作成しない場合は、nullまたは ""を名前として渡します。この場合、マスターサーバが割り当てをします。
Roomの作成に成功した場合、OnCreatedRoomとOnJoinedRoomコールバックを呼び出します。 Roomを作成できない場合、OnPhotonCreateRoomFailedが呼び出されます。

### OnJoinedRoom()
Roomに入室したときに呼ばれるメソッド。

### PhotonNetwork.Instantiate (string prefabName, Vector3 position, Quaternion rotation, int group)
同期したいオブジェクトをInstantiateするときに使用します。
第4引数はPhotonViewのグループの番号がはいります。

## スクリプトのアタッチ
PhotonControllerにRandomMatchmakerスクリプトをドラッグ＆ドロップして、アタッチしてください
Photon Objectの部分にProjctビューのPrefabｓフォルダにあるunitychanをアタッチしてください。
以下の動画も参考にしてください。

[![https://gyazo.com/b29f3fb24bf7880b00cf8451aeb85b50](https://i.gyazo.com/b29f3fb24bf7880b00cf8451aeb85b50.gif)](https://gyazo.com/b29f3fb24bf7880b00cf8451aeb85b50)

## Unityちゃんのスクリプトを編集
ProjectビューのUnityChanフォルダ内のScriptsフォルダにあるUnityChanControlscriptWithRigdBody.cdを編集します。

はじめに14行目を以下のように変更してください。

```
public class UnityChanControlScriptWithRgidBody : Photon.MonoBehaviour
```

Photon.MonoBehaviourクラスを継承することで、photonViewプロパティを追加します。

次にFixedUpdate関数内に以下の記述を追加してください。

```
if (!(photonView.isMine)) {
	return;
}
```

### photonView.isMine
PhotonViewが自分の物であるか、他のプレイヤーの物であるかを判定します。
自分の物である場合、trueが返されます。
今回の場合、自分がinstantiateしたもの以外は操作できないようにしています。


## メインカメラの設定を変更
Hierarchyビューにある「Main Camera」の「Third Person Camera」のチェックを外してください。

![alt](https://www.evernote.com/l/AgtQeYHUgG5NMJtlIDkQ4rJnucWO7dMWCIAB/image.png)

## 実行
複数人で同じ作業を行い、実行ボタンを押して実行してみましょう。


# PhotonVoiceの設定
## Photon Serverの設定を編集
ProjectビューにあるPhoton Unity Networkingをクリックしてください。
Resourcesフォルダ内にある、PhotonServerSettingsをクリックしてください。
Photon Voice Settingｓに **Photon VoiceのAppID**を入力してください。

![alt](https://www.evernote.com/l/AgsyF8NLTDBC2IgwM8CFTAKPz5w6ddR_DywB/image.png)

※リアルタイム同期とVoiceチャットのAppIDは分ける必要があるので、注意してください。

## Voice機能をつける
#unityちゃんにコンポーネントを追加
Assets以下のPrefanbsフォルダにあるunitychanに「Photon Voice Recorder」を追加します。
まず、unitychanプレファブを選択してください。Inspectorビューにある「Add Component」をクリックし、「Photon Voice Recorder」を追加してください。
![alt](https://www.evernote.com/l/AgusE608m71HRaxHJw569sKU-8C_Qx7CrIAB/image.png)
クリックをすると、下記のコンポーネントも自動で追加されます。
・Audio Source
・Photon Voice Speaker

![alt](https://www.evernote.com/l/AgsHRCT_8W5K4ovkv0hw-_U00FAbjtXhP0UB/image.png)

以上でVoice機能の追加は終わりです。

# 実行
複数人で同じ作業を行い、実行ボタンを押して実行してみましょう。