脳汁portal

アメリカ在住(だった)新米エンジニアがその日学んだIT知識を書き綴るブログ

UnityでXboxコントローラの3Dスティックではなく十字キーで移動させる場合

Unityでボタンを複数作成するとデフォルトでXboxコントローラの左スティックで移動できるようになりますが、左スティックを無効にして十字キーで動かしたい場合の方法です。

手順

1. Inputマネージャーを開く

Edit > Project Setting > Input
f:id:portaltan:20160518102823p:plain

2. Input マネージャの確認

Inspectorに以下のようなInputManagerが開きます
f:id:portaltan:20160518103025p:plain

カーソルの移動はこの中の「Horizonal」と「Vertical」の項目が担当しています
HorizontalもVerticalも2つずつありますが、上の方(青枠)はマウスやキーボードの矢印キーで動かすための設定ですので、デバッグ用にこのまま残します
下の方(赤枠)がコントローラによる移動の設定ですので、こちらの設定を変更していきます
 f:id:portaltan:20160518104248p:plain

3. Input マネージャの設定

それぞれの項目を開くと以下のように詳細が表示されます
 f:id:portaltan:20160518103605p:plain

まずはAxisの部分を変更します

  • X axis ⇒ 6th axis(Joysticks)
  • Y axis ⇒ 7th axis(Joysticks)

f:id:portaltan:20160518103839p:plain

 次にVerticalの方のInvertのチェックを外します
 (これを外さないと上下の入力が逆になってしまいます)
f:id:portaltan:20160518103923p:plain

4.確認

以上で作業は完了です
適当にボタンを作って確認してみましょう
f:id:portaltan:20160518104107p:plain

Unityでボタンの表示を文字じゃなくて画像にする方法

まずは普通にUnityを起動してHierarchyから「UI > Button」を選択すると以下のような感じになると思います。
この文字ベースのボタンを画像ベースのボタンに変更します

1. RawImageオブジェクトの作成

f:id:portaltan:20160516145508p:plain
RawImageオブジェクトが作成されると以下のように真っ白な画像がボタンの上に表示されます
f:id:portaltan:20160516145645p:plain

2. 画像を張り付ける

まずは画像を用意します。今回は適当に検索してきた以下の画像を利用します
f:id:portaltan:20160516145846j:plain
この画像をAssets以下に配置します
f:id:portaltan:20160516145928p:plain
次にD&DでRawImageのTextureの項目へ上記の画像を割り当てます
f:id:portaltan:20160516150044p:plain
そうするとキリンの画像が画面に表示されます

3. テキストボックスの削除

後ろにテキストベースのボタンが残っているので、まずはテキストコンポーネントを削除します
f:id:portaltan:20160516150240p:plain

次にImageも無効化します
f:id:portaltan:20160516150454p:plain


以上画像ベースのボタンの完成です
f:id:portaltan:20160516150622p:plain

gangliaでGPUの情報を監視しようとしてえらい苦労した話

gangliaでGPGPUサーバのデータを監視しようとしたのですが、はまりポイントが多数あって苦労しました

Gangliaのインストール

1. Master server
### install packages
sudo apt-get install ganglia-monitor rrdtool gmetad ganglia-webfrontend
ps -eaf | egrep "gmon|gmeta"
  ganglia  14057     1  0 06:05 ?        00:00:00 /usr/sbin/gmond --pid-file=/var/run/ganglia-monitor.pid
  nobody   14071     1  0 06:05 ?        00:00:00 /usr/sbin/gmetad --pid-file=/var/run/gmetad.pid
ss -lntp | egrep "86[0-9]{2}"
  LISTEN     0      5                         *:8649                     *:*
  LISTEN     0      10                        *:8651                     *:*
  LISTEN     0      10                        *:8652                     *:*
  
### setting configuration(gmetad)
sudo cp -ip /etc/ganglia-webfrontend/apache.conf /etc/apache2/sites-enabled/ganglia.conf
sudo cp -ip /etc/ganglia/gmetad.conf{,.org}
sudo vi /etc/ganglia/gmetad.conf
=================================================
 44 #data_source "my cluster" localhost
 45 data_source "好きなクラスター名" 60 localhost
