ホーム ブログ ページ 33

【0秒通勤】ワープについて考える

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

SF的な世界観を持ったアニメ・ゲーム等の多くのコンテンツにおいて、離れた場所へ自由に行き来(または一方通行)する手段が登場しています。今回はこのような離れた場所への移動術、ワープについて考えていきたいと思います。 ※本記事はフィクションを織り交ぜた説明を行っています。ご了承ください。

0秒通勤への道

今回考える、ワープの性質は次の1点のみです。
現状の実在するどの移動手段よりも速く移動できる。

コンテンツに登場するワープと言えば、体から光が出てふわっと消えたり、宇宙船でギューンと移動したり、ドア状の物体を通過するだけで目的地まで行けたり等々、不思議な性質を持ち合わせているものが多く見られますが、今回の記事で考える性質は上の1点だけになります。

ワームホール

早速本題に入りたいと思います。現状、物の速度は光の速度(秒速30万キロ)を超えることが出来ないと言われています。つまり、どんなに速い車やロケットを作っても、必ず上限が来てしまいます。
しかし、その上限値を超えた速さで移動ができる現象があります。それが、ワームホールです。
SF好きな方なら何度も耳にしているかもしれません。多くのSF作品の中でワープの説明として頻繁に用いられる現象です。
ワームホールは、時空と時空を繋ぐトンネルのようなもので、これを自在に扱えれば、通常の移動よりも高速で移動が可能になるのではないかと言われています。
時空と言っても難しいので、イメージとして書き下します。
私たちは普通、道路の上を歩いて目的地まで行きますが、ここにフタが外れた魔法のマンホールがあり、それが一直線にブラジルまで繋がっているようなものを考えてください。道路の上を歩いて進むと地球の表面に縛られるため、一直線にブラジルまで行くことはできません。しかし、魔法のマンホールを使えば、一直線にブラジルまで進むことが出来ます。同じ速度の乗り物を使っても、移動距離が違うため、結果的に速く移動できます。
enter image description here
これを応用して、どこの目的地にも一直線に行けるような魔法のマンホールが出来れば、現状実在するどの移動方法よりも高速な移動が可能になるわけです。

ワームホールは実在するのか

上述のようなワームホールは実在するのでしょうか。
最近、時空のさざ波と言われる「重力波」という現象をとらえることに成功した、とアメリカの研究機関が発表しました。このさざ波を詳細に解析すると、ワームホールがあるかどうか確かめられるようです。
これはイメージとして、水面に生活していると考えてください。水面に何もなければ、遠くから来た波はそのまま私たちのところへやってきます。しかし、水面に邪魔者があると、そこを波が通ろうとしても波の形が変形させられてしまいます。これと同じようなことがこの空間でも起こっていて、この邪魔者がワームホールということです。
現状取得できる信号では、信号の強度が十分ではないため、まだ決定的な証拠は見られていませんが、観測機のグレードアップによって、今後ワームホールを捉えられる日がすぐそこまで迫っているかもしれません。
従って、現状の答えは「現実味を帯びてきた」と言えるのではないでしょうか。

終わりに

SFよりも現実よりなお話をしたつもりですが、当記事はワープや0秒通勤が実現可能だと担保する物ではありません。また、繰り返しになりますが、イメージだけでもお伝えするために、事実にフィクションを織り交ぜた説明を行っております。「ホンマでっか!?」的な姿勢で読んでいただけたら幸いです。
*参考文献*
「Echoes from the Abyss: Evidence for Planck-scale structure at black hole horizons」Jahed Abedi, Hannah Dykaar, Niayesh Afshordi

EXCEL(VBA)から、JSONデータをHTTP送信してみよう。

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

はじめに

EXCELでマスタデータ等を作成して、直接サーバへリクエストしデータの格納/情報の取得をしたいと思いませんか?
それを実現する簡単な方法をご紹介します。

JSONデータを使用するために

BOXのAPIを使って見よう。(その3)でも紹介していますが、
EXCEL(VBA)でJSONを扱うには、VBA-JSONを使用するのが簡単です。

サンプル JSON

JSONデータ交換フォーマットの定義は、ECMA-404を参照して下さい。

{
  "id" : 1,
  "name" : "John Smith",
  "friend_ids" : [ 10, 20, 30 ],
  "shipTo" : { "name" : "Appirits Inc.",
               "address" : "5F Kyocera-Harajuku Bldg. 6-27-8, Jingumae, Shibuya-ku",
               "city" : "Tokyo",
               "state" : "Japan",
               "zip"   : "150-0001" },
}

VBA で JSON 生成

連想配列 Dictionary と、可変配列 Collection を使って JSONオブジェクトにデータをセットする

 '---------------------------------
 ' リクエストパラメタ生成
 '---------------------------------
 Dim JsonObject As Object
 Set JsonObject = New Dictionary

 JsonObject.Add "id", 1

 JsonObject.Add "name", "John Smith"

 JsonObject.Add "friend_ids", New Collection
 JsonObject("friend_ids").Add 10
 JsonObject("friend_ids").Add 20
 JsonObject("friend_ids").Add 30

 JsonObject.Add "shipTo", New Dictionary
 JsonObject("shipTo").Add "name", "Appirits Inc."
 JsonObject("shipTo").Add "address", "5F Kyocera-Harajuku Bldg. 6-27-8, Jingumae, Shibuya-ku"
 JsonObject("shipTo").Add "city", "Tokyo"
 JsonObject("shipTo").Add "state", "Japan"
 JsonObject("shipTo").Add "zip", "150-0001"

 ' イミディエイトウィンドウで確認(デバック用)
 Debug.Print JsonConverter.ConvertToJson(JsonObject, Whitespace:=2)

イミディエイトウィンドウで確認すると、JSONが生成されている事が確認できますね。
イミディエイトウィンドウで表示したJSON

VBAからHTTP通信

CreateObject(“MSXML2.XMLHTTP”)でIXMLHTTPRequestオブジェクトをを生成して送信するのが簡単な方法です。

'---------------------------------
' リクエスト
'---------------------------------
Dim objHTTP As Object
Set objHTTP = CreateObject("msxml2.xmlhttp")
objHTTP.Open "POST", "http://localhost:8080", False
objHTTP.setRequestHeader "Content-Type", "text/plain"
objHTTP.send JsonConverter.ConvertToJson(JsonObject)

' レスポンスコード(正常)
If objHTTP.status = 200 Then
    MsgBox "正常に終了しました"
End If

実際のHTTP通信内容を proxy ツールで確認

proxyツールfiddler を使った、HTTP通信内容を確認した様子です。

FiddlerでHTTP通信内容を確認

FiddlerでリクエストのPOSTデータが、JSONとなっていることを確認した結果です。
FiddlerでJSON内容確認

まとめ

送信するデータをEXCELから取得する部分は割愛しましたが、簡単にJSONデータが作成出来ましたね。
次回は、VBAで画像などのファイルをアップロードするにはどうすればいいか?
を考えて見ます。

Ruby on Rail 4.2 から 5.1 へ移行した際のメモ

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

Ruby on Railsのバージョンを 4.2 から 5.1 へ移行したときのメモです。 基本的にRailsガイドの手順通りにやれば問題ありませんが、Turbolinksではまります。

移行の前に

これはRuby on Rails 4.2 から新機能は使わずに5.1に移行したときのメモです。
rubyをとりまく環境の変化はとても速いので、前のバージョンがすぐに Deprecatedになったりします。
ですが、古いバージョンから一気に最新バージョンをあげるのはとても大変です。
日頃からバージョンアップを試みてJenkinsなどのCIで自動テストする環境を整えておきましょう。

環境

移行前

Ruby 2.3.3
Ruby on Rails 4.2.7.1

移行後

Ruby 2.4.1
Ruby on Rails 5.1

大きな変更点

  • rakeコマンドのかわりにrailsコマンドを使うよう変更になった。
  • ActiveModelの親クラスが ActiveRecord::Base から ApplicationRecord に変更になった。
  • ActiveJobの親クラスが ActiveJob::BaseからApplicationJobに変更になった。
  • assetsにyarn, webpacker が正式に導入された。
  • jquery-ujs が rails本体 (ActionView) に取り込まれ、jqueryに依存しなくなった。

おおまかな手順

  1. バージョンアップ用のブランチを切る
  2. Gemfileでロックされているrailsのバージョンを 5.1.2 に変更してbundle update rails
  3. エラーがでるので必要なgemのバージョンをあげたり、不要なgemを消したりして bundle update
  4. bin/rails app:update diffを確認して問題なければ上書きなどしてゆく
  5. ActiveModelなどの親クラスを変更
  6. アセットまわりの変更
  7. (余力があれば)アセットのライブラリを yarn管理に変更

使用しなくてもよくなったgems

  • debugger
  • jquery.turbolinks
  • quiet_assets

Turbolinksの対応

Turbolinks5に対応しているため変更になっています。

  • page:loadturbolinks:loadに変更になった
  • History.back(ブラウザの戻る)などでも呼ばれるようになった

上記の変更から、以下を実施しました。

  • jquery.turbolinksを使っていたがturbolinks5では動作せず使わなくてもよさそうなのでGemfile, application.jsから削除した。
  • Turbolinks.enableProgressBar() は本家に含まれたので削除した。
  • jquery.turbolinksでは $()を使うが、かわりに $(document).on "turbolinks.load", function()に変更した
  • javascript_include_tagdata-turbolinks-track 属性を “reload”に変更した

AdminLTEで表示崩れ

