【Unity】UniRxを使ってuGUIのイベントを監視する

f:id:tm8r:20160513202840p:plain
こういうのをつくります。
ざっくり言うと、InputFieldに入力されたディレクトリに存在するFbxファイルをDropDownに列挙するものです。

f:id:tm8r:20160513202844p:plain
Hierarchyはこんなかんじ。
InputFieldとDropDownを作り、DropDownはOptionsを初期値の1つだけにしておきます。

次に以下のスクリプトを用意して、Canvasとか適当なところにアタッチします。
gist.github.com

これで最初に書いた要件が実現できます。UniRx捗る。

ランタイムで任意のディレクトリにあるFBXを閲覧できるビューアーを作るつもりで実装を始めたものの、思いの外これがダルくて、どうやらFBXのパースをUnityに任せられない(自前で用意しないといけない)っぽいことが分かって膝から崩れ落ちたので現実逃避な記事です。つらみ。
それっぽい有料のアセットを使うか、assimpとか使ってなんとかする感じになるのかなー。むーん。

UniRx - Reactive Extensions for Unity - アセットストア - Asset Store

【Unity】同じMaterialが指定されているかチェックする

Rendererに同じMaterialが指定されているかチェックしたいという要件がありまして。

より具体的に言うとFBXとそこから作られたPrefabのMaterialに差分がないかチェックするという感じだったのですけど、ブログに載せる用のFBXファイルを用意するのもアレだなーということで、「ねーよそんな要件」って感じですけどProjectビューで選択された2つのオブジェクトにおけるルートのRendererのMaterialが一致するかチェックするものを書きました。

gist.github.com

Materialの比較は30行目の以下のコードで行っています。

var result = targetMaterials.SequenceEqual (compareMaterials);

SequenceEqualを使えば順序も含め、2つのシーケンスが等しいかどうかをチェックすることができます。
Enumerable.SequenceEqual(TSource) メソッド (IEnumerable(TSource), IEnumerable(TSource)) (System.Linq)

順序は考慮せずにチェックしたい場合、長さチェックをした上でそれぞれの全要素が合致するか見ていってもいいんですが、27-28行目みたいにソートしてしまえばSequenceEqualが使いまわせます。

本題からは逸れますが、MenuItemの第二引数にtrueを指定したboolを返すメソッドを用意することで、指定したメニューを有効にするか無効にするかを判定することができます。

上のコードでいうと、11行目のメソッドで「Assets/CheckSameMaterials」を選択したときの振る舞いを定義し、35行目のメソッドでこのメニューを有効にするか無効にするかを判定するものを定義しています。
具体的には、Projectビューで選択しているオブジェクトが2つであり、かつ両方ともプレハブまたはFBXファイルである場合だけtrueを返しているので、この条件に合致しない場合は「Assets/CheckSameMaterials」がグレーアウトします。

【Unity】Alfred+AppleScriptで楽々Unity複数起動

小ネタ。

AlfredのPowerpack(有料版)を使っていればシェル起動ができるのでいいんですけど、無料版を使ってる場合はそうもいかないので、Unityを複数起動するときいちいちターミナルを開いてました。

が、いよいよめんどくさくなってきたので、AppleScriptを使って楽ちんにしました。

続きを読む

【Unity】エディタ拡張でUniRxを用いてコルーチンを実行する

Unityさんのエディタ拡張をしているとコルーチンを利用したいみたいなシーンがたまに出てくるのですけど、エディタスクリプトではコルーチンが利用できません。
EditorApplication.updateを利用すればそれっぽいことが出来ますが、ハンドリングも大変だなーと調べてみると、以下のようなEditorApplication.updateをラップしたものを公開されているのがいくらか見つかります。
UnityEditor上でStartContinueっぽいのを動かす - Qiita
EditorCoroutine: coroutines for Unity editor operations. Usage: EditorCoroutine.start(myIEnumerator) · GitHub

他にうまいことやることないのかなーと思いながらいつも通り実装していると、UniRxでObservable.FromCoroutineというクラスがあることに気づきました。
こちらも結局内部的には上記のメソッドを利用しているようですが、普段からUniRxを使っているのであれば使わない手はない。

ということで以下サンプルです。

続きを読む

【Maya】pythonで指定されたフェースの頂点数を取得する

ポリゴンの情報を取得するpolyInfoってメソッドがありまして。
適当なフェースを選択してこいつを実行すると以下のような結果が得られます。

import maya.cmds as cmds
cmds.polyInfo(fv=1)
# 結果: [u'FACE      7:      8     12     13      9 \n'] # 

はい。

どれが何なのかよくわかりません!
とりあえずリファレンスを見てみます。
polyInfo command

なるほどわからん(困惑)

公式がまるで参考にならないので適当にぐぐってみたら以下のようなページが見つかりました。
MEL How-To #55

string $ftv[] = `polyInfo -faceToVertex m26_section.f[278]`;
// Result: FACE 278: 295 12 14 296 //
To extract the values in order to use them, use the tokenize command on the string. In the example below the string is split by stripping its space (" "), colon (":"), and carriage-return/newline ("\n\r") characters. This results in six tokens - the first of which is the string "FACE", the second being the index of the face, and the remaining four the indices for the vertices.

ざっくり言うと、一番上の例で言うところの「7」がフェースのインデックス番号で、その後に続くやつらが頂点のインデックス番号のようです。
つまり、この結果から4つの頂点で構成されたフェースであることが分かるわけです。
が、この結果から頂点数を得ようとすると、スペースとかでsplitしてその配列のサイズから2引くと頂点数になるみたいな気持ち悪いコードになりかねません。

他にやりようがないのか調べてみると、polyListComponentConversionとfilterExpandの組み合わせによって頂点の配列が得られることがわかりました。
polyListComponentConversion command
filterExpand command

というわけでコードと結果はこんな具合に。

import maya.cmds as cmds
len(cmds.filterExpand(cmds.polyListComponentConversion(ff=1,tv=1),sm=31))
# 結果: 4 #

polyListComponentConversionの引数は今回フェースを起点としているためfromFaceを示すffを、そして頂点の結果を得たいのでtoVertexを示すtvをtrueとしてます。
また、filterExpandの引数はポリゴン頂点を示す31を指定してます。
これによって頂点情報の配列が得られるので、あとはlenを使えば目的達成です。

mayaのリファレンスいまいちでpythonツール実装つらみがある。
みんなどうしてるんや…調べ方がアレなのか…。

【Unity】ProjectViewっぽいWindowをつくる

若干盛った感じのタイトルですけど、見た目的にそれっぽい感じのWindowをつくってみます。

f:id:tm8r:20160413202751p:plain
こんなかんじ。

基本的には割とありふれた記述で済むんですけど、Unityにもともと入ってるテクスチャ使ったり、それをいい感じにリサイズしたりする資料があんまり見当たらなかったので。

続きを読む

【Unity】uGUIのプレハブをインスタンス化する

昔ハマった内容をメモっておくシリーズ。

大した話じゃないんですけど、uGUIのオブジェクトをプレハブ化して、こいつをScriptでインスタンス化するとき、以下のようにしてハマりました。

var instance = Instantiate (buttonPrefab);
instance.transform.SetParent (gameObject.transform);
続きを読む

スポンサーリンク