仮想通貨のやり取りを体感してみよう!

はじめに

みなさんこんにちは。弥生のe-Sportsプレイヤー(自称)の上島です。 この記事は、Misoca+弥生 Advent Calendar 2019の24日目の記事です。

ブロックチェーンのことについて書きたいと思います。

目的

仮想通貨のやり取りを体感することにより、

  • ブロックチェーンとは何だ!!
  • この先はどんなことが起こるのか!!

ということに興味を持つきっかけにしてもらえることです。 まず、触ってみて、その後にいろんな記事を見ると、より理解が進むんじゃないかと!(^-^) (実際の仮想通貨取引所で、取引するわけではなく、自身のパソコン上で実験するだけなのでご安心を(笑))

僕は、ブロックチェーンに詳しいわけでもなく、具体的なアイデアは、なーんにも持ってないですが、なんとなくブロックチェーンが世の中をより良くしてくれるんじゃないか!!と信じてるんです。(今のところ)

ブロックチェーンとは

Wikipediaをご確認ください(笑) ja.wikipedia.org

ただ、ブロックチェーンの詳細は読まなくても、ちんぷんかんぷんでも気にせず進めましょう!

僕が大好きなゲームのキャラである、ガイル少佐が戦う前にいつもカッコいいことを言います。

「御託はいい、はじめよう。」

では、はじめよう!(^-^)/

シナリオ

  1. ヤヨイさんとミソカさんの二人が登場します。 f:id:ym_AdventC:20191216181446p:plain

  2. ヤヨイさんが仮想通貨を稼ぎます。 f:id:ym_AdventC:20191216181508p:plain

  3. ヤヨイさんが稼いだ仮想通貨をミソカさんにプレゼントします。 f:id:ym_AdventC:20191216181405p:plain

用意するもの

  1. Ubuntuの環境
  2. 好奇心(←一番大事!)

ブロックチェーンの体感

環境構築

sudo add-apt-repository -y ppa:ethereum/ethereum

sudo apt-get update
sudo apt-get install ethereum

// ヘルプが表示できるか確認
geth -h
NAME:
   geth - the go-ethereum command line interface

   Copyright 2013-2019 The go-ethereum Authors

USAGE:
   geth [options] command [command options] [arguments...]

VERSION:
   1.9.9-stable-01744997
  • ちょっとしたファイルを作成(ex. /tmp/geth/genesis.json)
{
  "config": {
    "chainId": 15,
    "homesteadBlock": 0,
    "eip150Block": 0,
    "eip155Block": 0,
    "eip158Block": 0,
    "byzantiumBlock": 0,
    "constantinopleBlock": 0,
    "petersburgBlock": 0,
    "ethash": {}
  },
  "difficulty": "1",
  "gasLimit": "8000000",
  "alloc": {
  }
}
  • 初期化
geth --datadir /tmp/geth init /tmp/geth/genesis.json
  • 起動
geth --networkid "15" --nodiscover --maxpeers 0 --datadir "/tmp/geth" console 2>> /tmp/geth/geth_err.log

お!なんか、JavaScript consoleってのが出たぞ!

Welcome to the Geth JavaScript console!

instance: Geth/v1.9.9-stable-01744997/linux-amd64/go1.13.4
at block: 0 (Thu, 01 Jan 1970 09:00:00 DST)
 datadir: /tmp/geth
 modules: admin:1.0 debug:1.0 eth:1.0 ethash:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0

>

ここから先は、JavaScript consoleにて実施!

ヤヨイさんとミソカさんの登録

// アカウント確認(何も登録されていません。)
> eth.accounts
[]

// ヤヨイさん登録
> personal.newAccount("yayoi")
"0xa4fc61a4bab3043b232519719c612e43d872c8c7"

// ミソカさん登録
> personal.newAccount("misoca")
"0xc4bf2220126765f71c66d41d0279df8b24155d50"

// アカウント確認(二人分登録された!)
> eth.accounts
["0xa4fc61a4bab3043b232519719c612e43d872c8c7", "0xc4bf2220126765f71c66d41d0279df8b24155d50"]

