ラベル SpriteKit の投稿を表示しています。 すべての投稿を表示
ラベル SpriteKit の投稿を表示しています。 すべての投稿を表示

2020年1月22日水曜日

SpriteKit で SKPhysicsBody の texture の形がおかしくなってしまったときの対処方法

概要

原因不明なのですが突如として SKPhysicsBody(texture: texture, size: texture.size()) で作成した物理ボディがなぜか指定した画像の形通りに動作しない場合の対処方法です
かなり一時的な対応ですが何とか対応できたので紹介します

環境

  • macOS 10.15.2
  • Xcode 11.3.1

解決策

png 画像を一旦削除して再度プロジェクトに取り込む

Xcode のプロジェクト内で管理している画像ファイルを一旦すべて削除します
そして、Finder などから再度画像を取り込むみビルドすることで SKPhysicsBody が正常に動作することが確認できました
バグのような挙動ですが解決しない場合はやってみる価値はあると思います

気づいたきっかけ

同じ画像を使って別の新規プロジェクトで同じ SKPhysicsBody の与え方をしたところ正常に動作するのを確認できたので既存のプロジェクト側に何かしら問題があるだろうと気づきました

しかし全く同じコードなのに物理ボディの挙動が違いなぜだろうと悩んだ結果「もしかしたら画像自体がおかしいのかも」ということでリフレッシュしてみたら直った感じです

もしかするとキャッシュなども影響しているのかもしれません

2019年12月5日木曜日

SKPhysicsBody を作成するときは極力 texture を使わないほうが良いと思う

概要

個人的な経験ですが SKPhysicsBody を生成するときは texture ではなくて circleOfRadius や rectangleOf を使ったほうが予期せぬ動作をしない印象があります
ハマった点などを紹介します

概要

  • macOS 10.15.1
  • Xcode 11.2.1 (11B500)

applyImpluse の挙動がおかしい

ある SpriteNode に対して物理エンジンを texture を使って作成しました
そして touchDown 時に applyImpluse を適用するような処理を実装したのですが iPhoneX 系の実機の場合挙動がおかしくなる現象が発生しました

シミュレータでやると問題ないのですが実機でやると力の入れ具合がおかしいのか本来のスピードよりも SpriteNode の動きが速かったり遅かったりしました
その度に端末のサイズごとの対応を入れていたのですが原因が texture によるものだとわかりrectangleOf で物理エンジン生成することで挙動がどの端末でも同じ動きをするようになりました

なぜ texture だとうまく動作しないのか明確な原因は不明ですがおそらく端末のサイズによるものかなと思います
小さい端末に比べて大きい端末の場合 texture 比率が小さくなると思います
おそらくそれにより質量などが端末ごとに変わってしまい力を与える applyImpluse の挙動もおかしくなってしまったのだと思います

SKPhysicsJointFixed の挙動がおかしい

指定したアンカーポイント同士で結合せず SpriteNode が重なったり逆に離れてジョイントするケースがありました
また本来は SpriteNode が上に重なるはずがなぜか texture を使っているとサイズが小さくなるのか上に乗らずに SpriteNode が重なってしまう現象も確認できました

これらの現象も texture ではなく rectangleOf を使って解決することができました

最後に

SKPhysicsBody を使う際のポイントを紹介しました
自分はなるべく rectangleOf を使うようにしています
特にゲームのコアとなる部分では texture は使わないようにしています

個人的に一番困ったのが texture を使うことによる端末ごとの挙動が異なる点でした
初めは SpriteKit の座標情報が実機とシミュレータで異なるのかなーと思っていたのですがそういうことはなく物理エンジンの作り方が悪かったというか物理エンジンの作り方に端末間で差異があるということがわかりました

もしかすると SpriteKit のバグで今後修正されることがあるかもしれませんが、それでも texture を使った当たり判定や結合処理などはやめたほうが無難かなと思います

2019年8月6日火曜日

iPhoneXs, XR で SpriteKit のシーンの表示を最適化する方法

概要

