PSVRを買った
予約しようとしたら予約開始早々にどこも売り切れになってしまったので、Amazon.co.uk(イギリス)で予約した。
到着は10/20予定となっていたけれど、発売日(10/13)に発送され10/17に届いたので、割とすぐに手元に来た感じ。
価格は42,240円(290.83ユーロ)で買えたので、定価48,578円に比べると結構安く買えた。
梱包が大きい。開けてみたらPSVR本体が結構大きかった。
電源ケーブルの形状が海外仕様だったので、家にある別のケーブルを付け替えた。それ以外は説明書が英語なくらいで、問題なく動作した。
付属のdemoをやってみて、あとは評判の良いRez Infiniteを購入してやってみてる。まだArea Xをちゃんとプレイできていないので、Rez Infiniteの感想はまた今度。
ディスプレイの解像度はドットが視認できるので気になるといえば気になる。シネマティックモードで映画を観ると大画面の迫力は素敵である反面、たまにドットが気になって没入感が薄れることがある。
ジャイロセンサー、加速度センサーやリフレッシュレートなどは今の所気になるところはなく、自分の動きにしっかり追従してくれていると感じる。音もちゃんと自分の位置、向きに対応していて臨場感がある。
接続ケーブルや端末が多くて辛いけれど、PSVRに対応した大御所ゲームの発売が待ち遠しい。
音楽のレコメンド機能を作るには音源の解析が必要に思う
Apple Musicなどのアプリでレコメンドされる音楽はなかなか好きに出会えない。
人によるだろうけれど、音楽は好き/嫌いと感じるポイントが非常に細かくあり、ちょっと違うとあまり好きではないものになる。
例えば、僕はDream Theaterが好きだけど、プログレッシブ・メタルというジャンルだけで好きに出会うことはほとんどない。Dream Theaterが好きな理由を列挙すると
- 音色/和音/旋律/展開/テンポなどが基本的に好み
- 歌にメロディーがある方が好き
- 綺麗に歌うボーカルが好き
- 和音が感じられる楽曲が好き(必然とキーボードの音がある楽曲の方が好き)
- 一塊のメロディーがたまたま変拍子であった、と感じられるような変拍子が好き(ランダムに切り取られたような激しすぎる変拍子は嫌い)
- 速い奏法を生かしたソロフレーズが好きだが、緩急がなくずっと速いだけであったり、メロディー性が薄いソロは嫌い
- ドラムやベースに繰り返しパターンが少なく聴き飽きないリズムが好き(特にポートノイ時代)
- 楽曲としても繰り返しが少なく展開するものが好きだが、旋律が頭に残らないほど展開しすぎると嫌い
- ヘビーなサウンドが好きだが、ドンシャリだったり低音を強調しすぎていると嫌い
キリがないけれども、こういう細かいポイントがいろいろあって好きなのであって、とあるジャンルが好き、というのでは全然ない。
また、上はDream Theaterが好きな理由であって、例えば、たかじんの歌が好きな理由は全く異なる。
こうしたことを考えると、好きな(好きそうな)音楽を提案するプログラムを作るのであれば、音源を解析し一つ一つの音楽がどういう情報を持っているのかを把握できないと難しいだろうなと思った。
Symfonyから手早くYAMLのFixtureを読み込めるAliceFixturesBundle
この記事は Symfony Advent Calendar 2015 の4日目の記事です。
開発環境向けのテストデータ(Fixture)作成は hautelook/AliceBundle を使えば便利だけど、テストコードからFixtureを読み込もうとすると一手間かかるので、何かないものかと探したところ h4cc/AliceFixturesBundle に出会った話。
データベースを利用したテストコードを書く場合、テストデータの準備が必要になることが多い。 「テストコードを書く労力を減らす」「テストコードの見通しを良くする」という観点から、テストコードのためのデータ準備は極力簡単にしたいところ。
Symfony + Doctrineを利用している場合に真っ先に選択肢に上がるものとして DoctrineFixturesBundle があるけれど、見ての通りFixture自体がPHPコードであり、テストデータの準備に苦労が絶えない。
そこで登場するのが nelmio/alice を利用できる hautelook/AliceBundle で、これについては去年の Symfony Advent Calendar 2014 の記事である [Symfony] AliceBundleで自動テストのfixtureをyml化しよう が詳しい。すごくわかりやすいのでご一読を。
どういうYAMLになるかというとこういう感じ。
AppBundle\Entity\User: user{1..10}: username: <username()> fullname: <firstName()> <lastName()> birthDate: <date()> email: <email()> favoriteNumber: 50%? <numberBetween(1, 200)>
これで10件のuserが作成され、それぞれにFakerを利用したランダムな名前や誕生日、メールアドレスなどが設定される。
PHPコードでテストデータを用意する苦労からは解放されたものの、まだ面倒な点があり、先に紹介した [Symfony] AliceBundleで自動テストのfixtureをyml化しよう から引用させていただくと、
<?php $this->loadFixtures( array( new UserFixtureLoader(), ) );
このように一つのFixtureごとにPHPのクラス(ここではUserFixtureLoaderのこと)を作らなければならない。これは結構面倒だ。
それで色々と探していたところ h4cc/AliceFixturesBundle を発見した。DoctrineFixturesBundle に依存しないため、より簡潔なFixtureの読み込みを実現している。
具体的な実装はデモのテストコード、AliceDemo/src/h4cc/AliceDemoBundle/Tests/Controller/UserControllerTest.php を見るとわかりやすい。
抜粋すると、
<?php public static function setUpBeforeClass() { $client = static::createClient(); $manager = $client->getContainer()->get('h4cc_alice_fixtures.manager'); static::$fixtures = $manager->loadFiles(array(__DIR__ . '/DataFixtures/Alice/alice.yml')); $manager->persist(static::$fixtures); }
こういう感じで直接AliceのYAMLを指定するだけとなっており、Loaderクラスを作成する必要がなく大変便利。
ということで、 h4cc/AliceFixturesBundle の紹介でした。なんと Symfony Advent Calendar 2015 の次の日、12/5はまだ空いているので、どなたかよろしくお願いします!
「フラットデザインで考える 新しいUIデザインのセオリー」を読んだ
- 作者: 宇野雄
- 出版社/メーカー: 技術評論社
- 発売日: 2014/11/21
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (2件) を見る
Modern UI 、Material Design、iOSなど、フラットデザインを冠するUIの違いを比較しながら、みんながざっくり呼んでいる「フラットデザイン」の正体を概観しつつ、それを踏まえてこれからのUIデザインを考えるための基本的な考察を提供するような感じになっている。
概観している部分の一例としては
つまり人が触るパーツを丸く、それ以外の要素をすべて 角のある矩形で構成するのです。これはGoogleが非常にうまく実現している手法です。
フラットデザインで考える 新しいUIデザインのセオリー P84
例えばiOS 7以降のiOSでは、基本のキーカラーを水色と定めて、水色になっている部分はすべて押せるパーツというルールを作り、その他の色を基本的に排除しました。
フラットデザインで考える 新しいUIデザインのセオリー P109
こういう感じで、それぞれどのようなアプローチでフラットデザインを実現しているのかを具に解説している。世の中的にはどうしてもiOSとAndroidにフォーカスしがちなところを、Windowsやフラットデザイン的なウェブサイトなど、幅広く扱っているところが良い。
フラットデザインの特徴を踏まえつつ、これからのUIデザインを考えるための考察として、配色、余白、フォント、各種UIパーツ(ボタンやチェックボックスなど)の表現手法など、フラットデザインに触れつつ解説されている。
最近、我々がよく見るソフトウェア上のUIデザインを改めて解説されてみる、というテーマとして良書だと思う。案外気付けていなかった部分や、普段自分が使っていないOSのデザイン手法など、なるほどなーと思うところが多かった。
UnityのWWW、WWWFormのハマりどころ
UnityにバンドルされているWWWクラスを使うと簡単にHTTP通信を行うことができて便利なのだけど、色々やろうとするといくつか判り難い挙動があったので、その辺りをメモ。
Unityのバージョンは4.5。
WWWのコンストラクタには下記の4つ(最後のものは非推奨)がある。ドキュメントはUnity - Scripting API: WWW.WWW。
- WWW(string url);
- WWW(string url, WWWForm form);
- WWW(string url, byte[] postData);
- WWW(string url, byte[] postData, Dictionary
headers); - WWW(string url, byte[] postData, Hashtable headers); // deprecated
ここでまず気をつける必要があるのが、WWWFormクラスをそのまま渡す場合は、第三引数にHTTPヘッダを渡すことができない点。下記、ここから引き起こされるハマりどころ。
ファイル添付したらヘッダを追加できない?
WWWForm.AddBinaryData() を使うとファイルアップロードが可能だけど、HTTPヘッダも同時に変更したい場合に困ったことになる。
Dictionary<string, string> headers = new Dictionary<string, string>(); headers.Add("Cookie", "a=b"); WWForm form = new WWWForm(); form.AddBinaryData("foo", binary, "foo.png", "image/png"); WWW www = new WWW("http://example.com/", form.data, headers);
このようにすると正しくファイルアプロードができない。ここでHTTPヘッダを変更せずに WWW(string url, WWWForm form); コンストラクタを利用すると正しく動作するようになる。
WWForm form = new WWWForm(); form.AddBinaryData("foo", binary, "foo.png", "image/png"); WWW www = new WWW("http://example.com/", form);
ということは、コンストラクタの第二引数がformそのものではなくform.dataなのが駄目で、WWWFormインスタンスだから動作するのか、と結論付けてしまうとヘッダの変更ができなくなってしまう。
実際にはそうではなくて下記の挙動が考慮できていないことが原因。
- WWW(string url, WWWForm form); コンストラクタを利用するとヘッダは内部でWWWForm.headersの値が利用される。
- WWWForm.AddBinaryData() を呼び出すとWWWForm.headersにContent-Typeが自動的に追加される。
- 実際の値は multipart/form-data; boundary="xxxx"' という感じ
つまり、WWWForm.AddBinaryData() 後に追加されているContent-Typeヘッダの存在を無視して自前のヘッダのみを追加したことが原因なので、下記のようにWWWForm.headersを値を最後に設定するようにすれば動作するようになる。
Dictionary<string, string> headers = new Dictionary<string, string>(); headers.Add("Cookie", "a=b"); WWForm form = new WWWForm(); form.AddBinaryData("foo", binary, "foo.png", "image/png"); foreach (DictionaryEntry entry in form.headers) { headers[System.Convert.ToString(entry.Key)] = System.Convert.ToString(entry.Value); } WWW www = new WWW("http://example.com/", form.data, headers);
GETだとHTTPヘッダを追加できない?
WWWクラスはコンストラクタ呼び出し時にWWWForm、もしくはpostDataが存在するとPOSTと解釈するようになっている。POSTの場合は単に第三引数にヘッダのDictionaryを渡せば良いが、GETの場合は適切なコンストラクタがない、ように見えるけれど、nullを渡せばGETでもヘッダを追加できる。
WWW www = new WWW("http://example.com/", null, headers);
POSTでpostDataがない場合はHTTPヘッダを追加できない?
応用編。POSTにも関わらず、POSTするデータはない。けれどもHTTPヘッダを追加したい。みたいな場合はどうしようもないので
form.AddField("dummy", "dummy");
とでもするしかないと思われる。postDataが空の場合は下記エラーになる。
Error when creating request. POST request with a zero-sized post buffer is not supported.
GET、POSTだけではなくPUT、DELETEも使いたい
使えない。上述のように、GETとPOSTが自動判定されるような機構で、PUT、DELETEはサポートされていない。
そういうわけでWWW用の便利なクラスを書いた
こういったハマりポイントを解決しつつ、もう少し楽にWWWとWWWFormを使いたいと思って、一つクラスを書いたのでGistに貼っておいた。
特徴としては
- コルーチンを使わないでコールバック(Delegate)で終了後の処理を書ける(内部ではコルーチンを使っている)
- タイムアウトをサポート(地味に必要ですよね)
- 上述の複雑なコンストラクタのハマりどころをできるだけ解決
タイムアウトに関してはDEBUG.LOG (WWWクラスのタイムアウト処理)を参考にさせてもらいました。
使い方は下記な感じ。
using WWWKit; public class WWWClientExample : MonoBehaviour { void Start() { // 単純なGETリクエスト。終了処理はOnDoneプロパティにDelegateを代入。 // DelegateにはおなじみのWWWクラスが渡されるのでレスポンスに関する // 処理は今まで通りWWWクラスのノウハウが利用可能。 WWWClient client = new WWWClient(this, "http://example.com/"); client.OnDone = (WWW www) => { Debug.Log(www.text); }; client.Request(); // POSTリクエストの場合は、WWWクラスの思想を継承して、下記のように // postDataを設定したらPOSTになる、という仕様。 WWWClient http = new WWWClient(this, "http://example.com/"); client.AddData("foo", "bar"); client.OnDone = (WWW www) => { Debug.Log(www.text); }; client.Request(); // ファイル添付したい場合。下記はstringをbyte[]にしてるけど画像など // 何でも可能。 byte[] binary = System.Text.Encoding.Unicode.GetBytes("bar"); WWWClient http = new WWWClient(this, "http://example.com/"); client.AddBinaryData("foo", binary, "test.txt", "application/octet-stream"); client.OnDone = (WWW www) => { Debug.Log(www.text); }; client.Request(); // エラーハンドリングをする場合は、OnFailプロパティにDelegateを代入。 // 正常終了のハンドリングと同じくWWWクラスが渡されるのでごにょごにょする。 client.OnFail = (WWW www) => { Debug.Log(www.error); }; // タイムアウトの場合はWWWクラスがDispose()された後で利用できなくなって // いるので、引数なしのDelegateをOnDisposedプロパティに代入する。 client.OnDisposed = () => { Debug.Log("Timed out"); }; // タイムアウトを設定する場合はTimeoutプロパティに値を代入(float)。 // デフォルトはタイムアウト設定なし(無制限)。 client.Timeout = 10f; // ヘッダを追加する。 client.AddHeader("Cookie", "cookiename=cookievalue"); } }
WebKitは欧文フォントによって和文フォントを切り替えている
知らなかった。CSSで和文フォントが指定されていない場合、ブラウザのデフォルト指定フォントで表示されるものだと思っていたけど、WebKit(Safari)やWebKitからフォークしたBlink(Chrome)では、欧文フォントによって和文フォントが切り替わるようになっているみたい。Safariは7.0.2、Chromeは33.0.1750.152で確認。
それぞれ和文フォントを指定していないのに欧文フォントの空気を読んで和文フォントまで明朝体、ゴシック体、ボールドに切り替わっている。ここに表示しているのは画像で実際のHTMLサンプルはこちら。
ただ、WindowsだとChromeでもこうならない。Linuxは未確認。
日本人が日本語のウェブサイトを作るときは日本語フォントを指定すると思うので気にするまでもないけど、最近Facebookのニュースフィードのシェアに明朝体が表示されるようになって、そういう趣味になったのかと思ってフォント指定を調べたら、欧文フォントしか指定されていなかったので、もしかしてと思ったらそうだった。