=================================================
 
### setting configuration(gmond)
sudo cp -ip /etc/ganglia/gmond.conf{,.org}
sudo vi /etc/ganglia/gmond.conf
=================================================
 20 cluster {
 21   name = "設定したクラスター名"
 22   owner = "unspecified"
 23   latlong = "unspecified"
 24   url = "unspecified"
 25 }
・
・
 34 udp_send_channel {
 35   #mcast_join = 239.2.11.71 # => commentout
 36   host = localhost           # => add
 37   port = 8649
 38   ttl = 1
 39 }
.
.
 42 udp_recv_channel {
 43   #mcast_join = 239.2.11.71  # => commentout
 44   port = 8649
 45   #bind = 239.2.11.71        # => commentout
 46 }
=================================================
 
### gmond & gmetad & apache restart
sudo service ganglia-monitor restart
sudo service gmetad restart
sudo service apache2 restart
  • はまりポイント1:スクリプトで全部同時に起動しようとしたらうまく起動しなかった
    • 手動でやったりsleepをかませたらうまくいった
2. Client server
### install package
sudo apt-get install ganglia-monitor
ps -eaf | grep gmond
  ganglia   1952     1 99 04:26 ?        00:02:21 /usr/sbin/gmond --pid-file=/var/run/ganglia-monitor.p
  
### setting configuration(gmond)
sudo cp -ip /etc/ganglia/gmond.conf{,.org}
sudo vi /etc/ganglia/gmond.conf
===============================================================================
  .
  .
 10   deaf = yes  # => change to yes
  .
  .
 20 cluster {
 21   name = "設定したクラスター名"  # => Change name
 22   owner = "unspecified"
 23   latlong = "unspecified"
 24   url = "unspecified"
 25 }
  .
  .
 34 udp_send_channel {
 35   # mcast_join = 239.2.11.71 # commment out
 36   host = 192.168.33.11       # add(master serverIP)
 37   port = 8649
 38   ttl = 1
 39 }
 .
 .
 41 /* You can specify as many udp_recv_channels as you like as well. */
 42 #udp_recv_channel {          # comment out
 43 #  mcast_join = 239.2.11.71  # comment out
 44 #  port = 8649               # comment out
 45 #  bind = 239.2.11.71        # comment out
 46 #}                           # comment out
===============================================================================
  
### ganglia monitor restart
sudo /etc/init.d/ganglia-monitor restart

この時点でGangliaのViewが表示されて、基本的な情報の取得ができるようになる

GPUのMetricsの設定

1. Client server
### modify gmond.conf
sudo vi /etc/ganglia/gmond.conf
======================================================================
 59 modules {・
・
・
 91   module {                                          # add
 92     name = "python_module"                          # add
 93     path = "/usr/lib/ganglia/modpython.so"          # add
 94     params = "/usr/lib/ganglia/python_modules/"     # add
 95   }                                                 # add
 96 }
 97
 98 include ('/etc/ganglia/conf.d/*.conf')
 99 include ('/etc/ganglia/conf.d/*.pyconf')            # add
======================================================================
  
### make dir
sudo mkdir /etc/ganglia/conf.d
sudo mkdir /usr/lib/ganglia/python_modules
  
### prepare python module
cd /usr/local/src
git clone https://github.com/ganglia/gmond_python_modules.git
cd ${download directory}/gpu/nvidia
wget https://pypi.python.org/packages/72/31/378ca145e919ca415641a0f17f2669fa98c482a81f1f8fdfb72b1f9dbb37/nvidia-ml-py-7.352.0.tar.gz
tar xvfpz nvidia-ml-py-7.352.0.tar.gz
ls -l
  drwxr-xr-x 2 root     root      4096 May 10 16:26 conf.d
  -rw-r--r-- 1 root     root      5093 May 10 16:26 ganglia_web.patch
  drwxr-xr-x 2 root     root      4096 May 10 16:26 graph.d
  drwxr-xr-x 3 root     root      4096 May 10 16:26 nvidia-ml-py-3.295.00
  drwxrwxr-x 3 root     root      4096 May 10 16:27 nvidia-ml-py-7.352.0
  -rw-r--r-- 1 root     root     20524 Apr 23 23:13 nvidia-ml-py-7.352.0.tar.gz
  drwxr-xr-x 2 root     root      4096 May 10 16:26 python_modules
  -rw-r--r-- 1 root     root      1661 May 10 16:26 README
  
