Terrarium

いわゆる掃き溜めの ありふれた有象無象

CEDEC2018の講演を聴いた感想(タイムシフト)

CEDEC2018

国内最大レベルのゲーム開発者カンファレンス,CEDEC2018のタイムシフトパスを購入し,いくつか講演を聞きました. https://2018.cedec.cesa.or.jp/ 去年のCEDECゼルダの講演でCEDECの存在を知り,今年申し込んで見たという感じです.

その中でも興味のある講演をいくつか聴いたので内容をまとめました.

明快で軽快なUI『Nintendo Switch 本体機能』の制作事例

https://2018.cedec.cesa.or.jp/session/detail/s5abdde297aa0e

任天堂の方々による講演です. NintendoSwitchにおける本体機能のUIをどう作ったか,ということに関するものでした.

良い例と悪い例の具体的な例があり,とてもわかりやすい講演でした. ポイントは次の通り.

  • WiiUまでは多機能であることを重視していたが,現在はスマートフォンなど似たデバイスは溢れている
  • そこで,「ゲームで遊ぶこと」に特化するUIを作るため
    • 圧倒的に明快にする
      • 簡単そうと思ってもらう
        • ゲームやサービスを「混ぜない」ようにする
        • 主役であるゲームの「アイコンを大きく」「絵の密度を大きく」
        • 他の機能も直感的に使えるよう「上下の意識」
          • 上がマクロ,下がミクロ
        • 数を少なく見せるために「グルーピング」
      • ガイドラインを迷わないようにする
        • 迷いそうなルールの例
          • カーソルの選択においてどのボタンに移るか?
            • 基本的にはボタン配置をグリッドに固定した
          • どの種類の効果音を使うか?
            • 「案内」と「消去」でそれぞれ作っても,じゃあ「終了」はどっち?となる
            • 効果音の種類を「正常系」「エラー系」「警告」の3つに制限
            • 視覚と聴覚を一致させるよう見た目も統一
    • 圧倒的に軽快にする
      • UIにかかる時間をできる限り削る
      • 車が停止する流れと同様,「ユーザの理解」「ボタンの操作」「システムの処理」の3つのフェーズが存在
      • これらの合計がUIにかかる時間
        • システムの処理
          • リソース読み込みを極限まで減らした
          • アニメーションをゼロにしたらどうか?
            • そのままだと何が起きたかわからないので,0.2s程度に
        • ボタンの操作
          • カーソルの初期位置を確定とキャンセルどちらにするか
          • 確定側にすることでユーザの操作数を減らした
          • 基本ユーザの操作を「信頼」し,確認は「端的」に行うように
            • 良いコミュニケーション
        • ユーザの理解 = 発見の速さ
          • アイコンは必要か?
            • Switchでは言葉のみにした
            • ダイアログが出ると,ユーザはその言葉を頼りに探す
            • アイコンがあるとアイコンを見てしまうが,わかりづらいアイコンがあるとアイコン → 文章という目の動きが発生してしまう
          • 斜め読みしやすい文章にした
            • 左上と右下だけ読めば何をすれば良いかわかるように
    • 快適にする
      • これまでは不快を減らす話,これは快を増やす話
      • 操作音の心地よさを生み出す方法
        • 移動:ボタンの種類で音を分けた
        • 決定:いくつか種類があるが,「カチッ」のうち「カ」と「チ」のテンポを揃えることで連続操作でも違和感がないように
        • 遷移
          • 遷移前には「繊維するよ」遷移後には「遷移したよ」と音のつながりを作った
          • 画像への遷移時には画像を選択する音に似た遷移音,設定への遷移時には設定の選択時の歯車音を使った遷移音を採用
      • 触りたいを作る

「どこから作ればいいんだろう?から10年」

https://2018.cedec.cesa.or.jp/session/detail/s5b1e23aaede0a

任天堂代表取締役・フェローの宮本さんの講演. 基調講演であり,10年を振り返りながら話すスタイルでした. BotWをはじめとするゴールが明確でないゲームやモバイルの普及による課金型ゲームについての話などでした. 詳細は割愛.

