2016-03-31 10 views
2

TLTR:デバッグなぜSKSceneの初期化(ゼロfileNamed :)戻り

問題:SKSceneサブクラスのinit(fileNamed:)戻りnil

理由:.sksファイルが第二初期化の時点で存在していませんコール。何とかODRの実装AND/OR動作に関係する問題です。

説明:

SpriteKitで構築されたゲーム。私のSKSceneサブクラスのinit(fileNamed:)nilを返します。私は「なぜ」を理解しようとしています。そしてどうやって?"この問題をデバッグします。

SKSceneサブクラス初期化するための私のコード:注意すべき

/// the hierarchy: SKScene -> TBTBaseScene -> TBTLevelScene 

let sceneType: TBTBaseScene.Type = TBTLevelScene.self 
let fileName = "Level1" 

let scene = sceneType.init(fileNamed: fileName) 

いくつかのこと:

  1. このコードは、実行中のある時点で動作しますが、他ではありません。
  2. ターゲットがXcode経由でビルドされている場合、[製品] - > AppName.appに移動し、[Finderで表示]を右クリックし、Level1.sksはありません。アプリはODRを使用し、Level1.sksが、それはブレークポイントがlet sceneType:...ラインに設定されている場合、私は簡単にを介して他のゲームシーンを
  3. を作成することができ初期インストールのタグであっても、「レベル1」のタグが付いているので、おそらくそれは、OKですそれぞれのサブクラスとファイル名はexpression TBTLevelScene(fileName:"Level1")、戻り値はnilです。
  4. メインバンドルにLevel1.sksがあるかどうかを確認しようとしましたが、以下のコードでは、すべてのシーンで常に「ファイルが使用できません」と表示されているため、アプローチが間違っているようです。
  5. シーンロードのためのゲームのアーキテクチャは、DemoBots Sample Codeから駆動されます。 LoadSceneOperation.swiftでも同様のアプローチが見られます。しかし、初期化はすべての場合にうまく機能します。

私はthis answerに基づいて存在する "レベル1" または "Level1.sks" を、チェックするために使用するコード:

let path = NSBundle.mainBundle().bundlePath 
let url = NSURL(fileURLWithPath: path) 
let filePath = url.URLByAppendingPathComponent(fileName).absoluteString 
let fileManager = NSFileManager.defaultManager() 
if fileManager.fileExistsAtPath(filePath) { 
    print("FILE AVAILABLE") 
} else { 
    print("FILE NOT AVAILABLE") 
} 

UPDATE:Michael Dautermannが提供するファイルをチェックするための

アプローチ理由を証明します:Level1.sksではありません。は2回目の読み込み中に存在します。

プロジェクトのLevel1.sksファイルが「バンドルリソースのコピー」領域に追加され、「レベル1」のODRタグがあります。このタグは初期インストールタグプリフェッチグループにあります。

ORDの実装にはいくつかのバグがあります。必要でないときにリソース(Level1.sks)を廃棄し、必要なときに再度ロードしません。私はそれを理解するために移動し続けます。

答えて

4

ここではいくつかのことが起こっていますが、最終的に起こっていることは、 "Level1"ファイルがビルドされたアプリケーションで終わっていないように聞こえるということです(つまり、SOコミュニティはそれとは関係ありません)。 。

1)

あなたのファイルの存在チェックコードまであまりにも多くのファイルURLのパスとファイルパスをミキシングがあります。あなたの.sksのファイルが構築されたアプリケーションにコピーされていることを確認します

に)

// if nodePath is nil, then it's not found in the bundle 
if let nodePath = NSBundle.mainBundle().pathForResource("Level1", ofType: "sks") 
{ 
    print("FILE AVAILABLE") 
} else { 
    print("FILE NOT AVAILABLE") 
} 

2:次のようになりますようにコードを変更します。

ターゲットの「ビルドフェーズ」セクションとclick on the "Copy Bundle Resources" areaを開きます。 .sksファイルがそこに含まれていることを確認してください。

+0

ファイルの存在を確認するアプローチが有効です。アプリがクラッシュしたときに「Level1.sks」が利用できないことを示しています。ただし、 "バンドルリソースのコピー"領域*には "Level1.sks"があります。 –

+0

ファイルがビルド済みのアプリケーションにコピーされていないことが何らかの理由である必要があります。ビルドログには何か有用なものはありますか? ( "show all messages") –

+0

私の更新を見てください。あなたのコードは、ケースを絞り込むのに役立ちました。ありがとう。 @Michael Dautermann –