2012年8月31日金曜日

PlaymakerでOSイベントに対応

今回はPlaymakerでOSイベントに対応する方法について。

Playmaker公式フォーラムのQAより翻訳します:

http://hutonggames.com/playmakerforum/index.php?topic=1591.0
July 17, 2012, 01:20:49 PM


質問
Playmakerでアプリケーションの終了、中断、フォーカス(onApplicationQuit, onApplicationPause and onApplicationFocus)をグローバルイベントとして登録する方法はないの?

iOSの場合onApplicatonPauseイベント(およびその引数)に対応できることは重要だし、そのタイミングでデータ保存しないといけない。これはユーザが電話を受けたときやホームボタンを押下したときに発生する。

ホントに、中断(onApplicatonPause)が自分にとっては一番重要で次に終了(onApplicationQuit)フォーカスで、最後にフォーカス(onApplicationFocus)の順でどうにかならないかな?(自分はonApplicationFocusがどの場合に発生するかもよくわかってないけど)

回答
次のスクリプトを試してみたらいけるよ。空のオブジェクトでも何でもアタッチするだけだから。
using UnityEngine;
using System.Collections;
using HutongGames;

public class ApplicationEventsBridge : MonoBehaviour {
 
 
 void OnApplicationQuit()
 {
  PlayMakerFSM.BroadcastEvent("APPLICATION QUIT");
 }
 void OnApplicationPause()
 {
  PlayMakerFSM.BroadcastEvent("APPLICATION PAUSE");
 }
 void OnApplicationFocus()
 {
  PlayMakerFSM.BroadcastEvent("APPLICATION FOCUS");
 }
 
}

それからはFSMのなかで次のグローバルイベントを呼べば良い。
APPLICATION QUIT
APPLICATION PAUSE
APPLICATION FOCUS

このスクリプトがやることは、単純に3つのグローバルイベントをブロードキャストするということで、それによって任意のFSMに通知することが出来る。
------

そういえばUnityでゲームをさわるようになってから、あまりOSイベントを気にしなくなってたな(爆)

EclipseでAndroid開発してたころもXCodeでiOS開発するときもOSイベントやら画面のXMLを検討するやらやってたけど、あらためてUnityやPlaymakerが便利になってもそのころの知識を大事にすべきだと認識を改めた(キリッ)

Playmakerで完成度の高いゲームを作ろうぜ!

2012年8月30日木曜日

NGUI Flashビルドのメモリリーク


今回はNGUIのFlashビルドでのメモリリーク報告について。

公式フォーラムの投稿より翻訳します:



http://www.tasharen.com/forum/index.php?topic=1471

August 24, 2012  at 05:16:46 AM

質問
ゲーム開発においてUnityの標準UIコンポーネントからNGUI2.1.4に切替をしている。残念ながらFlash開発に課題がある。内容はFlashで実行するときに発生して、アイドル状態でもメモリが膨れ上がり続けるものだ。
たとえばプレイヤーが何もせず、メインのゲームオブジェクト作成が行われていないにも関わらず。使用メモリは1GBを10分で超えてしまうんだ!同一条件(ゲームがアイドル状態)でNGUIを外すと(シーンから全ての
NGUIゲームオブジェクトを外す)メモリ使用は安定していてメモリリークは見られない。

短時間の調査(TheMinerプロファイラ)でNGUIがUINode.HasChanged()メソッドを頻繁に使用していてこれがUnityエンジンのコード内部でメモリをコピーしているようだ。テスト目的でこのボディ部分をコメントアウトしたところ
メモリ使用は抑えられたようだ。UINode.HasChanged()以外で同様にNGUIコンポーネントでUnityエンジンのメモリコピーにつながるものがある様子。

まだまだNGUIは愛してやまなくて、使用し続けたいのだけど、何か良いアドバイスないですか?

回答
FlashバグだからUnityに知らせてもらうしかないね。HasChanged関数ではいくつかのイコールチェックのほかないよ。
コードをつけるね:

#if UNITY_3_5
    bool isActive = mGo.active && (widget == null || (widget.enabled && widget.color.a > 0.001f));
#else
    bool isActive = mGo.activeSelf && (widget == null || (widget.enabled && widget.color.a > 0.001f));