ワンランク上のゲームデザインレベルデザイン・UIデザインを考える 「コンテキスト」「コンフリクト」「コントラスト」デザイン

https://2018.cedec.cesa.or.jp/session/detail/s5ac06de06756a

Slideshare↓↓↓

ワンランク上のゲームデザイン・レベルデザイン・UIデザインを考える 「コンテキスト」「コンフリクト」「コントラスト」デザイン

Unity Technologies の大野さんの講演. ゲームデザイン系の講演を初めて聞くのでとても面白かったです.

  • コントラスト
    • 難易度などにメリハリをつける
    • 線形にあげるのではなく,上下させたり急にあげたり
    • 詳しくは昔のセッション参照
  • コンテキスト
    • プレイスタイルやゲームに必要な知識,操作方法など
    • ハイコンテキストとローコンテキストがマッチしていない事例
      • ゲームが面白くない
        • コンテキストの相性が悪い可能性
          • モバイル・コンシューマ・PCのプレイスタイルの違い
      • 新しいゲームシステムを作ったが評価が悪い
        • コンテキストのレベルが悪い
          • 売れるゲームは入り口がローコンテキスト(前提知識不要)出口がハイコンテキスト(奥深い)
            • 徐々に狭まるのが良い
          • 新しい要素を入れると急にローコンテキストやハイコンテキストになる恐れ
  • コンフリクト
    • プレイヤーの目標達成を妨げるもの
    • 種類
      • 接近・接近:どっちにするか
      • 回避・回避こっちもダメ,あっちもダメ
      • 接近・回避:これはいいけどこっちはだめ
    • 複数のことを同時にやらせるとコンフリクトが起こる
      • 自発的:ユーザが選択可能
        • 敵の奥の宝箱
      • 強制的:選択不能
        • ボス線
    • ゲームのコンフリクト
      • 目的のコンフリクト(クリア or ハイスコアetc)
      • 敵のコンフリクト(どれから倒すか? etc)
      • 行動のコンフリクト(宝箱を取りに行く or 先に行く etc)
      • 選択のコンフリクト(どちらの道を選ぶか,選択肢が多すぎるとストレスになる)
      • 消費のコンフリクト(このアイテムを使うか否か)
  • ゲームは人生に必要か?
    • YESと考えている
    • プレイヤーの本質を自己確認できる
      • メディアで唯一?

コンフリクト周りの話はこれまでプレイしてきたゲームを考えても納得する内容でした. 任天堂はこれを作るのがとても上手だそうな.

フィールドとモンスターの制作工程から読み解く「モンスターハンター:ワールド」のゲームデザイン

https://2018.cedec.cesa.or.jp/session/detail/s5abe362fd7694

株式会社カプコンの徳田さんの講演. モンハンはプレイしたことがない(やりたい)のですが,モンハンという世界を作る裏側のような内容でした.

  • MHWのミッション
    • 初めての人でも楽しめる(シリーズの知識を必要としない)ため新大陸に
    • オープンフィールド
      • 広さではなく密度を重視
  • フィールドのレベル設計
    • 序盤:古代樹の森
      • 森なのでわかりやすい,難易度が高いところは湿度を高めにしてヤバさをわかりやすく
    • 瘴気の谷
      • 竜の墓場,エネルギーを求めるモンスターが集まる
    • 大蟻塚の荒地
      • ワイド感を表現
    • 中盤:陸珊瑚の台地
      • 歴代にはない驚きを与えるためのフィールド
        • 慣れているユーザにも驚いてもらう
      • 陸珊瑚というファンタジー要素
    • 終盤:龍結晶の地
      • 古竜の集まるボスMAP
  • モンスターの作り方
    • モンスター=プレイヤーを適度に追い詰めて,倒した後に気持ちよくなる存在
    • 何度戦っても,どの武器で戦っても面白いようなモンスター
    • モンスターづくりの2大ポイント
      • インパク
        • 感情を動かすことで倒した後の気持ち良さを増幅させる
    • 攻略
      • プレイヤーに選択肢を持たせ,何度遊んでも新たなアクションの可能性が生まれるようにする

