iOS で glBindTexture glGenTextures などテクスチャ系処理が 0x502 (GL_INVALID_OPERATION) を出す

今回は、UIView の init 系で処理をすると、

コンテキストが正しく認識されず、 OpenGL がちゃんと初期化されていない事で起こっていた。

なぜか gl****Texture 系のみで、他の設定系はエラーが出ていなかったので迷ってしまった。

これが原因で、glDraw 系は EXC_BAD_ACCESS で止まる。

結論として、layoutSubviews の中で OpenGL を初期化するようにしたら直った。

Application windows are expected to have a root view controller at the end of application launch.

StoryBoard を使用したアプリを Empty Applicaton のテンプレートから作成すると、

実行時に、

"Application windows are expected to have a root view controller at the end of application launch."

とログに表示され、画面が真っ白になる状態に陥った。


これは、テンプレートが作成した AppDelegate.m 内の、

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}


を、各種コメントアウトし、


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
//self.window.backgroundColor = [UIColor whiteColor];
//[self.window makeKeyAndVisible];
return YES;
}

とする事で正しく動作するようになる。

cast of indirect pointer to an Objective-C pointer

iOS7 対応しようとビルドしてみたらこんなエラーが出たのでメモ。

[Before]
NSData *data = NULL;
OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)attrDictionary, (CFTypeRef*)&data);
// (CFTypeRef*) のキャストの所で cast of indirect 〜 が出てビルド通らず


[After]

CFTypeRef cfref = NULL;
OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)attrDictionary, &cfref);
NSData *data = (__bridge id)cfref;
// 一度定義した CFTypeRef を渡した後ブリッジキャストで解決

error CS1010: Newline in constant

文字コードを変更して保存できるテキストエディタ( Terapad 等)で

文字コードを UTF-8 (BOMなし) にして保存すれば直る。

UTF-8N ではエラーが出たのでメモ。

なお、改行コードは関係ないようだ。

GameView内のマウス座標を得る方法

GameView はサイズによってマウス座標の値も変動するようで、

640*960 のプロジェクトをテストする際、GameView のサイズを狭くしてテストすると

マウス座標もそのサイズに依存して変わっているような状態になって困ったのでメモ。



// カメラオブジェクトを取得する
// 今回の例は NGUIのカメラを指定しているが、他のカメラの時も名前を合わせればよい
GameObject obj  = transform.Find("/UI Root (2D)/Camera").gameObject;

// マウス座標を縦横各種 0~1.0f の範囲に変換
Vector3    mpos = (obj.GetComponent<Camera>()).ScreenToViewportPoint ( Input.mousePosition );

// スクリーンサイズにその範囲をかければスクリーン上の座標が求まる
float xpos = mpos.x * PlayerSettings.defaultScreenWidth;
float ypos = mpos.y * PlayerSettings.defaultScreenHeight;


こうすると GameView のリサイズを気にしないでも大丈夫っぽい。

UnityEditor 内のクラスを使用しているが、iOS 実機でも動くのかは未検証。

NGUI の UIPanel のサイズを知る方法

Unity 上の Clipping の Size に当たる部分は、


UIPanel  panel = (UIPanel) GameObject.Find("YourObj").GetComponent("UIPanel");

float    pw    = panel.clipRange.w;
float    ph    = panel.clipRange.z;


で取得する。

You can't place widgets on a layer different than the UIPanel that manages them. を解決する方法

スクリプトでアトラスプレハブを読み込み、

それを作成したスプライトに割り当てようとしたら

以下の警告が出たが、解決したのでメモ。

[Warning]
-----------------------------------------
You can't place widgets on a layer different than the UIPanel that manages them.
If you want to move widgets to a different layer, parent them to a new panel instead.
-----------------------------------------




// このコードは警告が表示される (This code is displayed warning.)
//---------------------------------------------------------------

GameObject obj = new GameObject ("SpriteObjName");
UISprite sp = obj.AddComponent <uisprite> ();

sp.atlas  = yourLoadedAtlas;
sp.spriteName  = "yourSpriteName";