過去 に iPhoneX 時に SpriteKit のシーンを最適化する方法を紹介しました
iPhoneXs, XsMax, iPhoneXR を考慮した場合もっと良さそうな方法があったので紹介します

環境

  • macOS 10.14.5
  • Xcode 10.3

コード

if let view = self.view as! SKView? {
    // Load the SKScene from 'GameScene.sks'
    if let scene = TitleScene(fileNamed: Config.Scene.TitleScene) {
        // Set the scale mode to scale to fit the window
        scene.viewController = self
        if (UIDevice.current.model.range(of: "iPad") != nil) {
            scene.scaleMode = .fill
        } else {
            if (UIScreen.main.nativeBounds.height >= 1792.0) {
                // iPhoneXR 以上なら
                scene.scaleMode = .fill
            } else {
                scene.scaleMode = .aspectFill
            }
        }
        // Present the scene
        view.presentScene(scene)
    }
}

前回は height=2436.0 以上の場合に aspectFit を使っていました
2436.0 は iPhoneX なのですが XsMax の場合更に大きいので else に入ってしまいます
また iPhoneXR は 1792.0 になります

aspectFit にすれば上下に黒のバーが表示されてしまうことがわかったので aspectFit ではなく fill を使ったほうがキレイに表示されます
また iPhoneXR 以上のサイズの場合に fill にしたほうが良いので条件も変更しています

aspectFill を iPhoneXR や Xs で使うと一見キレイに表示されているように見えるのですが実は横幅がはみ出しているケースがあるので fill を使ったほうが良いです

2019年8月5日月曜日

SpriteKit で作成したアプリを Swift3.0 から 4.2 に対応させたときのメモ

概要

久しぶりに SpriteKit アプリを Xcode で開いたら Swift3.0 のサポートが終了しておりビルドできなかったので Swift4.2 にコンバートしビルドできるようにしました
その時のメモです
環境によってエラー内容等、異なるので参考程度に御覧ください

環境

  • macOS 10.14.5
  • Xcode 10.3
  • Swift 3.0 to 4.2

コンパイラのバージョンを 4.2 にする

まず以下のようなエラーが発生しました
SWIFT_VERSION が 3.0 はもうサポートしていないというエラーです

プロジェクトの設定から「Build Settings」で「Swift Language Version」 を 4.2 にしましょう

テストのプロジェクトがある場合はそれらの「Build Settings」も変更しましょう

最終的にはプロジェクト配下で git grep 'SWIFT_VERSION' を実行し 3.0 がなければ OK です

pod update

各種ライブラリが古いと Swift3.0 になっている場合があるのでライブラリをアップデートしましょう

  • pod update

YouTubePlayer のインストール

これはおそらく今回のコンバートとは関係ないと思います
が対応する箇所があったので紹介します

「No such module YouTubePlayer」が出た場合は単純にライブラリを追加すれば OK です

  • vim Podfile
pod 'YouTubePlayer'
  • pod install

インストール後ビルドすると 'UIWebViewNavigationType' has been renamed to 'UIWebView.NavigationType' というエラーが出るのでライブラリを unlock して fix すれば OK です

Realm のフィールドに @objc を付与

これも基本は fix すれば OK です

AVAudioSession のフィールド参照方法を修正

これも Xcode の言う通り fix していけば OK です

  • 'AVAudioSessionCategoryAmbient' has been renamed to 'AVAudioSession.Category.ambient' -> fix
  • 'AVAudioSessionCategorySoloAmbient' has been renamed to 'AVAudioSession.Category.soloAmbient' -> fix

UIApplication のフィールド参照方法を修正

fix で OK です

The Google Mobile Ads SDK was initialized without an application ID

Info.plist に GADIsAdManagerApp -> YES を追加すれば OK です (参考)

最後に

基本は Xcode の指示に従えば文法は修正できます
ライブラリ関連のエラーは unlock するかライブラリ側の修正を待つかプルリクエストを送りましょう
最新のライブラリのドキュメントを読むこともおすすめです

あとはトライアンドエラーで解決していくしかないかなと思います