上のゲームデザインの講演を聞いた後だったので,なるほどなぁと思える内容も多かったように思います. アクションの可能性とかもコンフリクトの一つであり,うまく選択肢を選ぶと報酬(短いタイムetc)が得られたり. 基本的にはローコンテキストでありながら,中盤に新しい内容を持たせることでハイコンテキストに. 最後がボスマップなのはお決まりなんでしょう(多分) ゲームを作ってみたくなる…

終わりに

ゲームデザインって面白いですね. というか設計行為自体がやっぱり面白い. ゲームに限らず,アプリのアーキテクチャとか. 時間がない中タイムシフトでみたのですがまあこれだけ見れれば元が取れたかなという感じ. (欲を言えばもうちょい任天堂の講演を聴きたかった…)

輝夜月ライブのライブビューイングに行ってきた + 輝夜月のススメ

(技術関係なく趣味全開の記事です)

輝夜月ライブ

2018/08/31,VTuberである輝夜月のワンマンライブが行われて,そのライブビューイングを見に行ってきました. その感想やらを書き連ねます.

liveviewing.jp

(メインの方のHPが見当たらない…)

VR空間でのライブ

このライブはご存知の通りZepp VRというVR空間にて行われました. 本当はVRで参加したかったのだが(チケットも買えなくもなかった)どうやっても20時に家に到着できない予定だったため,ライブビューイングの方での参加としました.

ライブビューイング

入場まで

当日新宿バルト9に行くと,30分前にも関わらずエレベータ待ちの待ち行列が. これは自分含め多くの人が驚いていたようです. 輝夜月というVTuberの人気が伺えます.

劇場に入ると,Twitterでも告知されていたように,輝夜月の等身大フィギュアが目に入ります.

f:id:tellusium:20180902214144p:plain
等身大の輝夜

これはバルト9の特権ですね.

場内ではアナウンスが入っており,ライブビューイングが行われるスクリーンは1つだけではない模様. それだけの人数がきているということでしょう. 自分のいたスクリーンの収容人数はおおよそ $13 \times 25 \approx 300$ であったため,スクリーン数が4だったとしても1000人以上がこのバルト9でライブビューイングにきていたことが予想できます.

20:00

20:00ぴったりにスクリーンに現れたのは,エビーバーとパブロッコリー. 観賞における注意事項を映画館さながらの演出で伝えていました.

注意事項が終わると,ついに月ちゃんが現れます. 予想していた以上に唐突な出現で,何があるのかと思いきや,始まったのはラジオ体操. よく聞く聞き覚えのあるピアノ曲…と思いきや微妙に違う. 内容もところどころ変わっていたり,会場ではすでに笑い声が. ライブでラジオ体操をするアイドルってこれまでにいただろうか.

次に流れたのは輝夜月のこれまでを振り返るムービー. 自分がVTuberを知った & ハマり始めたのが年末なので,月ちゃんのデビューその日は知らないんですよね… もうそろそろ1年経つんだなあ…と.

次はいよいよ「Beyond the moon」. ちゃんとiTunesで購入し予習済みです. さすがVR,ステージが飛んだりモニュメントが空中にあったりとなんでもありでした. これはVRで見たかったなぁ… いやもう演出が可愛い. これまでで最高だったんじゃないかなぁ…

ちょっとMCが入り,続いて「幸福論」. (聞いた時なんの曲か知らなかった…) まあここら辺の細かい話は他のレビュー記事で書いてあることでしょう.

次がフリートークタイム. いつものBGMが流れ,youtube (showroom) ライブさながらのフリートークが. (正直これが一番の楽しみでした,曲のライブではありますが月ちゃんに限ってトークなしはないだろうと) エビーバーのエモートをすると風船が膨らんでいく演出も挟みながら,VTuber最強レベル(主観です)のトーク力が繰り広げられます.

