「3DCG」カテゴリーアーカイブ

VRに使ったスクリプト(Unity側)

(関連記事)

  • VRについての記事はこちら
  • SerialHandlerについての記事はこちら

上記リンク先の記事SerialHandlerを使ったUnityの制御です.

 

using UnityEngine;
using System.Collections;
using System;//use for time
using UnityEngine.UI;//use for UI


//アセットSuperSplinesのメニューを追加
	[AddComponentMenu("SuperSplines/Animation/Regular Animator")]


	public class mySpline2 : MonoBehaviour{
		public Spline spline;
		public WrapMode wrapMode = WrapMode.Clamp;//SuperSplineの初期モード実際はLOOPで使用
		public float speed = 0f;//初期速度ゼロでないと起動したら動いてしまう
		public float offSet = 0f;//オフセット値/スタート位置を変えたい場合など.

		public float passedTime = 0f;//何に使ったかな?
	float myspeed = 0f;//何に使ったかな?

		public Text myText; //UIで使う用
		public SerialHandler serialHandler;//serialHandlerスクリプトがアサインされたゲームオブジェクトをアサインする用.

		//for arduino
		public bool spBool = false;//停止用

		//時間計算用,試行錯誤してるので要らない変数あるかも
		private int starttime;
		private int now;
		private int duration;
		private float truespeed;
		private float myPos = 0f;
		private float mytime = 0f;
		float lerpspeed =0f;
	float firstSpeed = 0f;

	float mymillsec= 0f;
	string kmspeed;



	void Start(){

			myText.text = "0km/h";//GUI表示用に0km/hいれる
		starttime = DateTime.Now.Hour * 60 *60 * 1000 + DateTime.Now.Minute * 60 * 1000 + DateTime.Now.Second * 1000 + DateTime.Now.Millisecond;//起動した時間をstarttimeにミリセカンドで入れる.ペダル停止検知用
		//信号を受信したときに、そのメッセージの処理を行う
		serialHandler.OnDataReceived += OnDataReceived;
		}



		void Update( ) {
			mytime += Time.deltaTime * speed;//いまの時間とスピードかけてspline動かす指標にする
		if (spBool) {//ペダル動いてるとき
		myPos += Mathf.LerpUnclamped (speed ,firstSpeed, mytime);//スプライン上の位置myPosを時間でslerpする
		}
		if (Input.GetKeyDown ("s")) {//停止用
			myPos += Mathf.LerpUnclamped (0f, 0f, mytime);
				spBool = false;
			myspeed = 0f;
		}

			if (Input.GetKeyDown ("r")) {//リセット用
				myPos = 0;
				spBool = true;
				myspeed = 0f;
			speed = 0f;
			}
// 下3行がsplineを動かすやつ
			float clampedParam = WrapValue (myPos + offSet, 0f, 1f, wrapMode);
			transform.position = spline.GetPositionOnSpline (clampedParam);
			transform.rotation = spline.GetOrientationOnSpline (clampedParam);

////
		}



	void OnDataReceived(string message){//arduinoから文字列を受信したら
		
		firstSpeed = speed;初期速度をさっきの速度に入れ替え(2回目以降用)
		mymillsec = float.Parse (message);//車輪が1回転した間隔を受信してるので,それをフロート値に変換
			myspeed = (3600000f / mymillsec) * 0.000628f;//速度km/hを計算
		if (myspeed < 0.9) {//速度が1km未満ならゼロに
			myspeed = 0f;
		}

			kmspeed = myspeed.ToString ("N2");//小数点2桁でカット
		speed = myspeed * 0.00005f;//乗数で速度感変わります
		//}
	
		myText.text = kmspeed + "km/h";//速度をUIに表示
		//以下使ってない(タブでデータ区切り用)
		var data = message.Split(
			new string[]{"\t"}, System.StringSplitOptions.None);
		if (data.Length < 2) return;

		try {
		} catch (System.Exception e) {
			Debug.LogWarning(e.Message);
		}

	}



	public void stopper(){ //使っていません.ペダルの回転間隔を調べて回っていないのならゼロにしようと思いましたが,惰性で進むことを優先してこちらはカット(ただしBoolだけ使ってる)
		now = DateTime.Now.Hour * 60 *60 * 1000 + DateTime.Now.Minute * 60 * 1000 + DateTime.Now.Second * 1000 + DateTime.Now.Millisecond;
		duration = now - starttime;

		if (duration > 3000) {
			spBool = false;
			kmspeed = "0";
			myText.text = kmspeed + "km/h";
		} else {
			spBool = true;
		}
		//Debug.Log (spBool);
		starttime = DateTime.Now.Hour * 60 *60 * 1000 + DateTime.Now.Minute * 60 * 1000 + DateTime.Now.Second * 1000 + DateTime.Now.Millisecond;
	}



	public void testBtn(){//センサを使っていないときに,GUIのボタンでテスト出来るよう

		int myrand = UnityEngine.Random.Range (150, 1800);
		string randStr = myrand.ToString ();
		OnDataReceived (randStr);


	}



//splineのモード設定用みたい
		private float WrapValue( float v, float start, float end, WrapMode wMode )
		{
			switch( wMode )
			{
			case WrapMode.Clamp:
			case WrapMode.ClampForever:
				return Mathf.Clamp( v, start, end );
			case WrapMode.Default:
			case WrapMode.Loop:
				return Mathf.Repeat( v, end - start ) + start;
			case WrapMode.PingPong:
				return Mathf.PingPong( v, end - start ) + start;
			default:
				return v;
			}
		}

	}

