doridoridoriand’s diary

主に技術的なことを書いていく予定(たぶん)

ブログを移行しました

気がつけば社会人2年目も半ばになっているっていう。 後輪矢のごとしとはまさにこのことですね。

HUGO+レンサバから、はてなブログ+S3(アセット)に移行しました。 理由としては

  • ブログをもっと気軽に更新したかった。
  • 自分のドメイン = 旧ブログにしてしまっていたので、気軽に自分のドメインを実験に使えなかった

などがあります。学生時代には予想もしなかったインフラエンジニアになっている、ほぼ毎日酒を飲んでいるなど、中々めまぐるしく変化している社会人生活ですが、 技術的なことを主軸にこのブログを更新していこうと思います。

インフラエンジニアになっても何故か仕事レベルで書ける言語は増える一方なので、インフラという枠(あるレベル以下は既にその境界線が無いようなものですが)に囚われずに書いていきます。

AWSをVagrantから使ってみる

卒研とか引っ越しとかで忙しくてねえ。。(言い訳)

AWS便利すぎて値段が割高というデメリットが完全に霞んでいる感ありますね。個人的にはもう少しGoogleCloudPlatform使いたいんですけど。 でも結局GCPあんま使ってないっていう

・・・

vagrant-awsというプラグインを利用することによって、AWSをあたかもVagrantVirtualboxなりVMWareなりのVMを立ち上げているかのように使えるということで、試しに使ってみました。 作者のページを見れば当たり前ですが詳しく書かれているのでどうぞ

まあまずプラグインをインストールしないことには始まりませんので、インストールします。(あ。VagrantAWSを普段そこそこ使用している方向けの記事ですので、Vagrantって何ぞやって方はまず普通にVagrantを使ってみてください)

$ vagrant plugin install vagrant-aws

次にvagrantが利用するboxをインポートします。そもそもVagrantはローカルにVMを立てて使うものなので、どうしてもVMのイメージが必要となります。

$ vagrant box add dummy https://github.com/mitchellh/vagrant-aws/raw/master/dummy.box

これでvagrant-awsを利用する下準備が出来ました。

次にAWSに接続するために必要な情報を集めます。今回はAWSに接続するためにアクセスキーIDとシークレットアクセスキーが必要となります。しかし、ルート権限を持った状態でのこの2つの発行は出来ないことになっているのでIAMユーザーを作成し、 そのユーザーのアクセスキーIDとシークレットアクセスキーを用いて接続することにします。

まずAWSのコンソールにログインし、上のメニューバーを[サービス] -> [IAM]の順にクリックしていきます。

するとこのような画面が現れます。

ここでVagrantから操作する専用のIAMユーザーを作成しましょう。 [個々のIAMユーザーの作成] -> [ユーザーの管理] -> [新規ユーザーの作成] とクリックしていきます。ユーザー名は任意で大丈夫です。ここで重要なのは、画面下に設置してある[ユーザーごとにアクセスキーを生成]のチェックボックスにちゃんとチェックが入っているかどうかです。 これにチェックしていないとちゃんとアクセスキーが発行されませんので注意してください。

これで無事作成すると、[これは、これらのユーザーセキュリティ認証情報をダウンロードできる最後の機会です。]などという文言と共にアクセスキーIDとシークレットアクセスキーが表示されると思います。 これをどっかにメモっておきましょう。

これでAWS側の準備は整いました。ではVagrantfileを作成してゆきましょう。 任意のフォルダでvagrant initを実行します。

最初に書かれているサンプルをさくっと削除して、次の内容を書き込みます。

VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|

  config.vm.box = "dummy"

  config.vm.provider :aws do |aws, override|
    aws.access_key_id = "さっき取得したアクセスキーID"
    aws.secret_access_key = "さっき取得したシークレットアクセスキー"
    aws.keypair_name = "いつも使用しているリージョンの公開鍵の名前"

    aws.tags = {'Name' => 'Vagrant'} # AWSのEC2に名前を付けられる。とりあえずVagrantにした
    aws.ami = "ami-a21529cc" # Ubuntu14.04LTS HVMのイメージ
    aws.instance_type = "t2.micro" #インスタンスのサイズはご自由に
    # セキュリティグループの設定がうまくいかない
    #aws.security_groups = {'groupId' => 'セキュリティグループID'}
    aws.region = "ap-northeast-1"

    override.ssh.username = "ubuntu"
    override.ssh.private_key_path = "公開鍵の絶対パス"
  end
end

以上の状態でvagrant upを実行します。するとこのようにAWS上にVagrantを立てることが出来ました。

AWS上でもインスタンスが稼働していることがわかります

Vagrant全ての機能を使えるわけではありませんが、気軽に実際にサーバーを立てて検証するには良いと思いました。個人的にはMulti-VMモードで複数起動出来るか試してみようと思います。

めっちゃ日付あいた

例によって画像は関係ありません笑

色々あってブログを書くことが出来ませんでした。すません しかし、新規にネタもない感じなので、とりあえず今気になっていることを列挙しておきます (書くことない時の手です)

  • RAXE
  • PHPのcodeigniter
  • HUGOのテーマ作成
  • JRubyでデスクトップアプリ作る
  • PlayFrameworkで書いていてストップしている案件どうにかする
  • GoのRevel
  • C++のCROW
  • C#のNancy
  • JavaのJetty
  • そういやPassengerV5(RAPTOR)出たけどためしてねーや