(誰もが予想していたであろうように)風船が爆発した後は,「Beyond the moon」がもう一回披露されます. 「夏休みの終わり」など多少歌詞が変わり,ライブらしさに溢れていました.

最後にスクリーンには風船の爆発により破壊された会場が映し出され,ライブは終幕. 45分ほどの短い時間でしたが,月ちゃんらしさに溢れた濃密な時間でした.

感想

  • 「ライブ」
    • サイリウムを振っている人がいたり,月ちゃんのトークに笑ったり,同じものを好きな人たちが集まった空間で,一体感のような楽しみがありました
    • これはライブならでは
  • VRという会場
    • (そもそも自分は賑やかなライブを知らないのですが)会場がダイナミックに変化してく様子はVRならではと感じました
    • まだまだ表現の余地がありそう

おまけ「輝夜月のススメ」

自分な好きなものを宣伝していくスタイルです(正直万人に薦められるのはこれくらいしかない…) VTuber好きの学科の方々は結構ブログにまとめているようなので,自分もここにまとめておきます.

自分がVTuberにハマったのは去年末. 正直アイドル系の趣味は全くなく,今でもハマった理由はよくわからず. 時期としてはちょうどTwitterでバズっておりVTuberの波が来ていたころですね. 色々苦しい時期と重なり,ドトールでハニーカフェオレを飲みながらVTuber動画を見ていた毎日(?)でした. 最初は電脳少女シロやキズナアイあたりの動画を色々見ており,その中に輝夜月の動画もあったというレベル. それでも初期の動画はなんども見るレベルの中毒にはなっていました. 時期は移り忙しくなってくると,毎日いろんな動画を見ている時間はなくなり,その中でも残っていったのが輝夜月の動画. 短い時間かつ一度見ると中毒になる独特なテンション,そして動画の面白さあたりが理由かと思います. 以上から,輝夜月を万人にお勧めできる客観的な理由は以下の通り.

  • 動画のレベルの高さ
    • どの動画も必ずといっていいほど面白い.2回以上見ていない動画は本当に少ないレベル.
  • 動画の時間の短さ
    • 月ちゃんの動画は基本2-5分程度と短い方.
    • 短い時間で確実に気分が晴れる.最高.
    • 長いほうが良いという方もいらっしゃるかと思いますが,次の理由も合わせて.
  • 動画の投稿頻度の低さ(?)
    • 他のVTuberでは毎日5-20分程度の動画を投稿しています(最近は短くなっている傾向?初期は20分が多かった)
    • 「毎日20分も動画に割ける余裕がない!」というもの
    • 専念という意識なく楽しめる
  • いつ見始めても追いつける
    • 上に書いた通り,動画は短く,また数日に1本.
    • ざっと計算してこれまでの動画の合計時間数は170分程度(ライブを除く)
    • 土日あれば見返せるレベル
  • ライブの時間も遅め
    • 19:00から始められても家にいられないという
    • そんな中でも月ちゃんは22:00から.
    • 頑張れば家にいれる時間帯.

以上になります. 最後に,自分の好きな動画を3つほど載せて,この記事を終わろうと思います.読んでくださってありがとうございました.

  1. USAゲーム

www.youtube.com

  1. 絵描き歌

www.youtube.com

  1. 細かすぎる声真似

www.youtube.com

SwiftでDropboxを利用するメモ

(注意:ほぼ自分用のメモです)

Dropboxを使う理由

現在自分用の簡単な消費管理アプリを作りたいと考えており,そのデータの保存先を色々検討していました. 次のような選択肢が考えられます.

  • AWSとかAzureとかのDBを利用
  • 自前のサーバのDBを利用
  • UserDefaultに格納
  • Google Spreadsheet
  • Dropbox

前者2つはコストがかかるので見送り,UserDefaultに全部しまってしまうのもアプリらしくない(?),Google SpreadsheetにはSwiftのライブラリがない(自分でAPIを叩く必要)などの理由から,今回はDropboxを利用してみることにしました.

SwiftyDropbox

