UnityのSteamVRでGripMove的に位置移動するスクリプト

Unityに読み込んだキャラモデルをSteamVRでいやらしく眺めるためにGripMoveっぽい事ができるスクリプトを結構前に作った。
しばらくしてからもっといいのがないか探したけど上手く見つからないので、前のをなくさないようメモしておく。
Viveしか持ってないのでそれのみ動作確認。
SteamVR Pluginのバージョンは1.2.2。

使い方

コントローラにスクリプトをアタッチし、InspectorからObjCameraRig変数にCameraRigかそれの入っているオブジェクトを指定する。
このサンプルではViveコントローラのグリップボタン(にぎりの所のボタン)で移動する。


using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.VR; public class GripMove : MonoBehaviour { // CameraRigもしくはそれを入れたオブジェクトを指定する public GameObject ObjCameraRig; //1フレーム前と差を比較するために前回のコントローラ位置・回転を格納する変数 private Vector3 beforeControllerPosition; private Quaternion beforeControllerRotation; void Update () { SteamVR_TrackedObject trackedObject = GetComponent<SteamVR_TrackedObject>(); var device = SteamVR_Controller.Input((int)trackedObject.index); //現在(移動後)のコントローラの位置・回転を格納 Vector3 afterControllerPosition = this.gameObject.transform.position; Quaternion afterControllerRotation = this.gameObject.transform.rotation; //"Grip"Moveなのでグリップボタンを入力したときに移動処理を実行 if (device.GetPress(SteamVR_Controller.ButtonMask.Grip)) { //1フレーム前と比較したコントローラの移動距離を算出 Vector3 distanceDifference = beforeControllerPosition - afterControllerPosition; //1フレーム前と比較したコントローラのY軸回転を算出 float rotationDifferenceY = Mathf.DeltaAngle(beforeControllerRotation.eulerAngles.y, afterControllerRotation.eulerAngles.y); //コントローラが移動した距離分、CameraRigを移動 ObjCameraRig.transform.position += distanceDifference; //コントローラのY軸が回転した分、コントローラ位置を軸としてCameraRigを回転移動 ObjCameraRig.transform.RotateAround(afterControllerPosition, Vector3.down, rotationDifferenceY); } //現在のコントローラの位置・回転を次回に移動前として使うために格納 beforeControllerPosition = afterControllerPosition; beforeControllerRotation = afterControllerRotation; } }

ワールド座標でルームスケールする位置を移動するので、部屋ごと移動してるような不思議感覚。


VultrのStartupScriptでUbuntuの設定を簡略化

2018/9/2
apt upgradeのダイアログで実行が止まらないよう変更

ちょっとした用途で一時的なVPSサーバを借りるときに、初期費用のいらないVultrがとても便利。
https://www.vultr.com/

検証のため何度もサーバデプロイするのだが、同じ設定を繰り返すのは面倒なのでStartupScriptを毎回使っており、その内容をメモする。
スナップショットからデプロイする手もあるけど、なんとなく手垢がついてそうでいやだった。

スクリプトはVultrのVC2で次のOSにて動作確認済み。

  • Ubuntu16.04
  • Ubuntu17.04

使う前に後述の準備で取得した値を定数に入れる。

スクリプト

#!/bin/bash

#ログインユーザ名
username='Foo'

#ログインパスワード(ハッシュ)
password_hash='$6$Q8~'

#SSH用公開認証鍵
public_key='ssh-rsa AAA~'

#ユーザを追加し、ついでにsudoできるようにする
useradd -p ${password_hash} -s /bin/bash -m $username
gpasswd -a ${username} sudo

#SSH用公開認証鍵を追加する
mkdir -p /home/${username}/.ssh
chmod 700 /home/${username}/.ssh
echo "${public_key}" > /home/${username}/.ssh/authorized_keys
chmod 600 /home/${username}/.ssh/authorized_keys
chown -R ${username}:${username} /home/${username}/.ssh

#sshdのパスワード認証を無効化し、公開鍵認証のみできるようにする
sed -i".org" -e '/^#PasswordAuthentication yes$/a PasswordAuthentication no' /etc/ssh/sshd_config

#ついでにSSHでrootログインできないようにする
sed -i".org" -e 's/^PermitRootLogin yes$/PermitRootLogin no/' /etc/ssh/sshd_config

#sshdへ設定反映
systemctl reload sshd

#スワップ領域の追加(以下は1GBの場合)
dd if=/dev/zero of=/swapfile count=1024 bs=1M
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
sed -e '$ a /swapfile        none        swap    sw    0        0' /etc/fstab

#ufwでsshの通信を許可し、その他をブロックする
ufw allow OpenSSH
ufw enable

#ufwのロギングをオフにする
ufw logging off

#日本語を設定する
apt install language-pack-ja-base language-pack-ja
localectl set-locale LANG=ja_JP.UTF-8 LANGUAGE="ja_JP:ja"

#日本時間にする
timedatectl set-timezone Asia/Tokyo

#パッケージを最新にする
apt update && DEBIAN_FRONTEND=noninteractive apt -yq upgrade

(準備)ログインパスワード用ハッシュの作成

ハッシュにしておけばスクリプトが見られてもあんまり問題にならないはず。
以下の[Password]と[Salt]の2箇所を変更して実行した結果を使用。

perl -e 'print crypt("Password", "\$6\$Salt");'

(準備)認証鍵の作成

公開鍵(id_rsa.pub)の内容をスクリプトで使用し、秘密鍵(id_rsa)はクライアントに保存しておく。

ssh-keygen -t rsa

bgm.xflから切り出したwavをそれっぽいoggに整える

必要になるたびメモを探すのでこっちにも残しておく。
oggSplitを使用するため、OSにUbuntuの入っている環境が必要になり、大抵の場合は準備に手間がかかると思われる。

うろ覚えだが、対象は中身のエンコードがoggでヘッダや曲情報?がwaveと同様なファイルになっていたはずなので、正常なoggにする加工が必要となるが変換ではないため「整える」と表記する。
昔はWindowsのエンコード変換ツールでヘッダを無視できるものを使ってたはずなのだが、何だったか思い出せなかった。

手順


切り出し

X-Ripperやスペシャルねこまんま57号などでWAVを指定して切り出し。

ヘッダをoggとして整える

以下の手順はUbuntu 16.04で確認済み

頭の66バイトを削除する

tail -c +67 sample.wav > sample_tmp

必要となるoggSplitがoggvideotoolsパッケージに含まれるためインストール

sudo apt-get install  oggvideotools

oggSplitでヘッダを綺麗にする

oggSplit sample_tmp

oggSplit実行後に出力される「vorbis_0.oga」というファイルが目的物なので、oggに拡張子を変更

mv vorbis_0.oga sample.ogg

以上で1ファイルの処理が完了だが、不要な中間ファイルなどは適当に削除すること。

複数ファイルを纏めて処理する場合


ヘッダを整える部分は以下を使うと、カレントディレクトリ内をまとめて処理できる。

for file in `\find . -maxdepth 1 -name "*.wav" -type f`; do
  tail -c +67 $file > "${file:0:-4}_tmp"
  oggSplit "${file:0:-4}_tmp"
  mv vorbis_0.oga "${file:0:-3}ogg"
done

Ubuntu 16.04でKVM仮想マシンからブリッジを通る通信のNetfilterをオフにする設定

全部Ubuntuマニュアルのsysctl.dディレクトリについてのページで書いてあることそのままだけど、sysctl.dの設定方法の一例として説明されているので気づくのに時間かかった。
試してはいませんが、マニュアルを見る限りubuntu 12.04以降で有効な設定みたい。

設定方法


以下2つの内容の設定ファイルを作成する。

/etc/udev/rules.d/99-bridge.rules

ACTION=="add", SUBSYSTEM=="module", KERNEL=="br_netfilter", \
RUN+="/lib/systemd/systemd-sysctl --prefix=/net/bridge"

/etc/sysctl.d/bridge.conf

net.bridge.bridge-nf-call-ip6tables = 0
net.bridge.bridge-nf-call-iptables = 0
net.bridge.bridge-nf-call-arptables = 0

これでbr_netfilterモジュールが読み込まれたときにbridge.confの設定が適用されます。
設定を有効にするには再起動が必要になるので注意が必要です。

こちらでは紹介しませんが、マニュアルにはモジュールの強制読み込みと一緒に設定を適用する方法も書いてあります。

上記設定にたどり着いた理由とか


Netfilterをオフにしない場合どう見えるか

意識して制御していなければ、おそらく以下の図のようになります。

仮想ブリッジ上でtcpdumpを取ると、仮想マシン/端末の双方から送ったパケットが見えますが、その先には届きません。

/etc/sysctl.confまたは/etc/ufw/sysctl.confに設定を記述する方法

以下のファイルに設定を入れる方法も試しましたが、起動時に設定適用されなかった。

  • /etc/sysctl.conf
  • /etc/ufw/sysctl.conf

ついでに書くと、/etc/sysctl.d/以下にただ設定ファイルを作るだけというのもうまくいかなかった。

/etc/sysctl.confに設定を入れて起動時にsysctl -pする方法

inidやsystemctldで[sysctl -p]を実行するようにしても以下のエラーが出て適用できなかった。
このため、モジュールの読み込みタイミングより前に設定適用してしまっていると推測している。

Apr 23 00:12:29 server systemd-sysctl[397]: Couldn’t write ‘0’ to ‘net/bridge/bridge-nf-call-iptables’, ignoring: No such file or directory