Landscapeでの起動画面の設定

横モードのみでiPhoneアプリを作るときにどうしてもiPhone5/6での起動画面が設定できなかったので調べてみた。
iPhone(iPhone6+以外)ではアプリが横でも起動画面は縦で用意する。
だけど、Asset Catalog(Images.xcassets)を使って起動画面を用意するとなぜか起動しても真っ黒。
どうしたらいいかと思って、xcassetsを使わずに以前のような命名規則に乗っ取った方法で設定したらうまくいった。

150410_default_setting

XCode6.3でまっさらなプロジェクトを作って試してもやはり真っ黒になるので、これはバグですよね…??
なので、横のみのアプリの際には起動画面はAsset Catalogを使わずに命名規則に沿った起動画面の画像を入れるのがよさそう。

UnityEventについて

Unity4.6からuGUIが追加された際に、UnityEventというイベントシステムも追加されました。
uGUIと同時に追加されたので、uGUIで扱うイベントシステム系かと思ってしまいますがあらゆる場面で利用ができます。
以前、イベントについてどのようなやり方がいいか試してみたんですが、その際に作ったものにUnityEventでのやり方を追加してみました。

>>サンプルプロジェクトダウンロード

Continue…

UnityゲームUI実践ガイド 開発者が知っておきたいGUI構築の新スタンダード

Unity4.6/5で追加された新たなuGUIの解説本
UnityゲームUI実践ガイド 開発者が知っておきたいGUI構築の新スタンダード
が発売されました。
いままではNGUIがスタンダードでしたが、これからはUnity標準のuGUIですべて実現できるレベルのものになっているようです。
RépubliqueシリーズのUIなどを担当されていた池和田さんが書かれているので実践的な内容になっていそうですね。
本にするかKindleにするか迷いますが僕もそろそろuGUIを勉強しようとおもいます。

インスペクタでのAnimationCurveの利用

インスペクタ上でAnimationCurveを使ったデータの利用。
グラフをいじって、Evaluate(float time)にて、timeに対する値が取得できる。

using UnityEngine;
using System.Collections;

/// <summary>
/// AnimationCurveのテスト。
/// </summary>
public class CurveTest : MonoBehaviour {
	/// <summary>
	/// AnimationCurve.
	/// </summary>
	[SerializeField]
	AnimationCurve curve;

	/// <summary>
	/// 経過時間。
	/// </summary>
	float passedTime = 0f;

	/// <summary>
	/// Update.
	/// </summary>
	void Update () {
		passedTime += Time.deltaTime;
		int sec = (int)passedTime;
		float per = passedTime - sec;

		Vector3 pos = this.transform.position;
		pos.x = this.curve.Evaluate(per);
		this.transform.position = pos;
	}
}

AppDelegateから現在アクティブなUIViewController

Storyboardを使っていて、現在のアクティブなUIViewControllerを調べる方法。

[self.window.rootViewController presentedViewController];

NSLocalNotificationなどから起動した際の処理を分けたりする場合に便利。

参考)てっくろぐ | Storyboardを使っているときにAppDelegateからアクティブなUIViewControllerを取得する

ちなみに
AppDelegateを取得する方法は

AppDelegate *delegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];

参考)CreativeStyle | AppDelegateの参照をカンタンに取得する方法

2DでのLookAt

2Dでの制作の際にLookAt()を使ったらオブジェクトが見えなくなった。
よく考えたら3D空間でLookAt()されるので奥行きの方に倒れてしまって見えなくなっていたようだった。
LookAt()を使わずQuaternion.FromToRotation()を使ったら向くようになりました。

	public override void Update() {
		Vector3 diff = (this.targetGO.transform.position - this.transform.position).normalized;
		this.transform.rotation = Quaternion.FromToRotation(Vector3.up, diff);
	}

参考)
テラシュールブログ | UnityのベクトルとQuaternionによる回転について

Instantiate()時のiTweenのエラー

プレハブをInstantiate()する際にTweenのエラーが出てしばらくはまってしまった。

NullReferenceException: Object reference not set to an instance of an object
iTween.RetrieveArgs () (at Assets/iTween/Plugins/iTween.cs:6811)
iTween.Awake () (at Assets/iTween/Plugins/iTween.cs:6559)
UnityEngine.Object:Instantiate(Object)

インスペクタ上で生成したいプレハブを設定する際に、自身のプレハブと同じものを設定しました。
期待としては自身のプレハブが増殖することを期待していたんだけど、プレハブの状態ではなく自分のGameObjectの状態で複製された。
自身のGameObjectにはiTweenコンポーネントが追加されていたので、新たなGameObjectをInstantiate()する際にもiTweenコポーネントが追加された状態で生成されてしまっていたため上記のエラーがでていたようです。
そこで、今回は自身のGameObjectをDestroy()するものだったので、その前にiTweenもDestroyしてから複製してみました。
ただ、Destroyして即座にInstantiate(thisPrefab)してもダメだったので1フレーム待ってやってみたところエラーを回避できました。
なんとなくこんな感じです。

	public override void OnCollisionEnter2D(Collision2D collision) {
		base.OnCollisionEnter2D(collision);

		foreach (iTween tween in this.dividePrefab.GetComponents<iTween>()) {
			Destroy(tween);
			tween.enabled = false;
		}
		StartCoroutine(this.CreateDivide());
	}

	IEnumerator CreateDivide() {
		yield return new WaitForEndOfFrame();

		for (int i = 0; i < 4; ++i) {
			GameObject divideGO = (GameObject)Instantiate(this.dividePrefab);
		}

		Destroy(this.gameObject);
	}

Destroyしない場合はもう少し工夫が必要か、自身のプレハブとは別のプレハブを用意するなどが必要そうです。
自身のGameObjectのプレハブを取得する方法ってのはないんですかね??

継承先から親クラスのイベントの発行

継承先から親クラスのイベントを発行しようとした際に

`****’ can only appear on the left hand side of += or -= when used outside of the type ` ****’

こんなエラーが出た。

どうも
event EventHandler MyEvent;
と定義をした際には実際には

private EventHandler _myEvent;

public EventHandler MyEvent {
	add(EventHandler handler) { 
		this._myEvent += handler;
	}
	remove(EventHandler handler) {
		this._myEvent -= handler;
	}
}

こんな展開がされているらしい。
ここで、_myEventはprivateなので継承先からは処理が呼べないらしい。
なので、継承元に

protected CallMyEvent() {
	this.MyEvent(this, EventArgs.Empty);
}

などを準備して、継承先から読んであげる必要があるようです。

参考)
devlog [naru design] | Unity3D:スーパークラスのeventをサブクラスから呼び出す
stackoverflow | Why can’t I invoke PropertyChanged event from an Extension Method?

Cycles RenderのGPUレンダリング

BlenderでのCycles RenderではGPUでのレンダリングができるようになってる。
そのためにはnVIDIAがグラフィックボードを使って、nVIDIAが提供するCUDAを入れる必要がある。
https://developer.nvidia.com/cuda-downloads

CUDAとはCompute Unified Device Architectureの略でGPU向けの統合開発環境らしい。
ざっくり言うと並列処理の得意なGPUを使って計算させちゃうためのものでしょうか。
Cycles Renderは将来的にはAMDのOpenCLにも対応するそうです。
Continue…