(ほんとは、引数はパスワードらしい。)

仮想通貨を稼ぐ

// ヤヨイさんの残高確認(ゼロ!
> eth.getBalance(eth.accounts[0])
0

// ミソカさんの残高確認(ゼロ!
> eth.getBalance(eth.accounts[1])
0

// お金を稼ぐ人の確認(ヤヨイさん)
> eth.coinbase
"0xa4fc61a4bab3043b232519719c612e43d872c8c7"

// お金稼ぎ開始!(マイニング/採掘)
> miner.start(8)
null

// マイニングしてるかな?
> eth.mining
true

// マイニング進んでいるかな?(ゼロは進んでない
> eth.blockNumber
0

> eth.blockNumber
0

> eth.blockNumber
0

// お!マイニング進んだ!
> eth.blockNumber
54

// マイニングを止める
> miner.stop()
null

// 稼ぎの確認(えええ!!!とんでもない報酬が!!
> eth.getBalance(eth.coinbase)
54000000000000000000

// と思いきや単位がおかしいので整えると54etherでした。
// さっきの単位は、wei(1wei = 0.000000000000000001ether)
> web3.fromWei(eth.getBalance(eth.coinbase), "ether")
54

// ヤヨイさんの残高
> web3.fromWei(eth.getBalance(eth.accounts[0]), "ether")
54

// ミソカさんの残高
> web3.fromWei(eth.getBalance(eth.accounts[1]), "ether")
0

仮想通貨をプレゼント

// ヤヨイさんからミソカさんへ30ether送るよ。
// ヤヨイさんのアカウントのロック解除
> personal.unlockAccount(eth.accounts[0], "yayoi")
true

// 送金!
// トランザクションのIDが出た!
> eth.sendTransaction({from: eth.accounts[0], to: eth.accounts[1], value: web3.toWei(30, "ether")})
"0x1b3f9f42680298472615c06df0069040d4fce7f5a699e1384a4125c8beca8c5b"

// トランザクションどうなってるかな?
// blockNumber:null -> ペンディング状態(合意されていない)
> eth.getTransaction("0x1b3f9f42680298472615c06df0069040d4fce7f5a699e1384a4125c8beca8c5b")
{
  blockHash: null,
  blockNumber: null,
  from: "0xa4fc61a4bab3043b232519719c612e43d872c8c7",
  gas: 21000,
  gasPrice: 1000000000,
  hash: "0x1b3f9f42680298472615c06df0069040d4fce7f5a699e1384a4125c8beca8c5b",
  input: "0x",
  nonce: 0,
  r: "0x39849ddf941ca7a8692fbe12a9713c0c482644a783c9890d04bf92fae42962a9",
  s: "0x66cf377744bea5cec28b93af715f725d1f4ac9c0400c0ef0055072c633688736",
  to: "0xc4bf2220126765f71c66d41d0279df8b24155d50",
  transactionIndex: null,
  v: "0x41",
  value: 30000000000000000000
}

// ペンディングになっているトランザクション確認
> eth.pendingTransactions
[{
    blockHash: null,
    blockNumber: null,
    from: "0xa4fc61a4bab3043b232519719c612e43d872c8c7",
    gas: 21000,
    gasPrice: 1000000000,
    hash: "0x1b3f9f42680298472615c06df0069040d4fce7f5a699e1384a4125c8beca8c5b",
    input: "0x",
    nonce: 0,
    r: "0x39849ddf941ca7a8692fbe12a9713c0c482644a783c9890d04bf92fae42962a9",
    s: "0x66cf377744bea5cec28b93af715f725d1f4ac9c0400c0ef0055072c633688736",
    to: "0xc4bf2220126765f71c66d41d0279df8b24155d50",
    transactionIndex: null,
    v: "0x41",
    value: 30000000000000000000
}]

// 取引の正当性を合意するために、マイニングだー!
> miner.start(8)