#endif

    if (lastActive != isActive || (isActive &&
        (lastPos != trans.localPosition ||
         lastRot != trans.localRotation ||
         lastScale != trans.localScale)))
    {
        lastActive = isActive;
        lastPos = trans.localPosition;
        lastRot = trans.localRotation;
        lastScale = trans.localScale;
        return true;
    }
------- 
んー。Flashでメモリリークかー。Unity仕様といっているけどもうちょっとNGUI側でも調べてもらいたいものだけど仕方ないのかな。

 バグフィックスされたらちゃんと知らせてね!NGUI!

NGUI 2.1.6


NGUIのアップデート情報。今回はバグフィックスのマイナーバージョンアップ。

フォーラムの情報を翻訳します:

http://www.tasharen.com/forum/index.php?topic=11.15
August 25, 2012, 01:26:43 AM

-新機能:セーブ機能(UISavedOption)をポップアップリストでも使用できるよう機能追加
-修正:Unity4のifdefを新しいヘルパー関数に置換しコード可読性を改善(NGUITools.GetActive、NGUITools.SetActiveSelf)
-修正:ドラッグパネル(draggable panel)が表(UITable)の外にコンテンツが飛び出るバグを修正
-修正:ドラッグパネルのスクロールバー(UIDraggablePanel.UpdateScrollbars)の更新時にソフトクリッピングを正しく考慮できていないため不安定となってたバグを修正
-修正:スプリングパネル(SpringPanel)が完了時に位置のセットとクリッピングをしてなかっため浮動小数点がずれていたバグを修正
-修正:入力(UIInput)の言語ローカライズ機能(UILocalize)が選択されていない
テキストだと適用されない仕様を修正
-------

最新のNGUIで安定した機能を提供しよう!

2012年8月29日水曜日

ちょっと休憩~Unity Editorを日本語にしてみる実験

最近にわかにUnityの日本語環境に関する議論が活発な様子。

[Unity][Unity3d]UnityでC#の新規作成ファイルをBOM付きUTF-8にするコマンド(Mac環境向け) - 強火で進め
http://d.hatena.ne.jp/nakamura001/20120824/1345832011

MonoDevelopが日本語OKになるんなら、いっそのことUnity Editorのメニューやインスペクタも日本語にしたらどうか?と思い立って実験することにしてみた。

また、ターゲットとしてはプログラミングができなくてもロジックが組めるPlaymakerというAssetとした。理由はプログラミングが出来なく、かつ英語が苦手だけどUnityを使って開発をしたい、という層が十分なマーケットとしてあるだろう、と考えたためだ。

なお今回はお遊びのつもりでやる実験なので、開発環境をおかしくするかもしれないため、試す場合は、①必ずバックアップをとり、②最悪の場合Unity環境が立ち上がらない場合も自己責任で直す覚悟でお願いしたい。

実験内容
PlaymakerのUnity Editorを日本語にしてみる

試したOS、Unity、Assetバージョン
Windows環境、Unity3.5.5f3、Playmaker1.3.2

実験手順
  1. 上のリンク先を参考にC#のテンプレート(雛形)ファイルをBOM付きUTF-8に書き換える
  2. Playmaker/Editor配下にある2つのスクリプトをデスクトップなどにバックアップした後、以下のファイルの「Language = 日本語」より下の行にある文字列を直したいメニューの文だけ、イコールより後の文字列に置換する
  3. コンパイルする
