太郎Work

Unityとかで困ったこと等を残しておきます

PlayerSettingsのアイコンをEditorから変える

dev版とrelease版で切り替えるEditorを作っていたのですが、アイコンも変えようと思ったら簡単に変えられたのでメモ

var icons = PlayerSettings.GetIconsForTargetGroup (BuildTargetGroup.Unknown);
if (icons != null && icons.Length > 0) {
    player.icon = icons [0];
}

if (player.icon != null) {
    PlayerSettings.SetIconsForTargetGroup (BuildTargetGroup.Unknown, new Texture2D[]{ player.icon });
}

ScriptableObjectのクラスで値を書き換えてAssetDatabase.SaveAssetsで保存しています。
Texture参照を保存できるので便利です。

UnityiOSのdevelopment build の場合スプラッシュスクリーンで止まる

UnityのiOS書き出しの際development buildにチェックを入れて出力すると
スプラッシュスクリーン表示中に停止してしまう問題が有り、解決に時間がかかったのでメモ

XCodeのLogを確認すると別スレッドからアクセス出来ない的な文章が出ているのみで
空のシーンを起動しても変わらず。

結局MonoBehaviourを継承していない普通のクラスのstaticフィールドでUnityのメソッドを呼んでいることが原因だった。

public static readonly Dictionary<eTest, string> dic = new Dictionary<eTest,string>() {
  {eTest.TEST1, Localization.Localize("test1")},
  {eTest.TEST2, Localization.Localize("test2")},
};

初期化時にローカライズのテキストをenumで取得できるようにしたかったがこの記述があるだけで呼んでいなくても停止してしまった。

挙動をまとめました。

non develop develop
Editor 動作 動作
iOS Localizationが初期化されずに動作 スプラッシュスクリーンで停止

Editor上だと何も問題なく動作してしまうため発見が遅れました。

なので必要になった時取得するように変更しました。

private static readonly Dictionary<eTest, string> _dic;
public static Dictionary<eTest,string> dic {
  if(_dic == null) {
    _dic = new Dictionary<eTest,string>() {
      {eTest.TEST1, Localization.Localize("test1")},
      {eTest.TEST2, Localization.Localize("test2")},
    };
  }
  return _dic;
}

Logを出してみるとUnityのAwake等よりも先にUnityでない通常クラスのstaticフィールドのコンストラクタが呼ばれるようです。

Editor上だと再生時にエラーは出ないが一度失敗してからUnityのAwake等のタイミングでまた呼ばれていることが確認できました。

なので、iOSのdevelopmentだと何か挙動が挟まるせいでUnity起動の前にクラスの初期化が呼ばれてるようです。

皆様もiOSのdevelopmentビルドのみ起動出来なくなった場合はこういったコードがどこかに埋まってないか確認してみてください。

Unityで文字エスケープ変換

C#でやろうとしていたがUnityに実はあったのでメモ

http://docs.unity3d.com/Documentation/ScriptReference/WWW.UnEscapeURL.html

WebViewのjsからJSON適当に送ろうとしたらエスケープ文字で来るのでこれで簡単に変換できる

WWWは結構使っていたがこのメソッドが目に入っていなかった。

ありがとうUnity

UnityのiOSディレクトリアクセスまとめ

結構複雑で忘れてしまったのでメモ 一部間違っているかもしれません。

Documents

バックアップ対象になるセーブデータ等の重要なファイルを保存 Application.persistentDataPath

Library/Preferences

バックアップ対象になる環境設定ファイル等 ・Unityからアクセスすることは多分ない

Library/Caches

バックアップされないがアプリを終了しても消されない領域、大量の画像データとか しかし、容量不足の場合消される可能性あり。ロード時は存在しない前提で実装する Application.temporaryCachePath

tmp

バックアップされずアプリが終了したら削除される領域。一時保存ファイルとか Cachesと違い、実行中は削除されないことが保証される

Unity4.3で作成したアニメーションがLegacyと言われて動かない

Unityに標準で組み込まれているAnimationは、NGUI等の通常オブジェクトにも簡単にアニメーションが追加でき、publicなパラメータもアニメーションで来て非常に便利。

特にUnity4.3で導入されたDopeSheetのお陰で劇的に作りやすくなった。

しかし、いざGameObjectに追加しようとすると今まではAnimationComponentが自動でアタッチされていたものがAnimatorになってしまう。 確かに動くが、スクリプトからスタートとストップが弄れない! 空のStateをデフォルトにして遷移させれば動きそうだが単純に再生させたいだけなのにState管理とかやりたくない。

方法があるのかもしれないが、殆どがやっぱりAnimationの説明でAnimatorはインポートされたモデルアニメーションの説明ばかり。

そこで諦めてComponentからAnimationを追加してクリップを追加したらアニメーションが再生されず、アニメーションクリップをLegacyにしろと言われて動かない…

モデルデータならインポート設定にLegacy項目があるが、Unity上で作ったのだからあるわけない…

4.3以前に作成したアニメーションはやっぱり普通に動くので調べたら同じ問題で困っている質問を発見。

Create a legacy animation without a model - Unity Answers

まさに同じ状況。

EditorをForceTextにしてから、.animファイルをテキストエディタで開いて以下のように修正

m_AnimationType: 2 -> m_AnimationType: 1

これで今までどおりの使い方が出来るようになった。animationでのアクセスも問題なし。

前回のEditorWindowで<size=~>が使えなくなっている件といい、地味に4.3で謎の改変が入っている。

最終的にAnimationからAnimatorにフェードしていくらしいけどAnimationのシンプルさは残しておいてほしいなあ…

他にもなにかありそうで怖くなってきた。。。

EditorWindowでのフォントサイズ設定

今までEditorWindow上の文字サイズを変更する際は

GUILayout.Label("<size=32>Test</size>");

のように指定していたのだが、恐らくUnity4.3にしてからこの指定が出来なくなっていた。

これを使うとボタン等も簡単にフォントサイズが変更できて重宝していたが、削除されたのだろうか…

でもDebug.Logでは今までと同じように使用できるのでますますわからない。

結局普通?に

GUI.skin.label.fontSize = 32;
GUILayout.Label("Test");
GUI.skin.label.fontSize = 0;

で対応したが3行になるのは気持ち悪い。

もちろんGUIStyleを保存しておいて代入でも大丈夫だけど、なんだかなぁ…

拡張EditorでTextFieldの表示を更新する

拡張Editorを使っているとよく起きる問題。

TextFieldの文字を選択中にその中身を書き換えても文字列が更新されない(内部的には更新されている)

f:id:tarowork:20131007174507p:plain

このように上のTextFieldを選択した状態で上のTextFieldを消すと本当は”TEST2”と表示されるはずが、 ”TEST”が残ったままになる。 実際には”TEST2”が代入されているので問題はないが、他のエリアをクリックしない限り更新されないのですごく紛らわしい。

今までは気にしないようにしていたが、調べたら出てきたのでここに書いておく

http://answers.unity3d.com/questions/180659/editorgui-refresh.html

キーボードコントロールIDを初期化してフォーカスを外す感じ?

GUIUtility.keyboardControl = 0;

値を削除するタイミング等でこの一文を入れておけば想定した挙動になる。

あとこんな使い方もできた

string s = EditorGUILayout.TextField(text);
if(s != text) {
    GUIUtility.keyboardControl = 0;
}

文字を打とうとするとフォーカスが外れるので、条件による選択フィールドっぽくも出来る。

UnityEditor奥が深い・・・