さけのさかなのブログ

同人ゲーム開発やってます。Unity使ったりする。

【Unity】CloudBuildでうまくいかない場合対応

概要

 以下の条件において、UnityCloudBuildでビルドしたものが上手く動かない場合の対応方法。

条件

  • windows環境で開発していて
  • Resourcesフォルダ下のファイル名に濁点/半濁点がある

 上記の条件をみたすとき、Resources.Load, Resources.LoadAsyncに失敗してコケる。

ナンデ?

 UnityCloudBuildのログを見ると、ファイル名がNFDになっていることがわかる。このためにファイルが見つからずにロードに失敗する。

5871: [Unity] Updating Assets/Resources/AbilityEffects/ヤンシャオグイ.asset - GUID: 407fd122216a3674f90de5822614aed0...

 テキストエディタとかにコピペしてみよう。

対応

 ロードする際のパスをNFDに変換してやれば良い。

1.シンボル定義

 処理を分けるため、CloudBuildの設定でシンボルを定義する。

f:id:enuenupi:20161219133230p:plain

2.ロード処理時にstring.Normalize

public T Load(string path)
{
#if CLOUD_BUILD
    path = path.Normalize(System.Text.NormalizationForm.FormD);
#endif
    return Resources.Load<T>(path);
}

 そもそもファイル名に日本語を使わないのが無難だけど、なんだかなあ。

+

【Unity】複数個所から安全にTime.scaleを操作する

あかんパターン

 たとえば一時停止処理などでTime.scale0fを入れて時間を止め、なんやかんやした後に1fを入れて戻す処理を書くとする。

 この時、なんやかんやしてる内部でTime.scale1fを入れてしまうと、勝手に時間が動き出してしまいマズイ。

やること

 いろんなところでTime.scaleを操作すると何かと問題が起こりやすい。そこで管理クラスを作る。

コード

gist.github.com

使い方

Time.scale = 0f;

// なんやかんや

Time.scale = 1f;

としているところを

var timeScaler = new TimeScaler();
timeScaler.SetScale(0f);

// なんやかんや

timeScaler.SetScale(1f);

 とする。

 変更した本人が1fに戻さないと永遠に戻らないので注意。それが流儀。

【Unity】Resources.LoadAsyncするけどパス指定したくない

やること

 ロード処理においてResources.LoadAsyncを使いたい。が、いちいちパス指定するのが嫌、という場合のための仕組みをつくる。  

コード

gist.github.com

使い方

 アセットのクラスごとに継承したクラスを作る。

using UnityEngine;
using System.Collections;

namespace TSKT
{
    public class PrefabReferer : ResourceReferer<GameObject>
    {
    }
}

 ScriptableObjectファイルを作成して、インスペクタでassetフィールドにResourcesフォルダ下のファイルを紐づける。

 すると、pathフィールドが自動で更新される。

 で、実行時にLoad()を呼び出すと、pathフィールドを使ってResources.LoadAsyncを行う。

参照

 ロード処理は前回のResourceLoaderを使っている。

toriden.hatenablog.com

びみょう?

 わざわざScriptableObjectファイルを作るのが面倒。

 [Serializable]なクラスを作ってその中で処理できれば最高だったんだけど、OnValidate相当の機能がなさそうだったのであきらめた。

 OnValidateさえあれば、参照しているassetファイルからパスを取得し、pathフィールドを自動更新する処理を書くことができる。

修正

 UNITY_EDITORを使ってビルド時にフィールドを減らしたりするとエラーになるので良くない。というわけで回りくどいけどguidを取得してやることにした。

answers.unity3d.com

【Unity】ResourceLoaderクラス

やること

 Resources.LoadAsync<T>を処理する便利クラスをつくる。

 これによって、たとえば、Resources.LoadAsync<T>はせっかくジェネリックメソッドなのに、assetを取り出すときにはキャストが必要、とかの煩雑さを解決する。

コード

gist.github.com

使い方

 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販売始めました。パッケージ版よりちょい安めに設定してあります。

www.melonbooks.com

www.dlsite.com

www.dmm.co.jp

拍手返信

幻想四倍剣の1の方もDLサイトで販売してほしいです。

 古い作品の公開は、気が向いたらするかもしれない程度の感じ。期待しないで。

進捗のこと

 イラストと曲がぼちぼち仕上がりはじめて、いよいよプログラム側にターンが回ってきた感じ。

 今回はドット絵などは仮置きのまま、先にデータ打ち込んでステージ組んでみたりしている。このやり方だと見栄えが悪いままなので、スクショを公開しづらいというのが難点な。

 タイトルは、「Magic Scroll Tactics」になると思う。たぶんなる。なるんじゃないかな。まちょっとは覚悟しておけ。

 (それにしてもアルファベットのタイトルは思いのほか考えるのに難儀した。)

【Unity】Spriteで高さフォグっぽいやつ

やること

 Spriteで高さフォグっぽいものを実装する。ワールド座標で低いところにあるとフォグがかかるやつ。

 Lightingビューのfog設定を反映させられれば完璧だったんだけど、よくわからんかったのでmaterialで色などを設定するような作りにした。

コード

Unity5.5.0b2。Sprites-Defaultシェーダに手を加えて作成した。

gist.github.com

サンプル

before

f:id:enuenupi:20160910075706p:plain

after

f:id:enuenupi:20160910075703p:plain

 これで天則の核融合炉心部的ステージが作れるって寸法よ。