ホーム ブログ ページ 29

flattenで多次元を1次元に

0

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

今回は、rubyのflattenメソッドの紹介をしていきます。

flattenメソッドとは

flattenは、配列とハッシュに使用することができます。
配列に対してflattenメソッドを使用すると、2次元配列や3次元配列などの階層の深い配列を1次元配列に再構築してくれます。

[ [1, 2], [3, 4], [5, 6] ].flatten
=> [1, 2, 3, 4, 5, 6]

[ [ [1, 2], [3, 4] ], [ [5, 6], [7, 8] ] ].flatten
=> [1, 2, 3, 4, 5, 6, 7, 8]

ハッシュに対してflattenメソッドを実行すると、ハッシュのキーと値の一次元配列が返ります。

{ "apple" => 3, "grape" => 2, "peach" => 5 }.flatten
=> ["apple", 3, "grape", 2, "peach", 5]

しかし、ハッシュの値がハッシュである場合は値のハッシュは変換されません。

{ "red" => { "apple" => 3 }, "purple" => { "grape" => 2 } }.flatten
=> ["red", {"apple"=>3}, "purple", {"grape"=>2}]

mapメソッドとの組み合わせて使用する

ここで紹介しているflattenメソッドですが、mapメソッドと組み合わせて使用することで階層の深い関連データを1次元の配列で取得することができます。
例をProject Programmer Workモデルで説明します。目的は、Projectに関係のあるProgrammerのWorkの一覧を取得することです。
enter image description here

以下のコードがProjectに関係のあるProgrammerのWork一覧を取得するコードです。

project = Project.find(1)
project.programmers.map(&:works).flatten

このコードが何をしているのか説明していきます。
まず、project.programmersでprojectに紐づくprogrammerを参照しています。

