MRが楽しい

MRやVRについて学習したことを書き残す

公式チュートリアル「MR and Azure 305 10章」を試してみる

本日はチュートリアルの実施枠です。
Academyの「MR and Azure 305: Functions and storage」の実施内容をまとめます。
docs.microsoft.com
前回記事の続きです。
bluebirdofoz.hatenablog.com
今回は「Chapter 10」です。

Chapter 10:Completing the AzureServices class

全てのスクリプトが揃ったので、AzureServices クラスを完成させます。

1.Script フォルダから AzureServices クラスを開きます。
f:id:bluebirdofoz:20181011073939j:plain

2-6.以下の通り、スクリプトを編集します。
・AzureServices.cs

// 名前空間の追加
using System;
using System.Collections;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.Networking;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.File;
using System.IO;
using System.Net;

public class AzureServices : MonoBehaviour {
    // インスペクタフィールドの追加
    /// <summary>
    /// Provides Singleton-like behavior to this class.
    /// このクラスをシングルトンと同じように動作させます
    /// </summary>
    public static AzureServices instance;

    /// <summary>
    /// Reference Target for AzureStatusText Text Mesh object
    /// AzureStatusText Text Meshオブジェクトの参照先
    /// </summary>
    public TextMesh azureStatusText;

    // メンバ変数の追加
    /// <summary>
    /// Holds the Azure Function endpoint - Insert your Azure Function Connection String here.
    /// Azure Function のエンドポイントを保持します 
    /// 第二章で作成した Azure Function のエンドポイントをここに挿入します。
    /// Connection String here.
    /// </summary>
    private string azureFunctionEndpoint = "--Insert here you AzureFunction Endpoint--";

    /// <summary>
    /// Holds the Storage Connection String - Insert your Azure Storage Connection String here.
    /// Azure Storage の接続用文字列を保持します
    /// 第一章で作成した Azure Storage の接続用文字列をここに挿入します。
    /// </summary>
    private string storageConnectionString = "--Insert here you AzureStorage Connection String--";

    /// <summary>
    /// Name of the Cloud Share - Hosts directories.
    /// 共有クラウドの名前 - ホストディレクトリ
    /// </summary>
    private const string fileShare = "fileshare";

    /// <summary>
    /// Name of a Directory within the Share
    /// 共有内のディレクトリ名
    /// </summary>
    private const string storageDirectory = "storagedirectory";

    /// <summary>
    /// The Cloud File
    /// クラウドファイル
    /// </summary>
    private CloudFile shapeIndexCloudFile;

    /// <summary>
    /// The Linked Storage Account
    /// リンクされたストレージアカウント
    /// </summary>
    private CloudStorageAccount storageAccount;

    /// <summary>
    /// The Cloud Client
    /// クラウドクライアント
    /// </summary>
    private CloudFileClient fileClient;

    /// <summary>
    /// The Cloud Share - Hosts Directories
    /// クラウド共有 - ホストディレクトリ
    /// </summary>
    private CloudFileShare share;

    /// <summary>
    /// The Directory in the share that will host the Cloud file
    /// クラウドファイルをホストする共有内のディレクトリ
    /// </summary>
    private CloudFileDirectory dir;


    /// <summary>
    /// Called on initialization
    /// 初期化処理
    /// </summary>
    private void Awake()
    {
        instance = this;
    }

    /// <summary>
    /// Runs at initialization right after Awake method
    /// StartメソッドはAwakeメソッドの直後の初期化時に実行されます
    /// </summary>
    private void Start()
    {
        // Disable TLS cert checks only while in Unity Editor (until Unity adds support for TLS)
        // Unity Editor上ではTLS証明書チェックを無効にする(UnityがTLSのサポートを追加するまで)
#if UNITY_EDITOR
        ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
#endif

        // Set the Status text to loading, whilst attempting connection to Azure.
        // Azureへの接続を試みている間、ステータステキストを[Loading...]に設定します
        azureStatusText.text = "Loading...";

        // Creating the references necessary to log into Azure and check if the Storage Directory is empty
        // Azureにログインし、ストレージディレクトリが空であるかどうかを確認するのに必要な参照を作成する
        CreateCloudIdentityAsync();
    }

