admin のすべての投稿

unity->Arduino->Unity開発メモ2019

UnitySerianHandloerのUnity2018で使えたやつ

 

SerialHandler.cs

using UnityEngine;
using System.Collections;
using System.IO.Ports;
using System.Threading;

public class SerialHandler : MonoBehaviour
{
    public delegate void SerialDataReceivedEventHandler(string message);
    public event SerialDataReceivedEventHandler OnDataReceived = delegate { };

    //ポート名
    //例
    //Linuxでは/dev/ttyUSB0
    //windowsではCOM1
    //Macでは/dev/tty.usbmodem1421など
    public string portName = "/dev/cu.usbmodem2101";//mac
    public int baudRate = 9600;

    private SerialPort serialPort_;
    private Thread thread_;
    private bool isRunning_ = false;

    private string message_;
    private bool isNewMessageReceived_ = false;

    void Awake()
    {
        Open();
    }

    void Update()
    {
        if (isNewMessageReceived_)
        {
            OnDataReceived(message_);
        }
        isNewMessageReceived_ = false;
    }

    void OnDestroy()
    {
        Close();
    }

    private void Open()
    {
        serialPort_ = new SerialPort(portName, baudRate, Parity.None, 8, StopBits.One);
        //または
        //serialPort_ = new SerialPort(portName, baudRate);
        serialPort_.ReadTimeout = 20;//Add this 2019
        serialPort_.Open();
        serialPort_.NewLine = "\n";//Add this 2019

        isRunning_ = true;

        thread_ = new Thread(Read);
        thread_.Start();
    }

    private void Close()
    {
        //isNewMessageReceived_ = false;
        isRunning_ = false;

        if (thread_ != null && thread_.IsAlive)
        {
            thread_.Join();
        }

        if (serialPort_ != null && serialPort_.IsOpen)
        {
            serialPort_.Close();
            serialPort_.Dispose();
        }
    }

    private void Read()
    {
        while (isRunning_ && serialPort_ != null && serialPort_.IsOpen)
        {
            try
            {
                message_ = serialPort_.ReadLine();
                isNewMessageReceived_ = true;
            }
            catch (System.Exception e)
            {
            //    Debug.LogWarning(e.Message);
            }
        }
    }

    public void Write(string message)
    {
        try
        {
            serialPort_.Write(message);
        }
        catch (System.Exception e)
        {
            Debug.LogWarning(e.Message);
        }
    }
}

 

Unityボタン側スクリプト

Btn.cs

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

public class Btn : MonoBehaviour
{
    //先ほど作成したクラス
    public SerialHandler serialHandler;


  void Start()
    {
        //信号を受信したときに、そのメッセージの処理を行う
        serialHandler.OnDataReceived += OnDataReceived;
    }

    void Updata()
    {
        //文字列を送信
       // serialHandler.Write("hogehoge");
    }

    //受信した信号(message)に対する処理
    void OnDataReceived(string message)
    {
        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 sendOn()
    {
        //Arduinoに文字列onを送る
        serialHandler.Write("4");
    }

    public void sendOff()
    {
        //
        serialHandler.Write("5");
    }
    public void ledOn()
    {
        //
        serialHandler.Write("6");
    }

    public void ledOff()
    {
        //
        serialHandler.Write("7");
    }

}

 

Arduino側コード

#include <Servo.h>
const int LED_PIN = 13;
int SERVO_SOCKET = 9;
Servo servo;
String InByte_strings;
int InByte;

void setup() {
 Serial.begin(9600);
 pinMode( LED_PIN, OUTPUT );
servo.attach( SERVO_SOCKET );
}

void loop() {
  
  if(Serial.available()>0){
    InByte_strings=Serial.readStringUntil(';');
    InByte=InByte_strings.toInt();
    Serial.println(InByte);

     switch (InByte){
    case 4:
      servo.write( 90 );
      break;
    case 5:
      servo.write( 180 );
      break;
      case 6:
      digitalWrite(LED_PIN,HIGH);
      break;
      case 7:
      digitalWrite(LED_PIN,LOW);
      break;
  }
}
}

 

 

Oculus Quest開発メモ

Oculus Quest 開発メモ

https://qiita.com/pira/items/1c935f30d5ba6c020333

https://framesynthesis.jp/tech/unity/oculusquest/

https://qiita.com/pira/items/1c935f30d5ba6c020333

 

細かい部分はGoの解説でも網羅できる.

MacにOculus接続時=開発者モードをONにするとつながる

つながった後は開発者モードONでいいらしい

OVRPlugin.aar” is denied.

てエラー出る(ビルドはできるけどapk表示されない)

Reveal in FinderでFinderでそのファイルを見つけ,拡張子を.aarから.bakにする

Oculusを接続したまま,Build & Run する

実行される.

 

Unity Timelineを利用したアニメーション

ピタゴラ装置を作る中で,巨大なピタゴラ装置を作りたくても画面からはみ出たりするかもしれません.そこで,次の方法でカメラアニメーションを入れてみましょう.

TimeLineを追加する