DropboxをSwiftから使うためのライブラリです.

github.com

使い方は上のREADMEに書いてある通りになります.

インストールなど

行なった操作は次の通り.

  1. pod経由でインストール
  2. Dropboxのサイトでcreate app -> API_KEYの取得
  3. Info.plist編集その1 LSApplicationQueriesSchemes
  4. Info.plist編集その2 CFBundleURLTypes

ここでInfo.plistにdb-<APP_KEY>という形で値を指定するのですが,プロジェクトをGithubなどに公開したときにこれはAPP_KEYは漏れても大丈夫なのか?と感じました(自分は初心者なのでわからないのですが,多分SECRET_KEYの方が漏れなければ大丈夫なのかな,と考えてます,公開するときまでには調べなければ)

コーディング

基本的には次の3つを記述すれば動作します.

  1. AppDelegateのapplication(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool内で
DropboxClientsManager.setupWithAppKey("<APP_KEY>")

これでAPP_KEYを登録します.

  1. ボタンを押した時などのメソッド内で
DropboxClientsManager.authorizeFromController(UIApplication.shared,
                                                  controller: self,
                                                  openURL: { (url: URL) -> Void in
                                                    UIApplication.shared.openURL(url)
                                                  })

するとボタンを押すとログイン画面が出るようになります. ただこれだけだと最後のAllowを押してもブラウザが終了しません.

  1. AppDelegate内で
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
    if let authResult = DropboxClientsManager.handleRedirectURL(url) {
        switch authResult {
        case .success:
            print("Success! User is logged into Dropbox.")
        case .cancel:
            print("Authorization flow was manually canceled by user!")
        case .error(_, let description):
            print("Error: \(description)")
        }
    }
    return true
}

を丸々追記. これで上記のログイン画面でAllowなどを押すと終了し,結果が返ってくるようになります.

  1. ファイルをアップロードするには,同様にボタンなどを押した時などのメソッド内で
if let client = DropboxClientsManager.authorizedClient {
    let fileData = "testing data example".data(using: String.Encoding.utf8, allowLossyConversion: false)!
    
    let request = client.files.upload(path: "/pocket_management/sample.txt", input: fileData)
        .response { response, error in
            if let response = response {
                print(response)
            } else if let error = error {
                print(error)
            }
        }
        .progress { progressData in
            print(progressData)
        }
} else {
    // error
    print("not logged in")
}

のようにやるのが良さそうです. clientの取得はControllerで1個用意しておくよりも毎回optional bindingで呼び出した方が良いのか…? (そのほうがエラー処理が書きやすそうに思える)

終わりに

本当にメモですが書いておきました. せっかくアプリを作るのでデザインからやったり色々試してみようと思います.

TrelloのUIを透明化するChrome拡張機能を作る

f:id:tellusium:20180709172959p:plain

はじめに

私はTrelloが好きで,タスク管理に使っているのですが,最近になって(ようやく)画面の背景に写真が(フリープランでも)使えることを知りました. 単色に飽きていたとこだったので,喜んで写真にしてみたところ,思ったよりパッとしないなという印象でした.

f:id:tellusium:20180708213630p:plain

これはまだ良いのですが,カードが多くなり

f:id:tellusium:20180708213840p:plain

のようになってしまうと,せっかくの綺麗な背景が台無しになってしまうわけです. そこで,カードを半透明にすれば良いのでは?と考え,chrome extensionで実装してみました.

Chrome Extension

Chrome extensionとは,

Extensions are small software programs that customize the browsing experience. They enable users to tailor Chrome functionality and behavior to individual needs or preferences. They are built on web technologies such as HTML, JavaScript, and CSS.

と公式ページに書かれています.すなわち,ユーザがChromeの機能を追加したりできるというものです.

What are extensions? - Google Chrome

Chrome extensionによって,Webサービスに機能を追加したりすることもできます. 様々なサイトにTogglのボタンを追加できるextensionや,Trelloにいくつか便利な機能を追加するUltimelloなどです.

chrome.google.com

chrome.google.com

