ブラウザで 3D モデルを作成できる Tinkercad を使ってみた
Tinkercad は AUDODESK 製の 3D モデリングツール。ブラウザでポチポチするだけで 3D モデルが作れちゃうやつです。 チュートリアルも充実していて、使いやすい印象です。
3D モデリングは初めてなので、まずは、スターターからやろうかなと思いつつ、ほとんど直感的に出来るのでハマったところだけ。
スターターには7種類のチュートリアルがありました。
- Place It
- View It
- Move It
- Rotate It
- Size It
- Group It
- Align It
View It (1/4)
単純にオブジェクトを回転させ、いろいろな方向から見るだけですが、直感的に空間をグリグリ動かせてしまうので説明が言いたいことがわかっていませんでした。
- Just left-click and drag anywhere on the ViewCube and see how it changes the point of view.
(左クリックしながらグリグリすれば視点が変わるよ) と読んだ。
にも関わらず、作業台のある空間を直感的に 右クリック しながらグリグリして視点を変更してしまったのだ。そのまま進めると View It (3/4) でおかしな問題にぶつかる。
Press and hold the right mouse button while moving your mouse to practice rotating your view of the design.
(右クリックを押したままグリグリすればビューを回転できるよ) と読んだ。
あれ?さっきやったよな?このチュートリアル何か間違っているのかな? と思い、そのまま進める。 間違っているのは自分の脳内変換だとは気づかずに。。。
後から気付いた話ですが、以下の画像の通り、メインビューの左上にある箱を 左クリック でグリグリすることが View It (1/4) の練習だったようです。
「obniz x LINE Things」ハンズオンのサポートスタッフをしてきた話
linedevelopercommunity.connpass.com
こちらで obniz の木戸さんのサポートをしてきました!
講師
木戸先生
ハンズオンの内容
LINE Things 名物、無限 PUSH 通知を obniz から実行する
流れ
- 事前確認
- obniz のバージョン確認・アップデート
- LINE のバージョン確認・アップデート
- BOT 作成
- Messaging API チャネル作成
- LIFF の設定
- LINE Things のシナリオ作成
- repl.io を用いて BOT サーバーを起動
- ペアリング
サポートした各種トラブル
- repl.io の使い方
- LINE Things シナリオの作り方
- repl.io のコピーする URL を間違えていた
- 連携デバイスが表示できない (LINE Things のバグの可能性も...と中の人が仰っていました)
その他
今回は、入り口の前に立って参加者をご案内しました。
また、同じフロアの別会場で別のイベントが開催されていたため、
そちらのご案内もちらほらしました。
デバイス連携が中々上手く行かず、ハマっている方々も多数いらっしゃいましたが、 なんとか突破して動いたときは感動です。
「TypeScript x Clova」ハンズオンのサポートスタッフをしてきた話
linedevelopercommunity.connpass.com
こちらで講師のみそさんのサポートをしてきました。
講師
みそ先生
ハンズオンの内容
JavaScript で実装されている公式のサンプルプログラムであるサンプルダイスを CEK_SDK 版で構築し、
最終的に TypeScript へ置き換えていくという流れとなっています。
そして TypeScript はいいぞ!っていうお話をするハンズオンですw
流れ
- サンプルダイスの JavaScript 版で CEK 上でテストができるところまで作業する
- TypeScript の説明と環境構築
- 【手順1】でやった JavaScript 版を TypeScript 版へ置き換えていく
サポートとしてやったこと
作業に詰まってしまって、資料より遅れてしまっている方々のサポートだったり、気づいたら(変なところを消してしまって)エラーが大量発生していた方のサポートだったりをしました。
みそさんの資料がとても良く Windows と Mac の両コマンドが記載されているため、コマンド関連で悩む方は少なかったように思いました。
最後に
JavaScript は実行してみないとエラーに気づかないことも多いですが、TypeScript では型定義があるとこによって事前にエラーに気づくことができます。(存在しないプロパティにアクセスしていたり等)
小さなプロジェクトでは TypeScript の恩恵は少ないですが、
大きくなってくると型定義や型推論、そして古い構文へのトランスパイルなど、
とても助かることが多くなるので、皆さんが型好きになってくれれば嬉しいなと!
「M5StickC + LINE Things + Amazon Connect 連携ハンズオン」に参加してきた
linedevelopercommunity.connpass.com
に参加してきました。
IoT よくわからないので Arduino IDE 初体験です。
講師
がおまる先生
流れ
- Amazon Connect で問い合わせフローを作る
- Lambda 関数・API Gateway を作る
- LINE Bot (LIFF) を作る
- LINE Things を設定する
- M5StickC にコードを書きこむ
完成システム構成図
だいたいこんなイメージだろうか?
1. Amazon Connect で問い合わせフローを作る
Amazon Connect を使って、コールセンターフローを作る。
フロー自体は Node-RED のようにブロックプログラミングで作れる。
2. Lambda 関数・API Gateway を作る
API Gateway 経由で実行する Lambda 関数を作る。
Lambda では、Amazon Connect の API をキックするだけの簡単な Lambda。
Amazon Connect の電話番号や各種 ID などを環境変数に設定して完了。
3. LINE Bot (LIFF) を作る
LINE Things を準備するために LINE Bot を作って LIFF の設定を行う。
この辺は LINE Developers のページでポチポチっと。
4. LINE Things を設定する
LINE Bot (LIFF) から LINE Things の サービスUUID を作る。
この辺はイマイチ理解できていないが本来であれば cURL 等で叩いて取得する。
今回はのびすけさんのツールを使って取得
5. M5StickC にコードを書きこむ
Arduino IDE を開いて、M5StickC にコードを書きこむ。
すると「LINE アプリ」の「LINE Things」に【手順.4】で作った「LINE Things デバイス」が表示される。
これをペアリングすることで「M5StickC」から「LINE Things」経由で「API Gateway」に到達することができる。
という感じっぽい
実行!
そして大きい方のボタンを押すと・・・ Amazon Connect 経由で電話がかかってきて、カウント値を教えてくれます。
トラブルシューティング
M5StickC にコードを書きこんでも何も表示されない
Arduino IDE で初書き込みだー!と喜んでいたら、何も表示されない。。。
初書き込みまさかの失敗!?
本当ならボタンを押せばカウントアップされるはず。。。
どうやら、稀に良くあるらしいとのこと。
そんな時は一度 Hello World で刺激を与えてみて!ということだった。
ということで、とりあえず Hello World を書き込み。
Hello World は出る。
この後、再度、メインコードを書きこむことで、無事に完了。
どうやら、刺激が足りなかったらしい。
obniz ファン meetup vol.2 に登壇しました
にて、登壇してきました。
経緯
この記事です。
先日、obniz にプルリクを出したのがキッカケです。
そして T シャツをいただきましたので、これは着て行くしかない。
ただ着て一般参加で座っていても格好悪いだろうと、登壇側で立つことにしました。
登壇を決意するまで
プルリクを出した頃、丁度 obniz ファン というグループを見つけました。そこで、なんと meetup vol.2 が開催されるという情報が、しかもまだ登壇者募集中、あと2名残ってる!!
しかし、私は人前で喋るのが苦手です。足は震えるし声は震えるし、とても怖い。ただ、LT 等に登壇する際には とりあえず手を挙げろ!(参加表明しろ) と良く聞きます。さて、悩む。。。 T シャツを着て立ちたいが、果たして話せるのだろうか?しかもいつもの LT よりも長い 10 分の LT。登壇したいけど怖いどうしよう。。。他の登壇者は戦車作るとか言ってるし怖ぇ。。。そんな感じで登壇が決定してもないのに緊張して寝れない。
とりあえずポチる なんて 勇気 は出ず、試しにマインドマップを使って、自分の話したいことはなんだろうか?というのを挙げまくってみた。うーーん。内容が薄い。スライド作りも苦手だし、こんなんで10分持つのだろうか?そんなこんなで2〜3日過ぎてしまい「一般枠満員+登壇枠はまだ1名ある」という情報が流れてくる。
あ、これはやばい、せっかくのチャンスが無くなるかもしれない。グループのコメント欄に登壇表明の文字列を打ち始めた。そして、送信ボタンで再び止まり、1回閉じる。再び とりあえず手を挙げろ という話を思い出し、開く。
そして、もう目を瞑って勢いよくポチる!
そんなこんなで登壇
登壇資料はこちら
動画はこちら
登壇した感想
- メッチャ楽しい!
- 言いたいこと言えた!
- 皆さん優しい!
聞いてくださった優しい皆さまありがとうございました。
準備はとても大変だったけど最初のマインドマップからアウトラインを作って「一番言いたいこと」の為の「前振り」や「流れ」を作ることができました。
まとめ
- 一番緊張したのはポチる前
- とりあえずポチる の気持ちがわかったかもしれない
- リハで時間オーバーして内容削るの大変
- 社内 LT の準備でもそうだったけど黙読だと早口だし。。。
- やったらやったで楽しい!とても良い経験になった!
obniz にプルリクを出した話
先日、obniz にプルリクを出しました。
https://github.com/obniz/obniz/pull/172
そしてマージされ、リリースされました!
https://github.com/obniz/obniz/releases/tag/v2.1.0
本人のスペック
IoT は全然できません。
obniz だからこそLチカやモーターが動かせているようなものです。。。
アノードやカソードも obniz で初めて知りました。
(正確にいうとデジモンのゲームで単語だけは聞いたことありました。)
ずっと C++ や Java(Android) を触っていて、
ここ最近 Web アプリケーション開発に携わるようになり、
Frontend, Backend 等の知識がなんとなく身について来た感じです。
※ちなみにスマホアプリ開発時代は API や Cloud も全くイメージ沸かなかった。。。
何故、プルリクを出そうと思ったか
簡潔にいうと、今までの経歴が C/C++, Java(Android) と来て、
型の無い JavaScript を気持ち悪いと思いつつ、
Web アプリケーション開発で TypeScript を触って JavaScript と少し仲良しになった。
でも、TypeScript で書いていると any
な型がどうしても辛い。
型を作りたくなる病になるわけです。
そんなこんなでやっぱり型が欲しい!
ハンズオンに参加する際は HTML に直接 JS を書くようなコードを書きますが、
自分でコードを整理する際は、やっぱりファイルを分けたりします。
そして TypeScript 化したり Webpack を導入したり・・・。
obniz は、当初 TypeScript を導入しても any
型のまま扱っていました。
ですが、ソースコードを共有したり、時間が経ってから再び触ったりすると型が欲しくなっちゃうんですよね。
どう対応していたかというと、自分のプロジェクト内に interface
を作るだとか hoge.d.ts
とか作って、必要最低限のみで any
型を無理矢理キャストして使う感じです。
import * as Obniz from 'obniz'; interface Obniz { wired(name: string, options: any): any } interface LED { on(): void; off(): void; } const obniz: Obniz = new Obniz('1234-5678'); obniz.onconnect = () => { const led: LED = obniz.wired('LED', {anode: 0, cathode: 1}); led.on(); }
必要分定義して、こんな感じだったりです。
時には index.d.ts とか作ってみたり。
徐々に使用するパーツが増えてくる・・・
IoT には疎いので、ハンズオンで学んだことくらいしか出来ませんが、
百均で「電飾」や「ミニプラレール」を買ってきたりして遊んでいます。
でも HTML で操作するにも API 経由で操作するにもやっぱり TypeScript で書きたい!!
キノコなどの仲間内でも obniz を購入する人が増えたり、
TypeScript を使うようになった人が増え、型定義が無いことが辛みになってくる。
じゃあ、途中まで型定義あるから、
少し定義不足があってもみんなが小さいプルリクをたくさん出せるように
土台だけでも作るか!そんなノリで始めた型定義生活。
型定義と過ごした日々...
一つ目の難関 (new)
トランスパイル後の以下のような形になる定義の仕方...
var Obniz = require('obniz'); var obniz = new Obniz('1234-5678');
試行錯誤を繰り返す。。。
定義1 (NG)
export class Obniz {}
定義が、上記の場合
import * as Obniz from ('obniz'); const obniz = new Obniz.Obniz('1234-5678'); ----- トランスパイル後 ----- var Obniz = require("obniz"); var obniz = new Obniz.Obniz('1234-5678');
となってしまうので違う。
もしくは、
import { Obniz } from 'obniz'; const obniz = new Obniz('1234-5678'); ----- トランスパイル後 ----- var obniz_1 = require("obniz"); var obniz = new obniz_1.Obniz('1234-5678');
となってしまって、違う。。。
定義2 (NG)
export interface ObnizStatic { hello(): void; } declare const Obniz: ObnizStatic; export default Obniz;
axios を真似てこんな感じの定義だと、
import Obniz from 'obniz'; const obniz = new Obniz('1234-5678'); // new できないよエラー
定義3 (OK)
そういえば、Node で Error を作る時に、
new Error()
するし、変わった型定義だったなーと思い、Error の定義を見てみることに。
interface Error { name: string; message: string; stack?: string; } interface ErrorConstructor { new(message?: string): Error; (message?: string): Error; readonly prototype: Error; } declare var Error: ErrorConstructor;
declare
しているのが var
の Error
で型は ErrorConstructor
という interface
new の戻り値で Error interface を返している。。。
new はこうやって定義するんだな!
--
そして、Express は以下のように使うなー。。。
と思って定義を見てみることに。
import * as express from 'express'; const app = express();
定義はこんな感じ。
export = e
...! これか...!!
declare function e(): core.Express; export = e;
そして出来上がったのがこれ。
interface Obniz {} interface ObnizConstructor { new (id: string, options?: ObnizOptions): Obniz; } declare const Obniz: ObnizConstructor; export = Obniz;
二つ目の難関 (wired)
obniz.wired()
は、第一引数のパーツ名に合わせて、戻り値の型が変わります。
これは document.createElement()
を参考にしました。
createElement<K extends keyof HTMLElementTagNameMap>(tagName: K, options?: ElementCreationOptions): HTMLElementTagNameMap[K];
こちらはそれほど迷わずにクリア!
三つ目の難関 (パーツライブラリ)
私は IoT には疎いので、使うパーツは2~3種類です。
Light 系や Motor 系
その辺はまぁ良かったのですが。。。
パーツライブラリの数が多いこと多いこと。
こんなに充実していたとは。。。
公式パーツライブラリ には 63 種類のパーツが載っています。
開発中なのかパーツライブラリに載っていないパーツも少なからずありました。
とりあえず、公式パーツライブラリに載ってないので wired 的にはコメントアウトしておきましたが。。。
途中で挫折しそうになりながらもなんとか。。。
テスト
とりあえず初めの段階で、手元でフォークしたリポジトリを npm install して動作確認。
ts ファイルで LED や DC Motor を動かしてみる。
そして、最後にも同じことをやる。
自分の持っているパーツではこの程度しかテストできないので、
この時点でプルリクを出そうとも考えたが、最低限全体的に型エラーにならないことを確認したい。
実コードには手を入れていなく、型定義だけなのでユニットテストは違う。
どうしようか考えた結果、パーツライブラリに載っている全てのサンプルコードを ts ファイルで記述して型エラーにならなければ良いだろう。と考えた。
とりあえず test ディレクトリ以下に ts ファイルを作って、
パーツライブラリに載っているサンプルコード全ての ts ファイルに記述した。
型エラーになる項目を検出することをテストとしました。
そして型定義を直す。
ざっと15ファイル程度に定義ミスを発見できました。
そしてプルリクに至る。
最後に
思った以上のパーツが対応していて、そして全てサンプルコードがある。
そして、ほぼ全ての I/F を知った。
IoT が疎い私でもパーツライブラリに載っている配線を真似すればなんでもできそうな気がする!
そんな気持ちになりました。
Unity - ブロック崩しチュートリアルで学んだこと
はじめに
本記事は自分の理解のために雑にまとめたもの。
参考 URL
http://tutorial.unity3d.jp/archive/my-first-unity/
http://baba-s.hatenablog.com/entry/2018/01/16/212800
http://baba-s.hatenablog.com/entry/2018/01/16/212900
http://baba-s.hatenablog.com/entry/2018/01/16/213000
第一回
まずは、各オブジェクトの大きさや配置などの設定。
パドルの操作とボールの制御を行う。
壁
Cube
を使って豆腐を「直方体」にして壁を作るGameObject > 3D Object > Cube
- インスペクタビューの
Transform
を使って位置や大きさの調整- Position, Rotation, Scales
カメラ
- シーンビューのカメラの向きを変更する
- シーンビューのカメラだけだとゲームビューは変わらない
Cube
と同じようにTransform
する
自機
- 壁と同じく
Cube
を使って自機となる「直方体」を作成&配置
パドルを操作できるようにする
C# Script
を追加するAssets > Create > C# Script
public class PaddleController : MonoBehaviour { public float accel = 1000; private void Update() { var force = transform.right * Input.GetAxisRaw("Horizontal") * accel; GetComponent<Rigidbody>().AddForce(force, ForceMode.Impulse); } } // Input.GetAxisRaw("Horizontal") により、 // 水平方向 (Horizontal) のユーザー入力を -1 ~ 1 の正規化された範囲で取得している // ユーザー入力はキーボードでもジョイスティックでも OK // ForceMode.Impulse は質量を考慮して動作に反映される
C# Script
をドラッグ&ドロップでPaddle
に設定するAdd Component
した状態と同じになる。
パドルに物理特性を追加する
- インスペクタビューから
Add Component
を押下してRigidbody
を追加するボール(Sphere)
にRegidbody
という機能を追加した感じ
Regidbody
のパラメータを設定する
ボール
- ボールも同じノリで
Sphere
を選択して作成&配置GameObject > 3D Object > Sphere
ボールに物理特性を追加する
- インスペクタビューから
Add Component
を押下してRigidbody
を追加するボール(Sphere)
にRegidbody
という機能を追加した感じ
Regidbody
のパラメータを設定する
ボールに初速度を与える
C# Script
を追加するAssets > Create > C# Script
- GameObject 起動時に速度を与える
public class BallController : MonoBehaviour { public float speed = 10; private void Start() { var force = (transform.forward + transform.right) * speed; GetComponent<Rigidbody>().AddForce(force, ForceMode.VelocityChange); } } // transform.forward はボールの正面 (Z方向) を示す単位ベクトル // transform.right はボールの右方向 (X方向) を示す単位ベクトル // これらを足して Speed を掛け合わせることで右斜めのベクトルを得ている
C# Script
をドラッグ&ドロップでSphere
に設定するAdd Component
した状態と同じになる
ボールをバウンドさせる
今のままだとボールが跳ね返らない
Physic Material
をボールに設定するAssets > Create > Physic Material
Physic Material
は物理パラメータを管理するもの
第二回
ターゲットとなるブロックを作成する
ブロックの作成と配置
- 壁と同じノリで
Cube
を追加してBlock
という名前にする C# Script
をBlock
に追加する
public class BlockController : MonoBehaviour { private void OnCollisionEnter(Collision collision) { Destroy(gameObject); } } // OnCollisionEnter は、Rigidbody で動作しているオブジェクトが接触したときに呼ばれる処理 // 引数の collision には接触対象オブジェクトが入っている // Destroy メソッドで gameObject、 // つまりコンポーネントを実行したオブジェクトつまり接触したブロックを削除している
Block を複製する
Empty
なゲームオブジェクトを作成してBlocks
という名前にするGameObject > Create Empty
- 今回は、ディレクトリ的(グループ化)な扱いに利用する
Blocks
にBlock
をドラッグ&ドロップするBlock
を選択してCtrl + D
で複製- 複製した
Block
それぞれにX座標を設定する Blocks
には Z座標を設定して全てのBlock
を制御する
Blocks を複製する
- 更に
Blocks
を複製して5行6列なブロック群を作る- 複製した
Blocks
にはそれぞれZ座標を設定する
- 複製した
ゲームオーバーの実装
- 下側の壁に
C# Script
を追加する
public class BottomWallController : MonoBehaviour { private void OnCollisionEnter(Collision collision) { Destroy(collision.gameObject); } } // ブロックの時とは異なり、接触対象の gameObject をデストロイしている // つまり、ボールをデストロイしている
第三回
サウンドを付ける
チュートリアル用の *.unitypackage をインポートする
ダウンロードした sound.unitypackage
には、BGM や SE が格納されているので、
Custom Package
としてインポートする。
SE の実装
C# Script
を追加する
public class HitPlaySound : MonoBehaviour { public AudioClip sound; private void OnCollisionEnter( Collision collision ) { AudioSource.PlayClipAtPoint( sound, transform.position ); } } // AudioClip は音を登録する変数 // AudioSource.PlayClipAtPoint にて音を再生 // 音の発生源は第二引数で指定
SE を設定する
壁
- 壁の
GameObject
を選択して、上記で追加したスクリプトをインスペクタビューのAdd Component
へドラッグ&ドロップ - 先ほどインポートした壁の音となる SE ファイルを
C# Script
のAudio Clip
へドラッグ&ドロップ
ブロック
- ブロック全ての
GameObject
を選択して、同様にスクリプトをインスペクタビューのAdd Component
へドラッグ&ドロップ - 先ほどインポートした壁の音となる SE ファイルを
C# Script
のAudio Clip
へドラッグ&ドロップ
パドル
- 上記に同じ
下側の壁
- 4つの壁のうち下側の壁にはゲームオーバー用の SE を設定する
BGM の設定
Main Camera
に BGM を設定する- 選択状態にして
Add Component
でAudio Source
を追加する Audio Clip
に BGM もドラッグ&ドロップ- 音がデカイ場合は
Volume
で調整
- 選択状態にして
ブロックの色を変更
Material
を作成するAssets > Create > Material
Mterial
のカラーを設定する- 全てのブロックを選択して上記で作成した
Material
をインスペクタビューへドラッグ&ドロップ