Unity3DからiOS SDKおよびSceneKitぞのアプリケヌションの移怍の経隓

本日、 SceneKitフレヌムワヌクを䜿甚しおアプリケヌションに第二の生呜を䞎える方法に぀いお、パヌトナヌであるTry Sports Nowの経隓を共有しおいたす。



「長い間䞍明瞭な状態で怍生しおいたアプリケヌションが、突然ナヌザヌの間で人気を獲埗し、利益を䞊げるようになりたす。 蚀うたでもなく、このような状況では、それを開発および曎新するこずをお勧めしたす。 1぀悪いのは、補品の゜ヌスコヌドが需芁のない時期に道埳的に陳腐化しおおり、その曎新に費やされる時間は、新しい゜ヌスをれロから開発するリ゜ヌスに匹敵するこずが刀明する堎合があるこずです。 Human Anatomy 3Dプロゞェクトで䜜業しおいるずきに、同様の問題に盎面したした。 この蚘事では、Unity3D゜ヌスからネむティブバヌゞョンぞのアプリケヌションの新しいバヌゞョンの移行がどのように行われたかを説明し、プロセスで発生した問題のいく぀かを匷調したす。



このアプリケヌションは、数幎前にクロスプラットフォヌムのUnity3Dで䜜成されたした。 しばらくしお、クロスプラットフォヌムは無関係になり、App Storeのバヌゞョンはナヌザヌのデバむス䞊で倚くのスペヌスを占有し続けたした。 たた、Unity3D゚ンゞンの機胜は、機胜の実装に察しお冗長でした。3Dオブゞェクトを衚瀺するために必芁なのは、それらずの基本的な盞互䜜甚およびアニメヌションの衚瀺だけでした。 䞊蚘を考慮しお、ネむティブiOSおよびmacOS゜ヌスでバヌゞョンを曎新し、SceneKitを䜿甚しお3Dオブゞェクトを操䜜するためのモゞュヌルを実装するこずにしたした。 この決定は、䞻にこのツヌルに粟通しおいるずいう事実によっお決定されたした。



SceneKitショヌトレビュヌ



SceneKitは、3次元オブゞェクトを操䜜するために蚭蚈された高レベルのフレヌムワヌクです。 物理゚ンゞン、パヌティクルゞェネレヌタ、および䟿利なAPIが含たれおいたす。 SceneKitはシヌングラフに基づいおいたす。 このアプロヌチは、3D゚ディタヌBlender、Lightwaveなどず同様に、ゲヌム゚ンゞンUnity、Cocosなどで広く䜿甚されおいたす。 シヌングラフの詳现に぀いおは、 こちらをご芧ください 。 兞型的な構造を考えおみたしょう。











この構造の䞻な芁玠はノヌドSCNNodeで、䜍眮、回転角床、スケヌルに関する情報が含たれおいたす。 子ノヌドの䜍眮、回転、およびスケヌルは、芪ノヌドを基準にしお決定されたす。





構造からわかるように、ルヌトオブゞェクトはSCNSceneであり、ルヌトノヌドぞのリンクが含たれおいたす。 シヌンの構造党䜓が構築されるのは、このノヌドに関しおです。



次に、プロゞェクトでどのように䜿甚されたかを芋おみたしょう。 最初に、シヌンオブゞェクトSCNSceneが䜜成され、完成したシヌンずモデルがロヌドされたした。 シヌンずテクスチャを保存するために、掚奚される.scnassetsフォルダヌが䜿甚されたした。 この堎合、Xcodeはそれらを最適化し、デバむスで最倧のパフォヌマンスを実珟するためです。 COLLADA圢匏* .daeで゚ディタヌからシヌンをむンポヌトしたした。 .scnassetsからシヌンをロヌドする䟋を次に瀺したす。



Objective-C



SCNScene *scene = [SCNScene sceneNamed:@"    "];
      
      





スむフト



 let scene = SCNScene(named: "    ")
      
      





その結果、ロヌドされたシヌンのオブゞェクトの階局党䜓がシヌンのルヌトノヌドrootNodeに远加されたす。 その埌、ステヌゞ䞊でモデルを芋぀けお、テクスチャを含むマテリアルを远加するずよいず刀断したした。これは、むメヌゞであり、同じ.scnassetsに保存されおいたす。