AdminLTEという管理画面テンプレートを使っていますが、リンクでページを遷移した際画面が崩れることがありました。
turbolinks.load内で、$.AdminLTE.layout.fix(); を呼び出すことで解決しました。

ブラウザの戻るボタンで表示崩れ

History API で戻った場合でも turbolinks.load で呼ばれるようになりました。
そのため、二重に表示されることがあります。
戻るボタン押下時にはキャッシュを使って表示しますので、turbolinks:before-cache イベントを使って不要なDOMのクリアなどを行う必要があります。

その他の変更点

ActiveRecord: time型にもタイムゾーンが適用される

案外メジャーになっていませんでした。 time型は従来はタイムゾーンは適用されませんでしたが、Rails5よりタイムゾーンを考慮するようになりました。 何も対策をせずにアップデートするとJSTの場合9時間ずれます。
移行時に、DBを確認してUTCに変換する必要があります。

または、以下のオプションで従来の動きに変更できます。

config.active_record.time_zone_aware_types = [:datetime]

ActiveRecord: uniqは廃止、distinctを使う

ActiveRecord::QueryMethod#uniq が削除されました。
以前はAnimal.uniq のような記述でselect distinct * from animalsを発行してくれましたが、Rails5以降はArrayに変換されます。

同じ挙動にするためには、Animal.distinct を使います。

ActiveModel::Dirty: attribute_was の挙動の変更

モデルオブジェクトの属性を変更すると、変更前の値が xxx_was に保存される便利な機能がありましたが、Rails5以降は取得できなくなりました。xxx_was は xxx と同じ値を返すようです。xxx_changeの最初の要素を使います

animal.name = "Pig"
animal.name_was # => nil
animal.name_change # => [nil, "Pig"]
animal.name_previous_change # => nil
animal.save
animal.name_was # => "Pig"
animal.name_change # => nil
animal.name_previous_change # => [nil, "Pig"]
animal.reload
animal.name_was # => "Pig"
animal.name_change # => nil
animal.name_previous_change # => nil

リソース

Railsガイドのドキュメントや他のリソースを検索するのは当たり前なのではぶきます。
(Railsガイドの日本語版は訳が追いついていないので英語版もあわせて参照してください)

Railsアップグレードガイド(日本語)
A Guide for Upgrading Ruby on Rails

ゲーム制作におけるコンセプトの作り方

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

コンセプトってどんなものを書けばいいのかわからない方にコンセプトの作り方についてまとめてみました。

はじめに

どうもモツ太郎です。
ゲーム業界を志望している方の中には<企画書>の提出が課題として出された方もいると思います。企画書ではそのゲームの一番のウリ<コンセプト>というものを書くことになります。今回はその<コンセプト>についてお話していきたいと思います。
※いつものように個人の考えになります。

失敗するコンセプト

さて、実際にゲームのコンセプトというものを考えた時に皆さんはどういうものを想像するでしょうか?
実際によく使われそうな例を思い付きでひとつ挙げてみたいと思います。

☆動物園の園長に!様々な動物を飼育する育成ゲーム!
(モツ太郎はけ〇のフ〇ンズを応援しています。)

はい、よく使われそうな耳障りのいいコンセプトが出てきました。
一見やりたいことはわかるコンセプトとなっていますが、このコンセプトには大きな問題があります。

それは、<ただのゲームの概要になってしまっている>というところですね。
このようなコンセプトにしてしまうと企画が通って実際に作る際に仕様変更をするとコンセプト変更に直結します。
また、偉い人(企画書を見る人)からするとツッコミどころが多いものになります。
ツッコミ例としては以下
・動物園である理由は?
・様々な動物って何を出すの?
などなど

コンセプトとは

ゲームにおけるコンセプトとは<ユーザーに対してどういう体験(経験)を与えたいか>というところところが重要になってきます。

それを受けて先ほどの例を変えてみたいと思います。

☆普段動物と触れ合えない人に、自宅でできる動物ふれあいゲーム!

こんな感じに変えてみました。
コンセプトからターゲットが明確になりましたね。
しかもゲームを作っている最中に仕様が変わってもコンセプトに関しては影響がないというものになっています。

おわりに

コンセプトについて書いてみましたがいかがだったでしょうか?
今回はコンセプトの内容について簡単にしか書いていないのでまだまだ言いたいことが言いきれていないというところもあります。
その部分に関してはまたどこかで書く機会があったら書いていきたいなと思いますので気長にお待ちください。

【Rails】バリデーションのエラーメッセージにI18nを使うとキャッシュされる

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

エラーメッセージをvalidatesメソッドに指定する際、
I18nで国際化した文字列を使用するとキャッシュされてしまうようです。

validates :name, presence: { message: I18n.t('.invalid') }

 
現象として、キャッシュされたものが表示されたり、エラーとなったり、
翻訳されずに英語のままになったりと、挙動が不安定になるケースがありました。

 
バージョン
 rails 4.2
 rails-i18n-4.0.9

 
対策としては、Procオブジェクトを使用すると解消されるようです。

validates :name, presence: { message: Proc.new{ I18n.t('.invalid') } }

lambdaでも同様ですが、
単純にブロックを指定しただけでは解消されません。
以下はどれも同様に解消されます。

validates :name, presence: { message: Proc.new{ I18n.t('.invalid') } }
validates :name, presence: { message: proc{ I18n.t('.invalid') } }
validates :name, presence: { message: lambda{ I18n.t('.invalid') }.call }

 
バリデーションメッセージだけでなく、scopでも同様の現象が発生するようですが、
とりあえず今回はバリデーションの表示のみです。

mongodbにおいてよく利用する基本的な操作について

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

mongodbにおいてよく利用する基本的な操作について以下に記載致す

DB操作

  1. DBの選択> use <DB名> もしくはMongoのシェル起動前に$ mongo <DB名>
  2. DBの一覧取得> show dbs

コレクション操作

  1. コレクションの一覧取得> show collections
  2. コレクションの作成> db.createCollection(“<コレクション名>”)
  3. インデックス
    3.1. インデックス確認> db.<コレクション名>.getIndexes() 3.2. インデックス追加> db.<コレクション名>.ensureIndex({ <フィールド名>: <値> }) 値)
    • 1: 昇順
    • -1: 降順
  4. データ取得
    4.1. 書式> db.<コレクション名>.find({検索オプション})
  • 結果表示を見やすくなるように調整
    db.<コレクション名>.find().pretty()
  • 制限付加
    db.<コレクション名>.find().limit()
  • 件数
    db.<コレクション名>.find().count()
  • ソート
    db.<コレクション名>.find().sort({<フィールド名>: <値>})
    値)
    • 1: 昇順
    • -1: 降順
  • findの第二引数に表示オプションを指定
    db.<コレクション名>.find({}, {<フィールド名>: <値>})
    値)
    • 0: 非表示(0を指定したもののみ消える)
    • 1: 表示(_idと、1をしていしたもののみ表示)
    • 0と1は混ぜて指定できない
  1. 検索条件 findの第一引数内に指定
  • 文字列 .find({<フィールド名>: “”})
  • 正規表現 .find({<フィールド名>: /aaa/})
  • 比較 .find({<>: {<比較演算子>: <値>})
    • 一致 $eq
    • 不一致 $ne
    • 以下 $lte
    • 以上 $gte
    • 大なり $gt
    • 小なり $lt 例) db.<コレクション名>.find({hoge:{$lt: 3}})

mongoが起動しない場合の対処方法

ホストOSがクラッシュし, 仮想環境の不正終了が発生した場合などに,
仮想環境再起動後、mongoが正常起動しない現象が発生した場合,
以下のコマンドで対処することが可能である.
(発生環境: CentOS 6)

# cd /var/lib/mongo
# rm -f mongod.lock
# mongod --dbpath=/var/log/mongodb --repair
# service mongod start

ActiveRecordのpluckを用いた処理の高速化に関する調査

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

大量のレコードに対してデータ処理を行う場合, ActiveRecordのpluckを使用することが有効な場合が存在する. 本記事では、処理速度向上に関する有効性の確認を行う.

処理内容

テーブル内の全レコードに対して、
現在レコードが所持しているパラメータを利用して、更新をかける処理

  • レコード:50万件
  • パラメータ:25種類

動作比較

1. レコード1件ごとに更新をかける(比較用)

比較用に1件ごとに更新をかける処理を行ってみたところ、
処理に時間がかかり実行が終わらないため、問題外であった

2. find_each

  • find_eachでレコードを取得して、パラメータごとのリストを作成
  • リストのパラメータごとに、update_allで更新をかける

処理の所要時間およそ10分

1SQL自体のログに出力されるSQL実行時間,
発行されるSQLの構文への explain の実行でのインデックスの適用具合自体は問題が無いように見られたが,
ActiveRecordオブジェクト生成にかかるコストが処理速度に影響を与えている可能性が考えられる.

3. pluck

  • pluckで、パラメータごとのリスト作成に必要なカラムの値を取得
  • リストのパラメータごとに、update_allで更新をかける

処理の所要時間およそ30秒

ActiveRecordオブジェクト生成を防ぐことにより,
同一のリスト作成処理において大幅な処理速度向上が見込まれた.

まとめ

上記のことから,
pluckの返却値はArrayでの取得となるため, ActiveRecordのメソッド等は使用できなくなるが,
取得値のみで処理が可能な場合など利用可能な場面においては,
pluckを使用することにより, 処理速度向上を行うことができることを確認することができた.

UnityEditor上で複数のゲームオブジェクトをプレハブ化する方法

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

はじめに

Unityを使っていて、複数のゲームオブジェクトを同時にプレハブ化したい時がありました。Unityではひとつずつしかプレハブ化できないようになっています。それでは不便なのでどうにかできないか調べ、作ってみました。