です.

VRアプリ開発メモ

実質2日間でOculusRift(DK2)対応のコンテンツを作っていました.

このレベルなら文系の私でもモデリング含めて2日(徹夜なし)で作れるので,卒研とかはこんなレベルじゃダメですよ〜

(ていうか,そもそも組み立てただけで研究でもなんでもない,,,)

そもそもOculusって何かってっつーと,PSVRのようなものです.

 

Oculus Riftはコケられない、だから値段も高くなる|WIRED.jp

製品版「Oculus Rift」の予約受付がはじまり、その価格の高さに驚いた人も多いだろう。しかしソニーやHTCといった手ごわいライヴァル企業と競わなければならないOculusにとって、いちばんの問題はその価格ではないようだ。

LINK: wired.jp/2016/01/11/oculus-rift-price/

 

このOculus社がDK1を出したのはずいぶん前です.当時は衝撃でしたね.私はジェットコースターで酔ってOculusは触らないことにしました.

でもこのあたりの衝撃が現在のVRブームを作ったとも言えます.

さて,このVRコンテンツ,作るのは超簡単です.

どのくらい簡単かというと,ドライバなどインストールしてれば,見るだけなら3分くらいで作れます.

研究室に前の住人が残しておいたエアロバイクがあったので,ちょいと分解.データが取れそうでした.

そこで,,,,

Arduinoでちょいちょいといじって,

bike1

こんなものができました.

八事の空を空中散歩♪

オーキャンで高校生が絶叫していました〜(それを見てる方が楽しい)

bike2

センサのデータ変換にはAruinoを使っています.

 

今回書いたプログラムは全部で200行以下です.

そのうち,エアロバイクのセンサをArduinoからシリアルで送るプログラム

unsigned long mytime = 0;
unsigned long hittime;
unsigned long duration;
boolean sensorBool = true;
int input_value;

void setup(){
Serial.begin(9600);
mytime = millis();
}


void loop(){
 input_value = analogRead(3);
if(sensorBool == true){
if(input_value < 200){
 sensorBool = false;
hittime = millis();
duration = hittime - mytime;
mytime = hittime;
send();
}
}else if(!sensorBool){
  if(input_value > 500){
    sensorBool = true;
  }
}
  
}

void send(){
Serial.println(duration);

}

これをUnityに送って,コースのスプラインを走るだけです.

うん,簡単ですね.

Unity側のプログラムは別記します

なお,数値変化をやさしくするために,

Mathf.LerpUnclamped

を使っています.

Mathf.Lerpでもいいのですが,これは0から1でしか動作しません.

Splineは0(始点)から1(終点)で動くので,1を入れると1周します.Mathf.Lerpですと,1周しかしません.

Mathf.LerpUnclampedにすると,1を越えても数値補完してくれるので2周3周したいお客さんがいるときにも対応できます.

もちろん,適宜データのリセットは大事ですが,,

Uniduinoが動かないとき

UnityでArduinoと通信できる魔法のプラグインUniduino(おそらく開発停止)をインポートして動かないとき,

