kazumalab tech log

流行りとリラックマと嵐が大好きです。技術的ログ。

UnityでOculus Touchを使うメモ ~銃を撃つ編~

かずまです。

昨日の記事ではOculus Touchでものを掴むところを実装しました。

blog.kazumalab.com

今日は銃を扱うところを実装していきます。

銃の設定

www.asset.techmatome.com

今回はこのアセットをつかいました。


f:id:kazumalab:20170217231856p:plain

持つ部分にColliderを付けます。
ちなみにもモデルの方ではなくて、一つ上の親の方につけます。

Rigidbodyも付けます。

f:id:kazumalab:20170217232337p:plain

こんな感じ。
打った時の音も入れたいのでAudiosourceのコンポーネントも付けます。
ちなみにTouchを振動させる場合はAudioClipが必要みたいです。


f:id:kazumalab:20170217233021p:plain

最後にBulletPointという空のオブジェクトを子オブジェクトとして設定します。
位置は銃の先端にします。

Gun.csを作成

銃を撃つためのスクリプトを書いていきます。
このGun.csを先ほどColliderを付けた銃のモデルにつけます。

OVRInputはOculus Touchの右左によって違うので

if (holdHand.whichController == OVRInput.Controller.LTouch) {
   hapticsChannel = OVRHaptics.LeftChannel;
   whichFinger = OVRInput.RawButton.LIndexTrigger;
}
if (holdHand.whichController == OVRInput.Controller.RTouch) {
     hapticsChannel = OVRHaptics.RightChannel;
     whichFinger = OVRInput.RawButton.RIndexTrigger;
}

昨日のコードでenumで設定したRTouchか、LTouchかをOVRHandからとってきます。
Triggerはものを持つ部分でつかいました。
今回銃を持ったのち、人差し指で発射します。

人差し指は

OVRInput.RawButton.RIndexTrigger

OVRInput.RawButton.LIndexTrigger

で取れます。

これを掴んだときにどっちの手でつかんだか、というのをgetHandメソッド内でやります。

弾痕を作る

gametukurikata.com
ここでは弾痕の実装を参考にします。
ありがたい。絵も提供されています。

Bullet.csをつくる

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Bullet : MonoBehaviour {

	public GameObject bullet_hit;

	// Use this for initialization
	void Start () {

		RaycastHit hit;
		if(Physics.Raycast(transform.position, transform.forward * 100f, out hit)) {
			GameObject obj = Instantiate (bullet_hit, hit.point - transform.root.forward * 0.001f, Quaternion.FromToRotation(Vector3.forward, hit.normal));
			obj.transform.parent = hit.collider.transform;
		}
	}

	private void OnCollisionEnter (Collision col) {
		Destroy (this.gameObject);
	}
	
	// Update is called once per frame
	void Update () {
		GetComponent<Rigidbody> ().velocity = transform.forward * 10f;
	}
}

Bulletオブジェクトをつくる

f:id:kazumalab:20170217234650p:plain

簡単な感じでそれっぽく作ります。
これにBullet.csをアタッチします。

たぶんこれでOKです。
ほとんどVR要素ないですが。笑

デモ

できました。

UnityでOculus Touchを使うメモ ~ものを掴む編~

かずまです。

ようやく卒業の方が落ち着いてきたのでOculusの開発メモを残しておきたいと思います。
今回はTouchでものをつかむという部分をメモっておきます。


結構基本的なことですがSteamとはちょっと仕様が違いますので書いておこうと思います。

Touch

https://www.instagram.com/p/BQP8q9VhuVZ/
Oculus Touch#oculusすごい#卒論終わり次第#開発する#VR

これがOculus Touchです。
めっちゃいい。ボタンとかにもセンサーがついてて、指がどのボタンを触れているか、みたいなのを検知できます。
すごい!

ちょっと発売から遅れましたのですでにTouchの記事はいっぱいあるかも。。。

Oculus SDKを入れる

参考にしたサイトはこちら

framesynthesis.jp

いやーk0rinさんのブログは毎回助かる...。
Steam VRの時もお世話になりました。

ここを参考にOculus SDKをOculus Developerサイトから落としてきて入れます。

さらにOculus Avatar SDKも入れておきます。
これは手とかTouchを表示する際に必要になってきます。

サンプルシーンを可変していく

Assets/OvrAvater/Samples/Controllers/Controller.unity
を開きます。

今回はこのシーンをいじっていきます。

ものをつかんでみる

ほんとは手の形にあわせた持ち方というのを提案したかったのですがちょっと実装不足。

Touchを表す位置は
OVRCameraRig/TrackingSpace/LeftHandAnchor
OVRCameraRig/TrackingSpace/RightHandAnchor
にあります。