新しくウィンドウを作る

では、新しくウィンドウを作ってみましょう。

Assetsフォルダの中に、Editorと言う名のフォルダを作りましょう。基本的にエディタ拡張関連のスクリプトはこの中に保存しておきます。

次に、そのEditorフォルダの中に新しくクラスを作りましょう。今回はExampleという名前のクラスを作ります。

注意点として、新しくUnity上でウィンドウを開きたいときは、必ずEditorWindowクラスを継承しなければいけません。

では、Openというメソッドを作り、そこにEditorWindow.GetWindow()と書きましょう。これで新しくウィンドウを作る準備は終わりました。ですが、実際に動かしてみると、どこにも表示させません。
では次に、新しいウィンドウを表示させるために、それを表示させるメニューを作ります。
下記のソースコードのように少し特殊な書き方になります。その下にあるopenメソッドは必ずstaticでなければなりません。
またOnGUIの中にウィンドウ内のレイアウトなどを記述します。
これでウィンドウが開けるようになりました。

public class Example : EditorWindow {
    //メニューに項目追加
    [MenuItem("Example/新しくウィンドウを出します")]
    static void open() {
        EditorWindow.GetWindow<Example> ("Example");
    }

    void OnGUI() {
        EditorGUILayout.LabelField ("ようこそ");
    }
}

実行結果が以下のようになります。

enter image description here

複数プレハブ化

では、複数プレハブ化するためにドラッグアンドドロップできるウィンドウを作りましょう。

UnityがDragAndDropと言うUnityEditor上で行われるドラッグ&ドロップを操作するクラスを用意してくれているのでこれを使います。

先ほど作ったOnGUIメソッドの中にソースコードを書き足していきます。
まず、ドロップするエリアを追加するコードを書きます。
Event.currentで現在のUnityが処理中のEventが取れます。
そのEventがドロップエリア内でドロップしているなら、DragAndDrop.objectReferencesでドラッグしているオブジェクトすべてをプレハブ化する処理になっています。
OnGUIの中に、以下のソースコードを書きます。

private string saveFolderPath = "Assets/Prefab/";

void OnGUI() {
    var dropArea = GUILayoutUtility.GetRect(0.0f, 50.0f, GUILayout.ExpandWidth(true));
    GUI.Box(dropArea, "drop");
    var evt = Event.current;

    switch(evt.type) {
        case EventType.DragPerform:
            if(!dropArea.Contains(evt.mousePosition)) break;
            DragAndDrop.visualMode = DragAndDropVisualMode.Copy;
            DragAndDrop.AcceptDrag();
            break;

        case EventType.DragExited:
            foreach(GameObject go in DragAndDrop.objectReferences) {
                Debug.Log(go);
                DropList.Add(go);
            }

            CreatePrefabs();
            Event.current.Use();
            break;
    }
}

//プレハブ化する関数
void CreatePrefabs() {
    foreach(GameObject go in DropList) {
        if(DropList == null) {
            return;
        }
        string prefab = saveFolderPath + go.name +".prefab";
        if(go.GetComponent<Image>() != null) {
            CreatePrefabImage(prefab, go);
        } else {
            PrefabUtility.CreatePrefab(prefab, go);
        }
    }
    DropList.Clear();
}

まとめ

今回は、複数のオブジェクトをプレハブ化する機能を実装しましたが、このエディタ拡張を使えば、自分の好きなようにカスタマイズすることができるようになります。
そうやって、Unityを自分好みに染めていってください

今回この機能を作るにあたっていくつか参考にさせていただいたサイトのリンクを載せておきます。
【エディタ拡張徹底解説】初級編①:ウィンドウを自作してみよう【Unity】
エディター拡張入門

rails で dbテーブルを truncate する

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

ruby からDBを操作するとき activerecord に頼らずにはいられません。insert, update, delete などは当然のように使っていますが truncate したいときはどうしたらよいでしょう。何故かよく忘れちゃうのでメモ

truncate するメソッドはモデルクラス用には用意されていませんでした。

ですので execute で直接 sql 文を実行します。

ActiveRecord::Base.connection.execute("TRUNCATE TABLE テーブル名;")

クラスメソッドとして登録してしまうときのサンプル

class TransactionTable < ActiveRecord::Base
  class << self
    def truncate
      connection.execute "TRUNCATE TABLE #{table_name};"
    end
  end
end

モデルには記載しないでトランザクションデータだけ削除するスクリプトを作っておくと安全かも

TRANSACTION_TABLES=TransactionTable, NotMasterTable
def clear_transaction
  TRANSACTION_TABLES.each do |transaction_model|
    ActiveRecord.execute "TRUNCATE TABLE #{transaction_model.table_name};"
  end
end

UnityでゲームのUI作りたい! 〜 物並べ編②

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

17新卒エンジニアがUnity関係で学んだことの備忘録を書きます。

はじめに

前回の記事では、Unityでシーンを作成し、キャンバス上に同じ形のボタンをVerticalLayoutGroupというコンポーネント(機能)を用いて自動配置で並べるところまで実装できました。
しかし、VerticalLayoutGroupで並べたボタンが画面外にはみ出してしまっています。

enter image description here

(前回の記事はこちら→UnityでゲームのUI作りたい! 〜 物並べ編①)

今回は、画像のようにはみ出してしまったボタン群を、スクロールしてクリック出来るようにしてみましょう。

準備

スクロールするUIを作るためには、大きく分けて
・スクロール対象となる領域
・対象を表示する領域

の二つが必要になります。

例として新幹線の窓から外の風景を眺める状況を挙げると、外の流れていく風景が「スクロール対象となる領域」にあたり、新幹線の窓が「対象を表示する領域」にあたります。
(この場合、実際に動いてるのはスクロール対象の風景じゃなくて新幹線ですが)

前回の時点で、スクロール対象となる領域の作成とボタンの配置が完了しているため、今回はまず対象を表示する領域を作成します。

enter image description here

さて、唐突ですが水色の部分が表示領域となります。
水色の領域の外にあるボタンは、たとえキャンバス上に存在していてもスクロールするまで見えないようにする必要があります。
その機能を追加する前に、この水色の表示領域の作り方をご紹介します。

前回はCanvas直下にScrollAreaというスクロール領域を作成しましたが、その間に表示領域となるオブジェクトを作成します。(本記事ではViewAreaとします)
親子関係の間に新たにオブジェクトを挟み込むため、まずCanvas直下にCreateでViewAreaを作成し、ScrollAreaをドラッグしてViewAreaの子オブジェクトにします。

enter image description here

ViewAreaを左側に寄せたかったので、PosXを-240にしています。
(前回は-160でしたが、さらに左側に調整しました。)

enter image description here

これで表示領域自体は作成できましたが、表示領域の外側にあるボタンが見えてしまっているので、自分の領域内だけ見えるようにする必要があります。
これを実現するためのコンポーネントが、 Mask です。
厳密には、マスク処理を行うコンポーネントは Mask と RectMask2D の2種類があります。

Mask

Maskコンポーネントを持っている親オブジェクトの子オブジェクトの形を、
親オブジェクトの形に制限する。
子オブジェクトが親オブジェクトからはみ出す場合、はみ出した部分が表示されなくなる。
マスクの形はImageコンポーネントに依存するため、画像次第でどんな形のマスクも作成可能。
(※画像に透過箇所がある場合、アンチエイリアスが効かないため境目が汚くなってしまいます。
綺麗な透過グラデーションを作る場合は、Mask機能を自前で実装する必要があります。)

RectMask2D

機能そのものはMaskコンポーネントと同じだが、
形が四角形(RectTransform依存)に制限される。
ただし、描画コストが少ないため、パフォーマンスはMaskより良い。

今回の表示領域は四角形なので、無駄の少ない RectMask2D を使用します。

enter image description here

RectMask2Dは、AddComponentするだけで自動的にそのオブジェクトの RectTransform を参照してマスク処理を行ってくれます。

さて、マスク処理を適用し、表示領域内のみボタンが見えるようになりました。

enter image description here

これでスクロール領域を作る準備が出来ました。
この勢いでスクロール機能を追加していきましょう。

スクロールの実装

早速ですが、スクロール機能は ScrollRect というコンポーネントで実現出来ます。
このScrollRectを、スクロールの対象となる領域(=本記事ではScrollArea)にAddします。

enter image description here

設定項目がたくさんありますね。一つ一つ見ていきましょう。

Content
 スクロール対象オブジェクトのRectTransformをアタッチします。
Horizontal 、 Vertical
 スクロールの方向を水平か垂直か決められます。
 両方にチェックを入れると上下左右にスクロール可能になります。
MovementType
 ・Unrestricted
  無制限にスクロール出来ます。
 ・Elastic
  マウス等のドラッグによりスクロール領域の端が表示領域の内側まで
  引っ張られた場合、ドラッグをやめることで表示領域の端と
  スクロール領域の端が一致するように、引っ張られたゴムが
  元に戻るような動作で自動的に戻ります。
 ・Clamped
  スクロールに制限を付け、スクロール領域の端が
  表示領域の内側に来ることがなくなります。
 ・Elasticity
  Elasticを選択した場合のみ設定可能。戻る際の弾力を設定します。
Inertia
 慣性の有無です。慣性がある場合、スクロールをやめても少しだけ
 慣性によってスクロール領域が動きます。
 ・DecelerationRate
  慣性の強さを0〜1の値で設定します。
ScrollSensitivity
 マウスのホイールや指によるドラッグに対する感度を設定します。