PlayerSettings.NET 2.0 subset.NET 2.0に変更する.これ大事.Uniduinoは以下リンクより.

 

Uniduino

LINK: www.uniduino.com/

 

 

なお,UnityでArduinoを扱えるシステムの最新版は,

 

ARDUnity Home Page

Innovative IoT base Physical Computing DIY Solution ‘ARDUnity’ Official Web Site

LINK: www.ardunity.com/

 

があり,しかも基本的なDOUT.INやAINなどは無料で使用可能です.

MB1(Maya to MB)

MayaのデータをMotionBuilder(以下MB)で編集しましょう。

はグラボ必須です.無いと起動できません.そのためMacでWindowsを使用可能にするパラレルデスクトップでもMayaは起動しますがMBは動きません.

モーションデータは、BVH又はc3dのモーションファイル使用します.
http://www.mocapclub.com/Pages/Library.htm
http://accad.osu.edu/research/mocap/mocap_data.htm
カーネギーのデータ
http://mocap.cs.cmu.edu/

 

  1. MBで使用するには,カーネギーのデータをBVH化したもの(MBはBVH形式が楽です.こちらを利用してください)
    https://sites.google.com/a/cgspeed.com/cgspeed/motion-capture
    Motion builder friendly versionを使う
  2. directories番号の内容はこちらに.リンク先に動きのサンプル動画があるので,それを手がかりにすること
  3. 通常は,MayaからMotinBuilderにシーンを送信するか,fbx(スキニング又はエンベロープ済み)を読み込むが.今回は配布されたデータを用いる
  4. MotionBuilderをMayaと同じショートカットで動かしたい場合,Interaction ModeMayaにする(下図参考)
    mb0701
  5. ドラッグ&ドロップでBVH(又はC3Dファイル)を読み込む
  6. 読み込み後,再生バーを調整し0フレーム目や-1フレーム目Tポーズが入っているか確認する
  7. アセットのTemplate内Character(C3DのときはActor)をシーンにドロップ
    chara
  8. ここまでで,読み込んだデータは概ね以下のような構造になっている
  9. 読み込んだBVHのデータをCharacterにアサインする.CharacterをダブルクリックするとCharacoter Definitionのタブを探しやすい下記画像を参考にMapping Listの部分に読み込んだBVHファイルのボーンをアサインする
    cahacter2
  10. referenceとBaseの項目は必須です.他は部位にあわせて近い部分をアサインしてください.
  11. Tポーズのフレームへ行き,Characterizeにチェックを入れる,その際にキャラクタのスタイルを聞かれるの二足歩行の場合はBipedにする
    chara3

つづく

 

 

 

Mayaが起動しない時の対処方法

Mayaが起動しない時はプロファイルを消去します

ただし,プロジェクトの場所を設定していない場合,保存していたものが全て消える可能性があります

必ずバックアップをとってください

プロファイル消去の方法

  1. マイドキュメント>maya
    または
    マイドキュメント>maya>(Maya2016)
    というフォルダを探します
  2. 正しくプロジェクトを設定していない場合,こちらにシーンファイルが保存されている可能性がありますので,必ずバックアップをとってから,このmayaフォルダを削除します
  3. その後Mayaをスタートさせる

参考WEB

cgjishu.net/blog-entry-32.html

 

アニメーション出力(2)