[PlayMakerMainMenu.cs]
Flag = Flag-JP
Language = 日本語
PlayMaker/PlayMaker FSM Editor = PlayMaker/状態遷移ブラウザエディタ
PlayMaker/Editor Windows/FSM Browser = PlayMaker/編集ツール/状態遷移ブラウザ
PlayMaker/Editor Windows/State Browser = PlayMaker/編集ツール/状態ブラウザ
PlayMaker/Editor Windows/Templates Browser = PlayMaker/編集ツール/テンプレートブラウザ
PlayMaker/Editor Windows/Edit Tool Window = PlayMaker/編集ツール/編集ツール
PlayMaker/Editor Windows/Action Browser = PlayMaker/編集ツール/アクションブラウザ
PlayMaker/Editor Windows/Global Variables = PlayMaker/編集ツール/グローバル変数
PlayMaker/Editor Windows/Event Browser = PlayMaker/編集ツール/イベントブラウザ
PlayMaker/Editor Windows/Log Window = PlayMaker/編集ツール/ログ
PlayMaker/Editor Windows/Console = PlayMaker/編集ツール/コンソール
PlayMaker/Components/Add FSM To Selected Objects = PlayMaker/コンポーネント/選択オブジェクトに状態遷移を追加
PlayMaker/Components/Add PlayMakerGUI to Scene = PlayMaker/コンポーネント/PlaymakerGUIをシーンに追加
PlayMaker/Tools/Custom Action Wizard = PlayMaker/ツール/カスタムアクションウィザード
PlayMaker/Tools/Load All PlayMaker Prefabs In Project = PlayMaker/ツール/全てのPlaymakerプレハブをロード
Loading PlayMaker Prefabs = Playmakerプレハブをロード中
No PlayMaker Prefabs Found! = Playmakerプレハブは見つかりませんでした!
Loaded PlayMaker Prefabs = PlayMakerプレハブをロードしました
PlayMaker/Online Resources/HutongGames = PlayMaker/関連リンク/HutongGamesサイトへ
PlayMaker/Online Resources/Online Manual = PlayMaker/関連リンク/オンラインマニュアル
PlayMaker/Online Resources/Video Tutorials = PlayMaker/関連リンク/ビデオチュートリアル
PlayMaker/Online Resources/YouTube Channel = PlayMaker/関連リンク/YouTubeチャンネル
PlayMaker/Online Resources/PlayMaker Forums = PlayMaker/関連リンク/PlayMakerフォーラム
PlayMaker/Online Resources/Release Notes = PlayMaker/関連リンク/リリースノート
PlayMaker/Submit Bug Report = PlayMaker/バグを報告
PlayMaker/Welcome Screen = PlayMaker/ようこそ画面
PlayMaker/About PlayMaker... = PlayMaker/Playmakerについて