Viewport
 表示領域オブジェクトのRectTransformをアタッチします。
 ここでアタッチしたオブジェクトに基づいて、
 MovementTypeのElastic、Clampedが動作します。
HorizontalScrollbar 、 VerticalScrollbar
 スクロールバーがある場合、水平・垂直それぞれここにアタッチします。
OnValueChanged (Vector2)
 スクロールが行われ、位置が変わったときに呼び出されるイベントを設定できます。

これらの設定を、本記事の実装に合わせて行ったものがこちらになります。

enter image description here

スクロール対象領域をScrollAreaに、表示領域をViewAreaにそれぞれ設定し、
垂直方向のみスクロールさせたいのでHorizontalのチェックを外しています。
また、Elasticとの選択は好みの問題な気がしますが、MovementTypeをClampedにすることで見せる必要の無い部分(スクロール領域の外側) を見られないようにしました。

スクロールバー以外の設定が出来たので、とりあえず実行して動作を確認してみましょう。

enter image description here

ボタンが全て同じなのでピンと来ませんが、いい感じにスクロール出来ていますね。
MovementType:Clampedにより、必要以上にスクロールさせてもスクロール領域の端までしかスクロールしないようになっています。

スクロールバーの追加

次は、無くてもいいのですがあった方がスクロール領域っぽさが出るため、スクロールバーを追加します。
スクロールバーを実装するためのコンポーネントはScrollbarです。そのまんまですね。
スクロールバーはScrollbarコンポーネントとImageコンポーネントを自力で組み合わせて作成することも出来ますが、実はUnityのUI機能にそれらが最初から準備されています。

ViewAreaの上で右クリックし、UI -> Scrollbar を選ぶと、ScrollAreaと同じ階層にScrollbarが作成されます。

enter image description here

Scrollbarの子オブジェクトにはSliding Areaがあり、さらにその子にHandleがあります。
どれもその名の通りで、Sliding Areaはスクロールバーの可動領域、Handleはバーの掴む部分です。

enter image description here

Scrollbarコンポーネントにもたくさんの設定事項があります。
案の定、一つ一つ見ていきます。

Interactable
 スクロールバーに対して入力を受け付けるかどうかの設定です。
 Inspectorで設定することはほとんど無いと思いますが、
 ゲーム中の特定の時だけスクロール出来なくさせたい時など、
 スクリプトから設定することで効果を発揮します。
Transition
 スクロールバーの状態に応じて、バーの色や画像などを個別に設定出来ます。
 今回は ColorTint の場合のみ説明します。(状態に応じて色の遷移を行う)
 ・TargetGraphic
  遷移対象となるグラフィックです。デフォルトではHandleが設定されています。
 ・NormalColor 〜 DisabledColor
  それぞれの状態の時の色を設定します。
  上から順に、通常時、ハイライト時、押下時、無効時の色を設定出来ます。
 ・ColorMultiplier
  上記設定の明るさに倍率を設定します。暗い画像を用いる際に使うと効果的です。
 ・FadeDuration
  遷移にかかる時間を設定します。
Navigation
実行中、方向キーによってオブジェクトに対するフォーカスを切り替える際の設定です。
今回は使用しないため無視して構わないと思います。
HandleRect
HandleのRectTransformを設定します。
Direction
スクロールバーの方向を設定します。
垂直方向のスクロールならBottom To Top
水平方向ならLeft To Rightが一般的だと思われます。
Value
Handleの(初期)位置を0〜1の値により設定します。
Size
Handleのサイズを設定します。
NumberOfSteps
Handleの移動の際、段階を設けることが出来ます。
0、1なら滑らかに動き、それ以上の数の場合、数に応じて移動の段階が決定されます。
(例:3に設定した場合、初期位置、真ん中、終点の3箇所にしかHandleが移動しない)
OnValueChanged (Single)
Handleが移動した際に呼び出されるイベントを設定できます。

これらを本記事の目的に合わせて設定してみます。
…とはいえ、特に拘りがあるわけではないので、DirectionをBottom To Topに設定するだけにしておきます。
もちろん、このままではスクロールバーの位置がおかしいので、座標やサイズの調整は行います。

enter image description here

enter image description here

高さをViewAreaと同じ400に設定し、位置を右端に持ってきました。
ここで、少し話が逸れますが、UIを作る際に大事なポイントをご紹介します。


上の画像をよく見ると、今までの画像のRectTransformと違うところがあると思います。
そうです、前回の記事でチラっと触れた、Anchorの設定がされています。
このスクロールバーがどんな画面サイズでもViewAreaの右端に位置するようにするため設定したのです。
Anchorとは、親オブジェクトに対する中央座標のことでした。
つまりこのスクロールバーは、ViewAreaの右端中央を中心座標として座標を設定するようにしてあるのです。PosXもPosYも0になっていますが、中心座標(右端)=自分の座標 にしたいので、このようにしてあります。
ただし、Anchorを設定して座標を両方0にしただけでは、望む結果は得られません。
きっと、以下の画像のようになると思います。

enter image description here

スクロールバーが半分はみ出てしまっていますね。
実は先ほどのRectTransformには、もう一点、手を加えてありました。
それはPivotです。
Pivotは、オブジェクトの座標の起点のようなものだと思ってください。
Pivotは0〜1の値でX、Y座標それぞれに設定でき、デフォルトは0.5です。
Xの場合、0が左、1が右。Yの場合、0が下、1が上になります。
デフォルトのままの場合、Xの起点が0.5、つまり真ん中に設定されているので、スクロールバーのオブジェクトは自身のX座標の起点(=真ん中)と中心座標を合わせようとします。
すると、先ほどの画像のように右側半分がはみ出してしまうのです。
PivotのXを1(=右端)にすることで、右端が起点となるため、オブジェクトは右端と中心座標を合わせることになり、結果として少しもはみ出さずに表示されるのです。

このようにオブジェクトの各座標の起点 Pivotと、オブジェクトの中心座標Anchorの設定を行い、PosX、PosYを限りなく0に近づけることで、画面サイズが変動しても親オブジェクトとの位置関係を保つことが可能になります。


さて、大事な話とはいえ話が逸れてしまいましたが、これで任意の位置にスクロールバーを作成出来ました。
早速、実行してスクロールさせてみましょう。

enter image description here

そりゃ動きませんよね
当然です、ScrollRectの方に、このスクロールバーを設定していないのです。

というわけで、ScrollRectにScrollbarオブジェクトを設定してみます。

enter image description here

今回は垂直方向のスクロールなので、VerticalScrollbarのみ設定します。
すると、Visibilityという項目が出現します。これは、スクロールバーの表示設定です。

Permanent
 どんな時でもスクロールバーを表示します。
AutoHide
 (今回の例で言えば)中身のボタンの数が少ないなど、
 スクロールの必要が無い時にスクロールバーを非表示にします。
AutoHideAndExpandViewPort
 AutoHideの機能に加え、スクロールの必要が無い時に
 表示領域を拡大して表示します。

今回はAutoHideを選びました。
実際のゲームでも、スクロールバーはあるけどスクロールの必要が無いなんてUIはなんだか変な感じがしますよね。(※個人の感想です)

さて、これでようやくスクロールバーが真の力を発揮できます。

enter image description here

うまくいきましたね。
ちなみに、ScrollAreaのAnchorをcenter・top(上端真ん中)、Pivot(Y)を1にして、PosYを0にすることで、ScrollAreaのスクロール初期位置を一番上にしてあります。
(これを設定しないと、スクロールが真ん中から始まると思います)

まとめ

今回も長くなってしまいましたが、無事にスクロール機能を実装することが出来ました。
少しだけ、おさらいをしましょう。

・マスク処理はMaskまたはRectMask2Dコンポーネント
・スクロール領域にはScrollRectコンポーネント
・スクロールバーにはScrollbarコンポーネント
AnchorPivotを適切に設定して表示ずれを防ぎましょう

次回は、少し話題の違った記事を書きたいと思います。

それでは、長々とお付合いいただきありがとうございました。

Ruby/Rails に潜む罠 (find_by編)

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

ActiveRecord::Baseのクラスメソッドの中で最も基本的なメソッドの内の1つである find_by 。Railsを使う案件では頻繁にソースコードの中に現れるだろう。 この至極基本的なメソッドに、実は罠が潜んでいて、稀な条件下では発動する可能性がある。 (条件がレアな為、ほとんど発動しないけれど)

find_by の基本的な使い方

モデル(モデルインスタンスではない)をレシーバにして、引数に条件をハッシュまたはSQL文字列をセット。
返り値はモデルインスタンスとなる。

例1

Artist.find_by(name: 'The Beatles')
# SELECT `artists`.* FROM `artists` WHERE `artists`.`name` = 'The Beatles' LIMIT 1

例2

Artist.find_by("name = 'The Beatles'")
# SELECT `artists`.* FROM `artists` WHERE (name = 'The Beatles') LIMIT 1

罠が発動する条件

モデルに対するテーブルが動的に変化する場合

class Artist < ActiveRecord::Base
  self.table_name = :artists_1 # デフォルトの参照テーブル
end
# 参照テーブルを切り替えるクラス
class TableSwitcher
  def self.exec
    if Artist.table_name == :artists_1
      Artist.table_name = :artists_2
    else
      Artist.table_name = :artists_1
    end
  end
end

この条件は、Railsの規約には沿っていない。つまりRailsの規約に全て沿っていれば、本記事の内容は気にする必要はない。
大半の案件はRailsの規約には沿うだろうが、大量データ更新の為、2つのテーブルを、TRUNCATE+INSERTしながら交互に参照を切り替えていく方針を取っている場合、この問題に直面する事になる。

