2017-01-30 15 views
3

以前は、シーンエディタを使用して複雑なSKSpriteNodesを作成することはできますか? @Anton Rogachevskyiの助けを借りてthe previous question私はunarchiveNodeFromFileを使用して.SKSファイルの位置を突き止めました。私は予想通りにsksファイルを読み込みますが、現在のシーンに追加しようとすると何も表示されません。私がaddChild行を壊して、プレビューウィンドウに適切に表示されるオブジェクトをプレビューすると、正しいファイルが見つかることがわかります。 sksファイルの中にカスタムダイアログクラスがあり、 "required init?(coder aDecoder:NSCoder)"にブレークポイントを設定すると、カスタムオブジェクトが正しく初期化されていることがわかります。ダイアログクラスの内部SpriteKitで親に追加されたときにアーカイブされていないノードが表示されない

dialog being created in the scene editor

私はプログラムでは、これは私が見つける方法ですクラスの初期化

class TeamDialog: SKSpriteNode { 

init(size: CGSize) { 
    super.init(texture: nil, color: .red, size: size) 
} 

required init?(coder aDecoder: NSCoder) { 
    super.init(coder: aDecoder) 

    setup() 
} 

func setup() { 

    let pinkBox = SKSpriteNode(color: .magenta, size: CGSize(width: 100, height: 100)) 
    pinkBox.zPosition = 500 
    addChild(pinkBox) 
} 
} 

、シーン内に達しないことを示すために、オブジェクトにピンク色のボックスを追加オブジェクトやシーンにそれを追加しようと、それはプレビューで表示されますが、何も画面に現れない

private func displayDialog() { 

    if let wtf = unarchiveNodeFromFile(file: "TeamDialog")! as SKNode? { 

     let layer = SKSpriteNode(color: .clear, size: self.size) 
     layer.zPosition = 5000 
     layer.position = CGPoint(x: self.size.width/2, y: self.size.height/2) 
     addChild(layer) 

     for child in wtf.children { 
      print("child \(child.name)") 
      if let teamDialog = child as? TeamDialog { 
       teamDialog.removeFromParent() 
       layer.zPosition = 1 
       layer.addChild(teamDialog) 
      } 
     } 
    } 
} 

func unarchiveNodeFromFile(file: String) -> SKNode? { 

    if let path = Bundle.main.path(forResource: file, ofType: "sks") { 

     let fileData = NSData.init(contentsOfFile: path) 
     let archiver = NSKeyedUnarchiver.init(forReadingWith: fileData as Data!) 
     archiver.setClass(SKNode.classForKeyedUnarchiver(), forClassName: "SKScene") 
     let node = archiver.decodeObject(forKey: NSKeyedArchiveRootObjectKey) as! SKNode 
     archiver.finishDecoding() 
     return node 
    } else { 
     return nil 
    } 
} 

break preview of the object

また、プレビューウィンドウで見ることができますが、シーンに追加すると何も表示されません。

シーンに追加する前に、別の方法でアーカイブされていないオブジェクトを処理する必要がありますか?

私はコードを取り出し、同じ結果を持つテストプロジェクトに入れました。

私は運を持つシーンに(ノードなど)SKSファイルを追加しようとした、と私はSKSファイルからダイアログを隔離し、問題がwasn

+1

これらの質問は素晴らしいです。他のすべてのレベルの徹底的で興味深いものです。 – Confused

+0

ありがとう、私はそれを感謝します。SpriteKitのポイントは、Appleが機能やサポートを強化するのを待っているのが失われた原因のように思えるから、より多くの機能を使い始める必要があるということです。 –

+0

メモリから、iOS 8〜9はSpriteKitに追加された機能よりも多くのバグを発見しました。 iOS 10はSKWarpNodeを振っている草を追加しました。それ以外は忘れました。確かに** _素晴らしい_ **でした。 – Confused

答えて

2

運でそれを追加しようとしましたアーカイブされていないファイルとしてロードされたかどうか、またはSKReferenceNodeとしてロードされたかどうか。このSKReferenceNodeのことを知り、研究した後、これは正確に行く方法であり、おそらくこの目的のために作られました。

問題は、シーンエディタでカスタムオブジェクトがシーン(x = -1500)の横に配置されていたことです。これは、最初に作成したときにscene.sksファイルにあり、シーンオブジェクト。私はそれを自分のsksファイルに転送すると、それはその位置づけを保っていました。変数にsksファイルをロードした後、コード内でCGPoint(x:0、y:0)の位置を設定するため、これは大きな問題ではないと私は思いました。問題は、ロードされたシーンオブジェクトを既存のシーンの周りに移動できないため、オフスクリーンの場合はオフスクリーンのままになります。位置を設定しても何も起こりませんでした。アーカイブされていないファイルや移動しないSKReferenceNodeの場合は問題ありませんでした。

私はsksファイルの最初の子を参照し、その位置とヴィオラを設定しました!

この設定で何ができるか興味があれば、自分のsksファイルで複雑なカスタムオブジェクトを作成してレイアウトし、シーンファイルにロードすることができます。このようにすることの美しさは、sksファイルが乱雑にならないようにして、カスタムオブジェクトsksを複数の異なるシーンで参照できるようにすることです。

let path = Bundle.main.path(forResource: "TeamDialog", ofType: "sks") 
    let dialogScene = SKReferenceNode (url: URL (fileURLWithPath: path!)) 
    if let teamDialog = dialogScene.childNode(withName: "//teamDialog") as? TeamDialog { 
     teamDialog.setup(scene: self) 
     teamDialog.position = CGPoint(x: 0, y: 0) 
     dialogScene.zPosition = 5000 
     addChild(dialogScene) 
    } 
関連する問題