神様は有休消化中です。

Unity関連の技術ネタを書いてます。

【Unity】EventSystemsから受け取った座標をRectTransform.localPositionに設定する方法

uGUIのEventSystems(IBeginDragHandler, IDragHandler, IEndDragHandlerなど)から受け取った座標をそのままRectTransform.localPositionに設定すると、Canvasのscaleによってはぶっ飛んだ位置(描画領域外)に移動してしまうことがあります。
EventSystemsから渡される座標はスクリーン座標のため、scaleが影響してぶっ飛んでしまうわけですが、今回はこのぶっ飛び現象を回避するためにスクリーン座標→ローカル座標へ変換する方法を共有します。

続きを読む

【Unity5】Visual Studio Codeを使ってデバッグする

Visuat Studio Codeを使ってデバッグするための情報が公式から出たので、試してみました。
今の所Mac OS X以外は未サポートみたいです。

環境

Mac OS X 10.10.1
・Unity 5.2.1f1
Visual Studio Code 0.8.0

やりたいこと

・UnityのエディタとしてVisual Studio Codeを使う
デバッグもしたい

続きを読む

【Unity5】【C#】string.StartsWithが激重いのでstring.IndexOfを使おう

先日Unityのプロファイラーを眺めていたところ、string.StartsWithが激重いことに気づいたので共有。

テスト用にこんなスクリプトを実行。

using UnityEngine;
using System.Collections;

public class Hoge : MonoBehaviour
{
	void Update () {
		string hoge = "abcdef";

		for (int i = 0; i < 1000; i++) {
			bool check = false;
			if(hoge.StartsWith("abc")){
				check = true;
			}
		}
	}
}

これをプロファイラーで確認すると、だいたい2.5msくらい。遅っ。

判定をstring.IndexOfに変更

//if(hoge.StartsWith("abc")){
if(hoge.IndexOf ("abc") == 0){
	check = true;
}

これを確認すると、だいたい0.3msくらい。2.2msほど軽くなりました。
なんでStartsWithは重いのかわからん・・・が、今後は使用を控えようと思います。

【Unity5】Vector3.DotとMathf.Acosの組み合わせでNan発生

Vector3.Dotで取得したラジアン値をMathf.Acosに突っ込んだところNanが発生することがあったので共有。
以下のようなソースで出ました。

Vector3 a = (end - start).normalize;
Vector3 b = hoge.transform.rotation * Vector3.forward;

float rad = Vector3.Dot(a, b); // a, bともにmagnitude=1のはず。
float result = Mathf.Acos(rad); // Nan発生

Mathf.Acosは-1〜1までの値しか与えられず、引数が範囲外になるとNanを返します。
しかし、上記例ではa, bともに正規化されているのでDotの戻り値は-1〜1のはず・・・
条件としては、a, b間のなす角が非常に小さい場合に出てました。
bの回転処理で若干の計算誤差が出て、長さが微妙に大きくなっちゃってる?うーん、わからん。

仕方ないので以下で解決しました。

Vector3 a = (end - start).normalize;
Vector3 b = hoge.transform,rotation * Vector3.forward;

float rad = Vector3.Dot(a, b);
float d = Mathf.Clamp(rad, -1.0f, 1.0f); // 追加
float result = Mathf.Acos(d);

【Rails】db:migrateでMySQLのLONGTEXT、MEDIUMTEXTを使う

MySQLで使用できる文字列型には

  • CHAR:255Bまでの固定長文字列
  • VARCHAR:64KBまでの可変長文字列
  • TINYTEXT:255Bまでの可変長文字列
  • TEXT:64KBまでの可変長文字列
  • MEDIUMTEXT:約1.6MBまでの可変長文字列
  • LONGTEXT:約4.3GBまでの可変長文字列

がありますが、rais g modelで普通にtextを指定するとTEXTが指定されちゃいます。

$ rails g model Test value:text

// こんな感じで作成される
$ rails db
mysql> show columns from tests;
+-------------+--------------+------+-----+---------+----------------+
| Field       | Type         | Null | Key | Default | Extra          |
+-------------+--------------+------+-----+---------+----------------+
| id          | int(11)      | NO   | PRI | NULL    | auto_increment |
| value       | text         | YES  |     | NULL    |                |
| created_at  | datetime     | NO   |     | NULL    |                |
| updated_at  | datetime     | NO   |     | NULL    |                |
+-------------+--------------+------+-----+---------+----------------+

上記に書いた通り、textだと64KBまでしか扱えません。
MySQLでは1文字1〜3文字と仮定するみたいなので、約VARCHAR(21845)が最大値になるということです。

これでは足りない場合は、migrationファイルに一工夫しましょう。

$ vim db/migrate/20150212101414_create_tests.rb
class CreateTests < ActiveRecord::Migration
  def change
    create_table :articles do |t|
      t.text :value, :limit => 4294967295   ←「 :limit => 4294967295」を指定

      t.timestamps null: false
    end
  end
end

// こんな感じで作成される
$ rails db
mysql> show columns from tests;
+-------------+--------------+------+-----+---------+----------------+
| Field       | Type         | Null | Key | Default | Extra          |
+-------------+--------------+------+-----+---------+----------------+
| id          | int(11)      | NO   | PRI | NULL    | auto_increment |
| value       | longtext     | YES  |     | NULL    |                |
| created_at  | datetime     | NO   |     | NULL    |                |
| updated_at  | datetime     | NO   |     | NULL    |                |
+-------------+--------------+------+-----+---------+----------------+

ちなみにlimitの値は、以下のように対応するそう。
1 ~ 255 :TINYTEXT
256 ~ 65535 :TEXT
65536 ~ 16777215 :MEDIUMTEXT
16777216 ~ 4294967295 :LONGTEXT