おもちゃラボ

Unityで遊びを作ってます

【Arduino】抵抗1本で作る静電容量式のタッチセンサ

静電容量式タッチセンサは、主にスマートフォンなどの液晶タッチセンサとして使われいます。

この静電容量式タッチセンサですが、スマートフォンのように2次元ではなく、1次元(タッチしたか、していないか)を判別するだけであれば、簡単に作ることができます

f:id:nn_hokuson:20170322195708p:plain

作成する回路

今回作成する静電容量式のタッチセンサは次のようになります。Arduinoの8番ポートから9番ポートへ1MΩの抵抗がつながっているだけです。

f:id:nn_hokuson:20170322193051p:plain:w350

タッチセンサになるのは9番ポートに刺さっている部分です。タッチしにくいようでしたら、みのむしクリップなどで延長してください。

回路の原理

「こんな簡単な回路で、タッチ判別できるのかいな?」と思うかもしれませんが、ちゃんとできます( ー`дー´)キリッ

原理は簡単で、8番ポートからはパルスを出して、9番ポートが立ち上がる(HIGHになる)までの時間を計測します。
タッチしていない状態では単に1MΩの抵抗を介して9番ポートへつながっているだけなので、一瞬で立ち上がります。

f:id:nn_hokuson:20170322184553p:plain:w250

一方、タッチしている場合は人間がキャパシタとなるため、抵抗とキャパシタでRC回路を作ることになります。

f:id:nn_hokuson:20170322193204p:plain:w250

CR回路はローパスフィルタとしても使われる回路で、パルスの立ち上がりが鈍ります
鈍り方はCとRの時定数で決まるのですが・・・考え出すと大変なので大きな値の抵抗を使えば使うほど、立ち上がりも鈍ると考えて問題ありません。

f:id:nn_hokuson:20170322184545p:plain:w250

この時間の差を使うことでタッチされているか、されていないかを検出します。

タッチ検出プログラム

タッチ検出プログラムは次のようになります。実際に入力してArduinoに転送してみてください。

int prevt = 0;
int t = 0;
int threshold = 5;

void setup()
{
  pinMode(8,OUTPUT);
  pinMode(9,INPUT);
  pinMode(13,OUTPUT);
}

void loop()
{ 
  t = 0;

  // パルスの立ち上げ
  digitalWrite(8, HIGH);

  // 立ち上がりまでの時間計測
  while (digitalRead(9)!=HIGH) t++;

  // 放電するまで待つ
  digitalWrite(8, LOW);  
  delay(1);

  // ローパスフィルタ
  //t = 0.8 * prevt + 0.2 * t;
  //prevt = t;

  // LED点灯
  if( t > threshold ){
    digitalWrite(13, HIGH);
  } else {
    digitalWrite(13, LOW);
  }  
}

このプログラムでは、センサをタッチしたら13番ポートに接続されているLEDが点灯するようにしてみました。Arduinoを使ってLEDを光らせる方法はこちらの記事で紹介しています。

nn-hokuson.hatenablog.com

センサから得られるデータにはばらつきがあるため、LEDが常時点灯しない場合には、ローパスフィルタで平滑化する部分のコメントを外してみてください。

最後にArduinoを使った静電容量式のタッチパネルの動画を載せておきます。
簡単に作れるので、Arduinoをお持ちの方は是非試してみてください!

www.youtube.com

参考サイト

こちらのサイトを参考にさせていただきました!
kousaku-kousaku.blogspot.jp

[asin:B01CZQANN0:detail]

【Unity】LODで負荷を軽減させて60FPSを維持する

スマートデバイスなどのモバイルがターゲットのゲームは計算量をいかに減らすかがキーになります。ここではLODを使ってパフォーマンスを改善する方法を紹介します。

LODとはLevel Of Detailの略で、オブジェクトが近くにあるときは高精細のモデルを使用し、オブジェクトが遠くにあるときはローポリゴンのモデルを使用しよう、という考え方です。

f:id:nn_hokuson:20170321193923p:plain

UnityではLODを標準でサポートしているため、簡単に実装することができます。

LODの準備

ここでは「近いとき用(dragon0)」「通常用(dragon1)」「遠い用(dragon2)」の3つのモデルを用意します。もちろんカメラから近いときにハイポリ、遠いときにローポリのモデルを使います。

これをすべてシーンビューにドラッグ&ドロップします。とりあえず位置は適当で問題ありません(あとで揃えます)

f:id:nn_hokuson:20170321192750p:plain

次に、これらを束ねる空のオブジェクト(dragon)を作成し、先程の3つのオブジェクトをすべて子要素にします。

f:id:nn_hokuson:20170321192810p:plain

3つのオブジェクト(dragon0〜dragon2)の位置がすべて等しくなるようにします。ヒエラルキービューで3つのオブジェクトを選択して、インスペクタで値を(0, 0, 0)に設定します。

f:id:nn_hokuson:20170321192913p:plain

これで、3つのオブジェクトが重なって表示されます。

親オブジェクト(dragon)にLOD Groupコンポーネントをアタッチします。LOD Groupコンポーネントは「Add Component」→「Rendering」→「LOD Group」にあります。

f:id:nn_hokuson:20170321192933p:plain

LODごとのモデルを設定

LOD用のコンポーネントがアタッチできたので、次はカメラがどのくらい離れたときに、どのオブジェクトを表示するかを設定します。

まずはインスペクタのLOD0をクリックします。その下にRendersの欄が表示されるので、ヒエラルキービューからdragon0を選択してドラッグ&ドロップします。

f:id:nn_hokuson:20170321192940g:plain

LOD1とLOD2にも、それぞれdragon1とdragon2を設定します。

これで、カメラがLOD0のゾーンにあるときはdragon0が、カメラがLOD1のゾーンにあるときはdragon1が、LOD2ではdragon2が表示されます。

LOD2のゾーンよりも遠くにカメラが移動した場合は非表示になります。

LODの距離を設定

最後にそれぞれのモデルを切り替える距離を設定します。こちらも、インスペクタからGUIで設定できます。LODの区切り線をドラッグすることで、各モデルを切り替える距離を設定できます。

f:id:nn_hokuson:20170321193016g:plain

バーを動かすことで、シーンビューにリアルタイムでLOD切り替えの距離が表示されます。めっちゃ分かりやすいですね!

f:id:nn_hokuson:20170321193049p:plain

これで設定は完了です。実際にカメラを動かしてみると、カメラからの距離によってオブジェクトが切り替わっているのがわかると思います。

f:id:nn_hokuson:20170321193155p:plainf:id:nn_hokuson:20170321193159p:plain
f:id:nn_hokuson:20170321193205p:plainf:id:nn_hokuson:20170321193208p:plain

その他

LODに関しては次の記事で実例とともに説明されています。詳しく知りたい方はこちらをどうぞ。

西川善司の3Dゲームファンのための「GRAVITY DAZE」グラフィックス講座(前編) - GAME Watch

【Unity】これは便利!カメラの位置をシーンビューの視点と一致させる

「いまシーンビューで見ている映像を、そのままカメラの撮影アングルとして使いたいな〜」ということはありませんか?

この記事では、シーンビューで表示されている視点をMain Cameraの視点と一致させる方法を紹介します。
この方法を使うことでシーンビューで見たままの映像をゲームビューで使うことが出来るようになります。

f:id:nn_hokuson:20170320200207p:plain

シーンビューの見た目とカメラの画像を一致させる

Blenderの場合は「カメラをビューにロック」にチェックを入れておくと、編集画面で見たままの映像をレンダリングすることができます。これと似たようなことがUnityでもできます。

まずは撮影したい位置とアングルになるようにシーンビューで画面を移動させて下さい。

f:id:nn_hokuson:20170320175932g:plain

次に、ヒエラルキービューでMain Cameraを選択した状態で「Command+Shift+F」を押します。(Windowsの場合は「Control+Shift+F」です)

f:id:nn_hokuson:20170320180643p:plain

これにより、カメラがシーンビューの位置に移動し、また、注視方向が現在のビューと一致するように回転します。

f:id:nn_hokuson:20170320190748p:plain

インスペクタからMain CameraのField of Viewを55度くらいに設定しておくと、シーンビューでの見た目とカメラからの見た目が綺麗に一致しますよ。

f:id:nn_hokuson:20170320185553p:plain

Unityの公式ページに、その他の便利なショートカットも紹介されているので、読んでおくと使えるかもしれません!
docs.unity3d.com