ここにColliderとかスクリプトを追加していきます。
まずはRight,LeftHandAnchorの子としてhavePointを作ります。

次にSphereのColliderのisTriggerをtrueにします。

次にLeftHandAnchorにOVRHand.csというスクリプトを作って貼り付けます。


OVRInputはどこでも呼べる!

UnityのInputのようにどこでも呼べるのは便利ですね。
Steamだと少し面倒だった気がする...。

enumを使ってどっちの手かを認識させる

もっといい方法ありそうですが、
Triggerを引いたときにRightかLeftを指定しないといけません。

if (OVRInput.GetUp (OVRInput.RawButton.RHandTrigger)) {
  // RightControllerのトリガーを引いた
}

あとはControllerのVelocityをとるときにどっちのコントローラーかを書く必要があります。
しかし、面倒なのでpublicのenumでInspectorでRightかLeftを選択できるようにします。

Awake()内でそれに合わせて(OVRInput.RawButton)RHandTriggerやLHandTriggerをセットします。
これで面倒はなくなります。

Oculus TouchのVelocity

OVRInput.GetLocalControllerVelocity(/* どっちのコントローラーかを記述 */);

これで取れます。

つかみたいオブジェクトの設定

2つ設定があります。

tagを"holdable"に設定します

Rigidbodyを付ける

これで再生すればできるはずです!
指とオブジェクトとかぶちゃってるのでほんとはつかんでる感じにしたいのですが...。
それは次回ですかね。

今回はこんな感じです。

第3回 技術的ログ Twitterから

かずまです。

今回もファボがたまったのでやります!
過去はこちら!
blog.kazumalab.com

知らない間のホロレンズブーム

ホロレンズが今熱い!(持ってないけど...)

MBSハッカソン

今週土日に本ハッカソンがあるらしい。
行きたい!!!(交通費&引っ越し!)

A-Frameの更新

sinariovr.com
このサイトではA-Frame 0.3.0だった....もうバージョン2個上がってる。すごい。

きのこモデル

関ゲ部にはキノコさんという方がいるらしい。
前回行ったときは会えなかったので次回トライしたい。

なんかすごい2Dアクション

カメラワークが独特で面白い!
あと絵もきれいだし、表現力すごい。

Hololensのアプリ

これなら英語バッチリ!

痩せる方かと思ったら完全なる技術ログだった

....ノーコメントで!!

unity エフェクト


UMLをテキストで書く

意外とこういうの便利。

技術ログではないけど沖縄ギークハウスのクラウドファウンディングが181万円!

すごい!!これから楽しみ!

手書き数式をLatexに...これは便利でした。


今回はこのような感じに!
ちょっとためすぎていっぱいになるので定期的にやろうかと。

広告

Asset Storeをまとめたサイトを大幅アップデートしました。
ぜひお使いください。

www.asset.techmatome.com

アセットストアをまとめたサイトを更新しました。

かずまです。

けものフレンズというアニメが流行ってますね。

わーすごーい!アセットを紹介できるフレンズなんだねーということで(笑)、
Unityのアセットを探して使い方やどういったものか〜みたいなのが書かれたサイトを同時に見つけられる
Assetストアまとめサイトを前回紹介しました。

あの段階ではほんと作りたて、という感じでしたが、今回のアップデートでかなり改善しました。
少しは使いやすくなっていると思われます。

...検索を充実させたい...けど。

アセットを探すなら UA

デザインの変更

前回のデザインも好きだったのですが、並びがどうもうまく収まらなくて止む終えなく変更しました。
今回のはOculusのサイトのような....感じのテンプレートを使用したのでかなり落ち着いています。

フレームワークなどは今まで同様Railsをつかってます。

並びや検索などもわかりやすくなっていると思います。

機能の追加

お気に入り機能

今回は右のメニューバーが追加されています。
これはサインアップ・ログインした場合に有効になります。

いつでも簡単にアクセスできるようになりました。
合計金額も書かれています。
(削除ボタンはまだ未実装なので有効ではありません。)

Twitterアカウント設立!(2/14)

twitter.com

Twitterでは特にゲームがアップされたり、ブログが投稿された場合にのみ更新されます!
ブログを書いたら紐付けてOK!

コンテンツ量

前回よりは20個ぐらいアップしましたが少ないです。
しかし!現在データをかき集めている最中です。
手作業きつい!!

追記

2/12 10:30

コンテンツを頑張って200ほど増やしました!

課題

ドメイン

まだHerokuのドメインを使ってますのでそのうち変更したい。

ドメインを変更しました!
www.asset.techmatome.com

サイト

ぜひ使ってみてください。

www.asset.techmatome.com

メッセージを以前頂いた方へ