  1. Window>Sequencing>Timelineを選択
  2. MainCameraを選択しながら,Timeline画面に表示されるCreateボタンをクリック
  3. MainCameraのTimelineを保存するか訪ねられるので,Saveで保存する
  4. TimelineのMainCameraトラックを選択し,赤丸のRecordingボタンをクリックする
  5. MainCameraを選択し,PositionやRotationなどを変化させる.キーフレームが打たれる.時間を変更しまたキーフレームを打つなどしアニメーションを作成する
  6. Timelineの再生ボタン(下図A)で動きを確認できる(ただしシミュレーションは働かない)
  7. アニメーションの編集などは,下図Bをクリックするとアニメーションカーブで編集できる
  8. 各キーフレームはベジェカーブで編集できる.またキーフレームを右クリックするとカーブの種類を変更できる.上図はキーフレームの左側を直線(Linear)に変更している
  9. 元に戻すには,Compared Autoを選択する

Unity入門-1_3

Physic Materialを設定します

  1. Assets>Create>Physic Materialを選択
  2. Assetsフォルダ内にPhysic Materialが作成されるので,名称をBounceに変更(名称は何でもいい)
  3. Bounceを選択し,InspectorのBouncinessを0.5に変更
  4. Cubeを選択し,BoxColliderコンポーネントのMaterialに作成したBounceをドロップする
  5. 再生し変化を確認する

Unity入門-1_2

(2019追加)

Rigid Bodyを使ってオブジェクトに重さを与える

 

