【Unity】CloudBuildでうまくいかない場合対応
概要
以下の条件において、UnityCloudBuildでビルドしたものが上手く動かない場合の対応方法。
条件
- windows環境で開発していて
- Resourcesフォルダ下のファイル名に濁点/半濁点がある
上記の条件をみたすとき、Resources.Load
, Resources.LoadAsync
に失敗してコケる。
ナンデ?
UnityCloudBuildのログを見ると、ファイル名がNFDになっていることがわかる。このためにファイルが見つからずにロードに失敗する。
5871: [Unity] Updating Assets/Resources/AbilityEffects/ヤンシャオグイ.asset - GUID: 407fd122216a3674f90de5822614aed0...
テキストエディタとかにコピペしてみよう。
対応
ロードする際のパスをNFDに変換してやれば良い。
1.シンボル定義
処理を分けるため、CloudBuildの設定でシンボルを定義する。
2.ロード処理時にstring.Normalize
public T Load(string path) { #if CLOUD_BUILD path = path.Normalize(System.Text.NormalizationForm.FormD); #endif return Resources.Load<T>(path); }
そもそもファイル名に日本語を使わないのが無難だけど、なんだかなあ。
+
@_enu cloudBuildもう一つ心当たりがあって、日本語のMonoBehaviourかScriptableObjectのクラスをつくると、ファイル名はNFDになるけどクラス名はそのままなので、ファイル名=クラス名のルールを違反して死ぬ。
— enu (@_enu) 2016年12月19日
【Unity】複数個所から安全にTime.scaleを操作する
あかんパターン
たとえば一時停止処理などでTime.scale
に0f
を入れて時間を止め、なんやかんやした後に1f
を入れて戻す処理を書くとする。
この時、なんやかんやしてる内部でTime.scale
に1f
を入れてしまうと、勝手に時間が動き出してしまいマズイ。
やること
いろんなところでTime.scale
を操作すると何かと問題が起こりやすい。そこで管理クラスを作る。
コード
使い方
Time.scale = 0f; // なんやかんや Time.scale = 1f;
としているところを
var timeScaler = new TimeScaler(); timeScaler.SetScale(0f); // なんやかんや timeScaler.SetScale(1f);
とする。
変更した本人が1f
に戻さないと永遠に戻らないので注意。それが流儀。
【Unity】Resources.LoadAsyncするけどパス指定したくない
やること
ロード処理においてResources.LoadAsync
を使いたい。が、いちいちパス指定するのが嫌、という場合のための仕組みをつくる。
コード
使い方
アセットのクラスごとに継承したクラスを作る。
using UnityEngine; using System.Collections; namespace TSKT { public class PrefabReferer : ResourceReferer<GameObject> { } }
ScriptableObject
ファイルを作成して、インスペクタでasset
フィールドにResourcesフォルダ下のファイルを紐づける。
すると、path
フィールドが自動で更新される。
で、実行時にLoad()
を呼び出すと、path
フィールドを使ってResources.LoadAsync
を行う。
参照
ロード処理は前回のResourceLoader
を使っている。
びみょう?
わざわざScriptableObject
ファイルを作るのが面倒。
[Serializable]
なクラスを作ってその中で処理できれば最高だったんだけど、OnValidate
相当の機能がなさそうだったのであきらめた。
OnValidate
さえあれば、参照しているassetファイルからパスを取得し、pathフィールドを自動更新する処理を書くことができる。
修正
UNITY_EDITORを使ってビルド時にフィールドを減らしたりするとエラーになるので良くない。というわけで回りくどいけどguidを取得してやることにした。
【Unity】ResourceLoaderクラス
やること
Resources.LoadAsync<T>
を処理する便利クラスをつくる。
これによって、たとえば、Resources.LoadAsync<T>
はせっかくジェネリックメソッドなのに、asset
を取り出すときにはキャストが必要、とかの煩雑さを解決する。
コード
使い方
new
してyield
で待つ。
取り出すときにはasset as T
のようなキャストが不要。
var loader = new ResourceLoader<Hoge>("path"); yield return loader; var hoge = loader.Asset;
クラスなので、↓のように継承することで機能を足せる。
public class HogeLoader : ResourceLoader<Hoge> { public HogeLoader(string path) : base(path) { } public HogeLoader(int id) : base("Hoge/" +id.ToString()) { } }
C91や、その他のこと
C91のこと
落ちた/(^o^)\
まあ、やれて体験版の予定だったので、ここは落ち着いて開発しましょ。くやしくない。
ダウンロード販売のこと
けっこう前の作品ですが、ぞろぞろぞふぃもDL販売始めました。パッケージ版よりちょい安めに設定してあります。
拍手返信
幻想四倍剣の1の方もDLサイトで販売してほしいです。
古い作品の公開は、気が向いたらするかもしれない程度の感じ。期待しないで。
進捗のこと
イラストと曲がぼちぼち仕上がりはじめて、いよいよプログラム側にターンが回ってきた感じ。
今回はドット絵などは仮置きのまま、先にデータ打ち込んでステージ組んでみたりしている。このやり方だと見栄えが悪いままなので、スクショを公開しづらいというのが難点な。
タイトルは、「Magic Scroll Tactics」になると思う。たぶんなる。なるんじゃないかな。まちょっとは覚悟しておけ。
(それにしてもアルファベットのタイトルは思いのほか考えるのに難儀した。)
【Unity】Spriteで高さフォグっぽいやつ
やること
Spriteで高さフォグっぽいものを実装する。ワールド座標で低いところにあるとフォグがかかるやつ。
Lightingビューのfog設定を反映させられれば完璧だったんだけど、よくわからんかったのでmaterialで色などを設定するような作りにした。
コード
Unity5.5.0b2。Sprites-Defaultシェーダに手を加えて作成した。
サンプル
before
after
これで天則の核融合炉心部的ステージが作れるって寸法よ。