RailsのプロジェクトにRSpecを導入したお話
かずまです。
前回の記事で徳島を紹介するサイトを作ったお話をしました。
今回はそのRailsプロジェクトにテストコードを書いていこうということでRSpecを導入しました。
RSpec
Ruby用のGemもありますが、今回はRailsのプロジェクトということrails_rspecをインストールします。
Gemfileの中に書いてbundle installです。
忘れないうちにrspecの初期化をやっておきます。
$ rails g rspec:install
ちなみにテスト用のデータベースを用意する必要があるので、MySQLを使っている方などはRakeでRAILS_ENV=testを指定して作って上げる必要があります。
qiita.com
そこら辺はここを参考にするといいかも。
テスト用のテストコードを書く
RSpecをインストールされるとspecディレクトリが出来ています。
ここにディレクトリを作成してRSpecのコードをカタカタ打っていきます。
ひとまずサンプルコードを書きたいと思います。
まずは言語のはじめに必ず書くとされる"Hello world!!"を出力してみます。
require 'rails_helper' RSpec.describe ApplicationHelper, :type => 'helper' do describe "sample spec" do it "should print" do p "Hello World!!" end end end
いいですね。これで後は
rspec spec/sample/sample_spec.rb
ここで僕の場合、以下の様なwarningが...
DEPRECATION WARNING: alias_method_chain is deprecated. Please, use Module#prepend instead. From module, you can access the original method using super. (called from <top (required)> at /Users/kazuma/Documents/github/Prefecture/config/environment.rb:5) DEPRECATION WARNING: alias_method_chain is deprecated. Please, use Module#prepend instead. From module, you can access the original method using super. (called from <top (required)> at /Users/kazuma/Documents/github/Prefecture/config/environment.rb:5)
これはググったところ、Rails5がサポートしていないGemがあるそうで、その警告でした。
まぁ警告してくれるのはありがたいですが毎回出るのは面倒なので切っておきます。
書くのはconfig/application.rb
ActiveSupport::Deprecation.silenced = true
これで消えました...!
あとは色々書いていくんですね。
Controllerのテストを書いてみる
今回はPictureという名前のモデルを使います。
そのPicturesControllerをテストします。
まずはRSpecのコード。
require 'rails_helper' RSpec.describe PicturesController, :type => :controller do describe "GET #index" do it "respons success with an http 200 status code" do get :index expect(response).to be_success end it "renders the index template" do get :index expect(response).to render_template("index") end end end
itの後ろは目的を書くらしいです。
何をするためのテストか?みたいな。
後は動作した結果、こうなってほしいというのを書くだけですね。
今回だとindexのレスポンスのステータスが200だと嬉しいよねってことでhave_http_status(200)です。
やる動作とそれに対応する返ってきてほしいものをit ... endの間に書くんでしょうね。
これはサンプルとか結構出回ってるので書いたという問題ではないけど....。
ちなみにここらへんを見るといっぱい書いてます。
File: README — Documentation for rspec-rails (3.6.0)
そんでRspecで叩く!
$ rspec spec/controllers/pictures_controller_spec.rb Failures: 1) PicturesController GET #index renders the index template Failure/Error: expect(response).to render_template("index") NoMethodError: assert_template has been extracted to a gem. To continue using it, add `gem 'rails-controller-testing'` to your Gemfile. # ./spec/controllers/pictures_controller_spec.rb:12:in `block (3 levels) in <top (required)>' Finished in 0.0513 seconds (files took 3.57 seconds to load) 2 examples, 1 failure Failed examples: rspec ./spec/controllers/pictures_controller_spec.rb:10 # PicturesController GET #index renders the index template
エラった、なんかgem rails-controller-testingを入れろ見たいなことを書いてますね。
念のためググって見る。
github.com
Readmeに書いてある、更にこっちも
github.com
Issueでも解決してるっぽい。
これを使ってみる。
Gemfileにgem rails-controller-testingを入れてbundle!!
localにも入れてもいいかも...と思ったけどまぁ今回は止めておくことにします。
入れ終わったら、今度こそ!
.. Finished in 0.06619 seconds (files took 2.64 seconds to load) 2 examples, 0 failures
通ったぽい!
これでガリガリテストも書けますね!
まとめ
すごく簡単に単体のテストができました。
次の課題としては一連の流れのテストと自動化ですね。
サービスとしてはテストの通ったものだけを入れたいので、CircleCIを使って検証します。
ついでにコード規約用のRubocopも導入してみました。
参考にしたURLはこちら。
qiita.com
最後に徳島を紹介するサービスはこちら!
オープンデータとかも使っています。
RubyでOpenGLを動かすところまでのお話
かずまです。
今日は入社式とか研修とかでした。
帰ってバタンキューだったのですがなんか妙な時間に目覚めてしまったのでRubyでOpenGLのAPI叩けないかなーってことで調べてたら
あった!
別にRubyでゲーム作りたいとか、ではないのですが、使えると便利かな、ぐらいです。
ちゃんとありました。
DirectXは基本WindowsのAPIになっているのでMacやLinuxユーザーとしてはOpenGLかなって感じですね。
まぁVM立ててWindows立ち上げるみたいなので力技はできますが。
Sampleを動かす
先程のgithubからCloneしてきてSampleを動かしてみることにします。
GemのOpenGLとかを入れるのですが、まぁプロジェクトごとに管理できるのが一番いいのでBundlerを入れてしまいます。
入ってる場合は飛ばします。
こことかを参考にして
$ gem install bundler Fetching: bundler-1.14.6.gem (100%) Successfully installed bundler-1.14.6 Parsing documentation for bundler-1.14.6 Installing ri documentation for bundler-1.14.6 Done installing documentation for bundler after 4 seconds 1 gem installed
OK、これでExampleディレクトリに移動して、
$ bundle init $ vim Gemfile
ここでGemfileの中身を書き加えます。
gem 'opengl' gem 'glu' gem 'glut'
これで後は
$ bundle install --path=vendor/bundle
これでここのディレクトリのみにGemがインストールされるはずです。
よしこれで動く環境は整いました、examples/Neheに移動してrubyで叩いてみます!
$ bundle exec ruby nehe_lesson02.rb
おぉー表示されました。
いいですね。
頂点をきめたりするところ
glBegin GL_POLYGON do glVertex3f 0.0, 1.0, 0.0 glVertex3f 1.0, -1.0, 0.0 glVertex3f -1.0, -1.0, 0.0 end
ここで三角形の頂点を決めてますね。
GL_POLYGONの部分でどんな形をレンダリングするかです。
ちなみにGL_QUADSのところを
glBegin GL_POINTS do glVertex3f -1.0, 1.0, 0.0 glVertex3f 1.0, 1.0, 0.0 glVertex3f 1.0, -1.0, 0.0 glVertex3f -1.0, -1.0, 0.0 end
GL_POINTSに変更すると
見えにくいですが点がレンダリングされます。
使うとよさそうな一覧が乗ったページがありますのでこちらを参考にするといいかも。
glBegin
今日は時間も遅いのでここまで。
お疲れ様でした。
敵ロックオン機能をUnityで実装する <ゼルダの伝説シリーズ>
かずまです。
今回も引き続き、ゼル伝シリーズをやっていきます。
そういえば今回のゼルダの伝説は一応ストーリー全クリしました。
ただマップの開放とかいっぱいやることはありますね。
ネタバレっぽくなっちゃいますが、感動した!これだけ言っておきます!笑
テーマ
今回は画面内に入った敵を注目してLボタンでロックオンするところです。
ロックオンして、タイミングよくバク転か、サイドステップをするとラッシュ攻撃ができます。
これです。
ちなみに一定の範囲内に入った時に注目できるよって示すマークを出します。
考察
ロックオン(注目)で重要な点は
- 注目できる敵の上になにか表示
- 注目したらなにか表示(上とは違うものを)
- 注目しているときは敵を見続ける
- 画面外になったときは解除される
これぐらいです。
下準備
まずは重要な点でも言ったなにか表示の部分の準備です。
注目している場合の画像は、今回いいのがあったのでフリーを使います。
yajidesign.com
この末広がりのやじるしです。
[指し示すだけの三角]
白紙ですが、この上に有ります。
これをSpriteRendererで違和感のないサイズに変更し、名前を"Point"に変更し、Prefab化します。
サイズ的にはこんな感じ。
そのPrefabに次のスクリプトをアタッチします。
これでPrefabにくっつけます。
この時、InspectorからSpriteをセットし忘れないように...。
EnemyManagerを作る
今回Enemyが画面に入ったらリストに追加、削除していきます。
そこから最短のEnemyを取り出したりすることができます。
これを作りました。
MonoBehaviourは継承しません。継承しちゃうとインスタンス生成できなくなりますかね。
次にEnemyManagerをPlayer.cs内でインスタンス生成します。
前回のPlayer.csを使い、変数とStart関数、新規メソッドを追加します。
ついでにXbox One ControllerのLBをLTriggerとしてUnityにセットしておきます。
// 変数 public EnemyManager EnemyMGR; // Start関数でインスタンス生成、コンストラクタとしてPlayerが必要なので自分をいれる private void Start () { EnemyMGR = new EnemyManager (this); CharactorCTL = GetComponent<CharacterControl> (); CameraCTL = GameObject.Find ("Main Camera").GetComponent<CameraControl> (); } // 新規メソッド追加 public void Locked () { if (Input.GetAxis ("LTrigger") > 0.9f) { Enemy enemy = EnemyMGR.getNearEnemy (); if (enemy != null) { // あとでEnemyにAttentionメソッドを記載します enemy.Attention (); } } }
Enemyスクリプトに追記
次にEnemyは画面に入った、出た場合のタスクとして、そのEnemyManagerに自身を突っ込んでもらいます。
画面外は自分をリストから削除します。
画面に入った入ってないは
このQiitaで完結に解説されています。
// 画面外にでた private void OnBecameInvisible () { player.EnemyMGR.DeleteEnemy (this); } // 画面内に入った private void OnBecameVisible () { player.EnemyMGR.AddEnemy (this); } private void OnWillRenderObject() { // あとで記載 }
EnemyはPlayerを常に見ている状態なのでPlayerのEnemyManagerにもアクセスできることになります。
これで画面に入ったりでたりというのが確認できます。
注目しているかしていないか、Player側に持っておくのではなくEnemy側で管理します。
Enemy.csに変数とメソッドをもう少し付け加えます。
private readonly float AttentionDistance = 4f; public bool isDrawingAttention = false; public void Attention () { player.transform.LookAt (transform.position); isDrawingAttention = true; } public void UnAttention () { isDrawingAttention = false; } private void OnWillRenderObject() { // あとで記載と書いていた場所 if (getDistance () < AttentionDistance) { transform.FindChild ("Point").GetComponent<SpriteRenderer> ().enabled = true; } else { transform.FindChild ("Point").GetComponent<SpriteRenderer> ().enabled = false; } }
あとはこれでEnemyの子どもとしてPointのPrefabをセットします。
isDrawAttentionがtrueのときは注目している画像になればOKです!
結果
もっと派手なエフェクトほしいけどまた今度!
なんか雑になってきたやばい...。
追記
- クラス図とか書こうと思う
- オブジェクト指向プログラミング意識しよう
- ちゃんと寝よう
敵の目線の動きをUnityで実装する <ゼルダの伝説シリーズ>
かずまです。
前回まではPlayerの動きを実装していました。
ちなみにSwitchのゼルダの伝説の動きが気になる方はこちら。
テーマ
今回のテーマは"敵の動き"です。
敵がいないと始まらないですからね。
考察
敵の動きを見てみます。
気づかれると注目して見られる
音に気づく
目線があうと気づかれる
隠れると見失う
ココらへんが結構重要だと思います。
この章では歩くことはあとで実装します。
Enemyを追加
EnemyをPlayerと同じものを作ります。
前回作ったCharactorControlをつけます。
今度はEnemy.csを作ります。
気づいたときのアクション
EnemyにつけるNoticeObjectを作ります。
気づいたときのびっくりマークとはてなマークをPhotoShopとかIllustratorで作ります。
[びっくり]
[はてな]
両方背景透明なので白く見えますがあります。
Notice.csを作成
先程用意した画像をSpriteにして、SpriteRendererで表示します。
その時につけるスクリプトです。
以下のように設定します。
WarningはHatenaのSpriteを入れて、
DiscoveryはBikkuriのSpriteを入れます。
これをPrefab化して、その後、NoticeObjectに入れます。
ここからは重要な部分だけを取り上げて解説していきたいと思います。
Playerとの距離
Unity C#では
Vector3.Distance (Vector3 a, Vector3 b)
で距離を求めますが、今回は簡単なので実装してみます。
PowはC++でもライブラリがあるみたいなので、ちょっと意識して...
// Enemy.cs Vector3 dv = player.transform.position - transform.position; return Mathf.Pow ((dv.x * dv.x + dv.y * dv.y + dv.z * dv.z), 0.5f);
unitylab.wiki.fc2.com
いや、ここのサイトのように正規化したほうが良さそう。
EnemyはPlayerを探す
EnemyにはSearchメソッドがあって、そこの中でPlayerを探しています。
検索方法としては、
目線
Enemy.cs内でenum設定している
- Warning
これは気づくか気づかないかを表します。
はてなマークのアイコンを使います。
- Discovery
これは気づいたときを表します。
ビックリマークのアイコンを使います。
距離
これは先程、使ったメソッドを使って距離を測っています。
次の足音が小さければ距離が近くても気づかれないです。
入力の力に合わせて足音を実装する
今回はXbox Controllerのスティックを使っているためGetAxisを使うことができます。
float dx = Input.GetAxis ("Horizontal"); float dy = Input.GetAxis ("Vertical"); WalkVolume = (Vector3.right * dx + Vector3.up * dy).magnitude; getWalkVolumeStatus ();
Player.cs内のこの部分でmagnitudeで入力の加減を取っています。
これを足音としています。
スティックを強く押し込むと足音が大きく、軽く押し込むと小さくなります。
VolumeのStatusでどの動きか、を取ることができます。
- Quiet
- Small
- Loud
こんな感じ。
これに音をつければそれっぽくなります。
後半へばってしまいましたが、今回はこんな感じです。
デザインとかも実装したいですがうーん笑
コードのデザインもうまくいかないのでそこまで手が回らなそう。
もっとこうしたらいいよ、みたいなのがありましたら言ってください...!
カメラワークとプレイヤーの動きをUnityで実装する Part2 <ゼルダの伝説シリーズ>
かずまです。
前回の記事はこちら。
そう、ゼルダの伝説です。
考察
リンクの動きはカメラの方向が正面になります。
なので、動いている時にカメラを回転させたらその方向に移動する感じですね。
Playerを実装
まずはPlayerを動かします。
今回は拡張性を踏まえてCharactorControllerを使わないで自分で実装します。
上記スクリプトを書きます。
CharactorControllerではisGroundがあったので、それも実装してしまいます。
- Raycastで距離を測る
- Colliderでのあたり判定
この2つによって実装されます。
Colliderだけだと天井などに当たったときに反応してしまうのでRaycastも使います。
つけるコンポーネントは以下の通りです。
RigidbodyをつけてFreeze Rotationをすべてチェックいれます。
これをしないと物に当たった時に制御できなくなります。
次にPlayer.csを実装します。
これをPlayerのオブジェクトにくっつけます。
前回のブログでもちょこっとかきましたが、それにすこし付け足します。
UnityでXboxOneコントローラを使う…前に | 蒼玉亭
ここを参考にして、Playerの動きはXbox Controllerの左スティック、カメラの動きは右スティックを使って制御します。
Edit -> Project Settings -> Input
からMouse XとMouse Yがあるとおもうので、以下のように変更してあげます。
これでInput.GetAxis("Mouse X")でOKになります。