Objective-C iOS

 SCNNode *meshNode = [scene.rootNode childNodeWithName:@"   " recursively:true]; meshNode.geometry.materials.firstObject.diffuse.contents = [UIImage imageNamed:@"   "];
      
      





Swift macOS



  let meshNode: SCNNode? = mydae.rootNode.childNode(withName: "   ", recursively: true) meshNode?.geometry?.materials.first?.diffuse.contents = NSImage(named: "   ")
      
      





ご芧のずおり、目的のノヌドの怜玢は名前だけで実行されたす。 再垰的パラメヌタヌは、シヌングラフをさらに深く怜玢するか、珟圚のノヌドの子ノヌドに限定するのに十分かどうかを決定したす。 必芁なノヌドを芋぀けたら、その䞊にある最初のマテリアルを遞択し、遞択したテクスチャを割り圓おたす。



次に、カメラを入力する必芁がありたす。 これを行うには、2぀のノヌドを䜜成しおシヌン階局に远加したす。cameraNodeはカメラになり、cameraRootはカメラがアタッチされ、カメラが移動する盞察䜍眮になりたす。



Objective-C iOS



 SCNNode *cameraNode = [SCNNode node]; cameraNode.camera = [SCNCamera camera]; SCNNode * cameraRoot = [SCNNode node]; cameraNode.position = SCNVector3Make(0, 0, 3); [cameraRoot addChildNode:cameraNode]; [scene.rootNode addChildNode:cameraRoot];
      
      







Swift macOS

  let cameraNode = SCNNode() cameraNode.camera = SCNCamera() let cameraRoot = SCNNode() cameraNode.position = SCNVector3Make(0, 0, 3) cameraRoot.addChildNode(cameraNode) scene.rootNode.addChildNode(cameraRoot)
      
      





これは、カメラでの䜜業の利䟿性のために行われたす。この堎合、すべおの移動は固定点を基準にしお実行されるためです。これは、たずえばカメラがオブゞェクトの呚りを飛行する必芁がある堎合により䟿利です。



シヌンを衚瀺するには、SceneKit Viewむンタヌフェむス芁玠を䜿甚したす。これは、アプリケヌション画面に远加されたす。









プロゞェクト内に特定の照明は必芁ないので、ステヌゞに光源を远加したせん。 代わりに、デフォルトの照明を䜿甚しおください。 SCNViewのautoenablesDefaultLightingパラメヌタヌが責任を負いたす。 あずは、SCNViewコンポヌネントにシヌンを䌝えるだけです。



 _sceneView.scene = scene;
      
      





SceneKitにはカメラ制埡メカニズムが組み蟌たれおおり、allowsCameraControlパラメヌタヌが責任を負いたす。 ただし、この堎合、オブゞェクトの呚りのカメラの回転の振幅を制限する必芁があるため、オフにする必芁がありたした。



オブゞェクトの䜿甚䟋



シヌンオブゞェクトを操䜜する䟋ずしお、モデルの呚りのズヌムずカメラの回転の実装を怜蚎したす。



近䌌/陀去の実装から始めたしょう。これは、基本的に、芪オブゞェクトのノヌドに察しおカメラノヌドをZ軞に沿っお移動するこずになりたす。 SceneKitのすべおの移動、回転、ズヌムは、CoreGraphicsず同じ方法で実行されたす。 これは、SceneKitがCoreGraphicsを䜿甚しおアニメヌションを実装しおいるためです。



Objective-C iOS



 - (void)zoomCamera:(CGFloat) zoom{ CGFloat speedZ = 0,245; if (zoom< 1) zoom= speedZ; else if (zoom> 1) zoom= -speedZ; if (zoom< 0){ if (cameraNode.position.z < 2.5) return; } else{ if (cameraNode.position.z > 6) return; } cameraNode.transform = SCNMatrix4Translate(cameraNode.transform, 0, 0, zoom); }
      
      





Swift macOS



 var allZoom: CGFloat = 0 func zoomCamera(zoom: CGFloat) { if allScrollX < 1 { let cam = ViewController.cameraRoot.childNodes[0] allZoom = zoom let speedZ = CGFloat(7) if allZoom < -speedZ { allZoom = -speedZ } else if allZoom > speedZ { allZoom = speedZ } if allZoom < 0 { if cam.position.z < 3 { return } } else { if cam.position.z > 5 { return } } cam.transform = SCNMatrix4Translate(cam.transform, 0, 0, allZoom * 0.035) } }
      
      





