Photon Cloud × Unity GameJam 事前勉強会資料

## 概要
GameJamの事前勉強会のために作った資料です。

> GameJam登録受付
http://kokucheese.com/event/index/95326/

ここでは、ロビーからルームの自動入室、キャラクター位置の同期、チャットの実装までをチュートリアルアセットを利用して学習します。

## 前提
Photon Cloudのアカウントを作成済みであること
Unityがインストール済みであること

## １．空のプロジェクト作成
Unityで空のプロジェクトを作成します。

## ２．アセットのインポート
Unity Asset StoreからPhotonのサンプルアセットをインポートします。

* Photon Unity Networking Free

>http://u3d.as/2ey

## ３．Photon Cloudの接続設定

PUN Wizardウィンドウが表示されるので、上から２番目のボタン”Setup”を押し、
![punwizard](https://dl.dropboxusercontent.com/u/46503306/qiita/Photon/ss_photon_3_1.png)

"Your AppId"に、Photon Cloudの管理画面に表示されているAppIDを、
"Cloud Region"は、”Japan”を選択し
”Save”を押して設定を終了します。
![punwizard2](https://dl.dropboxusercontent.com/u/46503306/qiita/Photon/ss_photon_3_2.png)

> 2956ba32-a017-446a-8adb-f0de57c02802

## ４．新しいシーンを作成する

"File -> New Scene"で新しいシーンを作成します。

## ５．Photon Cloudに接続する準備をする

"Hierarchy"に空のゲームオブジェクトを作成し（ここでは"photon script"と命名）、
![photon script](https://dl.dropboxusercontent.com/u/46503306/qiita/Photon/ss_photon_5_1.png)

"RandomMatchmaker"スクリプトをアタッチする。
![randommatchmaker](https://dl.dropboxusercontent.com/u/46503306/qiita/Photon/ss_photon_5_2.png)

ここでシーンを保存しておきます。

## ６．Playして動作を確認

ここまでのシーンを再生すると、何かがInstantiateされて床が無いので落ちていきます。
![6_play](https://dl.dropboxusercontent.com/u/46503306/qiita/Photon/ss_photon_6_1.png)

## ここまでで実はもうできていること

* Photonに接続
* ロビーに入室
* 部屋がなければ部屋を作成して入室
* 入室後に自分のキャラクターをInstantiate

## ７．床をつくってあげる

planeとDirectional lightで簡単なステージを作成する。
(planeのマテリアルはインポートしたアセットに含まれている"Pavement_01"を使用)
![make stage](https://dl.dropboxusercontent.com/u/46503306/qiita/Photon/ss_photon_7_1.png)

## ８．Playして動作を再確認

自分のキャラクターがステージ上にあらわれて操作できることを確認します。
![make stage](https://dl.dropboxusercontent.com/u/46503306/qiita/Photon/ss_photon_8_1.png)

## ９．モデルを差し替える

### （モデルが必要な人用）
* ドロイメライちゃん

>[doroimeraiSD.unitypackage](https://dl.dropboxusercontent.com/u/46503306/unity_bu/doroimeraiSD.unitypackage "doroimeraiSD.unitypackage")

* ドロイド君

>[DoroidModel.unitypackage](https://dl.dropboxusercontent.com/u/46503306/unity_bu/DoroidModel.unitypackage "DoroidModel.unitypackage")


まずは、Instantiateできるようにプレハブを作成します。
このときに、プレハブは"Resources"ディレクトリの下に入れるようにしてください。
（PhotonNetwork.Instantiateの第一引数はstring型。prefabは内部にキャッシュされていて、なかった場合にResources.Loadしているため）

![droimerai prefab](https://dl.dropboxusercontent.com/u/46503306/qiita/Photon/ss_photon_9_1.png)
作ったプレハブに、以下の４つのコンポーネントを追加します。

* myThirdPersonController

> PhotonUnityNetworkingアセットに含まれているもの
ThirdPersonControllerを継承したユーザスクリプト

IsControllableにチェックが入っているので、これをfalseにしておく

* CharacterController

> おなじみキャラクターコントローラ

* PhotonView

> PhotonUnityNetworkingアセットに含まれているもの
同期させる対象物に必ず必要なコンポーネント
UnityNetworkViewとほぼ同じもの

* NetworkCharacter

> PhotonUnityNetworkingアセットに含まれているもの
キャラクターの位置情報などを送受信するためのコンポーネント

![add component prefab](https://dl.dropboxusercontent.com/u/46503306/qiita/Photon/ss_photon_9_2.png)

"Photon View"コンポーネントの"Observe"に、今追加した"NetworkCharacter"スクリプトを設定します。
これによって、PhotonNetworkViewの観察対象として設定されます。

![photon view observe](https://dl.dropboxusercontent.com/u/46503306/qiita/Photon/ss_photon_9_3.png)


次に、"RandomMatchmaker"スクリプトを書き換えます。

before

```csharp:RandomMatchmaker.cs
void OnJoinedRoom()
{
    GameObject monster = PhotonNetwork.Instantiate("monsterprefab", Vector3.zero, Quaternion.identity, 0);
    monster.GetComponent<myThirdPersonController>().isControllable = true;
    myPhotonView = monster.GetComponent<PhotonView>();
}
```

after

```csharp:RandomMatchmaker.cs
void OnJoinedRoom()
{
    GameObject monster = PhotonNetwork.Instantiate("droimerai", Vector3.zero, Quaternion.identity, 0);
    monster.GetComponent<myThirdPersonController>().isControllable = true;
    myPhotonView = monster.GetComponent<PhotonView>();
}
```

これによって、入室時にInstantiateされるプレハブが変更されます。

## １０．Playしてモデルが差し替わっているか確認
kawaii
![play droimerai](https://dl.dropboxusercontent.com/u/46503306/qiita/Photon/ss_photon_10_1.png)

## １１．チャットの実装
次に、チャットの実装をします。
まずは空のゲームオブジェクトを作成します。
（今回は”Chat”と命名）
![create gameobject chat](https://dl.dropboxusercontent.com/u/46503306/qiita/Photon/ss_photon_11_1.png)
”Chat”ゲームオブジェクトに、以下の２つのコンポーネントを追加します。

* Chat

> PhotonUnityNetworkingアセットに含まれているもの
チャット用スクリプト

* PhotonView

> 同期させる対象物に必ず必要なコンポーネント
UnityNetworkViewとほぼ同じもの

## １２．Playしてチャットが実装できているか確認
チャット用のUIができています
![play chat](https://dl.dropboxusercontent.com/u/46503306/qiita/Photon/ss_photon_12_1.png)

## １３．自分の名前を設定する
このままでは名無しさんなので、誰がチャットで発言したのかわかりません。ですので自分の名前を設定します。
今回は、"RandomMatchmaker"の中で設定します。

before

```csharp:RandomMatchmaker.cs
void Start()
{
    PhotonNetwork.ConnectUsingSettings("0.1");
}
```

after

```csharp:RandomMatchmaker.cs
void Start()
{
    PhotonNetwork.ConnectUsingSettings("0.1");
	
	if (string.IsNullOrEmpty(PhotonNetwork.playerName))
	{
		PhotonNetwork.playerName = "guest" + Random.Range(1, 99999);
	}
}
```

## １４．Playして自分の名前が設定できているか確認
ちゃんと”guest + ランダムな数字"になっています
![chat name](https://dl.dropboxusercontent.com/u/46503306/qiita/Photon/ss_photon_13_1.png)

## まとめ
以上で、ロビーからルームの自動入室、キャラクター位置の同期、チャットの実装を終えました。

汎用的にできることが多い分、書けていない機能も多いので機会があれば続き書こうと思います。

## 初学者向け問題はこちら
[Unityに関する初歩問題](https://codeiq.jp/ace/kamata_yasuyuki/q362 "Unityに関する初歩問題")

## Photonサインアップマニュアル
[Photonサインアップマニュアル](http://goo.gl/NG3fp)

## published by
日本Androidの会 秋葉原支部 Unity部
https://www.facebook.com/groups/android.akb.unity/