[FsmComponentInspector.cs]
Flag = Flag-JP
Language = 日本語
States [ = 状態 [
Events [ = イベント [
Variables [ = 変数

注意点
コンパイル時に筆者環境では以下のエラーメッセージが表示された。ここで「Keep changes」を選ぶこと。Convertを選択すると、どうもBOMなしに変換されて文字化けが起きるようだ



実験結果
  • メニュー
変更前
変更後
  • インスペクタ
変更前
変更後

うーん、やっぱり日本語のほうが見やすいね!

まあ課題は山積みなわけで:

  • 日本語化をして良い箇所を特定する必要がある。残念ながら私のほうではUnity Editor自体、どこまで日本語を使用することが許容されているか確認する術もない(たとえば、ファイルパスや変数に日本語がNGなのはすでに情報があるが、今回のメニュー、インスペクタのラベルはどうなんだろうか)
  • Assetの場合、オリジナル作者で対応する必要がある。(技術的にラベルにあたる部分をローカライズできるようにあらかじめ作者側で行わないといけないし、規約上もソースコードの改変は問題がある)
  • Unity Editorの中に日本語化してよい情報がふくまれる場合に限定される。(今回もPlayMaker FSM EditorはUnity Editorのなかになかった。DLLライブラリに入っていたのか、私のほうでは確認する術がない)
またUnity Answersでエディタに関する回答は見当たらなかったが、タグが「Localization」となっていたトピックのうち、議論が多かったものを参考までに3つほど挙げる。大抵はゲームに日本語表示をする場合のトピックのなかでエディタで正しく表示されない場合のQ&Aのようだ。
http://answers.unity3d.com/questions/57395/how-do-i-localize-strings-in-the-editor.html
http://answers.unity3d.com/questions/38272/how-do-i-display-chinese-in-unity.html
http://answers.unity3d.com/questions/32615/does-unity-3-have-native-resource-localization-sup.html

なお、賢明な読者の方はお気づきかもしれませんが、NGUIで言語切替(Localization)をするデモと同様のフォーマットを踏襲したのでうまくスクリプトを組めばゲームのなかでの多言語化にも生かせるかもしれません。(エディタとゲーム中の用語は別物かもしれませんが・・・)

Playmaker作者は過去に別の質問で回答いただいたことあるので、今回も「どう思う?」って質問だけとりあえず投げてみた。

「動かなくなるかもしれないし、そこまでやる価値はあるの?」って怒られる気もしている(笑)が・・・。奇跡的に良い返事だったらここでまた共有することにする。

開発もたまには息抜きしてリフレッシュしよう!

2012年8月28日火曜日

Unityプログラミング応用(グラフ作成) ~その3


Unityプログラミング応用(グラフ作成)の続編です。

http://catlikecoding.com/unity/tutorials/graphs/



Mathfとは?
Mathfは構造体であり、便利な数学的な処理を行うことが出来るstaticメソッドや変数の集合体である。関数ライブラリである。

列挙型(enum)とは?
enumという型(列挙型)を用いて名前を順番に列挙した集合である列挙体を定義することが出来る。この型の変数は名前をこの変数のひとつとして持つことが出来る。これらの名前はデフォルト0から始まる数字と対応している。

限られた選択肢を提供した場合に便利である。

デレゲートとは?
値およびオブジェクト参照を変数に格納できるのであればメソッド参照も格納が可能できるだろうか。答えはイエスで、それがまさにデレゲートである。

デレゲートの型はメソッドを作成するのと同様に定義することが出来て、違いはコードの本文(body)がないことだけである。その後はこの型をしようしてデレゲート変数を作成し、型に合うメソッドを割り当てることが出来る。
その後はこの変数をメソッドであるかのように扱うことが出来る。

デレゲートはより複雑なものもあり、リストのように動作してより複雑なイベント処理も可能であるが本講座では割愛する。

メソッド名を2回用いているのは何故?
文章により言葉の文脈における意味がまったく異なる、と同じことを意識する必要がある。

FunctionOption列挙体の中を覗いてみると、ただの単語の一覧であることが分かる。メソッド名と同じ名前であるのは今回たまたま同じ名前の設計にしただけであって同じである必要性はない。

functionDelegates配列の宣言を覗いてみると、メソッドへの実参照であり、この場合は同じ名前でないと機能しない。

記号のはどのように用いる?
記号の?のを記号の:と組み合わせることで、if文を省略(インライン化した記載)出来る。例えば:
int y; if(x > 1) { y = 10; } else { y = 20; }を省略するとint y = x > 1 ? 10 : 20;
-------
Unityプログラミング応用のその1、その2をマスター出来ていると自信がある場合はリンク先の英語サイトのコードを参照下さい。

デレゲートなど私自身はうる覚えだということを確信しましたが(汗)、具体例があるので理解が深まります。プログラミングも応用することでゲーム開発に生かすぞ!

2012年8月27日月曜日

Unityプログラミング応用(グラフ作成) ~その2

Unityプログラミング応用(グラフ作成)の続編です:
http://catlikecoding.com/unity/tutorials/graphs/

newはどのように用いる?
newキーワードは、オブジェクトの新しいインスタンスや構造体の値をコンストラクトする場合に用いる。コンストラクタと呼ばれる特別なメソッドを直後に記載する必要があり、コンストラクタは所属するクラスあるいは構造体と同じ名前をつける。

チュートリアルでposition.yに値セットしないのは何故?
ポジションがオブジェクト参照であれば正しく動くが、実際には構造体の値である。

一意のオブジェクトインスタンスはひとつのみ存在することが出来るが、複数の変数から参照することが可能である。値に対してインスタンスをアサインすることと複製することは別のことである。
たとえて言うならば皆でAさんの名前を一斉に呼んで指示するようなものである。他の人がAさんの名前を聞いたからといってAさんが二人になるわけではない。

整数や構造体のインスタンスは先のオブジェクトインスタンスとは異なる動きをする。もし構造体の値を呼び出しした場合は、複製がそこで行われて独立に保持される。Aさんの名前の例でいうと、
今度は名前を呼んでも複製なので今度は当人から返事をもらうことが出来ない。

すなわちある地点のポジション(position)を呼び出ししても複製が行われる。今回のチュートリアルではこの複製された値に何かセットしても、もとの地点そのものを更新しないと何も値の変更は行われない。

returnはどのように用いる?
returnキーワードを用いることでメソッド終了後の戻り値を知らせることが出来る。戻り値はメソッドと型を合わせる必要があり、voidである場合には戻り値が存在しない。

returnステートメントはvoid、コンストラクタの場合を除いて必ず戻り値をセットするように記載する必要がある。

また、複数の戻り値をセットすることが出来る。その場合、複数の出口が存在することになり、どのreturnが用いられるかはifステートメントで分岐させる。

チュートリアルでstaticである必要性は?
チュートリアル記載のケースはstaticでなうとも良い。ただし、これらのメソッドは後にstatic配列に用いられる予定であり、これらもstaticである必要性はない。

多くのケースでstaticである必要性はないが、オブジェクトインスタンスと独立して値やメソッドが存在することが出来る場合にstaticにするように私自身はしている。
--------

第3回に続きます。

Unityプログラミング応用を自分のものにするぞ!

2012年8月26日日曜日

Unityプログラミング応用(グラフ作成) ~その1


今回はUnityプログラミングの応用編として優良なプログラミングチュートリアルのポイント解説部分の翻訳を行う:


http://catlikecoding.com/unity/tutorials/graphs/

チュートリアルを進めながらC#を応用してより複雑なグラフ作成を行う。
・グラフ作成を行い、線の作成から体積の表現まで行う
・パーティクルシステムを制御する
・数学的な関数を作成する
・実行中に動作変更を行う
・StartおよびUpdateのUnityイベントメソッドを用いる
・ループをネストされた場合とそうでない場合で用いる
・配列、列挙体、デレゲートを用いる

ポイント解説
Startはどのタイミングで呼び出しされる?

コンポーネントが作成され、アクティブとなり、Updateが初回の動作を行う前にStartは呼び出しされる?

配列はどのように用いる?
配列は固定長のオブジェクトであり、複数の連続した変数を取り扱う。変数宣言をする際に[]を後に記載することでその型での配列を表す。たとえばint myVariable;は整数を表しint[] myVariableは整数の配列を表す。

実際に配列のある変数にアクセスするためにはインデックス(何番目かではなく)を[]の中に記載する。たとえばmyVariable[0]で配列の最初のエントリを取得することが出来、myVariable[1]で二つ目のエントリ、といった要領で取得する。

実際に配列を作成し変数を割り当てる場合はmyVariable = new in[10];といったように記載し、10個のエントリからなる新しい配列が作成される。別の方法としてmyVariable = {1, 2, 3};というように初期値をあらかじめ設定することも出来る。

ParticleSystem.Particleとは?
ParticleSystem.Particleとはパーティクルのデータを保持する構造体である。型の中にドットがあるためネストされていることが分かる。パーティクル(Particle)型はParticleSystem型の中で定義されているためParticleSystem.Particleとしてアクセスする。

注意すべき点としてParticleSystemの中にないParticleも存在するが、その場合の型はShurikenパーティクルシステムが使用できない。

forループはどのように用いる?
forループにより繰り返しの動きを記載できる。この場合では整数iを反復する変数として用いる。第1部分で変数を宣言し、第2部分でループのクリア条件をチェックし、第3部分で変数をインクリメントする。

whileループを用いてまったく同じ結果を得ることはできるが記載方法として{}で括る範囲が異なる。

for(int i = 0; i < 10; i++) { DoStuff(i); }
と同じ記載をするためには:
int i = 0; while(i < 10) { DoStuff(i); i++; }

i++はどのような働きをする?
++演算子により変数は1つだけインクリメントされる。++表現を先に記載することで保持する値をあらかじめインクリメントすることが出来る。例として:

int x = 0; int y = 10 + x++; →xが1, yが10となる
int x = 0; int y = 10 + ++x; →xが1, yが11となる

--は減算する場合に同様に用いることが出来る。

-----

第2回ではポイント解説の続きを翻訳します。

プログラミングを応用することでゲームに磨きをかけるぞ!!

ブックマークに追加

このエントリーをはてなブックマークに追加

自己紹介

自分の写真
Unity3D公式マニュアル翻訳やってる人がスマホ(iPhone, Android)のゲーム開発しています。気軽に面白く初心者が遊べる内容がモットー。Blogでは開発情報をひたすら、Twitterではゲーム作成の過程で参考にしている情報を中心につぶやきます

ページビューの合計

過去7日間の人気投稿