project.programmers
=> [#<Programmer id: 1, name: "taro">, #<Programmer id: 2, name: "jiro">]

次にproject.programmers.map(&:works)でprogrammerに紐づくworkを参照しています。ただし、2次元配列で返ってきます。

project.programmers.map(&:works)
=> [[#<Work id:1, status: "new">, #<Work id:2, status: "fin">], [#<Work id:3, status: "fin">, #<Work id:4, status: "fin">]]

最後にproject.programmers.map(&:works).flattenで2次元配列を1次元配列に再構築しています。

project.programmers.map(&:works).flatten
=> [#<Work id: 1, status: "new">, #<Work id: 2, status: "fin">, #<Work id: 3, status: "fin">, #<Work id: 4, status: "fin">]

まとめ

eachなどのループを使用すれば、この記事で紹介したように階層の深いデータを取得することができますが、mapとflattenを使用すれば1行で納めることができます。自分の経験上、関連データの関連データを一覧で取得する機会があまりないですが、rubocopで行数を抑えたいときに使えるかと思います。

超高速通勤に注意!?未来に行く方法

0

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

またもや通勤がサブテーマですが、今回は社会人なら常に気を配りたい”時間”にまつわるお話です。

人によって流れる時間が違う!

時刻ピッタリに電車が発車したり、5分でも遅刻は遅刻であったり、期限を守らないと大変なことになったりと、現代日本はとても時間に正確な社会ではないでしょうか。
しかし、こんなにも社会の軸とされている”時間”というものが、そもそも人によって流れる速さが違うことをご存知でしょうか?

これは、超有名な物理学者アインシュタイン博士が発表した、「相対性理論」(正確には特殊相対性理論)によって導かれる結論です。
この理論によれば、運動している速度が速ければ速いほど、その人の流れる時間が遅くなるらしいのです。
例えば、ロケットに乗って1時間ぐらい超高速の宇宙お散歩をして帰ってくると、地球では1日経過していた、みたいなタイムスリップのようなことが起こるのです。
enter image description here
一見現実味がないようなこの理論ですが、実はすでに色々なものに応用されており、その身近な代表例がGPS時計です。
GPS時計は人工衛星を使って、いつでも正確な時刻を時計に送っているのですが、人工衛星は地球の周りを時速1万キロで回り続けているため、
速度による時間の遅れが無視できなくなってしまいます。そこで、内部で相対性理論に基づいた補正を行い、正確な時刻を出しているのです。

未来に行く!?

さて、すでに例で出したように、超高速のロケットに乗って、宇宙旅行を楽しんで帰ってくることで、地球ではロケットの中以上の時間が流れているため、結果として未来に行くことが出来ます。
ここでは、実際にどれぐらいの速度で走れば実感できるほど未来に行けるのかを計算してみたいと思います。
事前の計算でかなり速度が必要なことが分かったので、いきなりぶっ飛ばします。

①秒速269813.2122km
秒速約27万キロです。1秒あれば大体地球を7周ぐらいします。
この超高速ロケットに乗っている人の1秒は、地球の人の約2.3秒に相当します!
この速度を出せれば、このロケットの中の時間は、地球時間のおよそ半分の速度で流れることになります。
つまり、このロケットの中で5年過ごすと、地球では約10年が経過します。劇的ではないですが、まあまあなタイムスリップになるのではないでしょうか。

②秒速299792.158207542km
秒速約30万キロです。1秒で大体地球を7周半します。
この超高速ロケットの中の1秒間は、地球上の人のなんと707秒に相当します!
つまり、このロケットの中の時間は地球上の700分の1の遅さになるのです。
ここで1年過ごすだけで、地球では700年もの歳月が流れ、あっという間に浦島太郎状態です。

**考察**
この速さを実現するには1年のような長い時間をかけてロケットを加速し続ける必要があります。(ちなみに1時間ほどでこの速さまで加速しようとすると、体に8500G(体重の8500倍の力)が掛かります。注意してください)
従って、
①数年単位で加速し続けられるエンジンと燃料
②数年間人間が生活し続けられる環境
③途中の惑星などの影響をよけられるようなシステム
これらが実現できれば、この未来への旅行も現実味を帯びてくるのではないかと思います。未来に行ける世界は意外と近くまで来ているかもしれませんね。

補足:上の例で出している速度は、光の速さ(秒速299792.458km)を基準に、①その90%の速さ、②その99.9999%の速さ、で計算したものになります。
光の速度に近づくにつれて急激に時間が遅くなることが分かります。
(ちなみに、現在のロケットは、秒速数十km程度であるようなので、今のロケットに乗っても実感できるほど未来に行くには、まだまだ速さが足りません。)

過去には戻れるの?

未来に行くことが出来ることは分かりました。しかし、過去に行くにはどうすればよいのでしょうか。
相対性理論において、物体の速度をどんどん上げていくと、光の速度を超えたところで時間が逆転し、過去に進むようになります。
しかし、現在の物理学では、質量をもつ物体の速度は光の速度を超えることはできないとされています。
そのため、残念ながら現状では過去への行き方は分かりません。未来に行くときには、もう戻れないことに注意してくださいね。

終わりに

いかがでしょうか。通勤速度を追い求めるあまり、未来に行ってしまって結局遅刻する、のようなことが無い安全運転の通勤をしたいですね。

Rails×chart-js-railsで統計を表示する 1.

0

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

2は多分ある。

 ナポリタンの食品サンプルがデスクに増えました。

発端

「Railsでデータベース使って色々やってるんだから、それ使って簡単なグラフとか見れたら面白そうだな…..。Railsでグラフを表示する用のgem、探してみよう」
「今回はchart-js-railsを使ってみることにしよう。有名どころでも使われているみたいだし、このgem自体はjavascriptのライブラリのchart.jsをRailsで使う為に引っ張って来てるだけのものみたいだし」

使用方法

「Gemfileに一行付け足して、bundle installして、使う為には、application.jsに

//= require Chart.min

 を書き込む、と。
 それだけで、他にコマンドとかを打つ必要は全く無し。
 さて、まずは適当に新しいページ作ってchart.jsのサンプルページとか見ながら試してみるか……。
 新しくそれ用のコントローラ作ってroute.rbにルーティング付け加えて、それからviewを作成して」

Controller
graph_viewers_controller.rb

class GraphViewersController < ApplicationController
  def sample
  end
end

View
sample.html.erb

<canvas id="myChart" width="900" height="400"></canvas>
<script>
var ctx = document.getElementById("myChart").getContext('2d');
var myChart = new Chart(ctx, {
    type: 'bar',
    data: {
        labels: [1,2,3,4,5],
        datasets: [{
            label: "サンプル",
            data: [1,2,3,4,5],
            backgroundColor: 'rgba(255, 99, 132, 1.0)',
            borderColor: 'rgba(255, 50, 132, 1.0)',
            fill: false
        }]
    },
    options: {
        title:  {
          display: true,
          text: "タイトル"
        }
    }
});
</script>

bar graph test
「お、出来た。
で、これにデータやラベルを変数として組み込むには、配列部分を弄れば良さそうだな」

Controller

def sample
  pivotes = PiVote.pluck(:name, :vote_num)
  @labels = pivotes.map(&:first)
  @datas = pivotes.map(&:second)
  #@labels = ["◯っ◯◯","π","パイナップル", "ニシンパイ", "パイルドライバー"]
  #@datas = [9999, 3141, 2, 8, 1000]
end

View
「ラベルとデータ部分をそれぞれ弄って、と」

    data: {
        //文字列の入った配列やハッシュ等はこうしないと正しく表示されない
        labels: <%= @labels.to_json.html_safe %>,
        datasets: [{
            label: "投票数",
            data: <%= @datas %>,
            backgroundColor: 'rgba(255, 99, 132, 1.0)',
            borderColor: 'rgba(255, 50, 132, 1.0)',
            fill: false
        }]
    },

enter image description here
「おお、でけたでけた。
 一つ二つでも弄れば円グラフとか散布図とかも色々作れそうだし、オプション設定も色々あるし、夢が広がるぅ」

実際の使用感覚

 まあ、そんな感じで使ってみました。実際にデータが視覚化されると、特徴とかが分かりやすくなりますし、そこからプロジェクト等に対する改善策も見やすくなってくると思います。
 このchart-js-railsは実際、chart.jsをRailsで使えるようにしただけのgemみたいなものですが、Javascriptを余り深く知らない自分にとっては、Javascriptの勉強にもなって中々面白い所もあります。
 今もそれに関して主に弄っていて、グラフの色分けや、散布図の点をクリックしたらそのデータに関する画面に遷移したりとか、実際色んな事が出来るようになってきて、実際夢が広がるぅ、感じです。
 でも、一つ、難点として挙げるのならば、データベースから取ってきた値などを、javascriptにrubyとして組み込んでいくので、コードがとても汚くなりがちです。
 散布図を色分けやらしたい、なんて考えた時は、データを与える辺りのコードが以下のようになってしまいました。

  datasets: [
    <% @labels.each_with_index do |label, i| %>
    {
      label: "<%= label.html_safe %>",
      //色の設定。数に応じて変化。
      borderColor: "<%= "##{(16 * i / @labels.length).to_s(16)}f#{(16 * (@labels.length - (i + 1)) / @labels.length).to_s(16)}fff"%>",
      backgroundColor: "<%= "##{(16 * i / @labels.length).to_s(16)}5#{(16 * (@labels.length - (i + 1)) / @labels.length).to_s(16)}5ff"%>",
      pointRadius: <%= 4 + i %>,
      pointStyle: "<%= ['circle', 'triangle', 'rect', 'star', 'cross'][i].html_safe%>",
      showLine: false,
      data: [
      //データの配列。データの一つはx,y座標を格納した配列。
        <% @datas_array[i].each do |data| %>
        {
          x: <%= data[0] %>,
          y: <%= data[1] %>
        },
        <% end %>
      ]
    },
    <% end %>
  ]

enter image description here
まあ、もっと良いやり方はあると思うので、もっと色々試してみようとは思いますが。

指を動かして脳を活性化!?手と脳の関係とは?

0

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

手や指を動かすことによって脳にどのような影響があるのかについて調べてみました。

はじめに

1か月の更新になります。今回はプログラミングに関してではなく前々からちょっと興味があった「手と脳の関係」について調べてみたのでそれを記事にしたいと思います。

1.手と脳の関係

いきなりですがこちらの画像をご覧ください。
enter image description here
photo by Mike

なかなかにグロテスクな画像ですがこれはカナダの脳神経外科医であるワイルダー・グレイヴス・ペンフィールド(1891~1976)が考案した「ホムンクルス人形」と呼ばれるものです。手や唇は大きく、逆に足や胴、腕などはとても細いのが見て取れます。とても歪な容姿をしていますがこれはヒトの大脳皮質と体の部位の感覚の関係を部位の大きさで示したものです。大脳皮質とは大脳の表面にある神経細胞の集団で、100億以上の神経細胞がいくつかの層をなして配列しています。大脳皮質には触覚や温痛覚などの感覚を脳にインプットする感覚野や運動を行い外にアウトプットする運動野などがあります。
このホムンクルス人形を立体から平面図にした写真が下になります。
enter image description here
photo by Beth Scupham
これまた少し不気味な画像ですが、感覚野(Somatosensory Strip)と運動野(Motor Strip)に分かれてそれぞれ対応した部位の大きさでどれくらいの割合を占めているかを表しています。
運動野でも感覚野でも手や口の部分が大きな割合を占めているのがわかります。
この部位の大きさが大きいほど感覚が敏感であるとされ、その部位を使うことで脳のたくさんの部分を使っていることになります。

2.脳を活性化させよう

 さて、先ほどまでの内容で手と脳が密接に関係していることを確認してきました。手をたくさん使うことで脳細胞に刺激を与え、脳の活性化へと繋がります。
 手を使うと、手を使わない時に比べて脳の血流量が10%程度上がるという研究結果があるそうです。脳の血流量が低いと神経細胞が死滅してしまい、二度と復活することはありません。神経細胞が減っていくと物忘れが激しくなったり、ボケを引き起こしたりすることがあります。認知症の予防で手を使った体操や、先ほどの画像で手の次に大きな割合を占めている口を動かすことを薦められているのはこういった所からきていると思われます。
 しかし、ただ手を使えばいいという問題ではありません。普段の日常生活で行うような「物を掴む」「箸を使う」といった行為ではあまり刺激にはなりません。「外国の人が箸を初めて使った」といった場合ならとても刺激になると思いますが、何も考えなくても行えるぐらい体に染みついた行為は脳の活性化にはあまり効果がありません。
 脳を活性化させるのに効果的なのは考えながら手を動かすことです。特に、ピアノなどの楽器演奏や、キーボードタイピングなどは手を動かしながら頭も使うことができるのでとても良いとされています。ピアノは音の強弱やリズムなどを楽譜を追いながら頭で考えて指をたくさん動かす為、脳へたくさんの刺激が伝わります。しかし、そのためにやった事のない楽器を1から始めるのはかなり大変です。それに比べてキーボードタイピングは、打ちたい内容を考えながらキーをタイプするだけなので比較的簡単に誰でも始められます。そのほかにも普段行うことを利き手と逆の手で行うだけでも脳には刺激になりますのでちょっとだけ意識して生活してみるといいかもしれません。

おわりに

 いかがだったでしょうか。自分はルービックキューブが好きでよくやっているのですが、「指を使うと頭が良くなる」と聞いたことがあり、気になっていてちょうどいい機会だと思い調べてみました。結果的には全体的に頭が良くなるというより記憶力の部分が良くなるという感じでしたが、ちゃんとした理由を知ることができました。
 ルービックキューブやタイピングをしていて「脳が刺激されてるなー」とか、「今、脳の血流量が10%上がったな…」と感じたことは1度もありませんが、将来の記憶力や健康の為に普段から意識して指を動かす事が大事だと思うので、みなさんも是非意識して指を動かして脳をたくさん刺激しましょう!

Gitで間違えてブランチをマージしてしまった時の対処法

0

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

はじめに

こんにちは、motsukaです。
今回は、Gitでマージしてはいけないブランチをマージした時の対処法を紹介したいと思います。

状況

現在開発しているreleaseブランチと新ステージ実装をしているdevelopmentブランチがある状態で、
新ステージの実装が終わったのでdevelopmentブランチをreleaseブランチにマージしてpushしました。
ですが、まだその新ステージはマージしてはいけないものでした。

では、マージコミットを取り除くにはどうしたらいいでしょうか?

解決策

Gitにはコミットを取り消す方法は幾つか有ります。
有名なのが、resetとrevertですね。
今回はrevertを使ってマージコミットをrevertしてみます。
まずgit logでマージしたコミットのcommitIDをコピーします。

次に git revert commitID と打ってみます。すると

fatal: Commit commitID is a merge but no -m option was given.

と言うエラーが出ます。

これはマージコミットには -m をつけてくださいと言うエラーです。
-m オプションは、mainlineを指定するオプションです。
マージコミットをrevertした後の状態とは、二つのブランチの状態のどちらかになりますよね?
この二つのブランチのどちらに状態を戻すかを指定しなければなりません。
-m の後ろには1か2を指定することができて、1がマージされたブランチ、2はマージしてくるブランチです。
ここでは1がreleaseブランチ、2がdevelopmentブランチですね。

では、 git revert -m 1 commitID と打ちます。

すると、revertコミットがされたことが確認できます。
これでコミットを取り除くことができました。

ですが、これだともう一度新ステージをマージしようとした時、マージができません。
すでにマージされているというエラーが出てしまいます。
その解決策として、developmentブランチにreleaseブランチをマージします。
そして先ほど取り除いたコミットをまたrevertします。
そうするとまたマージした時にエラーが出ることがなくなります。

まとめ

gitで間違えた時の対処法は各自調べておきましょう。

コミュニケーション技術

0

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

コミュニケーションは「伝わらないが大前提」 今回は少しでも伝えるためのコミュニケーション技術についてのお話です。

なぜ伝わらないのか?

「話し手が考えていること」と「聞き手が考えていること」
果たして同じでしょうか?
それぞれの生い立ち、言語、文化、常識、年齢etc
人間100人いたら100種類の人生があるはずです。
話し手と聞き手の思考がまったく同じなんてことはほぼないと言っていいでしょう。
そのため、伝えたい内容と伝わる内容は根本的に同じではなくなり伝わらないといったことが起きます。

ラポールを意識しよう

人間関係は信頼関係です。
人間関係の深さは必ずしも関わった時間に比例しないというのはなんとなく理解してもらえるかと思います。
それでは何で決まるのか?相手との信頼関係です。
そしてなんと信頼関係の構築は技術で習得できます。
具体的にはどうするのか?
「ラポールを確立させる!」ことが重要です。

ラポールってなに?

互いに信頼し合い、安心して感情の交流を行うことのできる関係が成立している、心的融和状態を指します。
「親近感」や「信頼感」といった言葉が近いと思います。

実際にどうやるの?

これには様々な方法があります。
主に「同調」「傾聴」「自己開示」といった非言語行動を使用し、
コミュニケーションをすることで生まれると云われています。
今回は「同調」について少し掘り下げます。

同調の手法

ミラーリング

主に身体の使い方を合わせる同調手法になります。
合わせるのは姿勢、座り方、手振り、態度、表情などです。
ピシッとした姿勢に対してだらっとした姿勢、
笑った顔に対して真顔などされると話しづらいですよね。
相手と合わせることで各段に話しやすくなります。
ただし、手振りなどはやりすぎると気付かれて逆に不愉快にさせてしまうこともあるので注意が必要です。

ペーシング

これは相手の話し方や状態、呼吸などのペースを合わせることです。
合わせるのは声の調子、高低、大小、リズム、スピードなどです。
さらに感情の起伏や場の空気などに注意し、合わせてあげることが出来ると
相手と一体感が生まれてきて、同時に相手は安心して話すことが出来るようになると思います。

バックトラッキング

いわゆる「オウム返し」です。
事実を反復、感情を反復、確認を入れるなどになります。
相手の話をちゃんと聞いていることを示すこと、相手に自分が発した言葉を再確認してもらうことが目的です。そのため、一語一句同じでなくてはならないというわけではありません。
相手の使った表現に適していれば相手は自分の話がよく理解され受け入れられているという感覚を持ちます。

まとめ

少しでもコミュニケーションを上手くするために、
今回は代表的な同調の手法として
・ミラーリング
・ペーシング
・バックトラッキング

以上3点をご紹介しました。
良ければぜひ試してみてください。
他にもラポールを確立させるための手法は沢山あります。
今後また機会がありましたら他の手法についてもご紹介します。

ActiveRecordとデータベースについて知っておきたいこと

0

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

Ruby on RailsのActiveRecordをぼーっと使っていると、メモリにあるデータやdbにあるデータの整合性が取れなくなってバグを生んでしまう事があるという話です。

ActiveRecordが好きなのでたびたびActiveRecordの話をしますが、今回はうっかりやってしまいがちなDB上のデータとメモリ上のデータの不整合との話です。知らないと失敗しがちなので

railsは5.1.1を使っていますが、あまりバージョンには関係なく、rails固有というわけでもなさそうな話です。

うっかりしてしまった!

プレイヤーが複数持つデッキの中から、一つだけメインデッキを選べるような実装がしたいとします。

class Player < ApplicationRecord
  has_many :decks
  has_one :selected_deck, -> { where(selected_flg: true) }, class_name: "Deck"

  def select_main_deck(deck)
    transaction do
      self.decks.each{ |deck| deck.update!(selected_flg: false) }
      deck.update!(selected_flg: true)
    end
  end
end

素直に読むと、一度すべてを非選択状態にし、選択したいデッキを選択しているようです。
色々問題はありますが、この select_main_deck が同時に使われることがないと仮定しても、
今メインデッキとして選択されているデッキをまた選択した場合、全てのデッキが非選択状態になってしまうのです。

※ ふつうeachではなくupdate_allを使うところですが、update_allにはまた別の落とし穴があり、本筋からそれるここではeachを使っています。

どうしてこうなってしまうのか

一瞬何が悪かったのかわかりにくいですが、

ひとつめ: DBで変更があったとしてもメモリ上のデータは更新されない

下の例では first_player が指すものと another_first_player が指すものはメモリ上では別の場所におかれており
ActiveRecodr::Baseは勝手に変更を取ってきてはくれません。

first_player = Player.first # #<Player id: 1, name: "あああああ">
another_first_player = Player.first
another_first_player.update!(name: "いいいいい")
p first_player 
=>  #<Player id: 1, name: "あああああ"> # DB上のデータとは違う

another_first_player からupdateされたものはanother_first_playerには反映されますが、たとえ同じデータを参照していても、オブジェクトとして別のものである first_player にはその変更は反映されません。

これは絶対知っておいたほうがいいことです。
読み込んで表示するだけならば問題ないですが、今のデータをもとに更新を行う場合は、DBからデータを読み込んでから更新するまでの間に他で変更されないよう、きちんと排他制御をしましょう(後述します)。

ふたつめ: 変更がなければUPDATEは走らない

ActiveRecord:::Base は DBからデータをひいてきてメモリ上のオブジェクトが作られたあと、updateなりsaveなりを使ったとしても、変更がなければDB上のデータを更新しようとしません

player = Player.first # #<Player id: 1, name: "あああああ">
player.update!(name: "あああああ")
# UPDATEは走らない

これで何が起こっているかはっきりしてきたかと思います。

def select_main_deck(deck)
  transaction do
    # 全てのデッキのselected_flgがfalseになる
    self.decks.each{ |deck| deck.update!(selected_flg: false) }
    # DB上ではselected_flgがfalseだが、メモリ上ではtrueのまま変わらないのでUPDATEされない
    deck.update!(selected_flg: true)
  end
end

こういったバグ、特に他人や昔の自分がかいたコードを読んだ場合かなり見つけにくいですね。

上に挙げた

  • 同じデータを違うオブジェクトから参照する
  • データの取得と更新を行う

の2つはバグの温床になりがちなので気をつけたいところです。

さて、この悲しい事態を避けるにはどうすればよかったのか考えてみましょう。

どうすればよかったのか

そもそも構造を変える

この場合なら、playersテーブルに selected_deck_id というカラムを追加して、そこで選択中のデッキを持っておいたほうが筋がいい気がします。
選択中のデッキを切り替えるときに複数のレコードを更新しなくて済み、データ不整合を起こすことがなくなります。

class Player < ApplicationRecord
  has_many :decks
  belongs_to :selected_deck, class_name: "Deck"

  def select_main_deck(deck)
    self.update!(selected_deck: deck)
  end
end

この場合に限らず、何らかの操作をしたとき、更新する部分があまり多くならないよう考えておくとバグが起こりにくいですね。

ロックをとる

どうしても上に挙げた方法が使えないときは、きちんと不整合を防ぐ仕組みが必要です。
例えばロックというDBからデータを読み込んでから更新するまでの間にデータが更新されないようにするDBの仕組みがあります。

たとえば所持金を増やしたいとき、知らないうちにDBのデータが更新されてしまうと困ったりしますよね。

class Player
  def add_money(val)
    # 今の所持金を200とすると
    added_money = self.money + 100
    # ここで、DB上でのplayerの所持金が300になる
    self.update!(money: added_money)
    # 本当は400なのに300に...
  end
end

「所持金を増やす」間に他のところでデータが書き換えられないようにしないといけません。
たとえば rails では、以下のように with_lock メソッドを使って書くと、with_lockに与えたブロックの中の処理が終わるまで別の場所でDB上のデータが更新できなくなります(こういった、一つのレコードに対しての更新を制御するものは行ロックと呼ばれています)。

class Player
  def add_money(val)
    with_lock do
      added_money = self.money + 100
      self.update!(money: added_money)
    end
  end
end

さらに気をつけたいのは、複数のレコードに対してロックを取る場合です。
一度ロックを取ってしまうと処理が終わるまでは他ではデータの更新ができないため、順番次第ではお互い更新が終わるまで待ち状態になる、いわゆ
るデッドロックという状態になってしまうことがあります。「食事する哲学者の問題」がわかりやすい例ですね。

デッドロックに陥らないためには、たとえば必ずidが大きい方からロックを取るなど、一意な順番でロックを取っていく必要があります。

class Player < ApplicationRecord
  has_many :decks
  belongs_to :selected_deck, class_name: "Deck"

  def pay_for(target_player, val)
    if self.id < target_player.id
      self.with_lock do
        target_player.with_lock do
           target_player.update!(money: target_player.money + val)
           self.update!(money: self - val)
         end
       end
     elsif self.id > target_player.id
      target_player.with_lock do
        self.with_lock do
           target_player.update!(money: target_player.money + val)
           self.update!(money: self - val)
        end
      end
    end
  end
end

まとめ

基本的にこういったデータの不整合が起きやすいのは、 同じDBのレコードを指すオブジェクトが複数できるとき です。

まずそういう状況に気づくこと、気づいたら意図しない場所での更新が起きないようにすること、そもそも広い範囲での更新が起きないよう考え直すことを意識していきたいですね。

シェルスクリプトと戦う〜その1〜

0

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

はじめに

サーバ内部でバックアップを取るなど、特定の決まった作業をコマンドで打ち続けるとだんだん面倒になることがあります。こういう時は自動で作業するよう組みたくなるものです。
また、定期的ではないものの、よくやる一連の作業をいちいち入力するのも面倒ですね。なんとかしたいものです。
そこでシェルスクリプトというものが登場します。このシェルに普段入力しているコマンドを記述し、実行すれば、記述したコマンドを順々に実行してくれます。
今回はこのシェルに関しての話で触り始めて学んだことや思ったことを紹介していきます。

※ほとんどコマンドを触ったことのない人は迂闊に触らないほうがいいと思います。また、場合によってはファイルの消失や上書き等取り返しのつかないことが発生するコマンドもあるので、なるべく実行環境とは別の、構造が似た様な環境を構築してそちらでテストを行ってから実行環境に反映させることを推奨します。(コピー、削除等)

まずは書く

実行環境:CentOS5.9

helloWorld.sh

#!/bin/bash
echo ‘Hello!’
echo ‘Shell world!’

ただechoで2行表示するだけの簡単なシェルです。bash以外にsh等もあるようですが、環境によって動作が異なる部分があるようなのと、bashで見かけるソースが多かったので、こちらで記載していきます。

結果

enter image description here
確かに表示されました。
これで普段実行されているコマンドを書いていけばいいですね!

そこまで甘くない

シェルと同じディレクトリで実行する想定で記述したと仮定します。
実行は同じディレクトリからと、別のディレクトリからの両方を行います。

passCheck.sh

#!/bin/bash
echo '=== pass check ==='
pwd
echo '=== move ==='
cd Desktop
pwd
echo '=== end ==='

結果

enter image description here
pwdで確認したパスが変化しています。「shファイルと同じディレクトリに移動して実行しないと動かない」ルールで行えば、一応問題ありません(ミスをおこしかねないのでお勧めしません)が、今回のようにDesktopフォルダに移動してから実行すると、パスが変化するため、エラーが発生してしまいます。
今回はpwdで自身の位置を確認し、cdで移動するコマンドだけなので影響はありませんが、場合によっては実行されなかったり、想定外の事態が起こったりします。

さて画像から分かるかもしれませんが、実行時にディレクトリの移動を行っても、シェルの終了時に元の位置に戻されます。

対応としては、
・少なくとも最初のcdは絶対パスで記述する
あくまで「少なくとも」です。なるべくフォルダ移動の際は絶対パスの方がいいのではと思いますし、コピーコマンド等も、こだわりがなければその方がいい気がします。

cdのパス指定ですが、シェルと同じ位置に行く場合はdirname $0を利用した方法があります。ただ、実行およびソースの書き方によっては、期待する処理と結果が異なります。(参考:dirname $0 でスクリプト置いてあるディレクトリにならない 1年以上前の記事ですが同様の動作を確認)
$0ですが、これは初期値ではシェル自身のパスが格納されています。(〜.shの形)

終わりに

今回は触り始めになるだろう部分を紹介してみました。まだ紹介していませんが、if文や変数なども使用できます。これらを利用して処理を分けたり弾いたりできますが、後に簡単なもので紹介しようと思います。


関連記事:
dirname $0 でスクリプト置いてあるディレクトリにならない
シェルスクリプトと戦う〜その2〜

キャラクターでストーリーを動かす①

0

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

ゲーム内イベントのシナリオを書いていると、登場させるキャラクターの人選によって行き詰ってしまうことがあります。 手っ取り早く起承転結に導いてくれる優等生を探しましょう。

はじめに

お話を書いているうちに、展開が詰まってどうしてもストーリーが動かなくなってしまった…という経験がある方は少なくないと思います。
こうなってしまうと、にっちもさっちもいかなくなってしまいますね。
泥沼を回避するためにも、物語を動かすキャラクターに協力してもらいましょう。

今回のお話は、私自身が現在シナリオを担当しているタイトルを例に、一からキャラクターを作るのではなく、既にゲーム内に登場しているキャラクターを数人ピックアップしてイベントシナリオを書く、という想定です。

登場人物を決める①

私が現在担当しているタイトルでは、ほぼ毎回イベントの主役となるキャラクターが事前に決まっています。そのキャラクターを軸にイベントのシナリオを考えていきます。
登場人物が多いタイトルなので、イベントごとに登場させるキャラクターを変えて、色々なキャラクターの魅力を伝えていきたい…と思ってはいるのですが、キャラクター同士にも相性というものがあります。直近のイベントに登場していない、なおかつ主役となるキャラクターと相性の良いキャラクターを選ぶことを心がけていますが、中々うまくいきません。
(そもそも第一に考えなくてはならないのは、シナリオをうまく回すことではなく、ユーザーの方々に満足していただくことなので…。)

今回の例では、季節にちなんだイベントで「十五夜」をテーマにします。
まずはキャラクターを選んでプロットを組んでみないことには始まらないので、数人ピックアップします。

登場人物を決める②

enter image description here
※画像はイメージです。

主役として登場させることが事前に決定していた①の明るい女の子を軸に、過去のイベントに登場していないキャラクターの中から4人ほど選びました。
左から、
②中二病の子
③王子様のような子
④十五夜から「兎」を連想して、過去にバニーの恰好をしたことがある子(うさぎさん)
⑤生真面目だけど少し子供っぽいところがある子、です。

実際にこのメンバーでイベントシナリオを書こうとして数日間筆が進まず悩み続けてしまったので、後日練り直すことになります。
この中には、話の起点となる誰か……つまり「起承転結」の「起」の部分になってくれるキャラクターがいなかったためです。(私の力不足でもありますが…。)

登場人物を決める③

締め切りも迫って来たので焦り、試しに登場人物の変更を試みます。
ゲーム画面の仕様上、一度に5人以上のイラストを表示してしまうと会話画面が詰まりすぎてしまいますので、一つのイベントに登場させるキャラクターは、今のところ4~5人まで、としています。(演出上、全員を一斉に表示させることが多いので。)
ですので、前項の画像③の王子様のような子、④のうさぎさんの出番は次回のイベント以降に回し、新たに下の画像③のスピリチュアルさんを投入しました。

enter image description here
※画像はイメージです。

このスピリチュアルさんが起承転結をうまくコントロールし、ストーリーはするすると動いていくことになります。

「登場人物を決める②」の時点では、自由奔放に動き回るキャラクターは多いものの、場をおさめて新たな展開につなげる役割のキャラクターがいませんでした。
スピリチュアルさんは物静かで意味深なことを話す上に、カードによる占いを得意とするキャラクターなので、「占い」を起点にし、物語を動かしていくことが出来るのです。
このように、何か特別なことを得意とするキャラクターは特に、起点にしやすいです。

ようやく登場人物が決まりました。
続きは次回です。

第4回「TGSで日本ゲーム大賞に選ばれた作品たち!」

0

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

今年の東京ゲームショー2017について、日本ゲーム大賞を受賞した作品たちをいくつか取り上げて、筆者なりに人気が出た理由を分析してみたいと思います。

みなさんお久しぶりです!Lionです。
前回の記事いかがだったでしょうか?
少しでもゼルダの伝説 時のオカリナの魅力が伝わったのならうれしいです!
さて、本日は「TGSで日本ゲーム大賞に選ばれた作品たち!」」について話させていただきます。
今年はどんな神ゲーが僕らを待っているのか(੭ु´・ω・`)੭ु⁾⁾
受賞した作品を2つほど紹介していきたいと思います。

「やっぱり今年はあのゲームが受賞!」

今年の「年間作品部門 大賞」を受賞したタイトルは「ゼルダの伝説 ブレス オブ ワイルド」でした!
ファンからは「ゼルダの伝説 時のオカリナ」を超えたといわれ、海外ユーザーのレビューでは☆10評価で☆9以下にならないという現象も起こっているくらい素晴らしいゲームです。
ちなみにNintendo Switchのソフトになりますが、なんとNintendo Switchの出荷台数よりソフトが売れている!
らしいです(笑)
また、ゼルダの伝説シリーズ初のオープンワールドを採用。フィールドを際限なく「歩いたり、走ったり、キャンプをしたり、崖や木に登ったり…etc」ほとんど我々の世界でできるようなことはゲーム内でできるようになっています。
※料理だって作れちゃう!
ちなみに選考理由ですが、

・謎解きとバトルの爽快感が最高
・冒険が驚きと発見の連続で楽しい
・やりたいことがすべてできた
・歩いているだけでも楽しい
・シリーズ最高傑作
・まさに大賞にふさわしい

と絶賛の声しかなかったらしいです。
一般投票では、性別・世代を問わず、なんと「5歳から74歳」までの圧倒的な支持を獲得したということもゲーム業界を震撼しました。
ここで、選考理由の「歩いているだけでも楽しい」について少し深堀してみましょう。

「オープンワールドだからできる新しいゼルダの伝説」

   enter image description here enter image description here         
          Copyright © 2017 CESA, All Rights Reserved. /©2017 Nintendo
              日本ゲーム大賞年間部門賞より引用
歩くだけででも楽しい!と思わせた理由を私なりに3つに分けて分析してみます。
①今までになかった活きるをテーマに制作されている
 今までのゼルダシリーズは、ラスボスを倒し、世界を救う勇者になるというのが基本ベースでした。
 今作からは、リンクも普通の人間として生きている様に見せる工夫が多々盛り込まれています。

・山や崖をスタミナが尽きるまで登ることができる
・天候で周りの景色が変化する
・周りの気温によってリンクの体調が変化する
・自身で狩猟を行い、肉や魚などを採取できる
・集めた材料で料理を作ることができる
・武器は魔物から奪い現地調達することができる

などが大まかに上げられます。
これが、歩くだけでも楽しいゲームの秘訣になります。
まず、今回のゼルダの伝説は山や崖が沢山あり、どんな急斜面でも大体は登れる仕様になっています。
そのため、色々な場所に進むことができ、プレイヤーは「あっちには何があるんだろう!」と未知の世界に興味がわくようになっています。
基本的に、どこでも行けるということを知ったプレイヤーは、そのたどり着いた場所にある村、町、景色、魔物などと出会うわけです。
このような楽しみ方をプレイヤーが独自に発見して行くのが、今までのシリーズ作品と大きく異なる変化となります。

②過去のゼルダシリーズにはない戦闘システム
今作のゼルダな伝説は、※※過去作のような初めから剣を持っている※※という概念が取り払われています。
ではどうやって戦うのか?
それは、近くの木の棒や畑を耕す鍬などを武器にしたり、魔物から奪った武器を自分の武器にしたりして戦います。
ちなみに、これらの武器には耐久値があります。
※※これも今回のゼルダの伝説において大事な要素となります。※※
各武器は耐久値が0になると壊れてしまい、壊れた武器はその場で消滅してしまいます。
そのため、複数個の武器を所持できるようなシステムになっています。
この武器が壊れる、複数個所持できるというシステムがあることで、

・新しい武器を求めて新天地に向かう
・強そうな魔物がかっこいい武器を持っていたら、何とか倒して手に入れる方法はないか考える
・気に入った武器を大量にコレクションする
・ボス戦や普通の雑魚戦ですら武器の耐久値を考慮して戦わなければならない

このように、プレイヤーは武器という一つのコンテンツだけでもいろいろな目的で遊ぶことができるのです。

③ラスボスである「ガノン」にすぐ挑むことができる
今までのゼルダシリーズは、数々の困難を乗り越えて強くなったリンクでガノンと戦い世界を救うというお決まりのストーリーが王道でしたが、
今作は「チュートリアル部分さえクリアすれば、ガノンがいるダンジョンに行くことができる」という、王道な設計を覆しました。
これにも大きな理由があります。
プレイヤーに一本道で遊ばせるのではなく、プレイヤーが与えた環境でいかに自分の遊び方を見つけるかを体現するためだったのです。
プレイヤーにも色々なタイプの方がいると思います。

・ストーリーをなぞってクリアするプレイヤー
・ストーリーより色々寄り道をして遊ぶプレイヤー
・いかに早くガノンを倒すことができるかRTAをするプレイヤー

など、プレイヤーの数だけ遊び方がるようにゲーム設計を行ったのがわかります。
その結果として、性別・世代を問わず5歳から74歳までの圧倒的な支持を獲得したのだと思われます。

ゲームデザイナーズ大賞を受賞したちょっと不思議なゲーム

            enter image description here
   Copyright © 2017 CESA, All Rights Reserved. /©2016 Playdead. All rights reserved.
             日本ゲーム大賞年間部門賞より引用
次にINSIDEという一風変わったゲームが今年のゲームデザイナーズ賞を受賞しました。
選考理由として

・操作方法は極めてオーソドックス
・印象的な描写が心に残る
・主人公を含めた、謎めいた世界の表現手法は、数多の作品と比較しても、「似ている」と言  
 える作品がほぼ無い
とのことらしいです。

私自身もこのゲームを知ったのが賞を受賞した時からでした。
そのため、詳しくは知りません。
では、どのような作品なのか?一緒に見ていきましょう。

INSIDEのプレイヤーを引き込む世界観

   enter image description here enter image description here
    Copyright © 2017 CESA, All Rights Reserved. /©2016 Playdead. All rights reserved.
             日本ゲーム大賞年間部門賞より引用
まず、どういったゲームなのか少し書いてみると、

INSIDEとは、デンマークのインディー系ゲーム開発スタジオPLAYDEADによって開発された
2.5Dパズルプラットフォーマーアドベンチャーゲーム
となります

作品内容としては、主人公の少年は何かに追われており、やがて謎の大きな闇プロジェクトに巻き込まれていくお話になります。

操作方法はいたってシンプルで、方向キーでの移動、ジャンプ、アクションだけです。
最近のゲームと比べると、すごくシンプルと思います。

しかし、先に進むためにいろいろなギミックがあり、自身のヒラメキと、これまでクリアしてきたギミックの応用を解かなければいけないと少々難易度は高めの様子です。

この作品はの一番の見どころであるデザイン部分ですが、
モノクロに近い色彩で表現された世界となります。薄暗い雰囲気にすることで、プレイヤーは、プレイするときの緊張感や謎の何かに追われている恐怖感が倍増します。
しかも、ストーリの説明、キャラクターのセリフ、各種テキストが一切なく、
全てプレイしているプレイヤーの解釈に委ねられています。
この全てプレイしているプレイヤーの解釈に委るが実はとても凄い部分かなと私は思っています。
それはゲームに答えがないということです。
これを私風に言い換えるなら終わることのない物語と表現します。
どういうことかというと、
世界を救った勇者は次の世界を救うためにまた旅だった!
というゲームの終わり方があると、プレイヤーは「その後、どうなったのだろうか?」
「次の世界はどのようなところなのだろうか?」と考察し、それぞれのプレイヤーによって想像や考え方が違うようになってきます。だからこそ、考察したプレイした者同士が話すと話が弾んで話題性が生まれます。これが、先ほど言った終わることのない物語に当てはまります。
ただ、ほとんどのゲームは、ストーリーをすべてクリアしてその後勇者は~という
流れが多いのです。

しかし、このゲームに関しては、ゲーム開始からその終ることのない物語が始まっているのです。
これは、大きな挑戦だったっと思います。ストーリーの説明も何もない世界でただ何かに追われるのを逃げていくという内容をなぜ、追われているのか?などをすべて考えさせるように設計するのは至難の業且つ下手をすればプレイヤーは少しプレイしたら飽きてやめてしまうかもしれません。

そうならないように、世界観にこだわり、まるで自分が本当に逃げていると没入感を持たせる作りだからこそ、多くのプレイヤーの支持を獲得できたのだと思います。

今年の日本ゲーム大賞についてのまとめ

今年は、過去類に見ないほどゲーム業界で革命がおこった年だったと思います。
スマホアプリが流行る昨今、コンシューマーソフトが大きく息を吹き返した感じがします。
上記2タイトル以外も受賞されている作品は多々ありますので、こちたにURLを記載しておきます。

URL:http://awards.cesa.or.jp/prize/index.html

また、来年にもモンスターハンター:ワールドという過去最大規模のモンハンのゲームも発売されます。
※今年のフューチャー賞を受賞しており、来年の年間作品部門の大賞を受賞するかもしれないくらい期待度が高い作品となっています。

来年は、私自身もTGSに参加して生で色々なゲームの作品に触れてみたいです。

さて、次の記事ですが「プランナーはコミュニケーション能力が大事!」について
色々、書いていきたいと思います。

最近、寒さが増してきてますのでどうか風邪を引かずに来月も読みにいらしてください(/・ω・)/

重みに対しての誤差関数変化率の導出(Backpropagation)

0

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

ガバガバックプロパゲーション感漂う記事です。

はじめに

皆さんお久しぶりです、武道館のアリーナA一桁列引いて最近テンション高いくろすです。
マルチプロセス&複数サーバー環境下でのRailsの各キャッシュについてとか、stackprofを使ってプロファイリングしてみたって感じのこと書こうと思ってたんですけど、あまりうまく纏まらないので適当な流し記事を書くことにしました。

みなさん、微分積分いい気分で行きましょう。

Backpropagation

Backpropagation(誤差逆伝播法)はニューラルネットワークの学習に使われるアルゴリズムです。教師信号と出力の誤差をネットワークの各重みに反映するための勾配計算に使われます。この勾配を利用した最急降下法まで含めてBackpropagationと呼ばれることもあります。
Backpropagation自体はNNの学習に必要な数値の計算に使われるだけなので、何らかの形でネットワークの出力を誤差に変換することができるならば、教師ありなし問わず使えます。

導出

l層目k番目のパーセプトロンの入出力を以下のように設定
入力 : enter image description here
出力 : enter image description here
誤差関数Eに対する重みの勾配は以下の式

enter image description here

ここで右辺はパーセプトロンの入出力の式から
enter image description here

enter image description here
なので無事以下のようにl-1層目のi番目のパーセプトロンとl層目j番目の間の重みとEの勾配が既知の値を使って表現できるわけですね。
enter image description here

でこの勾配を指標にして学習率をかけて引いてみたり、慣性項を追加してみたり、正則化項を追加してみたり色々するわけです。

まあこれ自体はちょっとハチャメチャすぎてプログラムに起こすのが大変そうなのでざっくり行列で行きましょう。
活性化関数にシグモイド、誤差関数にクロスエントロピーを使うとサクッといけます。
enter image description here
enter image description here
enter image description here
tが誤差計算に使われる教師信号から計算される出力なので
enter image description here

o-1 は前段階の出力になってます
気持ちいいですね。

終わりに

以上、エンジニアにあるまじき思考放棄の数式画像の連投でした。

誤差関数と活性化関数の微分ができれば(微分可能であれば)データに合わせた関数を適宜選択して学習ができます。
自分で書く機会なんてほとんどない気もしますが。

今回ここに書いたようなことはだいたいここの2章や3章あたりに読みやすくまとまってると思います。

CSSの優先度を変える

0

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

業務でWebページをいじったときに地味にハマったので備忘録として投稿します。

経緯

 ボタンをCSS側の設定でデザインして作るのではなく、画像ファイルを使って実装したい。
…ということであれこれ検索しながらCSSでマウスオーバー時に画像を切り替えようと思い

<body>
<style>
  .button{
    background: url(/images/sampleA.png) left top no-repeat;
  }

  .button:hover{
    background: url(/images/sampleB.png) left top no-repeat;
  }
</style>
<img class="button" alt="" onclick="func()" />
</body>

関係ない箇所は全て省略しましたが、こんな感じでコードを書いてみました。
ページに飛んで試しにマウスオーバー…無事反応して出来た。と思ったのもつかの間、一度ボタンをクリックしたらその後クリックは効くものの、マウスオーバーしても全く効かなくなってしまった。
 

原因

 特定条件下でボタンが効かないように処理を加えたりしなければならず、JavaScript側でボタン押下時の処理をしていたのでそれに加える形で

<script>
  function func(){
    //
    // ボタン押下時の処理
    //

    button.style.display="none";
  }
</script>

こんな風にJavaScriptから表示非表示を切り替える処理を加えたり、CSSの設定を変更しているのが原因だったようです。
 
CSSには優先度というものがあり、JavaScriptでCSSの設定を上書きしてしまうとJavaScript側の設定が最優先されてしまい、CSSでの再設定もJavaScriptでの設定が優先されてしまい、何も変化しなくなってしまっていたようです。
 

対処

 CSS側で下のように、末尾に「! important」と加えるだけで問題なく動作しました。

<style>
  .button:hover{
    background: url(/images/sampleB.png) left top no-repeat ! important;
  }
</style>

この「! important」はこれを優先してください!というような命令なのでJavaScriptで変更した設定も変更することが可能になるそうです。
 

最後に

そもそもクリック時の処理をJavaScript側だけで済ませてしまおうと横着せずにCSSでcheckedとか使って処理すればハマることもなかったと思います…が、一つ勉強になりました。(おそらく結構初歩的なことだと思いますが)
今回はCSS内での優先度によるものでなかったのと、知識不足な今の私にはいまいち理解しきれなかったので今回はこれで終わりますが、どうやら「! important」を使わないクールな書き方もあるそうなので、もしマスターした時にはそちらも紹介しようと思います。

線の表現で変わるイラストの印象

0

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

イラストの線画による印象の違いをそれぞれ画像を作成し比較しました。

はじめに

nocoです。

このところイラストを描く際に「線画」の工程に時間をかけるようになりました。
強弱をつけたり、普段使わないブラシで線画を引いてみたり…少しずつこだわっていく中で線画によってイラストの印象が大きく変わることに興味を持ちました。

今回、イラストの線画のみを変えた画像をいくつか用意しました。
印象の違いに注目してご覧ください。

線画による印象の比較

ベースとなる線画

enter image description here
そのままバケツで塗り分けらえるような隙間のない線画です。
強弱を意識せず、スッと単色で線を引きました。
この線画に手を加え印象の違いを比較していきます。

線画の色を馴染ませる

enter image description here

それぞれの線の近くにある色を拾って線画に薄く乗せたものです。
線画と塗りが馴染み、やわらかな印象を与えます。

これは手法として確立し「色トレス」と呼ばれているそうです。
近年のゲーム系イラストのほとんどに使われているように思います。

線に強弱をつける

enter image description here
影の落ちる部分やすぼまった部分、手前にきている部分に線を加筆しました。
線に強弱をつけるだけでキャラクターの存在感がぐっと増します。

輪郭を縁取りする

enter image description here
輪郭を縁取るだけで、一気にまとまった印象になります。
背景に埋もれづらくなるため画面をスッキリさせることができます。

SDイラストの仕上げとして使用されることも多いですね。

ブラシの種類を変える

enter image description here
左から筆、水彩、鉛筆にブラシの種類を変えそれぞれ加筆したものです。
目指したいイラストの雰囲気に合わせてブラシを選びましょう。

近年のペイントソフトは、ベクターレイヤーに線画を描くことであとからブラシの種類を変更することができとても便利です。
ベクターレイヤーとは何ぞ?または詳しく知りたいという方は下記URLをご参照ください。

●レイヤーの種類1 ラスターとベクター – CLIP STUDIO (外部リンク)
https://howto.clip-studio.com/library/page/view/clipstudiopaint_tora_001_030

おわりに

着彩がシンプルなほど線画の表情は印象的になります。
目指したい表現に合わせた線画を作成し、より魅力的なイラストを目指したいですね。

Photoshopでgif動画が作れる!

0

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

はじめに

こんにちは、なすちゃです。
今回はPhotoshopCS6を使用した内容になります。
他のバージョンとは異なる部分もあるかと思いますがご了承ください。

Photoshop

画像編集に特化した有料ソフトです。
有名なソフトなので名前だけでも聞いたことがある方も多いかと思います。
写真の加工やグラフィックデザイン・イラスト制作など様々な機能があるPhotoshopですが、
今回はタイムライン機能を自身の復習も兼ねてご紹介します。

・タイムライン機能
動画編集、アニメーション制作ができます。
ペイント・画像編集をしながら動画のフレームの編集などができ、
作成した動画を書き出し簡単にweb上にアップすることができます。

今回は、7月の投稿で作ったコンテを使用します。

Photoshopを起動し素材を用意したら、ウィンドウ>タイムラインを開きます。
enter image description here

選択を「フレームアニメーションを作成」にします。
enter image description here

各レイヤーフォルダに秒数を設定していきます。
編集の時点で描き加えることも可能です。
enter image description here

編集ができたらレンダリングします。
web用に保存を選択
enter image description here

設定画面が表示されます
enter image description here

gifを選択>保存で完了です。
enter image description here

モーションを作る前にコンテを動かし確認したりと、簡単に作ることができます。

マージリクエストのレビュー 動作確認

0

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

 最近マジリク(マージリクエスト)のレビューを依頼されることがありました。今まではレビューの依頼が一切なかったので、他人がプッシュしたマージされていないブランチをどうやって確認すれば良いか分かりませんでした。今回の記事は、マージされていないブランチの確認方法をまとめてみました。

マージされていないブランチをローカルで確認する方法

 マージされていないのでpullしてもローカルで確認することができません。そこで、以下のコマンドで確認できるようにします。
git fetch
git checkout -b 「確認したいブランチ名」

 fetchコマンドで、リモートにプッシュされたブランチの履歴をローカルにコピーします。
次にcheckoutコマンドでローカルにコピーしたブランチに切り替えます。これで、他人がプッシュしたマージされていないブランチの確認ができます。

fetchコマンド

 上記のfetchコマンドについてもう少し説明すると、fetchはリポジトリとブランチを以下のように指定することができます。指定しない場合は全てのリポジトリのブランチをローカルにコピーします。
git fetch 「リポジトリ」 「ブランチ名」

リポジトリがorigin、ブランチ名がtest_branchの場合は、以下のようになります。
git fetch origin test_branch

 fetchは、リモートから履歴を取得しているだけなのでローカルのファイルに影響がありません。ちなみにpullは、fetchした後にmergeを行う為ローカルのファイルが更新されてしまいます。

まとめ

 普段は、fetch+mergeを使用せずにpullのみ使用していたのでfetchのことを知ることができる良い機会でした。gitはまだ使いこなせていないコマンドが多いので、少しでも多く使いこなせるように頑張っていきたいです。

ランチにオススメ!アピリッツ周辺飯処3店舗

0

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

社員もよくいくランチにおすすめのアピリッツ周辺のお店についてご紹介します。

 こんにちは飯処を探すのが趣味のtokinです。
皆さん勤務中の昼食は何を食べていますか?弁当やコンビニ・・・そして外食。昼の栄養摂取は様々です。その中でも社員さんとの昼の外食は、ただしっかりとした食事が楽しめるだけでなく、業務とはまた別の交流が深められる場であると最近痛感しております。
というわけで今回は現在アピリッツが位置している明治神宮通り~表参道周辺の社員もよく行くランチにおすすめの店を3店舗ご紹介したいと思います!

穏田 一甫 (オンデン イッポ)

 表参道から一つ裏に出た通りにある居酒屋定食屋。アピリッツの社員さんもよく利用しています。階段を下りた地下にある店内はちょっとした隠れ家のような内装で、落ち着いた雰囲気の中美味しい和食が楽しめます。さらにランチでは格安の海鮮丼が15食限定で登場。他にも刺身定食や煮魚、焼き魚の定食、出汁のきいた饂飩などほっと一息つける品ぞろえ。ご飯の量も大盛りから小盛りまで選べるのでお腹の具合に合わせられるのも嬉しいところです。夜のお酒のラインナップも充実しているそうなのでランチだけでなくゆっくり呑みに行くのにもオススメのお店です。ツイッターにて毎日日替わりのランチ定食の内容もご紹介されてますのでお昼ご飯に迷った際はぜひご利用ください。
穏田 一甫(食べログ)
twitter

北陸酒場

 キュープラザ4階にある居酒屋。ランチでは野菜を中心とした日替わりのお惣菜ビュッフェが楽しめます。数種類の和え物や煮物、こだわりの豆腐やご飯がおかわり自由のこちらのビュッフェは定食に付属しており、1000円台で肉も野菜もたっぷり味わえます。ランチ定食は野菜と日本海で捕れた魚中心の健康的な和食メニュー、夜は日本酒と北陸酒場自家製の美味しい干物や素材のうまみを引き出した温かなおでんが味わえる居酒屋。野菜をたっぷり食べたい時や、酒と共に美味しい干物を心ゆくまで楽しみたい時にいかがでしょうか。
北陸酒場

MIZUcafe

 浄水器でおなじみのクリンスイがプロデュースしたカフェ。
水にこだわり飲み物から食事まで“クリンスイのいい水”をベースに作られています。
メニューはパンネクックなどのデザート系からローストビーフ丼などのお食事系のものまで様々。なかでもローストビーフ丼はローストビーフの上にたっぷりの葉菜、加えて酸味のきいたドレッシングがかかっているためさっぱりとした味。上にのった卵の黄身を崩してもこのドレッシングの酸味により最後まで重くならずさっぱりいただけます。
更にこちらのカフェでは、セルフサービスで三種類のデトックスウォーターが味わえたり、「浄水、炭酸入り浄水、アルカリ水」の三種類の水の飲み比べまでが無料で体験できるそう。まさにクリンスイプロデュースならではの水を楽しむメニューですね(こちらの無料ドリンクのみの注文はご遠慮ください)。
日常的に摂取する水を此方のお店では様々な形で味わうことができます。水にこだわりをもったメニューぜひお楽しみください。

MIZUcafe

最後に

いかがでしょうか。アピリッツ近辺には他にも美味しい食事が楽しめるお店がたくさんあります。アピリッツに入社した際、近辺に立ち寄った際はぜひ散策してみてください。

イヤホンジャックが消えたら必須?従来のイヤホンとBluetoothイヤホンの違い

0

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

先日、AppleからiPhone8/iPhoneX(10)が発売されましたね。 しかし、そのどちらにも、6以前にはあったイヤホンジャックは搭載されていないようです・・・ 従来のイヤホン愛用のiosユーザーには辛いです。 そこで、今までちょっと敬遠していたBluetoothイヤホンについて、 普通のイヤホンと比べて、使ってみないと分からなかった所などをまとめてみました。

基本的に、iPhoneで使ったときの印象です。
ちなみに使っているのは、iPhone7。イヤホンジャックはありません。
なので、従来のイヤホンを使う場合は、充電用のLightning端子に、
イヤホンジャックとの変換用コードをかませる必要があります。
変換用のケーブルは、iPhoneを買ったときに付属してたものを使っています。

従来のイヤホン

1. 壊れやすい。

一番の懸念点ですね。
もともとイヤホンって、付け根の部分が接触悪くなりやすいんですが、
変換ケーブルをかませてると、イヤホンか変換ケーブルどっちかがダメになるとアウトなので、
通常よりも壊れるリスクが高いと思います。
しかも、壊れたときに「これ、イヤホンとケーブル、どっちがダメになったんだ?」
という感じになるので、他の機器にイヤホンだけ接続したりして確認するしか無く、若干面倒です。

2. 充電したままイヤホンを使えない。

当然ながら、充電に使ってるLightning端子にイヤホンを差してるので、充電ケーブルと一緒に使えません。
一応、Lightning端子からイヤホン端子とLightning端子に枝分けする周辺機器もありますが、
なんか見た目が非常にダサいので そんなに充電しながら使う場面が無いので、自分は今のところ使っていません。

3. 使い回せる。

これも当たり前のことですが、変換ケーブルを抜けば他のイヤホンジャック付きの機器にそのまま使い回せます。
ただ、そのとき変換ケーブルをなくさないように注意が必要です。

これに関しては、Bluetoothイヤホン対応機器も増えてきてるので、将来的にはあまり差別化にならなくなるかもしれませんが。

Bluetoothイヤホン

1. 意外と接続が楽。

無線機器なので、初期設定が面倒なのかと思っていたのですが。
iPhone側でBluetoothをオンにして、後はイヤホンの電源を入れて、iPhoneの設定画面でイヤホンを選ぶだけ。
これだけでイヤホンが近くにあると勝手に接続するようになります。
しかも結構範囲が広い。接続したまま隣の部屋に行っても切れません(イヤホンや状況にもよるでしょうが)。

2. 値段が高い。

購入するときのネックになりやすい点です。
同じメーカーのものでも、普通のイヤホンに比べ、1.5倍~3倍くらいの値段になります。ピンキリですが。
ただ、イヤホンジャックに挿す必要が無くなるので、付け根周辺の接続不良などでの買い替えは起こりにくいかもです。

3. 音ズレがある。

個人的に買って一番驚いた所。
買うまであんまり気づいてなかったのですが、有線のイヤホンと違い通信を使うので、
どうしても多少、音が耳に届くのが遅れます。

プレイヤーで音楽を聴くだけなら、全く問題ありません。
しかし、普通に動画などを見るとき、(通信の具合にもよるのですが)口の動きと声がかなりずれるとか、そういうことがたまにあったりします。

スマホでゲームをするときにもすこし影響が出ます。
とはいえ、普通のRPGとかならタップ時の演出と効果音がちょっとずれるかな?ぐらい。
最初は違和感があるかもしれませんが、慣れてしまえば大したことは無いと思います。

この音ズレが顕著なのは、いわゆる「音ゲー」をプレイする時です。
基本的に曲のリズムに合わせてタップしたりする関係上、数コンマのズレでかなりやり辛くなります。
ゲーム側でタイミングを調整できる場合もありますが、それでもやはりタップ時に出る音がずれるので、かなりリズムが取りにくい印象です。

慣れている音ゲーマーさんとかなら良いのかもしれませんが、
そもそも音ゲーをあんまりやらない層からすると、ものすごく難易度が上がって感じます。
もはや音聴かずにやった方が良いのでは?と思うくらいでした・・・。

音ゲーにハマっていたり、よく動画を見たりする人で、ずっと有線のイヤホンを使っていたって人は、Bluetoothイヤホンにするのはリスキーかもしれませんね。
音楽聞くときだけBluetoothイヤホン、その他は有線、とかの使い分けも在処も知れません。経費かかりますが。

おまけ:Lightningイヤホン

これは自分は買っていないのですが、家電量販店で見かけたのでついでに。
普通のイヤホンの端子じゃなくて、先端がLightning端子になっているので、iPhoneにも直接挿せる形になっている有線のイヤホンです。
最初見たときは、『イヤホンジャックが無くなっても、これがあるなら良いじゃん!』と思ったのですが・・・。

1. 値段が高い?

びっくりしました。
自分の行ったお店では、Bluetoothイヤホンより余裕で割高でした。平気で1万を超えてきます。
相場としては、普通のイヤホンの4~5倍くらい?という印象でした。

使う側からすると、先っぽの端子がちょっと違うだけなのに・・・。

ただ、ネットショップだとそこそこの値段のものもあったりしたので、ピンキリ、ということなんでしょうか。

2. 種類が少ない。

これもお店によるでしょうが、普通のイヤホンやBluetoothイヤホンより、圧倒的に種類が少なかったです。
作っているメーカーが少ないんでしょうか?
たしかに、使える機器が限られてて、需要は少なそうですが・・・ちょっと残念。。

Gem MechanizeでWebスクレイピング

0

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

Gem MechanizeでWebスクレイピング

以前Webスクレイピングを行う際に利用した、RubyのMechanizeが良い感じだったので紹介したいと思います。

参考
https://www.xmisao.com/2013/10/05/ruby-www-mechanize.html

環境

Mac OS X El Captain 10.11.5

ruby 2.4.1

Mechanizeとは

web上での操作を、rubyでも行えるようにしてくれるgemです。
フォームの操作や、リンクの取得・遷移などを簡単におこなうことが出来ます。

Mechanizeのインストール

$ gem install mechanize
# nokogiriを利用しているので、一緒にインストールされます。
# 2017/09/XX現在、最新バージョンは2.7.5です  

以下のように、Mechanizeクラスのインスタンスを作成することで、webページへのアクセス・情報取得が可能です。

require 'rubygems'
require 'mechanize'

# Mehcanizeのインスタンス作成
agent = Mechanize.new
# getメソッドでページへのアクセス
page = agent.get('https://www.google.co.jp')

# 例:ページタイトルの表示
p page.title
# => "google"

Mechanizeで出来ること

mechanizeには、便利なメソッドが数多く存在します。
自分がwebスクレイピングをする際に利用したものを、いくつか紹介したいと思います。

フォーム操作

自分はこれがやりたくてこのgemに辿り着きました。(調査不足だっただけで、ほかのgemでも出来るかもしれません。)

取得したページからフォームを取得して、値を代入・ボタンのクリックをすることで遷移先のページが取得できます。

##Googleの検索フォームで、Dorubyを検索する

#検索フォームの取得
form = page.forms.first
=> #<Mechanize::Form
 {name "f"}
 {method "GET"}
 {action "/search"}
 {fields
  [hidden:0x3ff22e4a64f0 type: hidden name: ie value: Shift_JIS]
  [hidden:0x3ff22e4a6388 type: hidden name: hl value: ja]
  [hidden:0x3ff22e4a6220 type: hidden name: source value: hp]
  [hidden:0x3ff22e4a60b8 type: hidden name: biw value: ]
  [hidden:0x3ff22e8afd94 type: hidden name: bih value: ]
  [text:0x3ff22e8af790 type:  name: q value: ]
  [hidden:0x3ff22e8ae9e4 type: hidden name: gbv value: 1]}
 {radiobuttons}
 {checkboxes}
 {file_uploads}
 {buttons
  [submit:0x3ff22e8af3d0 type: submit name: btnG value: Google 検索]
  [submit:0x3ff22e8aefc0 type: submit name: btnI value: Im Feeling Lucky]}>

# name: q に検索クエリを代入
form['q'] = 'doruby'

# 検索ボタンのクリック
search_result = form.click_button

p search_result.title 
=> "doruby - Google 検索"

リンクを辿る

clickメソッドを使うことで、ページに含まれるリンクを辿ることが出来ます。
下記の例では、link_withを利用してリンクの取得を行っています。
今回はtextで取得していますが、classやidで指定・取得することも可能です。

# リンクの取得とクリック
doruby_page = search_result.link_with(text: "DoRuby: Web技術・マーケティング情報発信ブログ").click

p doruby_page.title
=> "Web技術・マーケティング情報発信ブログ | DoRuby"

Xpathを利用したWebスクレイピング

取得したページは、Xpathを利用してスクレイピングすることが出来ます。
また、この際にMechanize::PageからNokogiri::XML::Nodeにパースされるので、返り値はNokogiriになっています

# page.search('Xpath')で、XPathを利用した探索が可能

# aタグのhref要素に、entriesが含まれるものを探す
entries_first = doruby_page.search('//a[contains(@href, "entries")]').first
p entries_first.values
=> ["/users/r357_on_rails/entries/Kali-Linux(2016-X)の日本語利用について"]

上記の3つがあれば、比較的楽にwebスクレイピングを行うことが出来ると思います。
また、数多くのメソッドがあるので、そちらを利用すればより快適に利用することが出来るかもしれません。
参考:: Ruby-docs::Mechanize

補足: ユーザーエージェントの指定

webページにアクセスする際に、ユーザーエージェントを指定することが出来ます。
以前コードを書いた時は文字列で指定したのですが、エイリアスを利用して簡単に指定出来るようです。

agent = Mechanize.new
#文字列でのUAの指定
agent.user_agent = "Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_2 like Mac OS X) AppleWebKit/603.2.4 (KHTML, like Gecko) Version/10.0 Mobile/14F89 Safari/602.1"

#エイリアスを利用したUAの指定
agent.user_agent_alias = "iPhone (iOS 9.1)"

おわりに

Rubyの便利なgem、mechanizeを紹介させていただきました。
他にもスクレイピングするのに便利なgem等ありましたら、ご紹介いただけるとうれしいです。

プログラムが苦手でもコピペで簡単 MelでMayaの効率化

0

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

一通りの作業に慣れてきたら次は作業の効率化に挑戦してみましょう。 Mayaではプログラミングの知識がなくても簡単にMelスクリプトを使って作業を効率化することが出来ます。 本記事ではそのやり方を紹介しています。

はじめに

Mayaのいくつかの機能の目的や使い方を理解し、だんだんと「自分流」のモデリングやアニメーションの作業が身についてくると、
作業の中で繰り返し行わなければならない単調なアクションがとにかく多いことに気づいてきます。

例えば私がモデリング作業の中でなにかとよく行うのが、オブジェクトの左右反転コピーです。
顔や体など対称軸がY軸上にあれば「ジオメトリのミラー」で反転コピーできますが、このコピーはオブジェクトを中心としたミラーしかできないので、猫耳だったりイヤリングなどミラーの基準軸から離れているパーツに関しては思っている結果になりません。

この左右反転コピーを行うには

オブジェクトを複製(Ctrl+D) 
 ↓
 ピボットをワールドの中心に合わせる(「修正」→「トランスフォームのフリーズ」+「トランスフォームのリセット」)
 ↓ 
チャネルボックス上でオブジェクトのスケールXの値を-1にしてもう一度「トランスフォームのフリーズ」

という3段階の手順を踏まなくてはなりません。(自分が知る限りでは)

Mayaには左右対称のモデリングをする際に便利な機能として「シンメトリの軸」を指定できたり、「特殊な複製」で複製して反面だけモデリングすればもう一方にも作業が反映されるというものがあります。
シンメトリのミラー

特殊な複製
しかし、いまいち冒頭で述べた「自分流」に合わないということもあり、結局左右対称のモデリングをするときに私がよく使うのが「左右反転コピー」になります。
15秒程度のちょっとした作業ですが、一日に何度も行う日もあるのでできればワンクリックで済ませたいですよね。

Mayaはスクリプトで自由にカスタマイズできる

Mayaは一つ一つの機能がMelという言語で制御されており
頂点一つ一つの移動からノードの接続関係までそのほとんどがMelで動いており使い手からもスクリプトでの実行が可能です。
保存時によく見かける保存形式の「.MB」(Mayaバイナリ)と「.MA」(Mayaアスキー)という2種類の内の「.MA」という種類では
複雑な3DシーンがすべてMelスクリプトで記述して保存されているようです。

感覚的に3D制作ができるイメージが強いMayaですが実はかなり論理的でお堅いソフトみたいです。

参考 チュートリアル / 読んで触ってよくわかる!Mayaを使いこなす為のAtoZ 第70回:Maya
ASCIIとMayaBinaryの違い

左右反転コピーをワンクリックでできるようにしよう

説明が長くなってしまいましたが、さっそくMelスクリプトの力を借りてこれまで行ってきた単調な作業に終止符を打ちたいと思います。

ただ私自身プログラミングの知識がほぼありません。
きっとこの記事にたどり着いた方の多くも同じかと思います。
でも安心してください。
Mayaでは「スクリプトエディタ」上からすべての実行されたスクリプトが見られるようになっているので自分のアクションに対応したスクリプトがわかりやすいです。

まずさっそくオブジェクトを選択して複製してみましょう
するとスクリプトエディタ上には
複製実行後
と表示されます。複製のスクリプトは

duplicate -rr;

みたいなので、ひとまずメモ帳などにコピペしておきましょう。
続けてトランスフォームのフリーズとリセットを行います。
エコー前
スクリプトエディタ上にはこのように出ますが見る限り今のアクションの実行文ではなさそうですね。
実行されたスクリプトが表示されていないみたいなのでスクリプトエディタ上のこの「すべてのコマンドのエコー」というボタンを押して再度同じアクションを行ってみます。
エコー後

フリーズ、リセット実行後
すると上の画像の通り新しく実行文が表示されました。

FreezeTransformations;
ResetTransformations;

この二つがそれっぽいですね。メモ帳に追加でコピペしておきましょう。
最後にスケールXを-1にします。
スケール実行後

setAttr "pCube2.scaleX" -1;

これも同じくコピペして
抽出した文が以下になります。

duplicate -rr;
FreezeTransformations;
ResetTransformations;
setAttr "pCube2.scaleX" -1;
FreezeTransformations;

ただこのままだと”pCube2″というオブジェクトの名前が入ってしまっているので他の名前のオブジェクトでは機能しなさそうです。
少し調べてみると、選択中のオブジェクトのスケールXを変えるには
setAttr .scaleX -1;
だけで十分みたいです。

というわけで出来上がったのが以下の実行文になります。

duplicate -rr;
FreezeTransformations;
ResetTransformations;
setAttr .scaleX -1;
FreezeTransformations;

試しにこの寄せ集めで作ったスクリプトで左右反転を実行してみます。
スクリプトを実行する際はスクリプトエディタ上の縦に2分割されている下の空白に打ち込んでこのボタンで実行できます。
実行ボタン
実行前
実行前
実行後
実行後

無事に左右反転コピーができましたね!
では、あとはこのスクリプトをボタンとしてシェルフに登録してあげるだけでワンクリック左右反転が実現します。

シェルフに登録

スクリプトを登録する手順を紹介します。
「ウィンドウ」→「設定/プリファレンス」→「シェルフエディタ」
でシェルフエディタを開きます。

シェルフエディタ説明1
シェルフエディタ説明2
「コマンド」タブを開いて先ほどの左右反転コピースクリプトをコピペ。
このボタンの名前やツールヒントなど自分に分かりやすいように入力してすべての「シェルフを保存」で登録完了です。

正常に動いていますね。
動作確認GIF

これで単調な作業におさらばして、作業の効率化と、省いた時間でクオリティ向上に注力していけますね。

まとめ

MayaではMelスクリプト以外にもPythonで動かすことが可能です。
今回の記事ではプログラミングの知識がない人でもMelスクリプトをコピペして簡単に作業の効率化を実現する方法を紹介しました。
ほかにも頭身の違う複数のキャラクターのセットアップ(コントロール作成等)をボタン一つで行うツールであったり、自分用にUIを作成してツールを使いやすくしたりと様々な事例があるみたいです。

人それぞれ作り方に「自分流」があって、ほしい機能もやはり個々によって異なります。
まずは自分の作業周りで困ったことやめんどくさいと感じたことを効率化していく努力をして、
徐々にチームでも重宝されるような開発ツールが作れるようになれば、一段と価値の高いデザイナーになれるのではと思います。

あなたも「テクニカルアーティスト」を目指してみてはいかがでしょうか。

Mel・Pythonコマンド一覧

【Unity】テクスチャの”Generate Mip Maps”を自動でオフにして手間とメモリを省きたい

0

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

テクスチャのインポート設定での一つである “Generate Mip Maps” を自動でオフにする方法を考えます。

はじめに

こんにちは、inoooooocchiです。
気付けばあと2週間程度で10月。
入社から半年が経過しようとしていることにびっくりしています。早すぎます。

そんなこんなで今までやってきた作業や実装内容を思い返していたのですが、毎週のように行っている作業の中でおまじない的に行っているものがあり、「この一手間によって何がどう変わるんだろう…」と思ったため、調べてみました。

その作業とは、テクスチャのインポート です。
私はオンラインゲーム部に所属しているエンジニアなので、ゲームのUIなどで新しいグラフィックを使う際には、Unityにテクスチャをインポートする必要があります。
この業務内容を教わる際、先輩から「インポートしたらGenerateMipMapsのチェックをオフにすること」と教わっていました。
もちろんその時に説明をして頂いたのですが、当時は入社直後で覚えることが多く、大まかな流れを覚えるだけで精一杯でした。

と、いうことで、GenerateMipMapsのチェックをオフにする 意味を追い求めて行きます。

MipMapとは?

GenerateMipMaps…つまり、MipMapを生成するということなのですが、
そもそもMipMapってなに?
という疑問が浮かんできました。

Unityの公式マニュアルによると、

ミップマップはかなり小さくした画像イメージを複数集めた一覧であり、これによりリアルタイム 3D エンジンでのパフォーマンスを最適化します。カメラから遠く離れたオブジェクトはテクスチャの小さいものを使用します。ミップマップを使用すると 33% 多くメモリを使用しますが、使用しないとパフォーマンスのロスが顕著になります。

とのこと。
どうやら、縮小したテクスチャのリストのようなもので、カメラとの距離が離れて小さく描画する必要がある際に、ミップマップの中から適切なサイズのテクスチャを選んで描画する、といったもののようです。
リストを保持しておくためにメモリ使用量は増えますが、描画の際に小さなサイズを描画させることが出来るのでパフォーマンスが良くなるということでしょうか。

MipMapの効果検証

MipMapの意味が分かったところで、何故GenerateMipMapsのチェックをオフにするのか考えてみます。

先ほどのマニュアルの説明では、”リアルタイム 3D エンジンでのパフォーマンスを最適化”するためにMipMapを使っていると書かれていました。
つまり2Dでゲームを制作する場合、カメラとの距離も何も無いので、基本的に使われることは無さそうです。
ただし、2Dでもテクスチャを縮小して使いたい場合はあります。
そのような時にMipMapがどのような影響を及ぼすのか、実際に見てみました。

今回は、MipMapによる描画の違いの例として、
弊社Appiritsのゲームシリーズ「式姫プロジェクト(公式サイト:式姫大全)」から「狛犬(詳細はこちら)」に出演して頂きました。

  • GenerateMipMaps オン
    enter image description here
  • GenerateMipMaps オフ
    enter image description here

この例では、もともとのサイズが1024×1024のテクスチャを300×300のImageにアタッチしています。
一目瞭然ですが、MipMapを使っている方は全体的にアンチエイリアスがかかり、少し滲んだ感じがしますが、滑らかに表示されています。
一方、MipMapを使わない方は、ジャギーが目立ちますが色合いや細部ははっきりと表示されています。

このように、どうやら2DでもMipMapによって画像の描画の仕方が変わるようです。

ゲームのUIにおけるMipMap

さて、先ほどはテクスチャのサイズを元より小さくした際にMipMapが適用されることを確認しましたが、ゲームのUIに使うテクスチャのように、サイズが変動しないことを前提としているテクスチャもあると思います。
これらのテクスチャに対し、GenerateMipMapsをオンにしてしまうと、使いもしないのに縮小されたテクスチャが生成されることになってしまいます。

これでようやく、私のインポート作業の中でGenerateMipMapsのチェックをオフにする意味がはっきりしました。
UIに使うテクスチャはMipMapを生成しても使わないので生成するだけメモリの無駄!
ということですね。

インポート作業を簡単にしよう

というわけで、テクスチャをインポートするたびにGenerateMipMapsをオフにする作業をこれからも続けていかなければならないわけですが、「2DゲームだからMipMapいらないか…」と割り切ってしまえば、この作業は簡単に自動化出来ます。

以下のスクリプトファイルを作成することで、インポート時及びインポート設定の変更時に、GenerateMipMapsを自動でオフにしてくれます。

using UnityEditor;
using UnityEngine;

public class TextureImportProcessor : AssetPostprocessor {
    // インポート設定のデフォルト値をインポート前に変更可能
    public void OnPreprocessTexture(){
        // assetImporterがインポート設定を持っている
        var importer = assetImporter as TextureImporter;

        // GenerateMipMapsをオフにする
        importer.mipmapEnabled = false;
    }
}

AssetPostprocessorというクラスを継承することで、インポート処理にフックしてスクリプトを実行することが出来ます。
今回はテクスチャのインポート設定を変更したいので、TextureImportProcessorというクラスを作りました。

OnPreprocessTexture関数は、インポート処理の前に呼び出されます。この時点でインポート設定を変更しておけば、インポートされるテクスチャの設定にその変更が自動的に反映されます。

AssetPostprocessorの詳細に関しては、公式のスクリプトリファレンスを見ればなんとなく分かると思います。

余談ですが、上記のスクリプトを使う場合、どう頑張ってもGenerateMipMapsをオンに出来ません。
オンにして設定を保存すると、即座にオフに変更されるからです。
UIだけオフにしたい等の場合は、UIとそれ以外でテクスチャのディレクトリや命名規則を分け、スクリプト内で判定して区別してあげる必要があります。

最後に

簡単なスクリプトを書くだけで、作業の手間が省けるのは非常にありがたいですね。
Unityの拡張性の高さに、改めて驚かされますね。
DoRubyでは、他のライターの方がUnityのエディタ拡張について書いているため、興味があればそちらもご覧ください。
UnityEditor上で複数のゲームオブジェクトをプレハブ化する方法)

これまた余談ですが、弊社のゲーム作品「かくりよの門」及び「うつしよの帳」で使われている式姫スタンプの、狛犬の「突撃ッスー!」がアホ丸出しでなんだか好きです。

トラックボールマウスのススメ

0

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

パソコンの入力デバイスとしてのマウスと聞いて、おそらくみなさんが同じものを思い浮かべることでしょう。 今回はそれとはちょっと違う、トラックボールマウスのご紹介をします。

トラックボールマウスとは?

現在主流となっているレーザー式や光学式が採用される以前、マウスの裏側にはボールが入っていました。それは、

マウスを動かす -> ボールが動く -> カーソルが動く

という仕組みの、現在ではほとんど見なくなった絶滅危惧種のマウスです。

そんなボール方式のマウスのボール部分を直接操作できるようにしたのが、トラックボールマウスです。

トラックボールマウスの良いところ

  • 省スペースで扱える

    本体を動かさずに操作できるため、設置するスペースさえ確保できれば使うことができます。

    ワイヤレストラックボールマウスの場合、膝の上やひじ掛けの上などお好きな場所で使うことが出来ます。

    マウスを動かすスペースがないほど机の上が物で溢れかえっている方は、ぜひトラックボールマウスを使いましょう。
  • 手首が疲れない

    指先のみで操作を行うため、手首への負担が軽減されます。

    手首の痛みに悩んでいる方は、ぜひトラックボールマウスを使いましょう。

トラックボールマウスの悪いところ

  • 慣れるまで操作が難しい

    普通のマウスを使っている人がトラックボールマウスを使用した際に最もネックとなるのが操作感です。

    慣れないうちは思ったようにカーソルを動かすことができず、イライラすることがあります。
  • 汚れが溜まりやすい

    ボールを動かしてカーソルを操作するという特性上、センサー周辺にホコリなどのゴミが溜まりやすく、ボールの動きを阻害してしまいます。

    操作感を保つためにもこまめな掃除が必要となります。

おわりに

トラックボールマウスを使いこなすには慣れが必要ですが、一度慣れてしまうと手放せない魅力があります。

これからトラックボールマウスを使おうと思っている方に私がおすすめするのは、Logicoolの Trackman Marble と ナカバヤシ株式会社の Digio2 Q です。

この機会にみなさま、トラックボールマウスを使ってみてはいかがでしょうか。

最近人気な記事