前回Slaaskでメッセージを頂いたかたがいらっしゃったのですが、
Slaaskでは長期の会話はダメそうなのでもしこのメッセージをみられましたら
TwitterのDMまたは、FacebookのMessengerでご連絡いただけると幸いです。

Unity C#でHaskellのmapっぽいものを実装したお話

かずまです。

最近、すごいHaskell楽しく学ぼう! を読み始めました。

おもしろおかしく書かれているところもあるので読み行ってしまいます。
なので、寝る前に少し読む、みたいなスタイルで。

Haskellの高層関数

Haskellには高層関数と呼ばれるものがあり、マッピング(map)や畳込みなどが例に挙げれらます。
その中でも今回はmapを実装してみたいと思います。

mapとは?

map関数はリストを返す関数で、引数にfの関数を取り、引数2つめのリストの中身にその関数を適用してくれるという優れもの。
例は以下のように書きます。

map (2 *) [1, 2, 3, 4, 5]
-- [2, 4, 6, 8, 10]

Haskellを僕も今回初めて読み書きしましたがこのように書くようです。
(2 *)は関数で引数としてintを一つ受取り2倍するというもの。

初見では何してるの!?これって感じでした。笑
今回はmapという関数を作って、関数とリストを投げて、マッピングして適用させます。

C#でのFunctional的に書く方法

  • Lambda式を使う

C#でもLambda式が使えるのでそれを利用します。
無名関数とも言いますね!

公式ドキュメントはこちら。
Lambda Expressions (C# Programming Guide)

  • 引数でデリゲートを使う

Lambda式を受けるデリゲートは

Func(T, TResult) Delegate (System)

ココらへんを使えば良さそうです。

** Func

これは一つ目のTは引数の型、TResultは返り値の型をGenericで指定するようです。

なんと、この2つを使えばできるはずですね!!

クラスとメソッドの作成

とりあえず、Funcというクラスを作って、staticでListを返すメソッドを用意してみます。

このような感じで書いてみました。
メソッドをGenericにするのはうーん、どうなのかな。
ClassをGenericにするのもいい気がするけど今はこっちでかきました。

使い方

先程のクラスとは別にFunctorTestクラスを用意します。
以下のように記述してみました。

public class FunctorTest : MonoBehaviour {

	private List<int> list = new List<int>(){ 1, 2, 3, 4, 5 };

	private void Start () {
		System.Func<int, int> f =  (int arg) => {
			return arg * 2;
		};

		list = Functor.map (f, list);

		print (list);
	}
}

追記 2/7

Lambda式をまとめるのもありです。

public class FunctorTest : MonoBehaviour {

	private List<int> list = new List<int>(){ 1, 2, 3, 4, 5 };

	private void Start () {

		list = Functor.map ((int arg) => {return arg * 2;}, list);
		print (list);
	}
}

このコードではHaskellと同じように2倍するLambda式を書いて、それをmapの第一引数として渡すだけ!
簡単ですね!ただHaskellと違ってタイプする数は多いのでスマートじゃない...

これぐらいなら許容範囲!


mapはGenericだけど型を指定しなくても良さそう

mapはGenericな型を要求するので実際は

list = Functor.map<int> (f, list);

と指定するのがいいのか、と想定していました。
ところがTestクラスを書いた時にmapの後ろに型の指定を忘れていたのです。

でもコンパイルエラーも出なく、きちんと出力されていたので
自動的に型を認識するのかと感動してしまいました。

f:id:kazumalab:20170130235140p:plain

きちんとint型だと認識していますね。
公式のドキュメントにもきちんとかいてありました。
Generic Methods (C# Programming Guide)

便利だしHaskellに一歩近づいた?笑

出力結果

f:id:kazumalab:20170130235534p:plain

素晴らしい、ちゃんと出てますね!

Stringでも試してみよう!

Listのintが出来たのでstringでも同様に使えるはずです。

	private List<string> slist = new List<string>() { "Hello", "World" };

	private void Start () {

		System.Func<string, string> fs =  (string arg) => {
			return arg + "(ΦωΦ)";
		};

		slist = Functor.map (fs, slist);

		print (slist);
	}

この様にHelloとWorldの後ろに(ΦωΦ)を付け足すスクリプトです。

結果

f:id:kazumalab:20170131003311p:plain

にゃーと猫がでてきましたね。

まとめ

Haskellはまだまだ初心者ですので間違ってる解説などありましたらご指摘ください。
あとこう書いたほうがいいよ〜みたいなのもぜひ!

今回はHaskellっぽくC#で書いてみよう!みたいな感じでしたが、
おもったより便利だと思います。

追記

C# やるなら LINQ を使おう | プログラマーズ雑記帳

LINQを使えば畳み込みも写像も出来るみたい。
次にそのことを書きたいではある。