agora.io VideoSDK for Unity クイックスタートガイド (2)

#概要
agora.io に VideoSDK for Unity が公開されています。

Unity とは Unity Technologies が開発しているマルチプラットフォーム対応のゲームエンジンです。
Unity プロジェクトに VideoSDK を組み込むことで iOS/Android/MacOSX/Windows のアプリ開発が可能となります。
※ 開発には C# でのコーディングが必要となります。

この記事では、チャンネル入室や映像表示といった基本的な機能がどのようにして実装できるか、VideoSDK のサンプルデモを使って紹介します。
※ VideoSDK および Unity にあまり馴染みのない方は、[予めクイックスタートガイド (1)](https://qiita.com/v-cube/items/b043065c7504a372f2b2) を読んでおくことをお勧めします。

#実装例

一連の処理は TestHelloUnityVideo.cs に実装されていますので、中身を見てみましょう。

##初期化
```c#:TestHelloUnityVideo.cs
    // instance of agora engine
    private IRtcEngine mRtcEngine;

    // load agora engine
    public void loadEngine(string appId)
    {
        ...
        // init engine
        mRtcEngine = IRtcEngine.GetEngine(appId);
        ...
    }
```

SDK を使う最初のステップとして、GetEngine() で IRtcEngine オブジェクトを初期化します。この時、引数として AppID を渡します。


##入室処理

```c#:TestHelloUnityVideo.cs
    public void join(string channel)
    {
        ...
        // enable video
        mRtcEngine.EnableVideo();
        ...
        // join channel
        mRtcEngine.JoinChannel(channel, null, 0);
        ...
    }
```

チャンネルへの接続は JoinChannel() を使います。接続前に予め EnableVideo() をコールして映像の送受信を有効にしておきます。
※ 音声についてはデフォルトで有効になっています。


##入室ロジック
```c#:TestHome.cs
    public void onJoinButtonClicked() 
    {
        // get parameters (channel name, channel profile, etc.)
        GameObject go = GameObject.Find("ChannelName");
        InputField field = go.GetComponent<InputField>();

        // create app if nonexistent
        if (ReferenceEquals(app, null))
        {
            app = new TestHelloUnityVideo(); // create app
            app.loadEngine(AppID); // load engine
        }

        // join channel and jump to next scene
        app.join(field.text);
        ...
    }
```
ここまで紹介した loadEngine() と join() は、別スクリプト (TestHome.cs) のメソッド onJoinButtonClicked() の中で順番に呼び出されています。 このメソッドはユーザーが Join ボタンが押された時のイベントハンドラとして登録されています。


##映像まわり
カメラ映像を Unity シーン内に表示するには VideoSurface コンポーネントを使います: 

```c#:TestHelloUnityVideo.cs
    public void onSceneHelloVideoLoaded()
    {
        // Attach the SDK Script VideoSurface for video rendering
        GameObject quad = GameObject.Find("Quad");
        if (ReferenceEquals(quad, null))
        {
            Debug.Log("BBBB: failed to find Quad");
            return;
        }
        else
        {
            quad.AddComponent<VideoSurface>();
        }

        GameObject cube = GameObject.Find("Cube");
        if (ReferenceEquals(cube, null))
        {
            Debug.Log("BBBB: failed to find Cube");
            return;
        }
        else
        {
            cube.AddComponent<VideoSurface>();
        }
    }
```

サンプルでは、シーン内に配置された PrimitiveType (Cube や Plane の総称) に、このコンポーネントを追加する処理をしています。
これにより、これらオブジェクトの表面上に自映像がマッピングされるようになります。

また、RawImage 上にカメラ映像を表示させることもできます。サンプル内、以下の箇所にて実装が確認できます: 

```c#:TestHelloUnityVideo.cs
    private void onUserJoined(uint uid, int elapsed)
    {
        ...
        // create a GameObject and assign to this new user
        VideoSurface videoSurface = makeImageSurface(uid.ToString());
        if (!ReferenceEquals(videoSurface, null))
        {
            // configure videoSurface
            videoSurface.SetForUser(uid);
            videoSurface.SetEnable(true);
            videoSurface.SetVideoSurfaceType(AgoraVideoSurfaceType.RawImage);
            ...
        }
    }
    ...
    public VideoSurface makeImageSurface(string goName)
    {
        GameObject go = new GameObject();
        ...
        go.name = goName;

        // to be renderered onto
        go.AddComponent<RawImage>();
        ...
        // configure videoSurface
        VideoSurface videoSurface = go.AddComponent<VideoSurface>();
        return videoSurface;
    }
```

onUserJoined() はリモート側のユーザーがチャンネル接続した時に呼ばれるイベントハンドラとなります。
サンプルでは、カメラ映像の表示枠として RawImage を組み込んだ GameObject を用意し、そこに VideoSurface を追加しています。
その後、VideoSurface のメソッドをコールして各種設定を行ないます:

* SetForUser()... 指定した UID のカメラ映像を使います（デフォルトはローカルのカメラ映像）
* SetEnable()... カメラ映像の表示・非表示のフラグを設定します
* SetVideoSurfaceType()... レンダラーを指定します。デフォルトでは PrimitiveType 向けの設定のため RawImage を指定しています

#関連リンク
・[UnityのAPIリファレンスはどこにありますか？](https://qiita.com/v-cube/items/510dab2360293b5008f9)

#最後に
[**agora.ioに関するお問い合わせはこちらから**](https://jp.vcube.com/lp/agora?utm_campaign=Agora&utm_source=Qiita&arc_id=510dab2360293b5008f9)
[<img width="912" alt="スクリーンショット 0001-08-15 13.41.56.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/300377/5d815376-9b89-08fa-9434-6fa7e8e67bcf.png">](https://jp.vcube.com/lp/agora?utm_campaign=Agora&utm_source=Qiita&arc_id=510dab2360293b5008f9)