これらはWebサイトのDOMを編集してボタンを追加し,それをトリガーに機能が書かれたJavascriptを実行することで実現されています.

すなわち,Chrome extensionを使うことでWebサイトの見た目やデザインを変更することもできるわけです. (Chrome extensionは非常に多くの機能を持つことができます.詳しくは公式ドキュメントなどをご覧ください)

Content script

今回は,Chrome extensionで使うことができる機能のうち,Content scriptというものを用います.

Content Scripts - Google Chrome

CSSをいじる方法はないかと探していたところ,下のページが見つかり,どうやらContent scriptを使っているようだということがわかりました.

marmooo.blogspot.com

公式ドキュメント曰く,

Content scripts are files that run in the context of web pages. By using the standard Document Object Model (DOM), they are able to read details of the web pages the browser visits, make changes to them and pass information to their parent extension.

すなわち,ブラウザが表示したWebページを読み込み,それらを変更したりできるらしいです.

詳細な作り方は公式チュートリアルなどを参考にしましたが,基本的にはフォルダを用意して,manifest.jsonというファイルに色々書き込みます. 変更したいスタイルについては,transparentize.cssに書き込みます. また,上で参照したブログにおいて!importantをつける必要があると書かれており,実際そうしないと反映されなかったため,全てに!importantをつけました(ここはもう少し賢くできるかもしれません).

https://developer.chrome.com/extensions/getstarted

// ディレクトリ構造
trello_transparentizer
├── manifest.json
└── transparentize.css

manifest.jsonです.matchesの部分に適用したいWebサイトのURLを記述します.今回はTrelloのボードのURLのはじめに付いている部分を指定しました.

{
    "name": "Trello Transparentizer",
    "version": "1.0",
    "description": "Transparentize trello interface.",
    "content_scripts": [
       {
        "matches": ["https://trello.com/b/*"],
        "css": ["transparentize.css"]
       }
    ],
    "manifest_version": 2
}

transparentize.cssです.Developer toolを使って変更したい要素のクラス名を探し,そのクラスのcssを上書きする形にしています.

/* リストの背景 */
.list {
    background-color: rgba(0, 0, 0, 0.5) !important;
}
/* カードの背景 */
.list-card {
    background-color: rgba(255, 255, 255, 0.7) !important;
    box-shadow: 0 0 0 #000 !important;
}
/* hover時のカードの背景 */
.list-card.active-card {
    background-color:  rgba(255, 255, 255, 0.9) !important;
}
/* リストの名前 */
h2.list-header-name-assist {
    color: white !important;
    font-weight: normal !important;
}
/* リストの名前(Ultimello使用時)*/
.list-header textarea {
    color: white !important;
    font-weight: normal !important;
}
/* カードをhoverした時に出てくる編集ボタン */
.expanded-list-card-operation {
    background-color: rgba(0, 0, 0, 0) !important;
}
/* スクロールバーの背景 */
.u-fancy-scrollbar::-webkit-scrollbar-track-piece {
    background: rgba(0, 0, 0, 0.3) !important;
}

以上を記述した後,その他のツール→拡張機能デベロッパーモードON→パッケージ化されていない拡張機能を読み込む→先ほどのフォルダを指定,という流れで拡張機能をインストールできます. 拡張機能を有効化した後にTrelloのボードを更新すると,次のように背景が透けて見えるようになります.

f:id:tellusium:20180709171418p:plain

以上でTrelloのUIを透明化し,背景の写真を映えさせることができるextensionが完成しました.

まとめ

カードが多すぎると背景の写真が全く見えなくなってしまうという問題を,UIを一部透明化するChrome extensionを作ることで解決しました. 今回は勉強も兼ねて新しくextensionを作りましたが,user style sheetを導入するという手法もあります. 指定したサイトに対し自分のCSSを適用できるという機能であり,これを可能にするいくつかのChrome extensionが公開されているようです.

今のところextensionとしてリリースはしない予定ですが(user style sheetの方が単純なため)一応Githubには公開しています.

github.com