obj.transform.parent = GameObject.Find("yourParentOfTheSprite").transform;



// このコードは大丈夫 (This code have not warning.)
//---------------------------------------------------------------
UISprite sp = NGUITools.AddSprite ( GameObject.Find("yourParentOfTheSprite"), yourLoadedAtlas, "SpriteObjName" );
sp.spriteName  ="yourSpriteName";

スプライトを作る時は NGUITools.AddSprite を使おう。

NGUI のアトラスプレハブをスクリプトから読み込む時


NGUI の AtlasMaker でアトラスとスプライトを作成すると、

プレハブとシェーダと統合画像が同名になる為、



GameObject prefab = GameObject.Instantiate ( Resources.Load("your atlas" );
のようにすると、Unity が正しく認識できない場合がある。

なので、この場合は
GameObject prefab = GameObject.Instantiate ( Resources.Load("your atlas", typeof (GameObject) );
と、後ろに GameObject の型指定のパラメータを付けてやる。

NGUI で新しいスプライトをアトラスに登録する方法

※ この記事を書いた時点での NGUI のバージョンは、「 2.6.4 」



1. 「メニュー」の「NGUI」 > 「Open the Atlas Maker」を選択。



2. 「Create」ボタンの右のテキストフォームに新しく作りたいアトラスセットの名前を入力し

「Create」ボタンを押すと、それ用のプレハブが作成される。



3. 自分でアトラス化した画像を使うのではなく、

このアトラスセットに画像 1 つ 1 つを登録すると NGUI 側で 1 枚のスプライトにまとめてくれる。

また、PNG で逐一用意せずとも、PSD ファイルのままで良い。



4. 「Project」ビューから追加したい画像をクリックすると、

AtlasMaker ウィンドウの下部にそのスプライト名が表示され、

緑の「Add/Update All」ボタンが出現するので、このボタンを押す事で

そのスプライトがアトラスセットに追加される。



5. UV などテクスチャ座標はNGUIがざっくり決めてくれるが、別途変更したい場合は、

Projectビューのアトラスのプレハブ( 立方体を斜め絡みたようなアイコン )をクリックし、

Inspectorの下の方にある「Dimensions」で設定する。

その下にある「Border」は Sliced スプライトにしたい時の境界線を決める。

「Sprite ▼」を押すと、アトラスセットに追加したスプライトの中から、

どのスプライトの情報を変更するかが選択できる。

なお、各数値はまとめられた画像に合わせたものとなる。元画像の座標云々は登録後は関係ない。

まとめられた画像を PhotoShop 等で開いて確認したければ、

「~~ atlas」というプレハブと同じ名前で画像も作成されているので、

Projectビューのそれを右クリックし、「Show in Explorer」した後、他のツールで開く事ができる。



これを繰り返して自分好みのアトラスセットを作成していく。

Unity + NGUI + TweenScale でクリッピングが効かなくなる

ダイアログを NGUI で作ったので、出現時の演出でもと

NGUI の Example に入っている TweenScale を使用してスケーリングさせる事にした。

が、スケール中クリッピングしているテキストがもりっとエリアをはみ出して表示されてしまい困った。

結果、XY だけではなく Z もスケール比率を合わせてやらないと正しく表示されなかったのでメモ。

Unity が起動しなくなった

Unity.exe を起動すると必ずクラッシュするようになった。

Bit defender Internet Security をインストールしたのが原因かもしれないと思い、

Bit defender Internet Security の例外に unity.exe を登録してもダメ。

アンインストールしてもダメなので、Bit defender が原因ではなさそうと他の手を考える。


結果、alt を押しながら Unity.exe を起動すると、プロジェクト選択画面に入るが

そこで新規プロジェクトを作成して起動すると無事に動いた。

その後は、もとのプロジェクトを開き直せばよい。


※ それでも動かない人は、Windows(ここで指すのは Windows7 ) に例外設定をしてない可能性がある。

コンパネ > 「システム」 > 「システムの詳細設定」 > 「詳細設定」タブ > 「パフォーマンス」にある「設定」ボタン >

「データ実行防止」タブ に 「Unity.exe」 と 「UnityEditor」 を追加してもう一度試してみよう。

Could not change executable permissions on the application が出る理由

同バンドル名で既に端末にインストールされているものがあるのが原因。

該当するアプリを削除してから再度実行すれば通る。


オブジェクト参照が必要です (CS0120) が出る原因

static 宣言されてないものにアクセスしようとしていると出る。

オブジェクトインスタンスを作成してからアクセスする。

GoogleAppEngineのアップロード済みプロジェクトを一式ダウンロードする

appcfg.py download_app -A <your_app_id> -V <your_app_version> <output-dir>

とコマンドを叩けば、任意のバージョンのプロジェクトをダウンロード可能。

その他、appcfg のコマンドについては、以下を参照。

https://developers.google.com/appengine/docs/python/tools/uploadinganapp

追記:

ある日突然、パスワードが違うと言われるようになった。(ブラウザではログインできる)

こちらの記事で解決方法を書きました

Shader.Find のパラメータはファイル名ではない

Shader.Find("ShaderName");

の "ShaderName" 部分に指定するのは shader ファイルのファイル名ではなく、

shader コードの頭で定義している部分を指定する。

例)

A.shader
=============================================

Shader "YourShaderNameHere"
{

// ...

}

B.cs
=============================================

void Start () {

Shader shader;

shader = Shader.Find("A"); // Failed. shader == null
shader = Shader.Find("YourShaderNameHere"); // Success. shader != null

}

ArrayList から任意の配列へ変換する

string[] s = ( string[] ) ary.ToArray( typeof(string) );

といった具合に、ToArray の引数に typeof (変換したい型) とし

その結果を変換したい型の配列にキャストする。

EditorWindow のサイズを知る方法

position.width

position.height で取得可能

using ディレクティブまたはアセンブリ参照が不足しています。の原因

調べると、拡張定義元と呼び出し元の .NET フレームワークのバージョン違いなどがあるようだが、

自分の場合は、拡張メソッドのクラスに public を付けていなかったのが原因だった。

他にも Unity の Assets > Open C# Project などで一度エディタとの同期をとってやると直る事があるので試してみる価値あり。

[追記]

自分のクラスでエラーが出ている時にビルドすると

NGUI など他のアセットで「using ディレクティブまたはアセンブリ参照が不足しています。」が出る事があるようだ。

自分のクラスのエラーを全て直してクリーン&ビルドすれば直った。

GameObject を他の GameObject の子にする方法

Unity の Hierarchy 内で GameObject を階層構造にしたい時、

例えば、B という GameObject を A の子にしたい時は、

GameObject a = new GameObject("A");
GameObject b = new GameObject("B");

b.transform.parent = a.transform;

のように transform の parent を親にしたい GameObject の

transform にすると階層化される。

A
└B

Unity で Window 上のマウス座標を知りたい時

Event.current.mousePosition でわかる。

EditorWindow 内で毎フレーム移動座標が欲しい場合は、

初期化時に wantsMouseMove を true にする必要あり。

参考:Unity のリファレンス
http://docs.unity3d.com/Documentation/ScriptReference/EditorWindow-wantsMouseMove.html

なお、 SceneView 内のマウス座標は、 Input.mousePosition を使う。

Flash CS6のスプライトシート書き出し後 C/C++用UVテーブルを作成する

Flash CS6 でスプライトシートを書き出すという便利な機能があるが、

各スプライトのUVがXMLで吐き出されるため

スプライトシートを作ったはいいけど、iOSのOpenGLで使う時など

C/C++ でも使える形式に変換するものがないので Python で簡易スクリプトを書いてみた。

動作確認は Python2.7.2 Windows7 。 バッチ処理は Windows 向けだが

Python スクリプト自体は他の環境でも動くと思われる。

まずは以下の Python スクリプトをコピペして保存。

=====[ convert.py ]=====
# -*- coding: utf-8 -*-
import codecs
import sys, re

sys.stdout = codecs.lookup('utf-8')[-1](sys.stdout)

print u"open file.\n"

inname = sys.argv[1]
trimname= inname.split('\\')[-1].split('.xml')[0]

f = codecs.open (inname, 'r', 'utf-16')

data = f.read ()

print u"file size: " + unicode (len (data)) + u" byte(s).\n"

#print data

f.close ()

print u"replace text.\n"

xlist = re.findall (r'x="([0-9]+)"', data)
ylist = re.findall (r'y="([0-9]+)"', data)
wlist = re.findall (r'width="([0-9]+)"', data)
hlist = re.findall (r'height="([0-9]+)"', data)
nlist = re.findall (r'name="([a-zA-Z0-9_]+)"', data)

out = u"typedef struct{ int x, y, w, h } ssuv;\n\n"

if len (xlist) == len (ylist) and len (xlist) == len (wlist) and len (xlist) == len (hlist) and len (xlist) == len (nlist):

 i = 0
 
 out += u"enum {\n"
 
 for x in xlist: 
  
  print nlist[i]

  out += u"\t%(name)s,\n" % {'name' : nlist[i][:-4] }
  
  i += 1
 
 out += u"};\n\n"
 
 i = 0
 
 out += u"ssuv %(valuename)s_tex[] = {\n" % {'valuename':trimname}
 
 for x in xlist:
 
  out += u"\t{%(X)d, %(Y)d, %(W)d, %(H)d},\n" % { 'X':int (xlist[i]), 'Y':int (ylist[i]), 'W':int (wlist[i]), 'H':int (hlist[i])}
 
  i += 1

out += u"};\n"

print u"output file."

f = open (trimname + "_out.txt", 'w')

f.write (out)

f.close ()
========================

あとは引数に xml のファイルパスを渡してやれば

ファイル名_out.txt というファイルで enum とテーブルに変換したものを吐き出す。

適当にバッチ化してやると楽かも。

例えば、Windows ならさらに以下の様なバッチファイルを作成する。

=====[ convert.bat ]=====

echo off
python convert.py %1
pause

=========================

以後、このバッチに処理したい xml をドラッグするだけでコンバートされる。

ちなみに enum で定義される名前は、

シンボル名をそのまま使うのでシンボル名に全角を使わないような工夫が必要です。






The left(right) operand of '/' is a garbage value の原因

ローカル変数を定義した際に、初期化していないまま計算すると出る。

なので、 適当に初期化してやればこの警告は消える。

例)

