Symptom
Crashed with “Thread 1: EXC_BAD_ACCESS (code=1, address=0x18)”
Cause
Case 1: You are accessing UI from the timer thread. UI parts should be accessed from the main thread.
Case 2: Invalidated the timer before the timer thread completion.
Blog of aiharasoft.com
Crashed with “Thread 1: EXC_BAD_ACCESS (code=1, address=0x18)”
Case 1: You are accessing UI from the timer thread. UI parts should be accessed from the main thread.
Case 2: Invalidated the timer before the timer thread completion.
Add following four lines of code to “SceneDelegate.swift” in your project.
import UIKit class SceneDelegate: UIResponder, UIWindowSceneDelegate { var window: UIWindow? func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). guard let _ = (scene as? UIWindowScene) else { return } // #### add following four lines of code. #if targetEnvironment(macCatalyst) window?.windowScene?.sizeRestrictions?.minimumSize = CGSize(width: 400, height: 400) window?.windowScene?.sizeRestrictions?.maximumSize = CGSize(width: 1280, height: 1000) #endif // ### end of code } ...
class UIImage : NSObject
画像オブジェクトはすべてのプラットフォームネイティブの画像形式をサポートしていますが、アプリのほとんどの画像にはPNGまたはJPEGファイルを使用することをお勧めします。画像オブジェクトは、両方の形式の読み取りと表示用に最適化されており、これらの形式は、他のほとんどの画像形式よりも優れたパフォーマンスを提供します。PNG形式はロスレスであるため、アプリのインターフェースで使用する画像に特にお勧めします。
このクラスのメソッドを使用して画像オブジェクトを作成する場合は、ファイルまたはデータ構造に既存の画像データを配置する必要があります。空の画像を作成してコンテンツを描画することはできません。画像オブジェクトを作成するための多くのオプションがあり、それぞれが特定の状況に最適です。
init(named:in:compatibleWith:)
init(named:)
使用方法(または、アプリケーションのメインバンドル(またはいくつかの他の既知のバンドル)にある画像アセットや画像ファイルから画像を作成する方法を)。これらの方法は画像データを自動的にキャッシュするため、頻繁に使用する画像に特にお勧めします。逆に、キャッシュされたメモリは解放されないので注意!
imageWithContentsOfFile:
init(contentsOfFile:)
初期データがバンドルされていない画像オブジェクトを作成します。これらのメソッドは毎回ディスクからイメージデータをロードするため、同じイメージを繰り返しロードするために使用しないでください。頻繁にアクセスするような場合は毎回読み込むため、遅くなる可能性がある。
animatedImage(with:duration:)
、またはanimatedImageNamed(_:duration:)
複数の連続した画像で構成される単一のオブジェクトを作成します。結果の画像をオブジェクトにインストールして、インターフェイスでアニメーションを作成します。
UIImage
クラスの他のメソッドを使用すると、コアグラフィックス画像や自分で作成した画像データなど、特定の種類のデータからアニメーションを作成できます。UIKitのUIGraphicsGetImageFromCurrentImageContext()
は、自分で描いたコンテンツから画像を作成する機能もあります。この関数は、描画コマンドをキャプチャするために使用するビットマップベースのグラフィックコンテキストと組み合わせて使用します。
イメージオブジェクトは不変であるため、作成後にプロパティを変更することはできません。ほとんどの画像プロパティは、付随する画像ファイルまたは画像データのメタデータを使用して自動的に設定されます。画像オブジェクトの不変の性質は、どのスレッドからでも安全に作成および使用できることも意味します。
画像アセットは、アプリに付属する画像を管理する最も簡単な方法です。新しいXcodeプロジェクトにはそれぞれ、複数の画像セットを追加できるアセットライブラリが含まれています。画像セットには、アプリが使用する単一の画像のバリエーションが含まれています。単一の画像セットは、さまざまなプラットフォーム、さまざまな特性環境(コンパクトまたは通常)、およびさまざまなスケール係数に対してさまざまなバージョンの画像を提供できます。
ディスクから画像をロードすることに加えて、オブジェクトを使用して利用可能なカメラまたはフォトライブラリから画像を提供するようにユーザーに依頼できます。画像ピッカーUIImagePickerController
は、画像を選択するためのカスタムユーザーインターフェイスを表示します。ユーザー提供の画像にアクセスするには、明示的なユーザー権限が必要です。イメージピッカーの使用の詳細については、UIImagePickerController
を参照してください。
ストレッチ可能な画像は、もとの画像データを美的に満足のいく方法で複製できる領域を定義する画像です。ストレッチ可能な画像は、利用可能なスペースを埋めるために拡大または縮小できる背景を作成するために一般的に使用されます。
resizableImage(withCapInsets:)
または resizableImage(withCapInsets:resizingMode:)
を使用して既存の画像にインセットを追加することにより、ストレッチ可能な画像を定義します。図は、画像を2つ以上の部分に分割します。各挿入図にゼロ以外の値を指定すると、図1に示すように、9つの部分に分割された画像が生成されます。
各挿入図は、指定された寸法で引き伸ばされない画像の部分を定義します。画像の上部と下部の挿入図の内側の領域は固定の高さを維持し、左右の挿入図の内側の領域は固定の幅を維持します。図2は、9つの部分からなる画像の各部分が、使用可能なスペースを埋めるために画像自体が引き伸ばされるときにどのように引き伸ばされるかを示しています。画像の角は、水平と垂直の両方のはめ込みの内側にあるため、サイズは変わりません。
isEqual(_:)
は、2つの画像に同じ画像データが含まれているかどうかを判断する唯一の信頼できる方法です。作成する画像オブジェクトは、同じキャッシュ画像データで初期化した場合でも、互いに異なる場合があります。それらの同等性を判断する唯一の方法は、実際の画像データを比較する方法を使用することです。リスト1は、画像を比較する正しい方法と正しくない方法を示しています。
let image1 = UIImage(named: "MyImage") let image2 = UIImage(named: "MyImage") if image1 != nil && image1!.isEqual(image2) { // Correct. This technique compares the image data correctly. } if image1 == image2 { // Incorrect! Direct object comparisons may not work. }
画像オブジェクトは、基になる画像データへの直接アクセスを提供しません。ただし、アプリで使用するために他の形式で画像データを取得することはできます。具体的には、cgImage
プロパティとciImage
プロパティを使用して、それぞれCoreGraphicsおよびCoreImageと互換性のあるバージョンのイメージを取得できます。
関数を使用して、PNGまたはJPEG形式の画像データを含むNSDataオブジェクトを生成することもできます。pngData()と
jpegData(compressionQuality:)
Creating a Mac Version of Your iPad
‘AppDelegate’ is annotated with @main and must provide a main static function of type () -> Void or () throws -> Void.
import UIKit @main class AppDelegate: UIResponder, UIApplicationDelegate { // Add following five lines of code to AppDelegate.swift #if targetEnvironment(macCatalyst) static func main() { UIApplicationMain(CommandLine.argc, CommandLine.unsafeArgv, nil, NSStringFromClass(AppDelegate.self)) } #endif
In the debug window, “Cannot create Swift scratch context” warning was displayed and po shows nothing.
Xcoce Version 12.1 (12A7403)
Unknown
Restarted Xcode.
https://developer.apple.com/documentation/scenekit/scnscenerendererdelegate
func renderer(SCNSceneRenderer, nodeFor: ARAnchor) -> SCNNode?
新しく追加されたアンカーに対応するSceneKitノードを提供するようにデリゲートに要求します。
func renderer(SCNSceneRenderer, didAdd: SCNNode, for: ARAnchor)
新しいARアンカーに対応するSceneKitノードがシーンに追加されたことをデリゲートに通知します。
func renderer(SCNSceneRenderer, willUpdate: SCNNode, for: ARAnchor)
ノードのプロパティが対応するアンカーの現在の状態に一致するように更新されることをデリゲートに通知します。
func renderer(SCNSceneRenderer, didUpdate: SCNNode, for: ARAnchor)
SceneKitノードのプロパティが対応するアンカーの現在の状態と一致するように更新されたことをデリゲートに通知します。
func renderer(SCNSceneRenderer, didRemove: SCNNode, for: ARAnchor)
削除されたARアンカーに対応するSceneKitノードがシーンから削除されたことをデリゲートに通知します。
renderer(_:nodeFor:)
新しく追加されたアンカーに対応するSceneKitノードを提供するように要求します。
renderer(_:didRemove:for:)
レンダラー(_:didRemove:for :)削除されたARアンカーに対応するSceneKitノードがシーンから削除されたことを通知します。
renderer(_:didUpdate:for:)
SceneKitノードのプロパティが対応するアンカーの現在の状態と一致するように更新されたことを通知します。
SceneKitは、シーンを表示しているSCNView
オブジェクト(または他のオブジェクト)が一時停止されていない限り、このSCNSceneRenderer
メソッドをフレームごとに1回だけ呼び出します。このメソッドを実装して、レンダリングループにゲームロジックを追加します。この方法でシーングラフに加えた変更は、表示されているシーンにすぐに反映されます。つまり、SceneKitは、シーンのレンダリングに使用するプレゼンテーションノードの階層を即座に更新します
renderer(_:didApplyAnimationsAtTime:)
アクションとアニメーションの評価後に発生する必要のある更新を実行するように指示します。
renderer(_:didSimulatePhysicsAtTime:)
物理シミュレーションの実行後に発生する必要のある更新を実行するように指示します。
renderer(_:willRenderScene:atTime:)
レンダラーがビューポートをクリアし、シーンをレンダリングしようとしていることを通知します。
renderer(_:didRenderScene:atTime:)
レンダラーがシーンをレンダリングしたことを通知します。
https://developer.apple.com/documentation/scenekit/scnphysicsbody
class SCNPhysicsBody : NSObject
SceneKitは、新しいフレームをレンダリングする準備をするときに、シーン内のノードに接続されている物理ボディに対して物理計算を実行します。これらの計算には、重力、摩擦、および他の物体との衝突が含まれます。ボディに自分の力や衝撃を加えることもできます。SceneKitはこれらの計算を完了すると、フレームをレンダリングする前にノードオブジェクトの位置と方向を更新します。
ノードに物理演算を追加するには、SCNPhysicsBodyオブジェクトを作成して構成し、それをSCNNode
オブジェクトのphysicsBody
プロパティに割り当てます。物理ボディは、力または衝撃をノードオブジェクトに適用する前に、ノードオブジェクトに関連付ける必要があります。
このSCNPhysicsBodyクラスは、シーンによってシミュレートされるときのボディの物理的特性を定義します。物理シミュレーションでは、次の3つのプロパティが最も重要です。
type
プロパティphysicsShape
プロパティSCNPhysicsShape
を参照してください。kinematic()
プロパティ。動的な物体に力またはトルクを加えると、その質量に比例した加速度(または角加速度)が発生します。SceneKitの物理シミュレーションのすべての値は、国際単位系(SI)を使用します。質量の単位はキログラムです。力、力積、およびトルクの単位は、ニュートン、ニュートン秒、およびニュートンメートルです。ノードの位置とサイズの距離の単位はメートルです。物理量に現実的な値を提供しようとする必要はないことに注意してください。探している動作やゲームプレイを生み出す値を使用してください。
Dynamic ボディの場合、力または衝突によってボディがどのように影響を受けるかを制御できます。力Defining How Forces Affect a Physics Body を参照してください。
物理学を使用するゲームを設計するときは、シーンに表示される物理学オブジェクトのさまざまなカテゴリを定義します。アプリに必要な動作に応じて、さまざまなカテゴリの物理ボディを定義します。ボディは、これらのカテゴリに必要な数だけ割り当てることができます。物理ボディは、独自のカテゴリを宣言するだけでなく、相互作用するボディのカテゴリも宣言します。
categoryBitMask
とcollisionBitMask
プロパティを使用して、オブジェクトの衝突動作を定義します。SCNPhysicsCollisionCategory
にリストされている定数は、これらのプロパティのデフォルト値を提供します。さらに、contactTestBitMask
プロパティを使用すると、ボディが衝突の影響を受けることなく、ボディのペアがコンタクトメッセージ(SCNPhysicsContactDelegate
プロトコルを参照)を生成するインタラクションを定義できます。
物理学の分野は、渦や重力の引力など、領域内のすべての物体に影響を与える力を生み出します。詳細および使用可能なフィールドタイプのリストについては、SCNPhysicsField
を参照してください。
関節や車輪付き車両など、複数のボディ間の相互作用を制御する高レベルの動作を追加できます。詳細および使用可能な動作のリストについては、SCNPhysicsBehavior
を参照してください。
シーンのphysicsWorld
プロパティは、シーン全体に影響を与える物理特性を管理するSCNPhysicsWorld
オブジェクトを保持します。
SceneKitは、SCNSceneRendererDelegate
で説明されているレンダリングループの一部として物理シミュレーションを評価します。このループを通過するたびに、SceneKitは、物理ボディがアタッチされたすべてのノードの状態を判別し、たとえば、速度と角速度に基づいてボディの位置または回転を更新することにより、これらのボディに対する物理の影響を1タイムステップでシミュレートします。その後、SceneKitは物理シミュレーションの結果をシーンに適用して表示します。
SceneKitコンテンツは、物理学だけでなく、アクションや暗黙的および明示的に定義されたアニメーションを通じてもアニメーション化できるため、SceneKitは、物理シミュレーションの結果をSCNNode
シーン内のpresentation
オブジェクトではなく、現在表示されている状態を表す各ノードのオブジェクトに適用します。そのため、物理学の影響を受けるノードのプロパティを変更するには、特別な考慮が必要です。
物理学の影響を受けるノードのtransform
値、または変換のコンポーネントであるその他のプロパティ(position
およびrotation
など)を変更すると、SceneKitはそのノードの物理シミュレーションをリセットします。以下に示すように、変換の1つのコンポーネントのみを変更し、他のコンポーネントは物理シミュレーション値のままにしておきたい場合は、変更を加える前にプレゼンテーションノードの変換をコピーします。
// Copy the presentation node's transform to the model node.node.transform = node.presentationNode.transform // Change one component of the new transform node.eulerAngles.z = newRollValue
init(type: SCNPhysicsBodyType, shape: SCNPhysicsShape?)
指定されたタイプと形状の物理ボディを作成します。
class func `static`() -> Self
力や衝突の影響を受けず、移動できない物理ボディを作成します。
class func dynamic() -> Self
力や衝突の影響を受ける可能性のある物理ボディを作成します。
class func kinematic() -> Self
力や衝突の影響を受けないが、移動すると他のボディに影響を与える衝突を引き起こす可能性のある物理ボディを作成します。
var physicsShape: SCNPhysicsShape?
衝突検出で使用するための物理ボディのソリッドボリュームを定義するオブジェクト。
var type: SCNPhysicsBodyType
物理体が力や衝突にどのように反応するかを決定する定数。
enum SCNPhysicsBodyType
物理ボディが力や他のボディとどのように相互作用するかを決定する定数。type
プロパティで使用され、物理ボディを作成するときに使用されます。
var velocityFactor: SCNVector3
SceneKitが物理シミュレーションによって計算された変換を物理ボディを含むノードに適用する方法に影響を与える乗数。
var angularVelocityFactor: SCNVector3
SceneKitが物理シミュレーションによって計算された回転を物理ボディを含むノードに適用する方法に影響を与える乗数。
var isAffectedByGravity: Bool
シーンの一定の重力が体を加速するかどうかを決定するブール値。
var mass: CGFloat
体の質量(キログラム)。
var charge: CGFloat
クーロン単位の体の電荷。
var friction: CGFloat
スライド運動に対する身体の抵抗。
var rollingFriction: CGFloat
転がり運動に対する体の抵抗。
var restitution: CGFloat
衝突で体が失うまたは得る運動エネルギーの量を決定する要因。
var damping: CGFloat
体の直線速度を低下させる要因。
var angularDamping: CGFloat
体の角速度を低下させる要因。
var momentOfInertia: SCNVector3
ボディを含むノードのローカル座標系で表される、ボディの慣性モーメント。
var usesDefaultMomentOfInertia: Bool
SceneKitがボディの慣性モーメントを自動的に計算するか、カスタム値を設定できるかを決定するブール値。
var centerOfMassOffset: SCNVector3
ローカル座標の原点に対するボディの重心の位置。
var categoryBitMask: Int
この物理ボディが属するカテゴリを定義するマスク。
var contactTestBitMask: Int
ボディのどのカテゴリがこの物理ボディとの交差通知を引き起こすかを定義するマスク。
var collisionBitMask: Int
物理ボディのどのカテゴリがこの物理ボディと衝突できるかを定義するマスク。
struct SCNPhysicsCollisionCategory
物理ボディとプロパティのデフォルト値。
categoryBitMask
collisionBitMask
var continuousCollisionDetectionThreshold: CGFloat
SceneKitが他のボディとの接触を検出するためのより正確な(ただしよりコストのかかる)アルゴリズムを適用するためにボディが移動する必要のある最小距離。
func applyForce(SCNVector3, asImpulse: Bool)
重心で体に力または衝撃を加えます。
func applyForce(SCNVector3, at: SCNVector3, asImpulse: Bool)
特定のポイントで体に力または衝撃を加えます。
func applyTorque(SCNVector4, asImpulse: Bool)
正味のトルクまたは角運動量の変化を体に適用します。
func clearAllForces()
現在のシミュレーションステップ中に物理ボディに作用するすべての連続的な力とトルクをキャンセルします。
var velocity: SCNVector3
現在の速度(メートル/秒)と物理体の運動方向の両方を表すベクトル。
var angularVelocity: SCNVector4
物理体の現在の回転軸と回転速度(ラジアン/秒)の両方を表すベクトル。
var isResting: Bool
物理ボディが静止しているかどうかを示すブール値。
var allowsResting: Bool
SceneKitが静止している物理ボディを自動的にマークできるかどうかを指定するブール値。
func setResting(Bool)
ボディを現在動いているものとして扱うかどうかをSceneKitに指示します。
func resetTransform()
物理シミュレーションでボディの位置と方向を更新して、ボディが接続されているノードの位置と方向に一致させます。
https://developer.apple.com/documentation/scenekit/organizing_a_scene_with_nodes
]
import UIKit import RealityKit class ViewController: UIViewController { @IBOutlet var arView: ARView! override func viewDidLoad() { super.viewDidLoad() // Load the "Box" scene from the "Experience" Reality File let boxAnchor = try! Experience.loadBox() // Add the box anchor to the scene arView.scene.anchors.append(boxAnchor) } }
import UIKit import SceneKit import ARKit class ViewController: UIViewController, ARSCNViewDelegate { @IBOutlet var sceneView: ARSCNView! override func viewDidLoad() { super.viewDidLoad() // Set the view's delegate sceneView.delegate = self // Show statistics such as fps and timing information sceneView.showsStatistics = true // Create a new scene let scene = SCNScene(named: "art.scnassets/ship.scn")! // Set the scene to the view sceneView.scene = scene } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) // Create a session configuration let configuration = ARWorldTrackingConfiguration() // Run the view's session sceneView.session.run(configuration) } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) // Pause the view's session sceneView.session.pause() } // MARK: - ARSCNViewDelegate /* // Override to create and configure nodes for anchors added to the view's session. func renderer(_ renderer: SCNSceneRenderer, nodeFor anchor: ARAnchor) -> SCNNode? { let node = SCNNode() return node } */ func session(_ session: ARSession, didFailWithError error: Error) { // Present an error message to the user } func sessionWasInterrupted(_ session: ARSession) { // Inform the user that the session has been interrupted, for example, by presenting an overlay } func sessionInterruptionEnded(_ session: ARSession) { // Reset tracking and/or remove existing anchors if consistent tracking is required } }