レンダリング設定(参考)

  1. レンダー設定をクリックします
    ren9
  2. (A)動画を提出する場合
    Windows版の場合は以下のように設定します.イメージフォーマットはAVIに,圧縮をクリックし,圧縮プログラムはMicrosoft Video1に,フレームレンジは1〜200(このサンプルの場合)に(※この設定はOSの設定に応じて変更することがあります)
    ren16
    (B)連番画像を提出する場合
    図のように設定してください.
  3. イメージサイズプリセットHD1080に設定するren17
  4. (※)動画ファイルで書き出すのは一般的ではありません.通常は連番ファイル(連続した番号の静止画ファイル)で書き出す
  5. 使用するレンダラMayaソフトウェアに(レンダラーとは描画エンジンのこと.Pixarならレンダーマンを使い,最近の商用レンダラーはV-Rayが増えてきました)Mayaソフトウェアのタブを選択し,精度制作の精度エッジのアンチエイリアシング(境界線のギザギザ=ジャギーをぼかす度合い)を最高精度に,レイトレーシングの精度レイトレーシングにチェックをいれます
    ren8
  6. パースのビューで,ビュー>カメラ設定>解像度ゲート の設定に変更します
  7. ビューポートに白い枠が現れます.この枠にあわせてアングルを調整してください
  8. レンダリング開始ボタン(下図赤線)をクリックし,レンダリング結果を確認します
    ren11
  9. この場合は,静止画でレンダリングされます
  10. 照明が暗い場合は,照明を追加してくださいlight
  11. 身体が黒い場合には,テクスチャのリンクを再設定してください.rendertex1
  12. ライティングなどを調整し,レンダリングの状態をベストなものにします
  13. メニューセットレンダリングにし,メニューバー>レンダー>バッチレンダー を選択します
    ren12
  14. レンダリングが開始する
    ren13
  15. レンダリングが完了されたら以下のように表示されます.動画の保存場所はこのページ2のレンダー設定の共通のパスの部分にも記述されていますren14
  16. 動画を確認する

お疲れ様でした

アニメーション出力(1)

サイクルアニメーション

  1. 1〜36フレームの1サイクルの動きを繰り返し動作にしてみます
  2. 基本:グラフビューで繰り返したい動きを選び,カーブ>ポストインフィニティ>サイクル を選ぶ
    ren1ren2
  3. では,全体を選択します.Charactor1_Ctrl_Referenceを選び,メニューバー>選択>階層 で下の階層まで選択します
    ren3
  4. カーブ>ポストインフィニティ>サイクル でサイクルアニメーションにします
  5. アニメーションの再生範囲を200までに拡大ren4
  6. 再生して動くことを確認し

テストレンダー

  1. 再生ボタンを右クリックし,プレイブラストを選択ren5
  2. 動画プレイヤーが開き動画を確認できます(プレーヤーはOSによって異なります)ren6
  3. Previs(Previsualization)プレビズあるいはプリビズとも呼ばれ,時間のかかるレンダリングをしないで,簡易動画によって動きの確認や,他のカットと組み合わせて映像編集の状態をチェックするというもの
  4. これはテストレンダーで,正規のレンダリングではありませんが,こうしてテスト版を作成し動きをチェックした後,本番レンダリングとなる

つづく

ボーンの設定(4)

ウェイト調整

  1. 各ボーンのモデルへの影響度合い(ウェイト)を調整することができます.スムーズバインドをした時点で設定するのが通例ですが,リグを設定した後でもスキンウェイトを調整できます
  2. モデルを選択し,ツールセットをリギングにし,スキン>スキン ウェイト ペイント□を選択しウェイトペイントツールを表示させます
  3. (ツールが表示されない場合)ペイントのツールをダブルクリックし,ウェイトペイントツールを表示させます
  4. 手足を動かし,ウェイトが破綻している場所を調べます
  5. ウェイトが破綻している箇所のボーンを選択します(下図1)
  6. ペイントモードなどを選択し,ペイントをする
    weightpaint1
  7. まずはスムーズ(上図4)で破綻しているあたりを塗り,調整する
  8. ウェイトが弱い,あるいは強い場合は,ウェイトの強さを設定したあと(上図3),ペイント操作の「置き換え」または「追加」などで(上図4)塗り,スムーズでならす
  9. 破綻がないように調整する
    weight
  10. なお,ペイントは頂点をクリックするように塗る
  11. ウェイト調整のやり直しは大変なのでウェイト調整前の状態を保存し,バックアップを残しておきましょう

ボーンの設定(3)

フロアコンタクトの設定

  1. キャラクタコントロールから編集>定義>プロパティの編集を選択
    floor1-2
  2. 足>足のフロアコンタクト の設定をオンにする
    floor2
  3. 左右どちらかの足のコントロールポイントを選択し,下図2の移動ロック,回転ロックをクリックしオフにする.もう一方の足のロックも外す
    floor3
  4. 自由なポーズをつけてみる
    pose1
  5. 適当なフレームへ移動し,ポーズをつけたコントロールポイントを選びSキーでキーフレームを打つ.移動させた全てのコントロールポイントにできたら,1フレーム目でまた繰り返す
    pose2
  6. モーションが作成される
  7. つづく