【Unity道場】Unity 5.4 & 5.5 新機能キャッチアップ講座に行ってきた。

Unity 5.4 & 5.5 新機能キャッチアップ講座」に行ってきました。

このような回を無料かつ軽食付きで開催してくれるUnity Japan様には頭が上がりません。ありがとうございます。

個人的に気になったポイントと所感をメモ。

Unity5.4

GPU Instancing

  • ライトプルーブの影響をうけられないとか、色々と制約が多いようなので、結局使い所が無いような気も... 何に使うのが良いんだろう?
    • 追記:弾幕シューティングになんか良いんじゃない?というご意見を頂きました。確かにそれは良さそう。

Transform周りがSIMDを利用するようになった

  • 使ってなかったのかぁ。
  • Transform周りだけなのかなぁ。Vector系の演算は全部使うようにできんのだろか?

処理のマルチスレッド化

  • 5.3 -> 5.4 -> 5.5 と徐々に進んでいるらしい
  • メインスレッドとレンダースレッドで分かれているだけ?
  • どこまでスレッドセーフなプログラムを意識すべきなのかが気になる。
  • メインスレッドとレンダースレッドだけなら、そんなに意識しなくても大丈夫そうだけど...
  • プロファイラーでマルチスレッドっぷりを確認できるらしい。

VRのSingle-Pass Stereo Rendering

  • パス変更回数が減るので負荷減
  • 色んなバッファを両眼で使いまわすのかなぁ
  • やったことないけど両眼用の画を作るときってシャドウマップを作るパスは一回しか走らせないのかな?
  • Image Effectは両眼の画に対してまとめてやるので交じる可能性があるらしい

AndroidのIL2CPP対応

  • ファイルサイズはmonoより大きくなるらしい
  • もちろんビルド時間は長い

Light Probe Proxy Volume

  • 初めて知った。
  • ライトプルーブってオブジェクト単位で使用するプルーブを決めるけど、それだと大きいオブジェクトだと破綻しちゃう
  • それを解決するために空間を区切って、区切られた空間単位でプルーブを決めるっぽい。たぶん。

Unity5.5

RigidBody2Dにsimulatedというパラメータが追加される

  • オブジェクトのアクティブ/非アクティブを繰り返すと、内部ではコライダーの生成と破棄をしていて、コストが有った。
  • simulated: offは破棄しないで物理演算から除外出来る
  • オブジェクト生成代わりに、ObjectをPoolしてアクティブ/非アクティブの切り替えることは多々あるので、これは良いことを知った。
  • 早く5.5来て欲しい。

Full Binary Shader Serialisation

  • 消費メモリ減少
  • コンパイル時間減少
  • Shader Binaryってどんだけ互換性あるんだろう?
  • プラットフォーム切り替えが遅くなる?

iOSで新しい画像フォーマットに対応

  • ASTC 6x6 〜 16x16
  • 圧縮率:クオリティ比率はかなり良い
  • ただし、A8以上のチップ。つまりiPhone6以上。
  • それ以下の場合TrueColorになる!
  • って、しばらくは使えないってことじゃない?

ライン&トレイルレンダラーがまともに

  • 今まではクオリティが低くて使えなかったらしい
  • これは使いたい!

その先のUnity

Monoのバージョンアップ

  • 拍手が起きてた
  • Mono4.6、C#6.0 対応
  • まだ何も出てきてないし、正直、遠い未来なのではないかという不安が...

2D

  • Tilemapが追加
  • Z軸でのソート
  • 早く来て欲しい!

Unityで transform.localPosition.x = 1.0f; ができないわけ

C#初心者の私がUnityで最初戸惑ったのはtransform.localPosition.x = 1.0f;というようなことができないことです。

これをやろうとすると、