int i = 100;
int aaa; // ここで初期化してない

i = i / aaa;
// ^ The right operand of '/' is a garbage value.

親ビューから子ビューの範囲にあるタッチイベントを処理したい時

親から子の範囲にあるタッチイベントを処理したいという時は、

子にも親で処理したいイベントを実装する。( touchesBegan など )

その中に以下のコードを入れる。

[self.superview /*EventMethod*/:touches withEvent:event];

/*EventMethod*/ には、touchesBegan、touchesMoved、touchesEnded など

そのイベントを記述。

こうすることで、このイベントを親に丸投げできる。

error: failed to attach to process ID ... が出たら

突然、上記エラーでシミュレータが起動しなくなり、

clean しても 再起動しても直らなくて困る。

最終的に、iPhone シミュレータの「コンテンツと設定をリセット...」で

設定周りをリセットしたら動くようになったのでメモ。



[ 追記 ]

再度発生&解決。

StackOverflow にも同様の現象で困ってる人がいたが、

サイトのアドバイス通りに、

「LLDB」から「GDB」に一度設定を変更し一度シミュレータで「実行」させる。

その後、また設定を「LLDB」に戻すと直った。

PCH file built from a different branch

Xcode をアップデートしたら今までエラーが出ていなかったプロジェクトで発生。