罠が発動する条件下でfind_byを使うとどうなるか

Artist.table_name # => artists_1
Artist.find_by(name: 'The Beatles')
# SELECT `artists_1`.* FROM `artists_1` WHERE `artists_1`.`name` = 'The Beatles' LIMIT 1

TableSwitcher.exec # 参照テーブル切り替え

Artist.table_name # => artists_2
Artist.find_by(name: 'The Beatles')
# SELECT `artists_1`.* FROM `artists_1` WHERE `artists_1`.`name` = 'The Beatles' LIMIT 1

参照テーブルは切り替わっているはずなのに発行されるSQL中の参照しているテーブル名が切り替わっていない!
これでは、(テーブルを切り替えて)データを新しても、実際は参照するデータが古いままになってしまう可能性がある。

原因

デフォルトのfind_byメソッドは発行したSQLをキャッシュする。(ActiveRecord::StatementCache)
よって、参照テーブルを切り替えた後でも、切替前のキャッシュが残って、切替前のテーブルが参照されてしまう。

対処方法

罠が発動する条件に該当するモデルでは、デフォルトのfind_byが使用されないよう、クラス内でオーバーライドし、where+firstに書き換える。
whereメソッドはキャッシュされないので、この対処が可能となる。

class Artist < ActiveRecord::Base
  self.table_name = :artists_1 # デフォルトの参照テーブル

  class << self
    def find_by(*args)
      where(*args).first
    rescue
      super # 例外処理はスーパークラスに任せる
    end
  end
end

注意点

rubocop を導入している場合は、「where+first は find_by と書き直せ」という警告が出る。
意図的にwherefirstに分けている訳なので、該当部分だけ以下のようにrubocopチェックの対象外とする必要がある。

def find_by(*args)
  # rubocop:disable Rails/FindBy
  where(*args).first
rescue
  super
end

【Rails】gem ‘global’の使い方【global】

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

環境ごとに値を設定する場合よくgem ‘config’が使われますが、個人的にgem ‘global’の方が使いやすいと思うので紹介します。

gem ‘config’との違い

gem ‘config’との大きな違いは.ymlファイルの持ち方です。

gem ‘config’

config/settings.yml
config/settings/development.yml
config/settings/production.yml
config/settings/test.yml

config/settings.yml

web_domain: localhost
api_domain: api.local

config/settings/production.yml

web_domain: web.com
api_domain: api.com

gem ‘config’は環境ごとに.ymlを持つのに対し、gem ‘global’は機能ごとや値の種類ごとにファイルを持つ形になります。

gem ‘global’

config/global/domains.yml

default:
  web: localhost
  api: api.local

development:
  web: localhost
  api: api.local

production:
  web: web.com
  api: api.com

test:
  web: test.com
  api: api.test.com

導入方法

1.Gemfileにgem ‘global’の追記

gem 'global'

2.config/initializers/global.rbの作成

Global.configure do |config|
  config.environment = Rails.env.to_s
  config.config_directory = Rails.root.join('config/global').to_s
end

使い方

基本

> Rails.env
=> "development"

> Global.domains
=> { "api" => "api.local", "web" => "localhost" }

> Global.domains.api
=>"api.local"
> Rails.env
=> "production"

> Global.domains
=> { "api" => "api.com", "web" => "web.com" }

> Global.domains.api
=>"api.com"

名前空間付き

config/global/name_space/domains.yml

> Global.name_space.domains
=> { "api" => "api.com", "web" => "web.com" }

> Global.name_space.domains.api
=> "api.com"

ネストを入れる

config/global/domains.yml

default:
  nest:
    web: localhost
    api: api.local

development:
  nest:
    web: localhost
    api: api.local

production:
  nest:
    web: web.com
    api: api.com

test:
  nest:
    web: test.com
    api: api.test.com
> Global.domains.nest
=> { "api" => "api.com", "web" => "web.com" }

> Global.domains.nest.api
=> "api.com"

ERB

config/global/domains.yml

default:
  web: localhost<%= 1 + 2 %>
  api: api.local
> Global.domains.web
=> "localhost3"

リロード

> Global.reload!

他にもjavascriptで使えたりするのでぜひ使ってみてください。

キーフレームアニメーション、絵コンテ制作

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

はじめに

この記事はspritestudioを使用する前提で書いております。
他のソフトには対応できない部分もありますのでご了承ください。

こんにちは、2Dモーションを勉強中のなすちゃです。
今回も自身の復習用にまとめていきます。

絵コンテとは

アニメーションとしてものを動かすことに関して必要になってくるのが絵コンテになります。
映像物を作る前にイラストなどで1つのカットを説明するものになります。

いきなり物体を動かすのではなく「こんな動きにしたい」「ここのシーンは尺を長くする」など設計図を組み立てていきます。
漫画のネームみたいなものですね。

自身で製作したものをわかりやすくまとめるものとして大切ですが、仕事として通す際には様々な人とチームとして製作します。食い違いや説明不足にならないようにする役割でもあります。

案出し

コンテを作る前に、このモーションはどの場面をイメージしているのかおおまかなプロットを考えるとやりやすいです。

たとえば、キャラの走るモーションを考えてみます。
走るといっても場面により演出が変わっていき様々なパターンが生まれます

・どんな場面で走っているのか
・喜怒哀楽が含まれるのか
・キャラの個性

など、基礎にある世界観・キャラクターの設定をもとに感情が含まれる動きを考えます。
今回は女の子のキャラクターを使用していきます。

・道を走るなど移動する場面をイメージ
・軽やかに走り、余裕のある表情
・長いスカートを身につけているのでフワッと揺れるように

ざっと思いついたネタを出していき、そこから組み合わせていくのも面白いと思います。

いざ、コンテを製作します。

キャラクターはキーフレームを打てるよう手足・頭部・胴体など各パーツに分かれたテクスチャを使用していますが、相手に伝われば手描きのスケッチでも棒人間などでも構いません。
各製作現場に沿ったスタイルで行いましょう。

プロットに沿ってキャラクターを動かしていきますが、
実際にコマ切をしていると当初のイメージに追加したい要素やここはこうした方が可愛くなるのでは…!というアイディアも出てきます。

enter image description here

この場合も、より個性が表現出来るように表情差分の追加をしました。
瞬きや笑う要素一つ加えるだけでも見栄えが変わっていきます。

ループで走っているように見せたいため、始まりと終わりに同じポーズを入れ後半に走りながらふと笑う要素を組みました。

こういったコンテから考えていくとモーションが制作しやすくなります。
自分がどういう動きをさせたいか、楽しんで案をだしていくことが大切だと思います。

簡単デザイン。ThemeRollerを使う

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

Webページに欠かせないボタン、フォーム、セレクトメニュー…。 デフォルトのものを使うと味気ないけれど、サイトの雰囲気にあったものを0から作るのはなかなか難しい… そんなときの強い味方。そんな「ThemeRoller」について紹介します。

http://jqueryui.com/themeroller/

上記URLにアクセスすると、アコーディオンメニューやボタン、チェックボックスなどのサンプルが並んでいます。

enter image description here
▲ボタンやオートコンプリートは、実際に押したり入力したり出来ます。

左にあるツールバーで、フォントや色合いを調節できます。
調節したものは右のサンプルで即確認でき、分かりやすいです。

enter image description here
▲背景のテクスチャなども設定可能。

基本的には、デフォルトのデザインをこのツールバーで調整し、
理想のデザインに持っていくのですが、
「デフォルトのデザインが理想と離れ過ぎていて調整が面倒…」という場合もあります。

そんなときはツールバーの「Gallery」タブをクリック。
ThemeRollerにあらかじめ用意されたテーマがずらりと表示されます。
それぞれのテーマの横にある「Edit」をクリックすると、そこから調整が出来ます。
自分の理想イメージに近いテーマから、調整していきましょう。

enter image description here
▲現時点で25種類のテーマが用意されています。もちろんこれをそのまま使うのもアリ。

調整が出来たら、「Download theme」をクリック。
作ったスタイルシートをまるまるダウンロードできます。
ダウンロードしたスタイルシートをWEBページで読み込むようにすれば完成です。


ThemeRollerではGUIで各フォームやボタン等のスタイル調整が簡単に出来ます。
ただし、ボタン間のマージンや、枠線の太さなどはサポートされていないので、
細かい部分は自分でCSSを改修する必要がありますが、
大まかにデザインをするのには便利だと思います。

【git】コミットログ散らかした!ログを編集する方法

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

コミットログの編集の仕方を簡単にまとめてみました。

はじめに

最近東京に馴染んできた(気がする)Be82Mです。
自分が業務上よくcommit漏れしてしまったり、ちょっと実装してはコミット、とちまちまコミットしてログを散らかしがちなのでpush前にコミットをまとめたりするのですが、どうだったっけ?と調べたり時間がなくて結局そのままpushしてしまったり…ということが何度もあったので、今回備忘録としてコミットの改ざんの仕方を自分なりにまとめることにしました。
 

手順

今回コミット漏れした場合を例にします。

とりあえずコミット漏れしたファイルをaddして再度コミットします。

h82w-no-MacBook-Pro:file Be82M$ git commit -m "コミット漏れ"
[branch_name f40110a] コミット漏れ
 1 file changed, 2 insertions(+)

ログを確認すると当然ですがコミットログに修正したのが残っています。

h82w-no-MacBook-Pro:file Be82M$ git log
commit igtismsmehyoowutrilmoevmeodvreihveorttafbaesaiton
Author: Be82M <be82m@doruby.com>
Date:   Mon Jul 24 18:19:48 2017 +0900

   コミット漏れ