error CS1612: Cannot modify a value type return value of `UnityEngine.Transform.localPosition'. Consider storing the value in a temporary variable

というエラーが出ます。UnityEngine.Transform.localPositionは変更できないよって言われてます。

なんで、こんなことになるかというと、localPositionが値型で、なおかつプロパティだからです。

Transformの定義を見ると、

public Vector3 localPosition { get; set; }

というようになっています。

これが、プロパティでなく、

public Vector3 localPosition;

という形であれば、localPosition.x = 1.0fは可能です。

また、Vector3が参照型(class)であった場合も、transform.localPosition.x = 1.0f;という風に書くことができます。

localPositionは値型を返すプロパティなので、メモリ上に一時的にできた一時変数が返されてしまうのです。
そこに値を入れたところで何も起きません。なのでエラーになるのです。

C++で考えると、プロパティは以下のような関数があるようなものです。

const Vector3 GetLocalPosition() { return localPosition; }
void SetLocalPosition( const Vector3 pos ) { localPosition = pos; }

そう考えると、Vector3で渡さないといけないのが理解しやすいんじゃないかと思います。

P.S 2018.11.25
自分の理解が浅はかだったので修正しました。

UnityでUnit Testを行う

先日、勉強会でUnity Tests Runnerというのものがあることを知りました。

もともと、Unity Test Toolsというものの一部だったのが、Unity5.3から組み込みになったらしいです。

docs.unity3d.com

というわけで使ってみました。

使い方は簡単で、図のように

f:id:wkpn:20160925160828p:plain

「create」 -> 「Editor Test C# Script」

を選び、スクリプトファイルを作ります。スクリプトはEditorフォルダ以下に置いて置きます。

Editorフォルダ以下に置いておかないと、

The type or namespace name `NUnit' could not be found. Are you missing a using directive or an assembly reference?

というエラーが出ますのでご注意を。

できたスクリプトは、以下のようになっています。EditorTest()の中身がテストコードになっています。

using UnityEngine;
using UnityEditor;
using NUnit.Framework;

public class NewEditorTest {

	[Test]
	public void EditorTest()
	{
		//Arrange
		var gameObject = new GameObject();

		//Act
		//Try to rename the GameObject
		var newGameObjectName = "My game object";
		gameObject.name = newGameObjectName;

		//Assert
		//The object has a new name
		Assert.AreEqual(newGameObjectName, gameObject.name);
	}
}

EditorTestを書き換えて、自分のテストしたい内容に書き換えても良いですが、テスト項目が増えるたびに新たに関数を作ったほうが良いでしょう。頭に[Test]属性をつけておくと、それがテストコードになります。

例えば、自分は以下のようなテストを書いています。ちなみにclass名は何でも良いみたいです。

public class WKLibraryTest {
    [Test]
    public void SwapTest()
    {
        int i1 = 0;
        int i2 = 1;
        Utils.Swap< int >( ref i1, ref i2 );
        Debug.Assert( i1 == 1 && i2 == 0 );
    }

    [Test]
    public void Tuple2Test()
    {
        MyTuple2 tuple_test2 = new MyTuple2( "tuple2", 0 );

        Debug.Assert( tuple_test2.Item1 == "tuple2" );
        Debug.Assert( tuple_test2.Item2 == 0 );
    }
}

できたテストはエディター上から走らせることができます。

「Window」->「Editor Tests Runner」を選びます。

f:id:wkpn:20160925161157p:plain

すると以下のような窓が出てきます。

f:id:wkpn:20160925161214p:plain

「Run All」を押すと、全部、「Run Selected」だと選択しているもの、「Rerun Failed」だと前のテストで失敗したものをテストします。

成功すると以下のように緑のチェックが付き、

f:id:wkpn:20160925161236p:plain

失敗すると赤いチェックが付きます。

f:id:wkpn:20160925161252p:plain

テスト書くの面倒くさいので、あんまりやりたくはないのですが、ちょっとしたオレオレUtilityをチェックするのに使おうと思います。

AudioSourceの再生が終わったかどうかを取得する方法(が見つからない...)

表題の件ですが、結局いまのところ解決していません。

