Kilimanjaro Warehouse

WEBとかゲーム開発のことについて書きます。

Unity: WebGLビルドでVRMファイルを読み込む(UnityWebRequest版)

UnityのWebGLビルドでVRMファイルを読み込む方法については、
既にこちらの記事で紹介されています。
qiita.com

上記の記事ではObsoleteなWWWを使用していたので、
単純にUnityWebRequestを使った形へと書き換えたものを作ってみました。
ただそれだけの記事です。

コード

using System;
using System.Collections;
using System.Runtime.InteropServices;
using UnityEngine;
using UnityEngine.Networking;
using VRM;

public class Sample : MonoBehaviour
{
    [DllImport("__Internal")]
    private static extern void FileImporterCaptureClick();

    public void OnButtonClicked()
    {
        #if UNITY_EDITOR
            Debug.Log("WebGLビルドで試してください");
        #elif UNITY_WEBGL
            FileImporterCaptureClick();
        #endif
    }

    public void FileSelected(string url)
    {
        StartCoroutine(LoadJson(url));
    }

    private IEnumerator LoadJson(string url)
    {
        using (UnityWebRequest webRequest = UnityWebRequest.Get(url))
        {
            yield return webRequest.SendWebRequest();

            if (webRequest.isNetworkError)
            {
                Debug.LogError("ネットワークエラー");
            }
            else
            {
                LoadVRMFromBytes(webRequest.downloadHandler.data);
            }
        }
    }

    public void LoadVRMFromBytes(Byte[] bytes)
    {
        var context = new VRMImporterContext();
        try {
            context.ParseGlb(bytes);
            var meta = context.ReadMeta(true);
            context.Load();

            var model = context.Root;
            model.gameObject.name = meta.Title;

            context.ShowMeshes();

        } catch(Exception e) {
            Debug.LogError(e);
        }
    }
}

プロジェクト

github.com


実際にビルドしたもの

kilimanjaro-a2.github.io

Node.js: 関数の中身を見る方法

node.js上でconsole.log()を使って関数の中身を見ようとすると、

console.log(hoge)
// [Function: hoge]

のように名前が返ってくるだけで、中身をみることができません。

中身をみるには、関数にtoString()をつければ良いようでした。

console.log(hoge.toString())
// function hoge() {
//     ~~~~処理~~~~
// }

参考: console.log javascript [Function] - Stack Overflow

VuePressでホットリロードが効かないときの対処法

vuepress dev

VuePressでは上記のコマンドでローカルサーバーを立てることができ、
ファイルに変更があった場合、ブラウザのリロードなしに自動的に更新が適用されます。

しかし、自分の環境(WSL1)ではこのホットリロードが効きませんでした。
その場合、以下のような記述をconfig.jsに記述することで解決しました。

module.exports = {
  host: "localhost"
}

情報元:Automatic Reload? · Issue #220 · vuejs/vuepress · GitHub


config.jsはVuePressの全般的な設定を書いておくファイルで、
慣習的にはdocs/.vuepress以下に配置されます。

hostプロパティではdevサーバーで使うホストを設定できます。
値はデフォルトで'0.0.0.0'になっているようですが、
今回は'localhost'と設定を変更することで正常にホットリロードが効くようになりました。

情報元:
Configuration | VuePress
Config Reference | VuePress

Unity: Interactive/Autodesk Interactive.shadergraph Null returned.の解消法

以下のようなエラーが出た時の解決法です。

Exception: Cannot load. Incorrect path: Packages/com.unity.render-pipelines.lightweight/Shaders/Autodesk Interactive/Autodesk Interactive.shadergraph Null returned.
UnityEngine.Rendering.ResourceReloader.Load (System.String path, System.Type type, System.Boolean builtin) (at Library/PackageCache/com.unity.render-pipelines.core@6.9.2/Runtime/Utilities/ResourceReloader.cs:138)
UnityEngine.Rendering.ResourceReloader.SetAndLoadIfNull (System.Object container, System.Reflection.FieldInfo info, System.String path, System.Boolean builtin) (at Library/PackageCache/com.unity.render-pipelines.core@6.9.2/Runtime/Utilities/ResourceReloader.cs:147)
UnityEngine.Rendering.ResourceReloader.ReloadAllNullIn (System.Object container, System.String basePath) (at Library/PackageCache/com.unity.render-pipelines.core@6.9.2/Runtime/Utilities/ResourceReloader.cs:45)

まず、PackageManagerからShader GraphとCore RP Libraryを削除します。
そして、High Definition RPもしくはLightweight RPの、
どちらか使用しているRender Pipelineを削除します。

その後、先ほど削除したPackageの最新版をインストールして、
Unityを再起動するとエラーが解消されます。

answers.unity.com

JavaScript: parseInt(0.000001)が0を返し、parseInt(0.000001)が1を返す理由

JavaScriptのparseIntというメソッドで、
0.000001(10の-6乗)を引数にすると、返り値は0になるのに、
0.0000001(10の-7乗)は1が返ってくるという、
意味不明な挙動がTwitterで話題になっていました。

parseInt(0.000001) // 0

parseInt(0.0000001) // 1