// 合意された!(空っぽになったから)
> eth.pendingTransactions
[]

// ミソカさんの残高が増えた~!
> web3.fromWei(eth.getBalance(eth.accounts[1]), "ether")
30

// トランザクションを確認してみましょう。
// ブロックがつながった!(blockNumber:に値が!)
> eth.getTransaction("0x1b3f9f42680298472615c06df0069040d4fce7f5a699e1384a4125c8beca8c5b")
{
  blockHash: "0x485681549c3bfe644b8e89062f733f362884232a7299d3cb92be4056e735b091",
  blockNumber: 28,
  from: "0xa4fc61a4bab3043b232519719c612e43d872c8c7",
  gas: 21000,
  gasPrice: 1000000000,
  hash: "0x1b3f9f42680298472615c06df0069040d4fce7f5a699e1384a4125c8beca8c5b",
  input: "0x",
  nonce: 0,
  r: "0x39849ddf941ca7a8692fbe12a9713c0c482644a783c9890d04bf92fae42962a9",
  s: "0x66cf377744bea5cec28b93af715f725d1f4ac9c0400c0ef0055072c633688736",
  to: "0xc4bf2220126765f71c66d41d0279df8b24155d50",
  transactionIndex: 0,
  v: "0x41",
  value: 30000000000000000000
}

// 無事に取引がブロックのチェーンに追加されました!

f:id:ym_AdventC:20191218165936p:plain

以上のように、

発生した取引が、あるルールに則り合意され、合意された取引はブロックとしてチェーンのようにつながっていく。

そしてその取引の内容は確認できて、改ざんできない!と言われている。

まとめ

いかがでしたか? 動かすだけならすごく簡単でしたね!!(といいつつ、動作確認するのにちょっとハマってたのは内緒です(笑)) ただ、裏側で使われている技術やアイデアは、非常にすごそうです。

テクノロジーって本当に興味深いですね!

僕もこれを機にブロックチェーンの理解を深めたいと思います!

では、いよいよ、明日はラスト! @kokuyouwindさんの「勉強会をtsudaる技術」です!チームワークのチェーンを繋ぎます!

あとがき

今回は、ブロックチェーンのプラットフォームとして、イーサリアムを利用しました。 本当は、NEMで表現したいなーと思って調べてみたんですが、サンプルが見つけられず、断念しました(笑)

ブロックチェーンと一言でいっても、色々な思想をもつプラットフォームがあって興味深いです。 それぞれのプラットフォームの思想を最も反映していることの一つが「コンセンサスアルゴリズム」ではないでしょうか。 コンセンサスアルゴリズムとは、「この取引ってOKだよね!?」って合意形成方法のようです。 それぞれメリットデメリットがあるようですし、どれが一番優れている!とかはないのかもしれないですね。

我々が解決したい問題がブロックチェーンで解決できそうなのであれば、

  • 本当にブロックチェーンで解決できるのか
  • 解決できるならどのプラットフォームを使えば良いのか
  • プラットフォーム利用しながら、どのようなシステム構成にすればいいのか