commit deaomcwmhniadgnoecwcennsaedtamnenfarweie
Author: Be82M <be82m@doruby.com>
Date:   Mon Jul 24 12:29:35 2017 +0900

    A機能実装完了
 

ここで改竄コマンドgit rebaseが登場です。

$ git rebase -i branch_name~number

branch_name: コミットを消したいブランチの名前
number: コミットログの表示数

これを実行するとテキストが開きます(稀にテキストエディタ等で開くことがあるそうですが、大概vimで開きます)

  1 pick d83743a B機能実装
  2 pick d99647d A機能実装
  3 pick f40110a コミット漏れ

消したいコミットである3行目のpickをfもしくはfixupに書き換えます。
※このオプションについては後述しています。

  1 pick d83743a B機能実装
  2 pick d99647d A機能実装
  3 fixup f40110a コミット漏れ

変更を保存して閉じます。
もう一度ログを確認して見ます。

h82w-no-MacBook-Pro:file Be82M$ git log
commit deaomcwmhniadgnoecwcennsaedtamnenfarweie
Author: Be82M <be82m@doruby.com>
Date:   Mon Jul 24 12:29:35 2017 +0900

    A機能実装完了
 

これでログをまとめることができました。
 

オプション

git rebaseしたときに開くvimの下部にも書いてありますが、毎回英語は読みたくないのでまとめておきます。

  • p, pick

 コミットを使用する
 そのままコミットを残す場合はこのコマンドのままにしておく。

  • r, reword

 コミットメッセージを編集してこのコミットを使用する

  • e, edit

 コミットをなかったことにする(またpickに戻せばコミットは戻ってくる)

  • s, squash

 コミットを前のコミットと融合する

  • f, fixup

 コミットを前のコミットと融合するが、コミットメッセージを破棄する

  • x, exec

 後に書かれたコマンドを実行する

絶対いらない保証もないので実際にやったことはないのですが、行自体を消すとその行に該当するコミットそのものが完全に消えてしまうようです。
間違って消してしまわないように気をつけましょう…!
 

最後に

業務上欠かせないgitですが、理解しきれておらずgitについて書いてある参考書やサイトを渡り歩いてる段階です。
まだまだ打ったことないコマンドもたくさんあり、そういった実際に体感していないものは全然身になっていないのでコマンド打つたびに怯える日々です。
状況に応じていろんなコマンドを少しずつ使ってマスターしたいと思います。

肥大化するAIと対峙する時に覚えておきたいこと

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

戦略的に切り崩していかなければ、立ち向かえない可能性もあります。

はじめに

みなさん、お久しぶりです。
新卒エンジニアのくろすです。

さて、残念ながらこの記事には最近話題のAIの話はほとんどありません。

言い訳

いや本当はMNISTのDataSetから手書き数字認識をやってみたって話を書こうと思ってたんです。今月半ばまでは。
弊社はrubyistが多いので、rubyでNNを書いて簡単に説明してみたってやるつもりだったんです。
昔MATLABで書いたプログラムがどっかにあるから、ピャーって書いちゃおうって。

9割遊びだからお家で作業を進めてるんですよ。
rubyでMNISTのデータセット取ってきて、バイナリデータだからそれを画像ファイルに変換してですね。
そして、こう、アニメがですね、アニメを見てるとですね……

rubyでNN作るやつはそのうち記事にはします。

そもそもAIとは

AI流行ってますよね。
映画でも機械学習がーって話があったり、ギークがリア充にボコボコにされたり、出身大学が悪の巣窟扱いされたり。

じゃあそもそもAIってなんですかって話です。
Artificial Intelligence
コンピュータ上で知能を実現しようとする試みやそれに関連する技術がそう呼ばれているよう思います。
人工知能学会の人工知能って何?には以下のように書かれています。

「人工知能」とは何だと思うでしょうか?まるで人間のようにふるまう機械を想像するのではないでしょうか?これは正しいとも,間違っているともいえます.なぜなら,人工知能の研究には二つの立場があるからです.一つは,人間の知能そのものをもつ機械を作ろうとする立場,もう一つは,人間が知能を使ってすることを機械にさせようとする立場です(注1).そして,実際の研究のほとんどは後者の立場にたっています.ですので,人工知能の研究といっても,人間のような機械を作っているわけではありません.

学習や推論をするゲームのAIだと囲碁や将棋が有名ですよね。
ニューラルネットワークなどの手法で学習を行なっているようです。

ゲームのAIって???

学習や推論等を行わないゲームのAIの場合は、なんらかの単語をトリガーに会話を返す人工無脳と似たような存在です。
条件分岐に従った行動しか取れない、要するにただ設定されているだけの戦略と言い換えてもいいかもしれません。

かなり適当ですがこんな感じです。

class AI

  def initialize(code)
    @code = code
  end

  def select_action(code)
    send("select_action_#{code}")
  end

  # ここからAI
  def select_action_1
    # 1の倍数のターンだけアホになる
  end

  def select_action_2
    # 2の倍数のターンだけアホになる
  end
  alias :select_action_4 :select_action_2 
  # code:4のAIはやっぱり2の倍数の時もアホになった方がいい感じ

  def select_action_3
    # 3の倍数のターンだけアホになる
  end
end

sendメソッドで動的にメソッドを呼び出すことで大量のcase文が並ぶことは避けられていますが、このクラス自身が全ての戦略を知っているということは様々な問題に繋がります。
AIが増えるにつれ条件分岐が増え、空は堕ち、大地は割れ、海が涸れます。
こんなところで死ぬわけにはいかないので大問題です。

生存戦略

さて、この肥大化する戦略群と向き合うとしましょう。
うまいこと戦略を切り分けてあげないと、とてもじゃないけど生き残れる気がしません。
取替え可能な戦略をうまいこと使いたいなぁ……
戦略を切り替えたいなぁ……
そうStrategy Patternの出番です。

module AIManager
  @codes_to_ai = {}

  def self.set_code_to_ai(klass, codes)
    codes.each do |code|
      @codes_to_ai.merge!({code => klass})
    end
  end

  class NotIntelligence < StandardError; end

  def self.get_ai(code)
    # ai = AIManager.get_ai(code).new(code)のように呼ばれた時の大域脱出で使う
    raise NotIntelligence unless @codes_to_ai.keys.include?(code)
    @codes_to_ai[code]
  end

  module StrategyInterface
    OVERRIDE_PROHIBITION = [:initialize].freeze

    def self.included(klass)
      klass.define_singleton_method(:method_added) do |symbol|
        if OVERRIDE_PROHIBITON.include?(symbol)
          raise "Do not override : #{symbol}" 
        end
      end
      AIManager.set_code_to_ai(klass, klass::CODES)
    end

    def initialize(code)
      @code = code
    end

    def select_action
      raise "Called abstract method : select_action"
    end
  end
end

このようなInterfaceを作り、AIManager.get_ai(code)を介して各AIクラスにアクセスすることで、codeさえわかれば欲しいAIを引っ張り出すことが可能です。
StrategyInterface 内で定義されているincludedというのはモジュールがincludeされた時にrubyが呼び出すメソッドで、引数にはclassが自動的に入ります。
Interfaceにせずにabstractなクラスを作っても良いのですが、同じことをやろうとしても、クラスが継承された時に呼ばれるinheritedメソッドは

class Hoge < SuperClass

のような一文を解釈した時に呼ばれてしまうためうまくcodeを管理者に渡せません。

module AIManager
  class AlwaysAho
    CODES = [1].freeze
    include StrategyInterface
    def select_action
      # 1の倍数のターンにアホになる
    end
  end

  class UsuallyAho
    CODES = [2, 4].freeze
    include StrategyInterface
    def select_action
      # 2の倍数のターンにアホになる
    end
  end

  class SometimesAho
    CODES = [3].freeze
    include StrategyInterface
    def select_action
      # 3の倍数のターンにアホになる
    end
  end
end

アホになる頻度でAIのクラスの名前を変更することに成功しました。
実際に使う側からはこのAIクラスが本当にAIかはどうでもよく、select_actionが呼べてたまにアホになれば、それはAIだというふうに捉えていきます。
アヒルのように歩きアヒルのように鳴くものはアヒルに違いない。ということです。

終わりに

アホになれないcodeを割り振られた子たちはNotIntelligenceエラーを返されるという、なんとも分かりにくい説明コードを書いてしまいました。
こんな書き方はしてますがrubyでのStrategyパターンではconcreat strategyはlambda式を使った方が良さそうな気がします。

話はちょっと変わりますが、醜いアホの子が実は人工知能だったら面白くないですか???
暇と余裕とゆとりがあれば、そのうち機械学習をアホの子に突っ込んでみたいなぁって思いました。

立ち絵を魅力的に描く①【ポーズと表情でキャラクターを伝える】

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

はじめに

nocoです。暑い日々が続いており、液晶ペンタブレットの発熱が気になる今日この頃です。

今年の春に入社してから1ヶ月間ほどキャラクターの立ち絵制作の業務に携わらせていただきました。私自身立ち絵への理解が浅く、短い期間の中でもたくさんの発見がありました。

立ち絵は、その性質上ゲームの中で長時間目にする重要なグラフィックです。
そんな立ち絵を魅力的に描くためのポイントを共有したいと思います。

立ち絵とは

enter image description here
弊社・株式会社アピリッツ運営のMMORPG「かくりよの門」の会話シーン