この挙動について調べてみました。


TL;DR 要約

  • parseIntは有効でない文字があると、それ以降の文字を無視する
  • 小数点以下7桁以下の数値は、指数表記に変換される

上の仕様によって、この不可解な挙動が説明できます。


解説

parseIntは第一引数に変換するstring型の文字列、第二引数に基数を取ります(省略可)。
string型ではないものが第一引数に渡されると、内部でstring型に変換されます。
そして、数字と認識されない文字があった場合、それ以降の文字は無視されます。

parseInt(0.000001)

小数点が含まれる数字を第一引数に取る場合、小数点は数字として認識されません。
よって、"0.000001"の".000001"は無視され、先頭の0のみが返されます。


そして、0.0000001が1を返す方については、
小数点以下7桁以下の数値は指数表記に変換されることが原因のようです。

parseInt(0.0000001)

0.0000001は内部的にstringに変換される際、"1e-7"のような指数表記になります。
"e-7"は有効な数字ではないので無視され、先頭の1のみが返されます。


このような理由により、
parseInt(0.000001)は0を返し、parseInt(0.000001)は1を返すようでした。


どのような経緯で指数表記の閾値が小数点以下7桁になったのかはわかりませんが、
この閾値ECMAの仕様で決められているようです。
ECMAScript Language Specification - ECMA-262 Edition 5.1


また、ChromeJavaScript実行エンジンであるV8のテストケースにも、
上記の挙動が正しい動作としてテストが通るように書かれています。

PASS parseInt(Math.pow(10, -6)) is 0
PASS parseInt(Math.pow(10, -7)) is 1

v8/parseInt-expected.txt at a28c760ef01d2b9749c26d96aa5278a736ad4591 · v8/v8 · GitHub


結論

一見意味不明な挙動に見えるが、
しっかり調べると動きの理由があるようでした!


WSLの環境構築についてのメモ

Windows Subsystem for Linux(以下WSL)で、
Webの開発を始める際に行った環境構築についてのメモです。
お試しする際は自己責任でお願いします。
(WSL1の情報です)

優先度高めな設定

Linuxbrewのインストール

パッケージ管理のためにLinuxbrewをインストールします。
macOSでお馴染みのHomebrewのLinux版です。
docs.brew.sh


ホストへのシンボリックリンクを張る

WSLのホームディレクトリはWindowsのものとは異なる場所にあります。
Windowsのホームと同一にする手段などもありますが、
その方法には安全性に問題があるようなので、
/mnt/c/にシンボリックリンクを張る方法を採用しました。
www.clear-code.com
これにより、ホスト側のファイルにアクセスしやすくなります。


/mnt/c/のパーミッション変更

/mnt/c/以下のファイルは、
Linuxファイルシステムメタデータを持てないので、権限の変更が行えません。
これが原因でnpm installなどに失敗することがあります。
以下の記事を参考にメタデータを扱えるようにします。
qiita.com



優先度低めな設定

ビープ音を消す

無効な入力をした際など、
ことあるごとにビープ音が鳴りうるさいので、設定から消します。
以下の手順が参考になります。
azukipochette.hatenablog.com


ターミナルエミュレータの変更

デフォルトのターミナルエミュレータは機能不足だったので、
高機能なものに変更しました。
WSL向けだと以下のものが人気なようでした。

私はwslttyを導入しました。
tanakh.jp


Shellの変更

デフォルトのshellをbashからfishに変更しました。
この辺になるとWSL要素が薄いですが、一応・・・。
qiita.com
fishはデフォルトでも様々な便利機能が使えるので便利です。

まとめ

WSLでもいい感じに開発が行える環境ができあがったはずです!

Daprの読み方(発音)

Daprの読み方がよくわからなかったので調べてみました。
Dapr自体がどういうものであるかについては、
公式や解説サイトなどを読んでください(丸投げ)
Dapr - portable, event-driven, serverless runtime.


TL;DR Dapr 読み方

ネイティブスピーカーの発音は「ダパァ」。
カタカナIT用語にすると「ダッパー」といった感じになると思います。


ソース

Daprのアカウントが、「Dapperのように発音する」とツイートしていました。

「dapper pronounce」でグーグル検索すると、
発音を聞くことができます。
f:id:kilimanjaro-a2:20191022122242p:plain
dapper pronounce - Google 検索

(ちなみにdapperは「こざっぱりとした、いきな」という意味の形容詞のようです。)
ejje.weblio.jp


また、Microsoft Channel 9の方が動画でDaprを紹介していました。
発音を聞くと、こちらも「ダパァ」のように聞こえます。
(該当箇所は4:28~)
youtu.be


また、"dapper" に似た単語として"rapper"(ラップする人)がありますが、
ネイティブの発音は「ラパァ」のように聞こえ、
日本語カタカナ読みに変換すると「ラッパー」となることも考慮しました。

f:id:kilimanjaro-a2:20191022120519p:plain


結論

「Dapr=ダパァ(ダッパー)」!
Daprのことを「ダプラ」とか「ダプル」とか言ってるおじさんがいたら、
「それってダパァ(ダッパー)のことですか?」と声を上げていきましょう!