みたいなことを議論していきたいなーなんて妄想しています(笑)(もちろん、議論だけじゃなく実装もね!

さてさて、長くなりましたが、ブロックチェーンに興味を持ってくれる人が増えたらうれしいです!

最後に、

量子コンピューターが来たらブロックチェーンどうなるんだろーーーー!!

おわり

Electronアプリの画面側をWebに配置する

こんにちは。弥生の内山です。
この記事はMisoca+弥生 Advent Calendar 2019 22日目の記事です。

はじめに

Electronでアプリを作っています。
弊社のイベントでも、なんどかそのお話をしています。
(本記事は、直近の12/19の回で発表した内容をベースに加筆したものになります)

Electronのアプリは、大きく分けて以下の2つのパートで構成されています。

  • Main側:Node.jsのプロセス。OSの機能を呼び出したり、Renderer側を起動したりできる
  • Renderer側:Chromiumによる画面描画のプロセス。要するにブラウザなので、HTML+JS+CSSを用いて画面を描画することができる

Renderer側は、ブラウザと同様に、HTMLファイル(とJS, CSSファイル)を読み込んで画面描画を開始するのですが、このHTMLは、アプリ内に同梱したものだけでなく、Webに配置したものを読み込むことが可能です。

WebにHTML, JS, CSSを配置すると何がうれしいかと言うと、アプリに何か修正を行いたい場合、Renderer側の修正だけであれば、修正したバージョンをユーザーにインストールしてもらうことなく、修正が全ユーザーに反映されるということです。
要するに、インストール型アプリでありながら、部分的にWebアプリのようなリリースの利点が得られるということです。

我々のアプリは、当初はRenderer側のファイルもローカルに保持する構成で開発していたのですが、途中から上記のようなメリットを得るために、Renderer側をWebに配置する構成への変更を行いました。
この変更が、思ったよりも大変だったため、具体的に何を考え、どのような変更を行ったのかをまとめたのが、本記事の内容となります。

やったこと

Same Origin Policyを回避する

Same Origin Policyは、ブラウザで読み込んだページが属するオリジンのみからしかリソース取得を行えない、という制約です。
詳細は、以下のサイトをご覧ください。

developer.mozilla.org

要するに、ブラウザ上からは、ドメインが違うサイトへのHTTPリクエストは発生させられない、ということです。

Renderer側のファイルをアプリ内に同梱していたときは、ブラウザ的にはファイルリソースへのアクセスなので、Same Origin Policyが発動することはありませんでした。
しかし、Webからファイルを読み込む場合は、この制約が発生してしまいます。

これにより何が困るかと言うと、Renderer側からWebAPI等へのアクセスができなくなるということです。
本アプリでは、認証などのためにWebAPIを叩く必要があったため、これは困ります。

そこで、本アプリでは、HTTPリクエストを発生させる元を全てMain側に移しました。
Main側では、ElectronのnetモジュールNode.jsのhttpモジュール、あるいはaxiosに代表されるようなHTTPクライアントライブラリを使うことができます。

Renderer側からは、ElectronのIPCを通じて、Main側のHTTP呼び出し機能にアクセスします。

例えば、Main側はIPCで"http"というメッセージを受けたら、HTTPリクエストを行うようにしておきます(httpRequestはHTTPリクエストを行う関数です)。

ipcMain.on("http", async (event, message) => {
  event.returnValue = await httpRequest(message);
});

そして、preloadスクリプトに上記のIPC呼び出しを行う関数を定義しておき、Renderer側ではこの関数を呼ぶことで、HTTPリクエストを行うようにします。

global.httpRequest = (message) =>
  ipcRenderer.sendSync("http", message);

この変更により、Same Origin Policyは回避できました。
これによる副次的な効果として、Webに公開しているコード内に、アクセス先のURLや、WebAPIに渡すトークン等のパラメータを埋め込む必要がなくなったので、セキュリティ的にもよかったと思います。

ローカルでの動作確認用にWebサーバーを立てる

開発中のローカルでの動作確認時に、Renderer側はどこにあるファイルを読みに行くべきか、は少し悩みました。
Node.jsでのアプリ開発ではNODE_ENV環境変数で動作モードを切り替える、という手法がよく使われるので、developmentモードを指定した場合はローカルにあるファイルを、productionモードを指定した場合はWebに配置したファイルを読む、というようなことは少し考えました。
しかし、これは以下の理由により避けました。

  • Rendererはローカルファイルを読む場合とWebから読む場合とでは動作が異なる(前述のSame Origin Policyなど)ため、日常的にWebから読む状態で開発しないと、いざリリースするときに想定していなかった問題が発生する恐れがある
  • developmentモードかproductionモードかは、ファイルをどこから読むかとは別問題

というわけで、開発中でもWebサーバーを立ててファイルをホストさせ、Renderer側はそれを読み込みに行くようにしました。

Webサーバーを立てるツールは、以下のようにしました。

  • developmentモードの場合:webpack-dev-server
  • productionモードの場合:http-server

webpack-dev-serverは一般的なフロントエンド開発でもよく使われるツールです。hot-reloadを有効にすれば、Electronであってもコードの変更時に自動的にリロードされるため、便利でした。

http-serverは、Node.js製の、手軽にWebサーバーを起動できるCLIツールです。

www.npmjs.com

productionモードの場合、実際のリリース物と同じビルドとなるため、webpack-dev-serverを使うのは適切ではありませんでした。
代わりに、webpack-dev-serverと同様にコマンドで起動して手軽に使える、http-serverを採用しました。

ローカルでの動作確認用にアプリとWebサーバーを同時に起動する

前述のように、開発中であってもWebサーバーを立てる構成としたので、動作確認の際には、ElectronアプリとWebサーバーの両方を起動させる必要があります。 ElectronもWebサーバーも、プロセスが端末を占有してしまうので、それぞれを起動させておくために端末を2つ立ち上げておく必要があります。
しかし、このような操作が必要な場合、以下のようなミスが発生しやすくなります。

  • なぜか動かないと思ったら、Webサーバーが起動していなかった
  • なぜか動かないと思ったら、Webサーバー側でエラーがでているのに気づかなかった
  • ElectronとWebサーバー、両方の再起動が必要なのに、それを忘れ、うまく動かなかった

いずれも些細な問題ではありますが、発生頻度がそこそこ高く、開発速度の低下につながるため、早めに対処しておきたいところです。

どのように対処するかというと、要するに以下のようなことが実現できていればよいと考えました。

  • コマンド一発でアプリとWebサーバーが両方起動すること
  • アプリを終了したら、Webサーバーも終了すること

上記を実現するため、今回はConcurrentlyというCLIツールを利用しました。

www.npmjs.com

このツールは、複数のコマンドを並行して実行できるため、この問題の解決にピッタリです。
このConcurrentlyを使い、アプリの起動コマンドを以下のように作成しました。

concurrently -k “run_server” “run_app” || exit 0 

上記のコマンドでのポイントは以下です。

  • -kオプションを付与すると、起動したいずれかのプロセスが終了すると、他のプロセスも終了するため、アプリを終了したらWebサーバーも終了させることができる
  • -kオプションによる終了はエラー終了扱いになり、エラーが出力されて気持ち悪いので、exit 0を直後に実行して、終了コードを強制的に正常終了にする

このようにすることで、Webサーバーの存在をほとんど意識せず、アプリの動作確認を行えるようになりました。

アプリからの参照先Web環境を切り替える

一般的なWebアプリを開発する場合、開発/ステージング/本番のように、用途ごとに環境を使い分けることはよく行われます。
Webアプリの場合は、ブラウザに入力するURLをそれぞれの環境のものに切り替えれば済むのですが、Electronアプリはアプリ内に参照先のURLを持たせなければならないため、Webアプリほど簡単に環境を切り替えることができません。

Electronアプリが参照するURLを切り替える方法を考えたとき、真っ先に思いつくストレートな方法としては、設定ファイルにURLを記載し、アプリはそれを参照してURLを取得する、というものがあります。
しかし、これは以下のような理由で避けることにしました。

  • ユーザーによって値を改変されたくない:もしユーザーがファイルの内容を書き換えたりしてしまった場合、アプリが動作しなくなる恐れがあります
  • ユーザーが普通に見える場所に値を置きたくない:URLや各種パラメーターが見えることで、アプリへの攻撃を行うヒントになってしまうかもしれません

ただ、個人的にはそもそも環境の値が可変値なのがしっくりこなかったのが理由としてあります。アプリ本体とWeb側は一体のものであり、Web側はパラメータとして気軽に差し替えするようなものではないと考えました。

結果として、アプリをビルドする際に、Web側の環境を埋め込むことにしました。
以下に、環境を決定する仕組みを示します。

まず、ビルドを行うコマンドを実行する際に、環境変数で参照先の環境を指定します。
ここでは、DEPLOY_ENVという環境変数で、環境指定を行っています。

DEPLOY_ENV=development npm run build

アプリのコード内では、上記の環境変数で指定された値に対応する環境設定ファイルをrequireするようにします。
環境変数は、WebpackのDefinePluginを用いてビルド時に埋め込みを行っています。

require(`./${DEPLOY_ENV || "development"}`)

以上の仕組みにより、ビルド時に例えば"development.js"のようなファイルが結合され、アプリ内に環境の値が埋め込まれるようになります。

参照先Web環境を上書きする

前述の仕組みにより、参照先の環境の問題は解決したと思ったのですが、開発工程の中で「本番環境向けのビルドを開発/ステージング環境へ向けるようにしてテストしたい」という要望があることがわかりました。
要するに、本番環境向けビルドと開発環境向けビルドは、同じソースからビルドしていても別物なので、開発環境向けビルドをテストしても、本番環境向けビルドをテストしたことにはならない、ただし本番環境でテストすることは避けたい、という理屈です…。

これを解決するため、特定の位置に設定ファイルがあれば、そこに記載された値をアプリに埋め込まれた設定値よりも優先する、という機構を追加しました。
先ほど「設定ファイルを避けた」と述べましたが、これは開発中のリリース前テスト等の工程で利用するものであり、ユーザーが使う機構ではないため、設定ファイルを回避した理由は維持しているつもりです(;・∀・)
なお、弥生の他の製品でも、実際にこのような設定の上書きを行うような機構を使ってテストを行っています。

おわりに

ElectronアプリのRenderer側をWebに配置するようにする際、どのような変更を行ったかについてご紹介しました。
同様のことでお困りの方の助けになれば幸いです。

明日は@t_haraさんの「Swift製ファミコンエミュレータ開発の進捗について書く」です。楽しみですね!

Aeroで手軽にARする話

🎄🎅🎄🎅🎄🎅🎄🎅🎄🎅🎄🎅🎄🎅🎄🎅🎄🎅🎄🎅🎄🎅🎄🎅🎄🎅
この記事は Misoca+弥生 Advent Calendar 2019 の21日目エントリーです。
🎄🎅🎄🎅🎄🎅🎄🎅🎄🎅🎄🎅🎄🎅🎄🎅🎄🎅🎄🎅🎄🎅🎄🎅🎄🎅

こんにちは、弥生のヨコヤマです。
最近入社したばかりのぺーぺーUI/UXデザイナーです。
弥生はデザイナーが少なく、開発本部社員全体の1%強です。
ガチャでいうと★5が出るくらいの確率です。SSRです。そのため、初めて日本に来たパンダのような感じであたたかく見守られています。やさしい世界。

ところでみなさんはAR好きですか?
日本語では拡張現実と呼ばれているアレです。私は好きです。ARもVRも好きです。
サンタさん今年のクリスマスはOculusください。
ARはたくさんの可能性を秘めています。AppleやMicrosoft、Googleと有名企業もこぞって取り組んでいるところを見るに、その勢いは弥増しているように思われます。
購入前の家具を部屋に置いた時のイメージを把握できたり、晴れた空にクジラを泳がせてみたり、もしかしたら、思い出せないあの人の名前を頭上に表示してくれたりなんてことも可能になるかもしれません。

f:id:ym_AdventC:20191220113407j:plain:w400
空を泳ぐクジラ見た~い🐳

そんなARコンテンツを自分の手でで作れたら最高だと思いませんか?思います。
「でも、ARってプログラムとか3Dモデルが必要だったり難しいんでしょ?」とお思いのそこのアナタ。かつての私もそうでした。しかし、Aeroなら気楽に手軽にARが楽しめるんです!すごい!ありがとう!👏

Aeroってなんすか

Adobe Aero

Adobe Aero

  • Adobe Inc.
  • 仕事効率化
  • 無料
apps.apple.com AeroはPhotoshopやIllustratorなどでおなじみの、Adobeが開発したARツールです。
今年のAdobe MAXで発表され話題を集めました。
以前よりAdobeがARに注力していることは知られていましたが、満を持してお披露目されたというわけですね。そんなAeroさんですが、何がステキなのか。その理由を以下に記します。

Aeroさんのここがすごい

無料

無料です。「Creative Cloud契約してるから実質無料」とかではなく、混じりっけなしのピュアな無料です('19/12/21現在)。iOS 13.1以降にアップデートされているデバイスをお持ちの方なら、誰でも利用することができます。いきなり入口が絞られた感じがしますが、iPhoneシェア率が異常に高い日本人にはそこまで高くないハードルではないでしょうか。多分。

コーディングスキルが必要ない

これこそが人々をARコンテンツ制作から遠ざけていた一番のハードルではないでしょうか?Aeroでは一切のプログラミングが不要です。アプリ画面を数回タップするだけであっという間にARコンテンツができあがります。

デザインスキルも必要ない

逆にデザインスキルがなくて、「自分で素材を作れないよ(><)」という方も大丈夫。Aeroには結構な数の「スターターアセット」が用意されていて、すべてロイヤリティフリーです。使いたいモデルを選んで、あとはアプリ画面を数回タップするだけであっという間にARコンテンツができあがります。

f:id:ym_AdventC:20191219193515j:plain
アセットたくさん!ここで紹介してるのはほんの一部です。アニメーション付きのアセットもあります。

サルでもわかるUI

わざわざ天丼してまでお伝えした通り、何も分からなくても数回タップすればとりあえず作品ができてしまうくらい直感的なUIです。何しろシンプル。サーフェス設定後の初期画面では、重要そうなボタンは1つしか見当たりません。「とりあえずそれを押す」以外の答えを導き出せるならむしろ教えてほしい。おサルさんでも使えますね。

f:id:ym_AdventC:20191219193636j:plain:w200
シンプル~~!青いボタン1個しかないもん。とりあえず押すよね!🐵

チュートリアルが手厚い

残念ながら使い方が分からなかったみなさん、ご安心ください。手厚いチュートリアルがあります。アセットの配置からスタートして、一般的な制作手順に乗っ取って進んでいくので、全体の流れも掴みやすいです。長すぎず短すぎず、しかしながら要点を抑えたコメントも随時出てくるので、きっと迷いも少なく次へ進めることでしょう。

f:id:ym_AdventC:20191219193728j:plain:w200
私はサル以下だったので大変お世話になりました。

お前もARにしてやろうか!

さて、Aeroの概要を把握したところで実際にARしてみましょう。 AeroではDimensionをはじめとして、Adobe製品のファイルを多くサポートしています(もちろんヨソで作った子も読み込めます)。ARなので派手に3Dモデルを使いたい気持ちもありますが、10年以上モデリングなんてしてないし時間もないので、今回はPhotoshopで作ったネコチャンのデータを使いたいと思います。2Dなのでペラペラです。良く言うとナニッパラッパーです。

Aero用のpsdファイルを書き出す

ネコチャンこと「nekochan.psd」は1枚のレイヤーで構成されているファイルです。

f:id:ym_AdventC:20191219193835j:plain:w100

まずPCでPhotoshopからAeroで読み込めるファイル形式にします。

f:id:ym_AdventC:20191219193906p:plain:w200

[ファイル] > [書き出し] > [Aeroに書き出し]
これだけです。これをモバイルデバイスのAeroで読み込むことになるので、Creative Cloudファイルにしておくと後々ラクチンです(その他の方法でもモチロン読み込めます)。
※[Aeroに書き出し]は最新のデスクトップ版Photoshop(バージョン21以降)のみに搭載されている機能です。iPad版ではできないのでご注意ください。

Aeroに読み込む

舞台をモバイルデバイスに移し、Aeroに今作ったpsdファイルを読み込ませます。Aeroで[新規作成]し、サーフェスを設定後左下の青丸ボタンをタップ、[Creative Cloud]から「nekochan.psd」を選択します。

f:id:ym_AdventC:20191219195332j:plain

無事ネコチャンが世界に顕現しました!1本指操作でX軸・Z軸の移動、2本指操作で拡大縮小・回転、3本指操作でY軸の移動ができます。配置場所を決めたら、アセットをタップして終了です。

インタラクティブ機能をつける

最後にインタラクティブ機能を追加しましょう。アセットをタップして、出てきた下部メニューの[動作]をタップします。そこからまずトリガーを選択します。トリガーには3種類あって、それぞれ開始時、タップ時、指定した距離に侵入した時にアクションが開始します。

f:id:ym_AdventC:20191219195419j:plain

アクションにはたくさん種類があるのですが、今回はトリガー:タップ、アクション:バウンスを選択します。いい感じのバウンスになるように各種数値を調整。納得できる動きになったら、もう一度アセットをタップして完了です。

完成

ショボいですがとりあえず完成です。上部メニュー右のプレビューをタップすると、実際の動作を確認したり、画面を撮影したりできます。初めてなのでファイルの書き出しを失敗したりもしましたが、それを含めても30分くらいでここまでたどり着けました。う~ん、簡単!

f:id:ym_AdventC:20191219195457g:plain
タップするとネコチャンがピョンピョンします。活きのいい猫だ。

実は複数レイヤー読み込める

ちなみにpsdファイルですが、複数レイヤーを保持したままAeroに読み込むことができ、読み込んだレイヤーを等間隔に配置することができます。
これだけだとピンとこないと思うので早速やってみましょう。ここではネコザイルのデータを使います。ネコザイルこと「nekoxile.psd」は以下の5枚のレイヤーで構成されています。

f:id:ym_AdventC:20191219195611j:plain

[Aeroに書き出し]をクリックすると、レイヤーをフラット化するか保持するかのダイアログが出てくるので[保持]を選択します。これでpsdファイルの準備は完了です。次にAeroに読み込みます。以下が読み込んだ直後の「nekoxile.psd」です。



レイヤーが多層的に配置されているのが分かります。しかし、このままではギュウギュウに詰まっていて、ネコザイル達が息苦しそうです。なので、ここでアセットをタップして、複数レイヤー情報を持つアセットのみに表示されるメニュー[レイヤー]をタップします。X軸・Y軸・Z軸それぞれの調整スライダーが表示されるので、Z軸を広げてやります。



すると……



程よく距離感ができて、いい感じのファンファンウィーヒッタステーッステーになりましたね。ちなみに縦並びや横並びにもできます。

f:id:ym_AdventC:20191219201720j:plain
タテザイルとヨコザイル

作ってみた

というわけで、今回得られた知見を駆使してARクリスマスディスプレイを制作してみました。



思ったところに配置できなかったり、考えていたものと違うアクションになったり、見た目の華やかさと裏腹に地味で地道な作業が目白押しです。けれど、自分の空想でしかなかったものが形を成して日常空間に浮かび上がっていく過程はとてもワクワクできる時間だと思います。これを見て「自分もARはじめよっかな」と興味を持ってもらえたら幸いです。

ちなみにお使いのiOS端末(13.1以降)で実際にご覧いただけるので、よろしければこちらのQRコードからお楽しみください。

f:id:ym_AdventC:20191219203906p:plain:w300
https://adobeaero.app.link/V2VLwYWPx2

まとめ

直感的なUIで、コーディングスキルが0でもサクサクARコンテンツが作れちゃうAdobe Aero。すでにデスクトップ版もプライベートベータとしてリリースされていて、これからの展開もとても楽しみです。私も今回の知見を活かし、弥生会計ARの開発に取り組んでいきたい所存です嘘です。
今回Aeroを通してARについても少し詳しくなれたので、次は若干上級者向けと噂のReality Composerにも挑戦してみたいですね。

次回、Misoca+弥生 Advent Calendar 2019 の22日目は、uchoさんです。
震えて待て!

それではみなさんハッピーホリデーよいお年を。