おわり (ぉ

C#のyieldに関して

まあなんか書くことなかったんだけど笑 C#のyieldを目にする機会が多かったので、ちょっと調べてみました。Microsoftのドキュメントを読んでみると

ステートメントで yield キーワードを使用した場合、メソッド、演算子、または get アクセサーが反復子であることを示します。 yield を使用して反復子を定義すると、カスタム コレクション型の IEnumerable および IEnumerator パターンを実装するときに明示的な余分なクラス (列挙の状態を保持するクラス。たとえば IEnumerator を参照) が不要になります。

フーン

まあコード書いてこのyieldの利益をえてみましょう。まずyieldを使っていない書き方から

class YieldTest {
  static void Main(String[] args) {
    foreach (var item in GenDataset()) {
      Console.WriteLine(item);
    }
  }

  static List<String> GenDataset() {
    List<String> dataset = new List<String>();

    for (int i = 0; i < 100; i++) {
      dataset.Add(i.ToString());
    }
    return dataset;
  }
}

まあ単純に0から99までの数字を配列に入れているだけです。次にyieldを使った書き方に変更してみます

class YieldTest {
  static void Main(String[] args) {
    var dataSet = GenDataset();
    foreach (var item in dataSet) {
      Console.WriteLine(item);
    }
  }

  static IEnumerable<String> GenDataset() {
    for (int i = 0; i < 100; i++) {
      yield return i.ToString();
    }
  }
}

ListからIEnumerableというインターフェースに変更して、かつ内部のListの変数宣言などが不要になっています

正直この例だと簡単過ぎてメリットを感じないのですが笑

ここでメソッドから帰ってきた配列の型を確認してみましょう。普通に書いた方は System.Collections.Generic.List1[System.String]`

ですが、yieldで書いた方は YieldTest+<GenDataset>c__Iterator0

という形で返ってきています。イテレータとなっていることから、List型ではなく、反復子として処理されたことがわかります。なので、内容はList型のような参照を行うことが出来ません(配列要素をカウントするCountなどをメソッドチェインすることは不能です)

。。結論として何を言いたいんだって感じになってしまいましたが、まあRubyにもYieldあったなあって思って色々試しただけですw

久しぶりにまとまらない話になりましたorz

C#の開発環境をMac上に整えてみる

C#面白いけどUnity上でしか触っていないので、コンソールから叩けるようにしようと思い、インストールしてみました

C#マイクロソフトが開発した言語で、.NET Framework上で動くように設計されています。 しかし、マイクロソフトが.NETに関する仕様を公開したのに伴って、オープンソースによる.NET Frameworkと互換性のあるフレームワークが作成されるようになりました。まあ詳しくはWikipediaでも見といてください
(ぉ

まあ長々と説明していてもしかたがないので、さくっとインストール方法を書いていきます。
といっても大変簡単で、Monoプロジェクトの本家のサイト に懇切丁寧な説明がありました。Macにインストールしていきます

・・・

まずインストールパッケージをダウンロードしましょう。MonoのサイトからDownloadに行き、Download Mono MDKをクリックして.pkgファイルをダウンロードします

ダウンロードしたファイルをダブルクリックすると以下のような画面が出てくると思います

あとはインストーラーにしたがってインストールを完了させてください

実際にインストールされたかを確認するには以下のコマンドを実行してください

$ mcs --version

僕の環境で実行したところ次のようになりました

では使えるか試してみましょう。以下のコードを適当なcsファイル内部にコピペしてください

using System;

class MonoTest {
  static void Main(String[] args) {
    Console.WriteLine("うぇぇいww");
  }
}

作成したファイルをコンパイルして実行しましょう。以下のコマンドで行うことが出来ます

$ mcs hogehoge.cs
$ mono hogehoge.exe

ここで$ mono hogehoge.exeとしている理由ですが、MonoのC#コンパイラがexeファイルを出力するためです。exeファイルの実行にはmonoコマンドを利用します

無事に実行できました。次回はUbuntu上で実行出来るようにします

Cocos2d-xをGenymotionで実行出来るようにする

Cocosで開発するときは、わざわざNexus7をUSBでつないで実機で動くか試していたのですが、いちいち持ち歩いているの嫌だなってこととUSBケーブルの調子が悪くてlogcatがブツブツ切れていたりして、地味にストレスだったので、エミュレーターで動くように変更しました(USBケーブル買い直せってツッコミは無しの方向で)

※既にGenymotionは入っている前提で行います

まずCocos2d-x本体側のコードの変更を行います。Cocosをインストールしたディレクトリに移動して、次の場所のファイルを編集してください

cocos2dx/cocos/platform/android/java/src/org/cocos2dx/lib/Cocos2dxActivity.java

このファイルにあるisAndroidEmulator()を探してください。次のような関数になっているかと思われます

private final static boolean isAndroidEmulator() {
  String model = Build.MODEL;
  Log.d(TAG, "model=" + model);
  String product = Build.PRODUCT;
  Log.d(TAG, "product=" + product);
  boolean isEmulator = false;
  if (product != null) {
    isEmulator = product.equals("sdk") || product.contains("_sdk") || product.contains("sdk_");
  }
  Log.d(TAG, "isEmulator=" + isEmulator);
  return isEmulator;
}

ここのor条件分岐が連なっているところでエミュレーターの種別を判断しているようです。Genymotionは裏でVirtualboxを動かしているので、エミュレーターの種類に含めてやる必要があります。よって分岐を以下のように書き換えます

isEmulator = product.equals("sdk") || product.contains("_sdk") || product.contains("sdk_") || product.contains("vbox");

これで保存してCocos本体側の変更は終了です。次にプロジェクトファイルの変更を行います。 以下のファイルを変更します
対象のプロジェクトフォルダ/proj.android/jni/Application.mk

このファイルの一行目にAPP_STL := gnustl_staticという記述があるので、この下にAPP_ABI := armeabi x86を追記してあげましょう。これで以下のように変更されたと思われます

APP_STL := gnustl_static
APP_ABI := armeabi x86

APP_CPPFLAGS := -frtti -DCC_ENABLE_CHIPMUNK_INTEGRATION=1 -std=c++11 -fsigned-char
APP_LDFLAGS := -latomic

これをし終わったら、再度コマンドラインから、プロジェクトフォルダで cocos run -p android を実行してみてください。無事にGenymotionで動くようになります

参考にしたサイト

フニゲの開発日記

Unityで大量のオブジェクトをランダムに生成して更にそれぞれランダムに行動させる

Unityロゴあればいいやと思ってタイトル無しにした笑
それにしてもUnityのDocumentationわかりやすくてよかった

とりあえず空間上に大量の障害物などをまき散らして、 更に自立して行動させたいとかってしたくなると思います。どうやるかちょっと悩んだので備忘録がてら

まず転がしたいプレハブちゃんを用意します。まあ適当に3Dオブジェクトを作りましょう

とりあえずUnity公式のチュートリアルのやつを持ってきました。 ここからプレハブを生成します。まずからのGameObjectをとりあえず新規で追加します

ヒエラルキー(hierarchy)にこんな感じで生成できたと思います↓

次にこの空のオブジェクトに対してmodelから対象となるものを子要素としてアタッチしてあげましょう

選択して…

ドラッグアンドドロップで子要素として追加

で、GameObjectだと普通にわかりづらいので、わかりやすい名前にリネームします。とりあえずRotationRockとでもしておきます

次に、このオブジェクト自身を動かすためのコードを書きます。とりあえず回転させながら適当な方向に運動でもしてもらいましょう

先ほど子要素にしたモデルを選択して、

Inspectorから、[Add Component] -> [New Script] -> 名づけたいクラス名を入力&追加します。とりあえずRotatorとしました

すると、C#ファイルが生成されたかと思います。これを編集していきます。右上のギアアイコンをクリックし、Edit Scriptを選択します

以下のようなコードを書きます

using UnityEngine;
using System.Collections;

public class Rotator : MonoBehaviour {

  // オブジェクト生成時に初速度を与えて等速直線運動をさせる
  void Start() {
    GetComponent<Rigidbody>().velocity = transform.forward;
  }

  // オブジェクトを(x, y, z)すべての成分をランダムにして回転運動をさせる
  void Update() {
    transform.Rotate(new Vector3(Random.Range(0, 180),
                                 Random.Range(0, 180),
                                 Random.Range(0, 180)
                                ) * Time.deltaTime);
  }
}

以上のコードを書き終わったら、子要素にしたモデルのInspectorをから[Add Component] -> [Physics] -> [Rigidbody] を追加してください。これを追加することによって物理的な要素を与えることが出来ます

ここで試しに実行してみましょう

これで1つの時が出来るようになりました。次はこれをランダムに生成しようと思います。ひとまずRotationRockをプレハブとして保持するようにします。
ヒエラルキーに入っているRotationRockをドラッグアンドドロップでAssets/Prefabs配下に持っていきます

次に空のGameoOjectを作成しましょう(Create Emptyです)
とりあえずRocksとでもリネームしましょうか。ここで先ほどのようにInspectorからRigidbodyを追加します。 また、新たにコードが必要になるので適当な名前(個人的にはRandomObjectsとしました)で新規に追加します
Inspectorは以下のようになっているかと思います

ではコードを書いていきましょう。以下のようなコードになります

using UnityEngine;
using System.Collections;

public class RandomObjectGenerator : MonoBehaviour {

  public GameObject targetGameObject;
  public float MinRange, MaxRange;

  // 今はとりあえず決め打ちで500個生成しています
  void Start () {
    for (int i = 0; i <= 500; i++) {
      Instantiate(targetGameObject, new Vector3(Random.Range(MinRange, MaxRange),
            Random.Range(MinRange, MaxRange),
            Random.Range(MinRange, MaxRange)),
            Quaternion.Euler(Random.Range(0, 180),
                             Random.Range(0, 180),
                             Random.Range(0, 180)));
    }
  }
}

Instantiateは、実行時にオブジェクトを複製する関数です。これに対象となるGameObjectと初期座標、初期のオイラー角を入れてあげればランダムに生成されます

ちなみにpublic float MinRange, MaxRangeで初期座標部分に関しての上限値と下限値はInspectorから入力可能にしています

実行してみると次のような結果が得られるかと思います

あまり生成数が多いと重くなるかもしれませんが、普通に面白いので色々試してください
久しぶりにめっちゃ書いたなw