  1. GameObject>3D Object>Plane で平面を取り出す
  2. GameObject>3D Object>Cube で立方体を取り出す
  3. Cubeを適当な位置に置く
  4. 再生ボタンを押す(変化なし)
  5. Cubeを選択し Component>Physics>Rigid Bodyを選択する
  6. CubeのInspectorを見るとRigid Bodyコンポーネントがアサインされていることがわかる
  7. 再生ボタンを押し変化を確認する
  8. Rigid BodyコンポーネントのMass(重量)の値を変化させ,挙動がどう変わるか確認すること

つづく

 

サイクルアニメーション

繰り返し動作をしてみたい方は,サイクルアニメーションを設定してみましょう.

サイクルアニメーションとは,ある周期(サイクル)の動き設定せずとも繰り返させることです.(参考WEB

この設定では作成されたキーフレームの最初と最後の間を繰り返します.

  1. 移動アニメーションが無い(その場歩行)場合,1歩分の動き(1サイクル)を作成し,グラフエディタを開きます.グラフエディタ>カーブ>ポストインフィニティ>サイクル を選択.
  2. その後移動アニメーションを設定する.
  3. すでに移動アニメーションがある場合は,ラフエディタ>カーブ>ポストインフィニティ>オフセットつきサイクル を選択
  4. グラフに変化はありませんが,再生してみると繰り返しているのがわかります
  5. レンダリングについては適宜指示します.

 

椅子にジョイントを入れる

ここではジョイントを入れて椅子をアニメーションさせる.

2つの方法で取り組むので,どちらかを選択してください.

 

A.モデリングをそのままにして,椅子の脚先だけを動かす.

(Aの作例)変更しました

※master ←これはロケーターと呼ぶ,位置情報のみのオブジェクトです.作成>ロケーター を選択し作成してください.

作成手順を動画で確認

B.全体を1つのオブジェクトにしてアニメーションをさせる

  1. ツールセットをモデリングに切り替える
  2. 結合したいオブジェクトを全て選ぶ
  3. メッシュ>結合□ を選択
  4. 結合の設定(下図を参照)を確認し,適用して閉じるを押す
  5. 1つのオブジェクトに結合される(ただし結合前の情報も残る)
  6. 結合前の情報が残っていると,突然形状が変わるなど不都合が起きることもあるので,この情報を削除する
  7. 編集>種類毎に削除>ヒストリ を選択
  8. ヒストリが消える

(Bの作例2)

 

アニメーションチャレンジ

アニメーションにチャレンジしてみましょう.前から転がってくる円柱などをよけるアニメーションを作成してみましょう.

 

ウェイトの確認

ウェイトの確認

  1. 各ジョイントの影響度をウェイトと呼びます
  2. ウェイトを確認してみる.円柱を選択し,スキン>スキンウェイトペイント□を選択,スキンウェイトペイントツールが開くのでjoint2を選択しjoint2の影響度を見る
  3. (参考情報)このウェイトはあくまでも計算式で作成されたもののため,思うように変形できない場合がある.図はjoint2の影響度をjoint3の近くまで広げた状態でjoint3を曲げたもの
  4. joint3を曲げてもjoint2の影響が強くjoint3の曲げが伝わらず破綻してしまっている.
  5. 人体などの複雑な形状ではウェイト調整が難しいので日頃から肉と骨についてはよく観察することや,解剖学を学ぶことをお勧めします.

スキニング(基本)

スキニングの基本

ジョイントについての確認事項

  1. アウトライナを開き,作成したジョイントがどこに対応しているか確認する

  2. このジョイントは根元側を回転することができ,そこから先が全て回転される.これは親子付けがされているからである.アウトライナで確認すること.確認が終わったら回転は元に戻しておく

 

スキニング(関連付け)

  1. 根元のジョイントを選択する.根元のジョイント(親)を選択すると子のジョイントも選択される
  2. Crtlキー(飛び越し複数選択)またはShiftキー(連続複数選択)を押しながら円柱を選択する.(2つ選択される)
  3. スキン>スキンのバインド□  を選択し,図の設定にし,スキンのバインドボタンを押す(表示されない場合メニューセットをリギングにする)
  4. (予備知識)バインドオプション画面を初期設定値に変更する方法
  5. 画面に特に変化は起こりませんが
  6. 選択を外すと,ジョイントに色が付いています
  7. joint3を回転させると図のようになる
  8. このように,ジョイントとオブジェクトとの関連付け骨と肉を関連付ける=することをスキニングと呼びます(ソフトウェアによって呼び方は異なる)
  9. また,根元側から先端へ向け回転の影響を伝えるためForward Kinematics(FK)と呼ぶ.(反意:IK)

ウェイトの確認へ

ジョイントの作成(基本)

テストピースで実験

テストピースで実験すると,本番データを壊す危険性を下げられます.新しいことをする前にはテストピースで試してみましょう.
少し煩わしいですが,手戻りを少なくし,結果的に締め切りに間に合わせるテクニックとして覚えておいてください.

 

ボーンの作成(基本)

  1. メニューセットリギングにする
  2. ジョイントのツールがすぐに出せるようにシェルフリギングを選択する
  3. 円柱を作成する.サイズ等は画像を参考に.(作成後,円柱を移動させない)
  4. ボーンを作成時にクリックした点がグリッドに重なるように,グリッドにスナップ機能をONにする.(スナップ機能は様々なソフトで実装されている)
  5. fron-zビューでシェーディング>X線表示 にチェックを入れる.これでオブジェクト内にジョイントが隠れている場合もジョイントを表示できる.
  6. ジョイント作成ツールを選択
  7. 円柱の下部から2グリッドずつクリックし,ジョイントを作成する.

  8. 円柱の先端をクリックしたらEnterキーを押し作成を確定する

次はジョイントと円柱とを関連付け(スキニング)を行います

次へ