立ち絵とは、その名の通りキャラクターの立ち姿を描いたイラストのことです。
主にノベルゲームやアドベンチャーゲームの会話シーン(ストーリーパートなど)に用いられます。
会話シーンという性質上、複数のキャラクターが並ぶことが多いため「動」ではなく「静」の印象を受けるポーズで描かれることがほとんどです。

多くの場合、キャラクターごとにそれぞれ表情の差分を用意します。
異なる表情をシーンの状況に合わせて表示することで止め絵ながら会話を華やかに演出することができます。
また、必要に応じて表情の他にもポーズ差分や衣装差分が用意されることもあります。

立ち絵はキャラクターの外見を伝えることは勿論ですが、「誰がどういった表情で話しているか」を視覚的に伝えることができます。
小説でいうところの地の文が必要なくなり、会話のテンポも良くなりますね。

キャラクターを作ろう

立ち絵の描き方についてお話する前に、前提となるキャラクターデザインのことを簡単にお話させていただきます。
ゲーム制作の現場では依頼としてこういったキャラクターを作ってくれ!と指定がある場合がほとんどですが、自分で1からキャラクターを作ることもあります。

最初に、描きたいキャラクターの設定を文字で書き出してみましょう。

【外見】性別・年齢・髪型・服装 など
【内面】性格・信念・声・話し方・過去 など


筆を動かしているうちに良いアイデアが浮かぶことも多いので、最初から完璧な設定を作り込む必要はありません。設定を元にイメージスケッチを描き、デザインが固まったら立ち絵の制作に入ります。

外見はもちろんですが、内面をしっかりと作り込んでおくことでキャラクターが活き活きとしてくるように感じられます。
キャラクターの内面の情報をどこまで視覚的に伝えられるかがデザイナーの腕の見せ所です。
設定の段階からキャラクターの要素を立ち絵の中にどう盛り込んでいくかイメージしておくと良いですね。

キャラクターデザインについて詳しく知りたい方は、本やWeb上に専門的な講座や記事があるためそちらをご覧ください。
次項より、立ち絵を魅力的に描くポイントについて解説していきます。

立ち方で人柄を表現する

立ち絵において、キャラクターの立ち方はとても重要です。

まず、ベースとなる素体を用意します。6頭身の何の変哲もない少女です。
enter image description here
この素体を、4つの性格をイメージしてそれぞれポーズを取らせました。
enter image description here
体型は同じでも、ポーズを変えるだけでまるで別人のようになります。
このように、立ち方ひとつでキャラクターの人柄を表現することができます。

棒立ちではキャラクターの魅力が十分に伝わらず、人形のように生気のない印象を受けます。
意図してそういった表現をしたいのでなければ、どこか一か所でも動きをつけてあげましょう。
片手や片足を動かすだけでもキャラクターが活き活きとしてきます。

例にあげたような「元気」「内気」という括りの中でもさまざまな種類があります。
キャラクターのイメージを膨らませ、それに合った最適なポーズを決めてあげましょう。

表情でさらに魅力的に

前述したように、立ち絵にはベースの表情に加え基本的な喜怒哀楽の表情が用意されます。
目の伏せ方や眉の位置、口の開け方など、パーツを一部描き変えて表情を作っていきます。
手間は掛かりますが、差分の種類が多いほどキャラクターの個性を繊細に伝えることができます。

先ほどの「元気」ポーズを元に1人のキャラクターを描き起こしました。
enter image description here

このキャラクターに喜怒哀楽の表情を付けてみます。

enter image description here

元気な子というポーズからの情報に加え、差分によって表情がコロコロと変わる感情豊かなキャラクターということが伝わるかと思います。
立ち方に加え、表情でさらにそのキャラクターの人柄を掘り下げることができます。
特に、外見と内面にギャップのあるキャラクターはその魅力をアピールするチャンスです。

一口に喜びと言ってもさまざまな種類があります。
大きく口を開けてニカッと笑ったり、目を細めて優しく微笑んだり…これだけでも与える印象が大きく変わります。
キャラクターたちが皆同じ顔をして笑うなんてことはありませんよね。

立ち方と同様に、キャラクターのイメージを膨らませて魅力的な表情を引き出してあげましょう。

まとめ

今回は立ち絵の根幹となるポーズと表情を描くポイントについて書かせていただきました。
ポーズや表情だけでもキャラクターの個性を引き出せているのなら、衣装や装飾を描き込んでいくことでさらに魅力が増していきます。
ベースをしっかり作り込んでおくことで描画もスムーズに進めることができます。

立ち絵を描くときには、頭の中で動き出すくらいキャラクターのことをたくさんイメージしてあげるのが大切です。
また、日頃から既存のアニメやゲームのキャラクターの魅力や特徴がどこに表れているのか考えて観察してみると良いかもしれません。

次回も立ち絵についてのお話を続けて書きたいと思います。

Googleデータポータルの計算フィールドが役立つ!REGEXP_MATCH関数編

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

Googleデータポータルの計算フィールドでは正規表現を使った記述が可能です。一致条件の正規表現に使えるのがREGEXP_MATCH関数。特定のルールに一致するデータをフィルタリングすることができ、CASE関数などと組み合わせると実用の幅が広がります。REGEXP_MATCH関数の使い方について、実例を踏まえてご紹介いたします。

この記事でまとめられていること

こんにちは。株式会社アピリッツでアナリストをしているssekiです。
以前、Googleデータポータルの計算フィールドでCASE関数の使い方について記事を書きました。
CASE関数は置換・統合を行う際にとても役立つということで実例を踏まえてご紹介しました。
CASE関数があるからマイレポートの代わりにデータポータルを使ってみよう、という方も多いのではないでしょうか。
ただし、アナリティクスとデータポータルでは仕様や記述方法が違う部分も多々あり、難しく感じることもあるでしょう。

今回紹介するREGEXP_MATCH関数はCASE関数と一緒に使って、データの抽出条件を正規表現で記述することができる関数です。
REGEXP_MATCH関数が使えるようになると、Googleアナリティクスの「計算指標」の代わりに計算フィールド上で正規表現が使えるようになります。

※計算指標は1ビューあたり5個までしか作成できませんが、計算フィールドは無制限に作れます。そのため、多数の計算指標を作成したいとの悩みを抱えているならば、Googleデータポータルの計算フィールドがおすすめです。

今回は、Googleデータポータルの計算フィールドで正規表現を使う方法、第一弾として一致条件ができる「REGEXP_MATCH関数」についてご紹介します。

正規表現とは

まず簡単に正規表現についておさらいしておきましょう。
正規表現とは、「いろんな文字列を一つの文字列で表現するための記述方法」です。
例えば、こんな例を考えてみましょう。
以下のようなページURLがあるとします。

20170701.php
20170702.php
20170703.php
...
20170731.php

ブログなどでは、このように投稿日をページURLにしている例がよく見られますね。
このうち、2017年7月1日~2017年7月7日までの1週間に書いたブログ記事のPV数を計測したいとします。
まず、Googleアナリティクスの正規表現にしたがって対象のブログ記事を抽出するよう記述してみます。

(20170701|20170702|20170703|20170704|20170705|20170706|20170707)\.php

ここでは、3つの正規表現記号が使われています。
()と|と\ですね。それぞれ丸カッコとパイプとバックスラッシュと呼びます。
まず、丸カッコは「他の正規表現をグループ化」する記号です。丸カッコで囲われている正規表現はカッコ内でしか効果を発揮しません。
次に、パイプは「OR条件」を意味します。
最後に、バックスラッシュは「次の正規表現記号を打ち消し」、普通の文字として解釈します。
実は、「.」(ドット)も正規表現記号として使うことができるため、その効果を打ち消すために使っています。
つまり、先ほどの正規表現を日本語に直すと、

「20170701か20170702か20170703か20170704か20170705か20170706か20170707」と「.php」がついている文字列

となります。
でも、この書き方だと選択する数が増えたとき大変です。今回1週間分を例にしましたが、1か月分だと最大31個も入れなきゃいけないですよね。
この他にもいろいろな正規表現記号があり、今回の例をもっと楽に書くこともできます。
例えば、こんな感じに。

2017070[1-7]\.php

新たな正規表現記号として[]と-を使いました。読み方は角カッコとハイフンです。
まず、角カッコは「囲まれた文字が任意の順序で文字列に含まれる場合」を表す記号です。
そして、ハイフンは「角カッコ内の文字範囲」を表します。
この二つは合わせて使うことが多く、先の[1-7]は「1から7までの範囲の数字を含む」を表すようになります。
先ほどの正規表現を日本語に直すと、

「2017070」の次に「1から7までの範囲の数字を含み」、その後「.php」がついている文字列

となるので、今回の条件では最初の例と同じ文字列と一致することがわかりますね。

説明が長くなりましたが、Googleアナリティクスではこのような正規表現記号を使うことができ、データから必要な分だけを抽出することを助けています。
その他の正規表現を知りたい人は公式のヘルプページを見てみてください。

計算フィールドでの正規表現の使い方

さて、ここまでGoogleアナリティクス上での正規表現記法についてご紹介いたしました。
実はGoogleデータポータルの表やグラフで用いるフィルタ機能では、アナリティクスと同じ正規表現をそのまま使います。
ただし、計算フィールドだけは特殊で、アナリティクスの正規表現をさらに高機能にしたもの(使える正規表現記号が多くなったもの)を用いることができます。
その方法の一つが今回紹介するREGEXP_MATCH関数です。
REGEXP_MATCH関数は「Google RE2」という正規表現を使ってフィールドの式と一致するものを抽出する関数です。
先ほどと同じ例を考えてみましょう。

20170701.php
20170702.php
20170703.php
...
20170731.php