cd nvidia-ml-py-7.352.0
sudo python setup.py install


cd ../  
sudo cp -ip python_modules/nvidia.py /usr/lib/ganglia/python_modules/.
sudo cp -ip conf.d/nvidia.pyconf /etc/ganglia/conf.d/.

### restart
sudo service ganglia-monitor restart
  • はまりポイント2:python_moduleの設定でpathは相対でいいって書いてあるドキュメントがあったけど絶対パスじゃないと動かなかった
  • はまりポイント3:git cloneで取得できるgmond_python_modules内のnvidiaパッケージは古くて(nvida-ml-py3.295.00)、setup.pyを実行すると使えないパッケージがinstallされてしまう
    • 対応としてnvidia-ml-py-7.352.0を直接取得する
  • はまりポイント4:しかし逆にnvidia-ml-py-7.352.0の方のpython_moduleファイルは使用できず、confファイルは存在すらしないため、この二つはnvida-ml-py3.295.00の方のものを使用しなければいけない
  • はまりポイント5:一度nvida-ml-py3.295.00の方のsetupスクリプトを使用すると手動で関連ファイルを削除したりPythonのload_pathを戻さなければならない
2. master server
cd /usr/local/src
git clone https://github.com/ganglia/gmond_python_modules.git
cd ${download directory}
cd gpu/nvidia/graph.d
ls -l
  total 24
  -rw-r--r-- 1 root root  596 Mar 18 09:12 gpu_common.php
  -rw-r--r-- 1 root root 2139 Mar 18 09:12 gpu_graphics_clock_report.php
  -rw-r--r-- 1 root root 2143 Mar 18 09:12 gpu_mem_clock_report.php
  -rw-r--r-- 1 root root 1526 Mar 18 09:12 gpu_power_usage_report.php
  -rw-r--r-- 1 root root 1586 Mar 18 09:12 gpu_power_violation_report.php
  -rw-r--r-- 1 root root 2169 Mar 18 09:12 gpu_sm_clock_report.php
  
sudo cp -ip * /usr/share/ganglia-webfrontend/graph.d
  
sudo service apache2 restart
  • はまりポイント6:多くのドキュメントでganglia_web.patchを実行する手順があったが、これも古くて動かない
    • 最新のganglia-python-moduleライブラリはnvidia GPU monitoringをサポートしていないので、自分でViewシステムを作る必要がある

Make view system

1. master server
cd /var/lib/ganglia-web/conf/
vi view_gpu1.json
===========================================================
### 環境にあわせて作成
===========================================================
  • このviewファイルの作成の仕方のドキュメントがとても少ない

gangliaで任意のグラフを作成する - 脳汁portal

他はまったポイント

nvidia.pyがデータを取得できない
Failed to build descriptor : gpu0_ecc_db_error : Not Supported
Failed to build descriptor : gpu0_ecc_sb_error : Not Supported
Failed to build descriptor : gpu0_power_violation_report : global name 'nvmlDeviceGetViolationStatus' is not defined
Failed to build descriptor : gpu0_bar1_memory : global name 'nvmlDeviceGetBAR1MemoryInfo' is not defined
Failed to build descriptor : gpu0_bar1_max_memory : global name 'nvmlDeviceGetBAR1MemoryInfo' is not defined
Failed to build descriptor : gpu0_shutdown_temp : global name 'nvmlDeviceGetTemperatureThreshold' is not defined
Failed to build descriptor : gpu0_slowdown_temp : global name 'nvmlDeviceGetTemperatureThreshold' is not defined
Failed to build descriptor : gpu0_encoder_util : global name 'nvmlDeviceGetEncoderUtilization' is not defined
Failed to build descriptor : gpu0_decoder_util : global name 'nvmlDeviceGetDecoderUtilization' is not defined