Clean すれば難なく解決した。

padding が効かなくなったら試すこと

調べると、親要素に overflow:hidden; を指定すると直るとか

情報があるが諸々試しても改善しない!

そんな時は、padding を上下左右個々の定義に変えてみる。

例)

padding: 8px 12px 8px 16px;



padding-top: 8px;
padding-right: 12px;
padding-bottom:8px;
padding-left: 16px;

margin-top が効かなくなった時の対処方法

position をいじった後にこの現象が起きた。

margin が聞かない Box の1つ外にある要素に

position:relative; すれば直った。

body にあらかじめこのスタイルを定義しておくのが手っ取り早いかも。

それと、margin 系と clear 系は同時に指定しない方がいい模様。

もし、relative を指定しても発生する箇所がある場合は、

margin と clear の同時指定がないか確認しよう。

Divのボックスから文字がはみ出るのを折り返したい

スタイルに

word-break: break-all;

を設定すると解決した。

Assigning retained object to weak variable; object will be released after assignment.

すぐに解放されるから代入する意味が無い的な事っぽい。

ゴリ押しでいいなら、ローカル変数に一度代入したものを入れると警告はなくなる。

// ここで警告が出る
yourWarningValue = [[YourClass alloc] init];

// ↓こうすると警告は消える

YourClass* newvalue = [[YourClass alloc] init];
yourWarningValue = newvalue;