AudioSourceクラスにはisPlayingというプロパティがあります。一番最初に思いつくのは、これがfalseになったら再生が終わったと判断するという手です。

しかし、これには落とし穴があって、Pause()を呼ぶとisPlayingがfalseになるのでPauseしているのと、再生が終わっているのとを区別できません。


次にtimeというプロパティを見るという手があります。こちらが0になっていたら再生が終わったと判断するという手です。

しかし、AudioSourceをPlay()した直後はtimeが0なので、これも誤作動してしまいます。

最後に、上記を併用するという手があります。

public static bool IsFinished( this AudioSource audio )
{
    return audio.time == 0.0f && !audio.isPlaying;
}

このような判定です。

しかし、これもうまくいかないことがあります。Play()した直後にPause()すると、timeは0だしisPlayingはfalseなので再生終了したと判定されてしまうのです。

結局、今のところ良い方法は思いついておりません。再生終了したタイミングでcallbackを呼ぶような仕組みを作りたかったのですが...

何か良い案があればご教授お願い致します。

追記
Pauseせず再生状態のままピッチを0.0fにすればいけるとコメントで頂きました。ありがとうございます。

C#のlock構文

FruitsNinjaのCloneのソースコードを見ていてc#にlock構文があることを知りました。

https://www.assetstore.unity3d.com/jp/#!/content/65879


マルチスレッドのプログラムでは、ちゃんと排他制御をしないと問題がおきます。

その代表格がsingletonクラスで、自分もC++でゲーム作ってたときは、それ周りのバグで悩まされました。

上記のAssetでは、singletonの生成時にロックを掛けるようになっています。

簡略化して書くと、

private static object _lock = new object();

public static T Instance
{
    get
    {
        lock (_lock)
        {
            if (_instance == null)
            {
                _instance = (T)FindObjectOfType(typeof(T));

                if (_instance == null)
                {
                    GameObject singleton = new GameObject();
                    _instance = singleton.AddComponent<T>();
                    singleton.name = "(singleton) " + typeof(T).ToString();

                    DontDestroyOnLoad(singleton);
                }
            }

            return _instance;
        }
    }
}

というような感じになっています。

これをちゃんとやっておかないと、タイミングによってはシングルトンなのにオブジェクトが複数できちゃいます。

けど、そもそもUnityのユーザースクリプトってシングルスレッドで動いていると聞いたので、そんなに神経質にlockしなくても良いんじゃ...って思ったり。そのあたりどうなんでしょう???

全てのシーンに存在し、一つしか存在してはいけないマネージャー的存在の実装

kan-kikuchi.hatenablog.com

この記事を読んで、最近読んだFruitsNinjaをCloneしたアセットのことを思い出したので記事にします。

https://www.assetstore.unity3d.com/jp/#!/content/65879

ところで、このアセット、凄いです!画像変えるだけで、vegetable ninjaでもmeat ninjaでも何でも作れます!
こんなん無料で出すなんて太っ腹すぎる!しかもコードに書かれたコメントがめちゃくちゃ丁寧!
オススメです!

本題に戻ります。
上記の記事で問題として挙げられていることを列挙すると

  1. 全てのシーンに存在して欲しいが、いちいち全てのシーンに配置するのは面倒だし、シーンが変わる度にマネージャーが新しくなるので、シーンを跨いでの処理ができなくなる。
  2. かといってDontDestroyOnLoadを使ってマネージャーが消えないようにすると、シーンを移動した時にマネージャーが重複してしまう。
  3. かといって最初のシーンだけに設置すると、他のシーン単体でテストが出来ない。

ということです。なので、

  1. 全てのシーンに存在し、
  2. 重複せず
  3. シーン単体でのテストができる

ことが重要になります。

FruitsNinjaCloneのスクリプトにあるSingletonは、かなり上記の条件を満たしています。

コードを一部簡略化して載せると、

public class Singleton<T> : MonoBehaviour where T : MonoBehaviour
{
    private static T _instance;