このうち、2017年7月1日~2017年7月7日までの1週間に書いたブログ記事を抽出するには次のように記述します。

CASE WHEN REGEXP_MATCH(ページ,"2017070[1-7]\.php") THEN "2017年7月1日~2017年7月7日" END

REGEXP_MATCH関数ですが、CASE関数との相性がとてもよい関数です。
ちなみに、CASE関数は置換するのに使った関数でしたね。詳しくは「Googleデータポータルの計算フィールドが役立つ!CASE関数編」の記事を参照していただければと思います。

REGEXP_MATCHはカッコ内に2つの変数をとります。
REGEXP_MATCH(X,Y)と置くと、Xに当たるのが「抽出元となるディメンションあるいは指標」です。
そして、Yが「一致条件の条件式」に相当します。
この例ではXに「ページ」、Yに「先ほどの正規表現」を設定することで、THENの後に記述された「2017年7月1日~2017年7月7日」という文字列に条件に一致したページ群がまとめられます。

あとは、お好きな表やスコアカードでページビュー数を指標にセットしていただければ、2017年7月1日~2017年7月7日までの1週間に書いたブログ記事のPV数を計測することができますね。

Googleデータポータルでアナリティクスのデータ管理が可能に!

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

Googleデータポータルに新機能が追加され、アナリティクスデータを閲覧レポート上で切り替えることが可能になりました。データポータルの閲覧権限だけで複数のアナリティクスデータを使えるので、情報共有のリスクが減る機能といえます。今回はデータ管理機能の使い方についてご紹介いたします。

この記事でまとめられていること

こんにちは。株式会社アピリッツでアナリストをしているssekiです。
最近Googleデータポータルを使う機会が多くなり、作成したレポートを共有することが多くなりました。
データポータルは共有が簡単な反面、編集権限を与えていると知らぬ間に誰かに書き換えられていて困ることもしばしば・・・。
そんな不満を持っている最中、Googleが7月14日に神アップデートしてくれました!
enter image description here

「データ管理・・・?」

これを見つけた時の僕の気持ちです。
とりあえずググったのですが、日本語ページが何ひとつとして見つからなかったのでGoogleヘルプページ(英語版)を参考に使い方を理解しました。
今回は、データソースのGoogleアナリティクスビューをレポート上で変更できるデータ管理の機能について、使い方を交えてまとめてみました。

Googleデータポータルのデータ管理とは

Googleデータポータルの共有権限には2種類あります。

  1. 編集者権限:リンクURLを知っていればレポートを閲覧・編集どちらも可能
  2. 閲覧者権限:リンクURLを知っていればレポートを閲覧可能だが、編集は不可

1つのデータソースだけを定点観測する分には閲覧者権限のみでも問題ないのですが、複数のデータソースを見たり適宜フィルタリングをかけたり編集したい場合には編集者権限が必要でした。

しかしながら、複数人が勝手にレポート内容を変えると管理が煩雑になり、結構面倒くさくなります。
それを防ぐために、これまではデータソースごとに同じテンプレートのレポートを複数作成することで対応していました。(これも管理が面倒ではあるけど)

そんな状況で、データ管理が役立ちます。
データ管理はざっくりいうと「閲覧者権限でもレポートで使われているデータソースを(アナリティクスに限り)変更できる機能」になります。

データ管理の使い方

データ管理の使い方は極めて簡単です。まず、普通にレポートを作成しておきます。
とりあえずGoogle Merchandise Storeのデータを使って、メディア別のセッション数を表にしてみました。
enter image description here
次に、データ管理をクリックした状態で長方形を書きます。
enter image description here
「ビューを選択」が出ましたね。この状態で閲覧画面に戻りましょう。
するとこのように表示されます。
enter image description here
「ビューを選択」をクリックすると自身が持っているアナリティクスの閲覧権限一覧が表示されます。
変更したいビューにカーソルを合わせてクリックすることで、レポート内の全データを変更することができます。
enter image description here
新卒コミュニティサイトのデータを使って表のデータを入れ替えてみるとこんな感じです。
enter image description here
現在表示しているアナリティクスビューの名前が表示され、表のデータが変更されました。
ほぼワンタッチで変更できるので、データポータルに慣れていなくても簡単に使えます。

データ管理を使う際の注意点

簡単に使えて有用なデータ管理ですが、いくつか問題点もあるため記載しておきます。

1つ目に、アナリティクスデータだけしか対応していないことです。
もし、Search ConsoleやAdwordsなどの他のデータソースを切り替えたいと思っている場合、現段階ではデータ管理の機能を使用することはできません。

2つ目に、アナリティクスビューの閲覧権限を持っていなければいけないことです。
データポータルのレポートにデータソースとして使われている場合はそのまま見ることができますが、データ管理として変更する場合には閲覧者自身が該当のアナリティクスビューの閲覧権限を持っている必要があります。

1つのレポート内で複数のデータ管理をする方法

上記では、データ管理によってレポート内の全データを総入れ替えする方法についてご紹介しました。
実際のレポート内で使うには場面が限られますが、1つのレポート内で異なるデータ管理を2つまで切り替える方法を見つけたのでご紹介いたします。

先ほど作ったレポートを利用して説明します。
まず、表とデータ管理をそれぞれコピーします。(わかりやすいように並べました。)
enter image description here
レポート上にある表やグラフなどすべての要素には、レベルというものが存在します。
データ管理で変更しているデータは同じレベルのものを変更しているため、レベルを変更することで異なるデータ管理の効果を受けることができます。

デフォルトでは、「ページレベル」に設定されているので、左側の表とデータ管理を「レポートレベル」に変えてみましょう。
表にカーソルを合わせて右クリックすると図のように表示されるので、「レポートレベルに変更」をクリックすると変更できます。
enter image description here
ちなみに、もう一度同じことをすると「ページレベルに変更」と文言が変わって、「ページレベル」に変更できます。
左側の表と「ビューを選択」をページレベルに変更した後、閲覧画面に戻ります。
左側の「ビューを選択」のみを変更してみます。すると、左側の表だけが変更されました。
enter image description here
右側についてもアナリティクスビューを変更することで、右側の表だけが変更されます。
このように、レベルを変更することでデータ管理を複数設置することも可能です。

まとめ:データ管理はどんなときにおすすめか

データ管理は閲覧者権限でもアナリティクスデータのビューを変更することができる機能でした。
アナリティクスビューごとにデータポータルレポートを作成するとなると作成も管理も面倒ですが、ひとつのレポート上で切り替える分にはワンタッチなのでお手軽です。
今回はチーム内での共有に視点を置いて説明しましたが、その他にも例えば次のようなことに使えるかなと思います。

  1. テンプレートとなるデータポータルレポートをコンサルに作成してもらい、他のアナリティクスビューでも使いまわす
  2. 報告や会議にデータポータルレポートを使う場合、質問に答える際に他のビューで見た場合の結果をすぐに表示できる

これまでの流れからすると、Googleアナリティクスのマイレポートにあるソリューションギャラリーのように、いろんな人がデータポータルレポートのテンプレートを作成して公開するようになるのかもしれないな、と思います。
今後のアップデートに期待ですね!

JMeterでCSRFトークンを取得する方法

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

WEBサイトの負荷テストに便利なツール JMeter で、CSRFトークンを取得する方法をご紹介します。

CSRFトークン

CSRF対策として、入力フォームにhiddenでトークンを埋め込んでいるサイトは多いと思います。
最近ではフレームワーク側でデフォルトでこの機能が付いている場合もありますね。
このような場合、JMeterでPOST系のテストするためには、どうにかしてこのトークンを取得しなければなりません。

正規表現抽出

まず、CSRFトークンが表示されている画面のサンプラーを追加します。
そしてサイドバー上のそのサンプラーを右クリック
 →追加→後処理→正規表現抽出

表示された、正規表現抽出画面で以下のように設定します。

Apply to:● Main sample only
Field to check:● Body
参照名:csrf_token ※後ほど参照する時のキーとなります
正規表現:<input name="token" value="(.*?)" type="hidden" /> ※例です。各サイトに合わせてください
テンプレート:$1$

Parametersに追加

正規表現で取得したトークンをフォームをPOSTするサンプラーのParametersにセットします。

名前:_csrf
値:${csrf_token}

以上です。

寝だめや夜更かしは太りやすい?

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

はじめに

週末の朝は目覚まし時計を設定しないで、お昼頃まで寝たいという人が多いと思いますが、
起床時間や睡眠時間が毎日バラバラだと代謝機能の問題が起こりやすく、太りやすい体質になると言われています。

夜更かしによる体の影響

休日の夜遅くまで起きている人や、毎日の睡眠時間が一定ではない人は、インスリン抵抗性を発症したりBMI値が高くなったりするなど、代謝機能に問題が起きやすいとのことです。

また、規則的な睡眠を取らない生活を長く続けていると、心疾患や糖尿病などの長期的な病気が起こりやすくなるとのこと。

平日と休日で違った睡眠パターンを取っている人は、体内時計が狂った結果、代謝のサイクルが他の体のサイクルとはズレてしまうそうです。

さらに、平日と休日の睡眠時間の差が開けば開くほど、代謝機能の病気を発症しやすいようです。

睡眠時間の差が開くと血液中の脂肪量が増えて、インスリン抵抗性にかかりやすくなったり、
ウエスト周りが太くなったり、血圧が上がったり、善玉コレステロール値が下がったりといった健康被害が起こってしまいます。

まとめ

健康のため適度な運動も重要ですが、睡眠の質に気を掛けるのも健康の為には重要になると思われます。

最近人気な記事