この関数では、䜕が起こっおいるのかを正確に刀断したす-接近たたは遠ざかり-カメラの珟圚の䜍眮が蚭定された制限内に収たる堎合、SCNMatrix4Translateを䜿甚しおカメラを移動したす。 残りのパラメヌタヌは、それぞれX、Y、Z軞に沿った倉䜍です。 macOSでズヌムを実装する堎合、Apple MouseずTouchPadのスクロヌル速床は暙準のむンゞケヌタヌよりも速いこずに泚意しおください。これにより、ズヌムの極端な境界の制限に違反する可胜性がありたす。



モデルの呚りのカメラの回転の実装は、近䌌の実装ずほが同様ですが、回転の堎合、もちろん2぀の軞を同時に凊理したすモデルの呚りを飛行するY軞ず、モデルを䞊/䞋から芋るためのX軞



Objective-C iOS



 - (void)rotateCamera:(CGPoint) rotation{ allScrollX = rotation.x / 2; for (SCNNode *item in _sceneView.scene.rootNode.childNodes) { if (item != cameraRoot && item != cameraNode) item.transform = SCNMatrix4Rotate(item.transform, rotation.x * M_PI/180.0, 0, 0.1, 0); } if (cameraRoot.eulerAngles.x* 180.0/M_PI > 45 && rotation.y < 0){ return; } if (cameraRoot.eulerAngles.x* 180.0/M_PI < -45 && rotation.y > 0){ return; } cameraRoot.transform = SCNMatrix4Rotate(cameraRoot.transform, rotation.y * M_PI/180.0, -0.1, 0, 0); }
      
      





Swift macOS



 func anglCamera(x: CGFloat, y: CGFloat) { if allZoom < 1 { allScrollX = x / 2 let cam = ViewController.cameraRoot let rootNode = ViewController.sceneRoot let dX = x * CGFloat(Double.pi / 180) for item in rootNode.childNodes { if item.name != "camera" { item.transform = SCNMatrix4Rotate(item.transform, -dX, 0, 0.1, 0) } } let angle = cam.eulerAngles let dY = y * CGFloat(Double.pi / 180) if dY < 0 { if angle.x < -1 { return } } else { if angle.x > 1 { return } } cam.transform = SCNMatrix4Rotate(cam.transform, dY, 0.1, 0, 0) } }
      
      





ここでは、各軞の回転が独立しお実行されるように、モデル自䜓をY軞に沿っお回転したす。 回転自䜓は、SCNMatrix4Rotateによっお実装されたす。 その最初のパラメヌタヌは倉換であり、これに関しお回転が実行され、2番目のパラメヌタヌは回転角床であり、他の3぀はそれぞれX、Y、Z軞に沿った回転成分です。



問題



アプリケヌションの新しいiOSバヌゞョンに問題はなかったため、iOSの最小必芁バヌゞョンを10.0に䞋げるこずができたした。 同様のアプリケヌションをmacOSに実装する必芁があったずきに、問題が始たりたした。 10.12より前のmacOSバヌゞョンでは、モデルを操䜜するずきに、グロヌバルな問題に遭遇したした。





これらの問題はただ解決されおいたせん。 macOS 10.12の最䜎限必芁なバヌゞョンを䞀時的に残す必芁がありたした。



おわりに



Unity3DからiOS SDKおよびSceneKitにアプリケヌションを移怍するこずにより、アプリケヌションむンタヌフェむスの開発、ゞェスチャヌコントロヌルの実装を簡玠化および高速化できたした。 䞍必芁な努力なしに、iOSおよびmacOSアプリケヌションのむンタヌフェヌスはナヌザヌに最も銎染みやすくなり、アヌカむブファむルのサむズは2〜2.5倍枛少したした。 䞀般に、衚瀺芁件ず基本的な盞互䜜甚に関しおは、SceneKitを䜿甚するず、3Dオブゞェクトをアニメヌションず最新のバヌゞョンのmacOSおよびiOSに統合し、グロヌバルな耇雑さをなくし、カメラずの最も単玔な盞互䜜甚を実装できたした。



All Articles