【VRChat】VRCPlayerApi と Networking【SDK3】

## 更新情報
2022年2月28日: [VRCPlayerApi 操作系](#操作系)について、`Respawn`ノードについての説明を追加。それに伴い、画像を差し替え。

## 目次
<details><summary></summary><div>

- [対象者](#対象者)
- [この記事の概要](#この記事の概要)
- [そもそもUdonが分からない人へ](#そもそもudonが分からない人へ)
- [重要な用語説明](#重要な用語説明)
- [VRCPlayerApi](#vrcplayerapi)
  - [プレイヤー情報系](#プレイヤー情報系)
  - [データ取得系](#データ取得系)
  - [操作系](#操作系)
- [Networking](#networking)
- [作例](#作例)
- [おわりに](#おわりに)
</div></details>

## 対象者
- プレイヤーやその情報に関連するギミックを作りたい人

など...

## この記事の概要
- プレイヤーに関する情報を扱う方法(`VRCPlayerApi`と`Networking`)について説明
- 主要なノードのみ説明
- UdonGraphでの説明
- プログラミングが分からなくてもOK

UdonGraphの情報が少ないので記事を書きました。
VRCユーザーがUdonをもっと手軽に扱えるようになりますように。

わかりにくいところや問題点があれば、[Twitter](https://twitter.com/Sayabeans_0011)などにお願いします！
ちなみに、UdonGraphを用いたサンプルを[Booth](https://sayamame-beans.booth.pm/)で無料配布していますので、良ければ参考にどうぞ。(随時更新)

:::note warn
動作確認環境
・Unity 2019.4.31f1
・VRCSDK3-WORLD-2022.02.16.19.13_Public

この記事は2022年2月28日時点の情報です。
Udonはアップデートされていくため、情報が古くなりやすく、最新版とは仕様が違うことがあります。
:::

## そもそもUdonが分からない人へ
入門記事を作成しておりますので、ご参考にどうぞ。
[【VRChat】Udon Graph 入門【SDK3】](https://qiita.com/Sayamame/items/c36a1a87d4189d51099c)

## 重要な用語説明
- VRCPlayerApi
VRChat内のプレイヤー情報。
プレイヤー名やワールド上の位置などが取得出来る。

- ローカルプレイヤー
自分自身のこと。

- インスタンスオーナー
インスタンスを建てた人。

- インスタンスマスター
インスタンスに最も早く入ったプレイヤー。そのプレイヤーがインスタンスを抜けた場合は、次に早く入っていたプレイヤーに移る。

- オーナー
オブジェクトの操作権限があるプレイヤー。

- プレイヤーID
インスタンスに入った順で割り振られる番号。同じプレイヤーが入り直した場合、新たな番号が割り当てられる。

## VRCPlayerApi
検索では「VRC→PlayerApi」の位置にあります。

### プレイヤー情報系
![Player_Info.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592409/31a9ec01-8d98-2725-fda2-0f88f521e0ca.png)

| ノード名            | 説明                                                                                                                    |
| :------------------ | :---------------------------------------------------------------------------------------------------------------------- |
| get displayName     | VRCPlayerApiデータに格納されているプレイヤー情報から、プレイヤーの表示名を得る。                                        |
| get isInstanceOwner | VRCPlayerApiデータに格納されているプレイヤー情報が、インスタンスオーナーのものであればTrue、そうでなければFalseを得る。 |
| get isLocal         | VRCPlayerApiデータに格納されているプレイヤー情報が、自身のものであればTrue、そうでなければFalseを得る。                 |
| get isMaster        | VRCPlayerApiデータに格納されているプレイヤー情報が、インスタンスマスターのものであればTrue。そうでなければFalseを得る。 |
| get playerId        | VRCPlayerApiデータに格納されているプレイヤー情報から、プレイヤーIDを得る。                                              |
| GetPosition         | VRCPlayerApiデータから、該当するプレイヤーの位置を得る。                                                                |
| IsUserInVR          | VRCPlayerApiデータから、プレイヤーがVRを使用していればTrue、そうでなければFalseを得る。                                 |
| IsOwner             | VRCPlayerApiデータから、プレイヤーがオブジェクトのオーナーであればTrue、そうでなければFalseを得る。                     |
| IsValid             | VRCPlayerApiデータが有効なものであればTrue、そうでなければFalseを得る。                                                 |
| Equals              | VRCPlayerApiデータの内容が同じであればTrue、そうでなければFalseを得る。                                                 |

### データ取得系
![Data_Get.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592409/16dc92af-f083-39e4-4198-bbed8347a260.png)

| ノード名       | 説明                                                                                                                  |
| :------------- | :-------------------------------------------------------------------------------------------------------------------- |
| GetPlayerById  | プレイヤーIDから、VRCPlayerApiデータを得る。                                                                          |
| GetPlayerCount | インスタンスに居るプレイヤーの人数を得る。                                                                            |
| GetPlayers     | インスタンスに居るプレイヤー全員の情報が含まれる、VRCPlayerApi配列を得る。(使い方が若干特殊なので、[作例](#作例)参照) |

### 操作系
![Control_2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592409/203dbe25-deb9-1f58-7f45-66211682dd10.png)


| ノード名   | 説明                                                                                                                        |
| :--------- | :-------------------------------------------------------------------------------------------------------------------------- |
| TeleportTo | VRCPlayerApiデータから、該当するプレイヤーを指定した座標にテレポートさせる。(teleportRotで向きを決められますが、今回は割愛) |
| Respawn    | VRCPlayerApiデータから、該当するプレイヤーをリスポーンさせる。(`(Void)`の部分を`(int)`に変えると、spawnsIndexという項目が現れます。これはVRCWorldで設定出来る複数のスポーン地点から1つを指定するための番号です。詳細は下図を参照) |

![VRCWorld_Spawns.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592409/9c52a943-22c3-76cf-9468-4827910c9f8d.png)


## Networking
検索では「VRC→Networking」の位置にあります。

![Networking.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592409/c3914a34-eb25-7130-a82c-f5dff92b1d1b.png)

| ノード名            | 説明                                                                                |
| :------------------ | :---------------------------------------------------------------------------------- |
| get IsInstanceOwner | ローカルプレイヤーがインスタンスオーナーであればTrue、そうでなければFalseを得る。   |
| get IsMaster        | ローカルプレイヤーがインスタンスマスターであればTrue、そうでなければFalseを得る。   |
| get LocalPlayer     | ローカルプレイヤーのVRCPlayerApiデータを得る。                                      |
| GetOwner            | オブジェクトのオーナーのVRCPlayerApiデータを得る。                                  |
| IsOwner             | ローカルプレイヤーがオブジェクトのオーナーであればTrue、そうでなければFalseを得る。 |
| SetOwner            | VRCPlayerApiデータが示すプレイヤーを、オブジェクトのオーナーに設定する。            |

## 作例
![GetPlayers使い方.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592409/f5561e3b-4b82-44c3-6c46-13e0b60191f2.png)
これは、GetPlayersの使い方です。
GetPlayerCountでプレイヤーの人数を取得して、VRCPlayerApi[]のConstructorに渡すことで、人数分の大きさのVRCPlayerApi配列を作成出来ます。
この配列をGetPlayersに渡すことで、プレイヤー全員の情報が入ったVRCPlayerApi配列を得ることが出来ます。

![作例.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592409/b84bdbe5-8e68-499a-0876-0357693ed79a.png)
これは実際にVRCPlayerApiとNetworkingを使って、インタラクトするとテレポートするオブジェクトを作ってみた例です。
別の場所に配置したゲームオブジェクトをpublic変数を使って参照し、その座標にテレポートさせます。

## おわりに
ご覧いただきありがとうございます。
参考になれば幸いです。