    /// <summary>
    /// Call to the Azure Function App to request a Shape.
    /// Azure Function の App を呼び出して図形を要求します
    /// </summary>
    public async void CallAzureFunctionForNextShape()
    {
        int azureRandomInt = 0;

        // Call Azure function
        // Azure function を呼び出す
        HttpWebRequest webRequest = WebRequest.CreateHttp(azureFunctionEndpoint);

        WebResponse response = await webRequest.GetResponseAsync();

        // Read response as string
        // レスポンスを文字列として読み取る
        using (Stream stream = response.GetResponseStream())
        {
            StreamReader reader = new StreamReader(stream);

            String responseString = reader.ReadToEnd();

            // parse result as integer
            // 結果を整数として解析する
            Int32.TryParse(responseString, out azureRandomInt);
        }

        // add random int from Azure to the ShapeIndexList
        // ShapeIndexList に Azure から取得したランダム int を追加する
        ShapeFactory.instance.shapeHistoryList.Add(azureRandomInt);

        ShapeFactory.instance.CreateShape(azureRandomInt, false);

        // Save to Azure storage
        // Azure Storage に保存する
        await UploadListToAzureAsync();
    }

    /// <summary>
    /// Create the references necessary to log into Azure
    /// Azure にログインするのに必要な参照を作成する
    /// </summary>
    private async void CreateCloudIdentityAsync()
    {
        // Retrieve storage account information from connection string
        // 接続文字列からストレージアカウント情報を取得する。
        storageAccount = CloudStorageAccount.Parse(storageConnectionString);

        // Create a file client for interacting with the file service.
        // ファイルサービスと対話するためのファイルクライアントを作成します
        fileClient = storageAccount.CreateCloudFileClient();

        // Create a share for organizing files and directories within the storage account.
        // ストレージアカウント内のファイルとディレクトリを整理するための共有を作成します
        share = fileClient.GetShareReference(fileShare);

        await share.CreateIfNotExistsAsync();

        // Get a reference to the root directory of the share.
        // 共有のルートディレクトリへの参照を取得します
        CloudFileDirectory root = share.GetRootDirectoryReference();

        // Create a directory under the root directory
        // ルートディレクトリの下にディレクトリを作成する
        dir = root.GetDirectoryReference(storageDirectory);

        await dir.CreateIfNotExistsAsync();

        // Check if the there is a stored text file containing the list
        // リストを含む格納されたテキストファイルがあるかどうかをチェックする
        shapeIndexCloudFile = dir.GetFileReference("TextShapeFile");

        if (!await shapeIndexCloudFile.ExistsAsync())
        {
            // File not found, enable gaze for shapes creation
            // ファイルが見つからない場合、図形作成の注視を可能にする
            Gaze.instance.GazeEnabled = true;

            azureStatusText.text = "No Shape\nFile!";
        }
        else
        {
            // The file has been found, disable gaze and get the list from the file
            // ファイルが見つかった場合、注視を無効にしてファイルからリストを取得する
            Gaze.instance.GazeEnabled = false;

            azureStatusText.text = "Shape File\nFound!";

            await ReplicateListFromAzureAsync();
        }
    }

    /// <summary>
    /// Upload the locally stored List to Azure
    /// Azure に、ローカルで保存されたリストをアップロードする
    /// </summary>
    private async Task UploadListToAzureAsync()
    {
        // Uploading a local file to the directory created above
        // 上記で作成したディレクトリにローカルファイルをアップロードする
        string listToString = string.Join(",", ShapeFactory.instance.shapeHistoryList.ToArray());

        await shapeIndexCloudFile.UploadTextAsync(listToString);
    }

    ///<summary>
    /// Get the List stored in Azure and use the data retrieved to replicate 
    /// a Shape creation pattern
    /// Azureに格納されたリストを取得し、取り出されたデータを使用してシェイプ作成パターンを複製する
    ///</summary>
    private async Task ReplicateListFromAzureAsync()
    {
        string azureTextFileContent = await shapeIndexCloudFile.DownloadTextAsync();

        string[] shapes = azureTextFileContent.Split(new char[] { ',' });

        foreach (string shape in shapes)
        {
            int i;

            Int32.TryParse(shape.ToString(), out i);

            ShapeFactory.instance.shapeHistoryList.Add(i);

            ShapeFactory.instance.CreateShape(i, true);

            await Task.Delay(500);
        }

        Gaze.instance.GazeEnabled = true;

        azureStatusText.text = "Load Complete!";
    }
}

f:id:bluebirdofoz:20181011073955j:plain

7.Visual Studio で変更を保存して Unity に戻ります。
f:id:bluebirdofoz:20181011074003j:plain

Chapter 10 はここまでです。
次回は Chapter 11 を実施します。
bluebirdofoz.hatenablog.com