これは最新版使うことで解決

tpl file
$ sudo patch -p0 < /usr/local/src/gmond_python_modules/gpu/nvidia/ganglia_web.patch
patching file host_view.php
Hunk #1 FAILED at 17.
Hunk #2 FAILED at 37.
Hunk #3 FAILED at 144.
Hunk #4 FAILED at 153.
Hunk #5 FAILED at 169.
5 out of 5 hunks FAILED -- saving rejects to file host_view.php.rej
patching file templates/default/host_view.tpl
Hunk #1 FAILED at 80.
Hunk #2 FAILED at 89.
2 out of 2 hunks FAILED -- saving rejects to file templates/default/host_view.tpl.rej

動かない
現在のversionのgangliaでは不要とのコメントもあったのでそもそもいらないTool?

view ファイルのhost指定
  1 {
  2   "view_name": "GPU1",
  3   "view_type": "standard",
  4   "items": [
  5     {
  6       "aggregate_graph": "true",
  7       "host_regex": [ { "regex":"192.168.33.11" } ],

7行目のように監視対象のHostをIPで指定していたのだが、いつからのversionかHost名で指定しないと動かなくなった
host名で指定したら問題なく動くように戻った

Ubuntu14.04でApacheがphpを使えない場合

PHPがインストールされていない可能性があるのでinstallしてapacheを再起動します

php install & apache restart

sudo apt-get install php5 libapache2-mod-php5
sudo service apache2 restart

まだおかしい場合

ログ確認
# cd /var/log/apache2
# tail -f *.log
   ### => 問題のあるサイトにアクセスしてみる

Installing LAMP On Ubuntu For Newbies

Unityでコントローラを利用したセレクト画面の作り方2(Submit取得の改良)

前回

前回のポストではクリック情報を取得するために、

1. ButtonFunction.csスクリプトを作成
using UnityEngine;
using System.Collections;
using UnityEngine.SceneManagement;

public class ButtonFunction : MonoBehaviour {

	public void StringArgFunction(string s){
		SceneManager.LoadScene (s);
	}
}
2. スクリプトをAttachする空GameObjectの作成

f:id:portaltan:20160510093930p:plain

3. ボタンのuGUIからOnClickイベントの登録

f:id:portaltan:20160510093637p:plain

という手順を踏んでいましたが、少し手順が多く面倒に感じ、スクリプト側で処理をまとめられないかと思い少し改良しました

今回

大元のmenu.csを以下のように変更します

using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using UnityEngine.EventSystems;    // 追加(get EventSystem(Hierarchy) action)
using UnityEngine.SceneManagement; // 追加(enable to use change scene(latest))

public class menu : MonoBehaviour {
	Button cube;
	Button sphere;
	Button cylinder;

	void Start () {
		cube     = GameObject.Find ("/Canvas/Button1").GetComponent<Button> ();
		sphere   = GameObject.Find ("/Canvas/Button2").GetComponent<Button> ();
		cylinder = GameObject.Find ("/Canvas/Button3").GetComponent<Button> ();

		cube.Select ();
	}


        // ↓ここから追加
	void Update() {
                // ボタンが押されたら・・・
		if (OVRInput.GetUp(OVRInput.Button.Start)){

                        // 選択中のオブジェクト情報を取得
			GameObject selectedButton = EventSystem.current.currentSelectedGameObject;

                        // オブジェクトの名前で条件分岐して
			switch (selectedButton.name) {
			case "Button1":
				Debug.Log ("Pushed Button1");
                                // 該当のシーンへ飛ばす
				SceneManager.LoadScene ("Cube");
				break;
			case "Button2":
				Debug.Log ("Pushed Button2");
				SceneManager.LoadScene ("Sphere");
				break;
			case "Button3":
				Debug.Log ("Pushed Button3");
				SceneManager.LoadScene ("Cylinder");
				break;
			}
		}
	}
}


不要な以下のファイル/オブジェクト/イベント処理は削除します

  • ButtonFunction.cs
  • 空GameObject
  • それぞれのButtonで登録していたOnClick()イベント

セレクトシーンに戻る機能

ついでにセレクト画面に戻る機能も追加しました

using UnityEngine;
using System.Collections;
using UnityEngine.SceneManagement; // enable to use change scene(latest)

public class back : MonoBehaviour {

	// Update is called once per frame
	void Update () {
		if (OVRInput.GetUp(OVRInput.Button.Back)){
			SceneManager.LoadScene ("select");
		}
	}
}

これをCube/Sphere/CylinderシーンのOVRCameraRigにAttachします

  • (OVRInputはMainCameraでは使えません)

Unityでコントローラを利用したセレクト画面の作り方

Unityでシーンやキャラクターの選択画面を作ろうと思ったのですが、タップやVRの場合の視線を利用する方法は比較的ドキュメントが多いのですが、コントローラ(Gamepad)を利用した時の方法を探すのに少し手間取ったので、メモ代わりに手順を残しておきたいと思います

セレクト(メニュー)シーンの作成

ボタンの作成

まずは選択肢となるボタンを作成します(Hierarchy > Create > UI > Button)
今回は3つボタンを作成し、それぞれTextをCube, Sphere, Cylinderにします
f:id:portaltan:20160509160302p:plain

Standalone Input Moduleの確認

Buttonなど入力に関するUIコンポーネントを作成すると、自動でヒエラルキーにEventSystemというコンポーネントが作成されます。
最初からある程度のInput情報を取得するようになっており、画像では上から4つがアクションの割り当てになります
f:id:portaltan:20160509160658p:plain

色の変更

この時点でマウスのアクションに反応するようにはなっていますが、わかりにくいので状態別に色分けをします
f:id:portaltan:20160509161137p:plain
Button1コンポーネントを選択して、InspectorのButton(Script)のTransitionを変更します。

  • TransitionをColor Tintへ(通常デフォルト)
  • Highlighted Colorに赤色を指定
  • Pressed Colorを青色に指定

変更が完了したらシーンを保存してデモを実行してみます。
マウスオーバー時には赤色に、クリック時には青色になることが確認できます
f:id:portaltan:20160509161450p:plain
f:id:portaltan:20160509161525p:plain
確認ができたら他のボタンも同じように色の設定を行います
キーボードやコントローラ(Xbox360コントローラなど)で選択項目の移動ができるようになります
f:id:portaltan:20160509163217p:plain

スクリプトの作成

次にデフォルトの選択項目を設定します
設定用のスクリプトを用意します

  • 今回はmenu.csという名前にしました
using UnityEngine;
using System.Collections;
using UnityEngine.UI; // UIコンポーネントの使用

public class menu : MonoBehaviour {
	Button cube;
	Button sphere;
	Button cylinder;

	void Start () {
                // ボタンコンポーネントの取得
		cube     = GameObject.Find ("/Canvas/Button1").GetComponent<Button> ();
		sphere   = GameObject.Find ("/Canvas/Button2").GetComponent<Button> ();
		cylinder = GameObject.Find ("/Canvas/Button3").GetComponent<Button> ();

                // 最初に選択状態にしたいボタンの設定
		cube.Select ();
	}
}

スクリプトができたらメインのカメラ(今回はOVRCameraRig)にAttachします
デモを起動すると、何も入力しない段階からCubeボタンが選択状態になっていることが確認できます
f:id:portaltan:20160509163734p:plain

アニメーションの付加

ここまでは選択時のハイライトは赤く色を変えるだけでしたが、次はanimationを設定してみます
Button1のTransitionをColor TintからAnimationへ変更します
f:id:portaltan:20160509164232p:plain

するとAuto generate Animationというボタンが出現するので選択してアニメーションをファイルを保存します。

  • 今回はMyButtonAnimationにしました

Auto generateが完了すると以下のようにanimationファイルとAnimatorという項目が追加されます
f:id:portaltan:20160509164713p:plain

この段階ではなんのアニメーションも設定されていないので、次にアニメーションの設定を行います
ボタンコンポーネントを選択した状態で、「Window > Animation」を選択します
f:id:portaltan:20160509164903p:plain

すると以下のような動画編集っぽいWindowが表示されるので、無心で左上の設定を変更します

  • 対象のモードをnormalからHighlightedへ変更
  • 赤丸のレコードボタンをクリック

f:id:portaltan:20160509165339p:plain

するとデモの時などに使用していた再生ボタンが赤色に変化します
f:id:portaltan:20160509165544p:plain
この状態で変更した操作が、アニメーションの設定となります

試しにScaleを1.2, 1.2, 1.2、色を黄色にしてみます
f:id:portaltan:20160509165709p:plain

設定が終わったらレコードボタンをもう一度クリックします
ScaleとColorの項目が追加されたのがわかります
f:id:portaltan:20160509165741p:plain

デモモードで確認してみると、Cubeボタンが選択されているときは色が黄色に、大きさも少し大きくなるのが確認できます。
f:id:portaltan:20160509165946p:plain

アニメーションの流用

次にCubeボタンで作成したanimationを他の2ボタンへ流用します
それぞれのボタンのTransitionをAnimationへ変更し、AssetsにあるMyButtonAnimationをそれぞれのAnimationのInspectorへD&Dすることで設定を使いまわすことが可能です。

遷移先シーンの作成

次にボタンをクリック後に遷移するシーンを作成します。
ここは移動したことの確認に用いるだけなので適当に名前の通りの3Dオブジェクトが存在するだけのシーンを作成します
f:id:portaltan:20160509170810p:plain

シーンを作成したら、一度Build settingを開き、すべてのシーンをbuild対象に入れます
f:id:portaltan:20160509172503p:plain

各シーンへの遷移処理

スクリプトの作成

ボタンを選択した状態でsubmitボタンを押したときに各シーンへ遷移する処理を作成します
空のGameObjectを作成し、ChangeSceneと名付けます
次にInspectorのAdd componentからC#スクリプトを作成します

  • 今回はButtonFunction.csという名前にしました
using UnityEngine;
using System.Collections;
using UnityEngine.SceneManagement;

public class ButtonFunction : MonoBehaviour {

	public void StringArgFunction(string s){
		SceneManager.LoadScene (s);
	}
}
ボタンコンポーネント側の設定

ボタンでクリックされたときに上記で作成したStringArgFunctionを呼び出すように設定します
ボタンコンポーネントのOn Click()項目右下の「+」ボタンを押し、下記のように設定します

  • None (Object)をChangeSceneに変更(スクリプトを張り付けてある空のGameObject)
  • No Functionを「Button Function > StringArgFunction」へ変更
  • 右下のテキストボックスに遷移させたいシーン名を入力

f:id:portaltan:20160509172228p:plain

確認

以上でセレクト画面の作成の完了です
実際に選択したボタンに対応したシーンに遷移することを確認しましょう
キーボードの場合は矢印キーをEnter、Xboxコントローラーの場合は左スティックとAボタンがそれぞれ移動と決定ボタンに割り当てられています
f:id:portaltan:20160509172759p:plain
f:id:portaltan:20160509172815p:plain

HTC viveをベースステーション1台で起動

HTC viveは通常

の5つのデバイスの設定が必要だが、一応以下のみっつだけでも動くらしい

Steam VRの表示は以下のようになる
f:id:portaltan:20160506162431p:plain

このとき注意しなければいけない点として、通常ベースステーションを二台で使用する場合はチャンネルがb(またはc)に割り振られるが、1台で使用するときはAにしなければいけないらしい。

f:id:portaltan:20160506163920p:plain


また、完全にベースステーションの反対側を向くと自分の頭でHMDのセンサが隠れてしまうため画面が表示されなくなってしまう。
f:id:portaltan:20160506163653p:plain


とはいえある程度の動作確認やチュートリアルもできるので、常にスペースを確保しておくのが難しい場合は、この3つだけセットして、立位モードで起動するのもありかもしれない。