    public static T Instance
    {
        get
        {
            if (_instance == null)
            {
                _instance = (T)FindObjectOfType(typeof(T));

                if (_instance == null)
                {
                    GameObject singleton = new GameObject();
                    _instance = singleton.AddComponent<T>();
                    singleton.name = "(singleton) " + typeof(T).ToString();

                    DontDestroyOnLoad(singleton);
                }
            }

            return _instance;
        }
    }
}

というような形になっています。

キモは、instanceが無かったらGameObjectを生成して、AddComponentしているところです。

これで、Instanceにアクセスが発生した瞬間にオブジェクトが生成されます。

問題点としては、Instanceへのアクセスが無ければオブジェクトが生成されずEditor上にもオブジェクトが現れないことですが、たいてい、どっかでアクセスがあるし、明示的にInstanceへのアクセスをしてやれば無理やり作ることもできるし、まあまあ良い感じなんじゃないかと思います。



1分間たまご - 激ムズ!

1分間たまご - 激ムズ!

開発元:Ken Watanabe
無料

posted with アプリーチ

個人ゲーム開発者が送ってみた無料でレビューしてくれる海外サイト30個

まず最初に"無料で"と書きましたが、無料の場合はレビューをしてもらえるかどうかの保証はありません。

そもそも無料のレビューは受け付けていないところもあります。

基本的には以下の記事を参考にしています。
www.find-job.net

上記の記事の中にはサイトが閉じちゃっているところとか、既に更新されてないところとか、ゲームを扱っていないところとか、ハードコアゲームばかりなところとかあるので、それらを除いた30サイトに実際にレビュー依頼を送ってみました。

さらに掲載依頼先URLが新しくなっているところを修正し、一言コメントをつけたのが以下になります。

なんで、○○が無いんやー!っていうツッコミ大歓迎です。

iPhone専門

AppPicker

148Apps

iPhone Blog

  • トップページ :http://blogdoiphone.com/
  • 掲載依頼先  :review[at]blogdoiphone.com.
  • ゲームは少なめっぽい

Iphone Application List

Android専門

Android AppStorm

Android Apps Review

Android community

Android App Log

Droid gamers

Ask your android

  • トップページ :http://www.askyourandroid.com/
  • 掲載依頼先  :webmaster[at]askyourandroid.com
  • 載っているアプリ的になんとなく敷居低そう。

Android run down

Android zoom

Android spin

Android-apps

Get Android Stuff

Android Guys

iPhoneAndroidどっちも

AppScout

  • トップページ :http://appscout.pcmag.com/
  • 掲載依頼先  :pcmagdigital[at]emailcustomerservice.com
  • 割りと小さめのゲームも載っていたので出してみた。

Appolicious

iFanzine

  • トップページ :http://ifanzine.com/
  • 掲載依頼先  :ifanzine[at]gmail.com
  • ゲーム多め。Contact欄がフレンドリーだったので出しやすい。

Apps 400

Apps To Use

Touch Archive

Apps 4 Review

Nine Over Ten

  • トップページ :http://www.nineoverten.com/
  • 掲載依頼先  :jason.lee[at]nineoverten.com
  • 無料。だからこそ、好き勝手書くよというスタンスらしい。

Touch Arcade

  • トップページ :http://toucharcade.com/
  • 掲載依頼先  :tips@toucharcade.com
  • ゲーム多め。載っているレビューは大手ばかりの印象。

VideoGamer.com

Slide To Play

QuickJump Gaming Network

pocket Gamer

  • トップページ :http://www.pocketgamer.co.uk/
  • 掲載依頼先  :reviews[at]pocketgamer.co.uk
  • ゲーム専門だし、送ってみた。

Gamezebo


P.S
というわけで下記のゲームに関するレビュー依頼を30件送ってみたわけですが...


Divide

Divide

開発元:Ken Watanabe
無料

posted with アプリーチ

1件も返信が来なかった。

もっと3Dバリバリのゲームじゃないと取り上げてもらいにくいのかも。