no visible @interface for declares the selector

引数の数が違わないか確認する。

例えば、引数が1つ必要なのに引数なしでコールしたりすると出る。

The executable was signed with invalid entitlements.

ProvisioningFile を再作成すれば直る。

設定云々より古くなった ProvisioningFile の整合が疑わしかったので

最初から素直に作りなおしておけばよかった…。

iOSアプリ開発をする時にやっておきたい例外対応

main.m のmain関数を以下のようにしてから開発を始めると、

例外時にコールスタックをざっくり見られるので何かとデバッグが捗る。

突然 SIG_ABRT するも、どこで止まったかわからないみたいな事で迷う事も減る。

( iOS6で動作確認 )
int main(int argc, char *argv[]) {

#ifdef DEBUG

 int ret;

 @autoreleasepool {

  @try {
  
   ret = UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
  
  }

  @catch (NSException *exception) {

   NSLog( @"%@", [exception callStackSymbols] );
   @throw exception;
  
  }

 }

 return ret;

#else

 @autoreleasepool {

  return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));

 }

#endif

}

IE + FancyBox で inline 表示すると Flash の方が上に表示されてしまう


Flash を設置している <object> タグ内に

<param name="wmode" value="transparent" />

を追加すると直った

GoogleAppEngine 1.7.5

遅ればせながら、GAE/P の最近のバージョンを見てみました。

db.Model → ndb.Model とする事で、

memcache やコンテキストが付いた新しいdbモジュールが使える模様。

ただし、key_name が廃止されて id に統一されていたり、

ListProperty が廃止されて厳密になっていたりするので、

作り変えの場合は注意が必要。

# --- String ---

# db
str = db.StringListProperty()

# ndb
str = db.StringProperty( repeated=True )

# --- float ---

# db
floatList = db.ListProperty()

# ndb
floatList = db.FloatProperty( repeated=True )


Eclipse ( Mac ) + GoogleAppEngine + Python のブレークポイントで止まらない

Mac( MountainLion ) + GoogleAppEngine 1.7.5 + Pydev + Eclipse4.2 ( + Pleiades ) で

ブレイクポイントが止まらなくなった。

まだ、直らずあれこれ試行錯誤中ですが、他にもお困りの方が同じ手間を踏まないように

ダメだった事をメモ。

検索してみると、JDK が 1.6.0_41 だと不具合がある模様と思ったが

JDK を 1.6.0_29 にして設定& clean をするもダメ。

eclipse/dropin/下を

pydevd_constants.py

で検索をかけて開く。その中の

DEBUG_TRACE_LEVEL = -1
DEBUG_TRACE_BREAKPOINTS = -1

を両方 3 にして保存、同名の pyc を削除し、 clean してもダメ。

ちなみに PHP + Eclipse でブレークポイントが効かない場合は こちら