אנו מתמחים בפיתוח משחקי תלת-ממד ל-iOS באמצעות הפריימוורק המקורי SceneKit. לקוחות מגיעים אלינו לעתים קרובות עם רעיון מלוטש אך מתקשים לבחור בין Unity, Unreal ו-SceneKit. SceneKit אינו Unity וגם לא Unreal: אין עורך pipeline ויזואלי, אין Asset Store, ופחות פתרונות מוכנים מראש. אבל הוא גם לא Metal גולמי: מנוע פיזיקה, אנימציות, שינויי shader, אינטגרציית AR דרך ARKit — כל זה כלול ב-SDK ללא תלות בצד שלישי. עבור משחקי תלת-ממד בלעדיים ל-iOS ברמת מורכבות בינונית, זו אפשרות מעשית לחלוטין, במיוחד אם הצוות בקיא עמוק ב-Swift/Objective-C.
סצנה, צמתים, עיבוד
יחידת הבסיס היא SCNNode. סצנה היא עץ של צמתים: SCNScene.rootNode שורשי, צמתים יכולים לכלול גאומטריה (SCNGeometry), תאורה (SCNLight), מצלמות (SCNCamera), וגופי פיזיקה (SCNPhysicsBody). ההבדל המרכזי מ-SpriteKit הוא ש-SceneKit פועל במרחב תלת-ממדי עם קואורדינטות SCNVector3, וטרנספורמציות מוגדרות דרך simd_float4x4 (או מאפיינים נוחים כמו position, eulerAngles, simdTransform).
טעינת סצנה מקובץ .scn (ניתן לעריכה ישירות ב-Xcode Scene Editor):
let scene = SCNScene(named: "GameLevel.scn")!
let scnView = SCNView(frame: view.bounds)
scnView.scene = scene
scnView.allowsCameraControl = false
scnView.rendersContinuously = true // важно для анимаций
view.addSubview(scnView)let scene = SCNScene(named: "GameLevel.scn")! let scnView = SCNView(frame: view.bounds) scnView.scene = scene scnView.allowsCameraControl = false scnView.rendersContinuously = true // важно для анимаций view.addSubview(scnView) חיוני — אם לא מוגדר, rendersContinuously = true מצייר רק כשהסצנה משתנה. עבור משחקים עם תנועה מתמדת, יש צורך בעיבוד רציף. החיסרון הוא צריכת סוללה. עבור תפריטים עם שינויים נדירים, השאר אותו כ-SCNView.
פיזיקה והתנגשויות בתלת-ממד
false מגיע בשלושה סוגים: SCNPhysicsBody (אובייקטים בלתי ניתנים להזזה, collider לא זז), .static (מונע על ידי פיזיקה), .dynamic (מוזז על ידי קוד, מתעלם מכוחות אך משתתף בהתנגשויות). דמות השחקן היא בדרך כלל .kinematic — אנו מזיזים אותה דרך קוד, אך קירות ורצפה עוצרים אותה.
צורת ה-collider משפיעה על הביצועים יותר מאשר בתלת-ממד. השתמש בקפסולה עבור הדמות, לא בגאומטריה מורכבת:
let capsule = SCNCapsule(capRadius: 0.3, height: 1.8)
let physicsShape = SCNPhysicsShape(geometry: capsule, options: nil)
player.physicsBody = SCNPhysicsBody(type: .kinematic, shape: physicsShape)התנגשויות מטופלות דרך kinematic. הגדר let capsule = SCNCapsule(capRadius: 0.3, height: 1.8) let physicsShape = SCNPhysicsShape(geometry: capsule, options: nil) player.physicsBody = SCNPhysicsBody(type: .kinematic, shape: physicsShape) , SCNPhysicsContactDelegate, categoryBitMask — רק עבור זוגות נדרשים כדי לא להעמיס על collisionBitMask.
אנימציות: CAAnimation ו-SCNAnimationPlayer
אנימציית שלד מיובאת מ-contactTestBitMask (Collada). מעברים בין עמידה, ריצה, קפיצה נעשים עם didBegin לחלקות:
func transition(to key: String, blendDuration: CGFloat = 0.3) {
let player = characterNode.animationPlayer(forKey: key)!
player.blendInDuration = blendDuration
player.play()
currentAnimationKey.flatMap {
characterNode.animationPlayer(forKey: $0)?.stop(blendOutDuration: blendDuration)
}
currentAnimationKey = key
}ללא .dae, הדמות "קופצת" בין תנוחות — זה הדבר הראשון ששחקן מבחין בו.
Shaders ואפקטים פוסט-עיבוד
SceneKit מאפשר הצמדת shaders של GLSL/Metal דרך blendInDuration. מקרה שימוש טיפוסי הוא התמוססות אובייקט במוות:
let dissolveShader = """
#pragma transparent
#pragma body
float threshold = u_dissolveAmount;
float noise = ... // шум по координатам
if (noise < threshold) discard_fragment();
_output.color.a = smoothstep(threshold - 0.05, threshold, noise);
"""
material.shaderModifiers = [.fragment: dissolveShader]func transition(to key: String, blendDuration: CGFloat = 0.3) { let player = characterNode.animationPlayer(forKey: key)! player.blendInDuration = blendDuration player.play() currentAnimationKey.flatMap { characterNode.animationPlayer(forKey: $0)?.stop(blendOutDuration: blendDuration) } currentAnimationKey = key } משמש לעיבוד פוסט-מסך מלא (bloom, outline, depth of field). מוגדר דרך מילון plist.
אינטגרציית ARKit
SceneKit הוא ה-renderer הראשון והעיקרי עבור ARKit:
let arView = ARSCNView(frame: view.bounds)
let config = ARWorldTrackingConfiguration()
config.planeDetection = [.horizontal, .vertical]
arView.session.run(config)blendInDuration מסנכרן אוטומטית את SCNMaterial.shaderModifiers עם מרחב הקואורדינטות של AR. זהו הבסיס למשחקי AR — שוק let dissolveShader = """ #pragma transparent #pragma body float threshold = u_dissolveAmount; float noise = ... // шум по координатам if (noise < threshold) discard_fragment(); _output.color.a = smoothstep(threshold - 0.05, threshold, noise); """ material.shaderModifiers = [.fragment: dissolveShader] מכוסה היטב על ידי הדוגמאות של אפל.
כיצד לייעל את ביצועי SceneKit?
SCNTechnique משתמש ב-Metal כברירת מחדל ב-iOS 9+. מספר כללים שמשפיעים בפועל על FPS.
Batching: SceneKit ממזג אוטומטית קריאות ציור עבור צמתים עם אותו חומר. לכן, 1000 עצים עם חומר אחד זולים בהרבה מ-100 עצים עם 100 חומרים שונים. השתמש במופעי let arView = ARSCNView(frame: view.bounds) let config = ARWorldTrackingConfiguration() config.planeDetection = [.horizontal, .vertical] arView.session.run(config) , אל תיצור אובייקט חומר חדש עבור כל צומת.
רמת פירוט דרך ARSCNView: עבור אובייקטים במרחק של יותר מ-20 מטרים, ניתן להציג גאומטריה מפושטת. זה מפחית את העומס על ה-GPU.
חיתוך הסתרה: SceneKit מבצע חיתוך frustum אוטומטית, אך חיתוך הסתרה (הסתרת אובייקטים מאחורי אחרים) אינו אוטומטי. עבור סצנות מורכבות, יש לעשות זאת ידנית דרך SCNScene בהתבסס על תוצאות ray cast או לוגיקת רמה.
כלי פרופילינג: Xcode → Metal System Trace + Render Graph. מטרה: לא יותר מ-30–50 קריאות ציור עבור 60 fps יציבים ב-iPhone X.
מתי להימנע מ-SceneKit?
ריבוי פלטפורמות (iOS + Android + PC) — השתמש ב-Unity או Godot. פיזיקת soft-body מורכבת — Unity עם Havok. עולמות פתוחים מסיביים — שוב Unity/Unreal. SceneKit הוא הטוב ביותר עבור כותרים בלעדיים ל-iOS עם מורכבות תלת-ממדית בינונית, יישומי AR, ומשחקים שבהם אינטגרציה מקורית (Game Center, CloudKit) חשובה.
תהליך העבודה שלנו
- בדיקת דרישות: סוג משחק, צורך ב-AR, מכשירי יעד, גרסת iOS מינימלית, נכסים.
- אב טיפוס משחקיות: תנועה, פיזיקה, מצלמה בסיסית — 1–2 שבועות.
- משחקיות ליבה: רמות, אויבים/מכשולים, ממשק משתמש (SwiftUI מעל
ARKit + SceneKit). - אודיו:
SCNViewעבור סאונד תלת-ממדי. - אינטגרציה של Game Center, IAP, ARKit.
- ליטוש ביצועים, בדיקות על מכשירים חלשים.
מה כלול בעבודה שלנו
- קוד מקור עם הערות
- תיעוד ארכיטקטורה ובנייה
- בניית בדיקה דרך TestFlight
- פרסום ב-App Store (חשבון מפתח מסופק על ידי הלקוח)
- תמיכה באחריות ל-30 יום לאחר השחרור
הערכות לוחות זמנים
| סוג פרויקט | משך זמן |
|---|---|
| אב טיפוס / הוכחת היתכנות | 2–3 שבועות |
| משחק תלת-ממד קז'ואל ללא AR | 1.5–2 חודשים |
| משחק תלת-ממד עם AR + Game Center | 2–3 חודשים |
| פרויקט מורכב (עולם פתוח, מרובה משתתפים) | נדון בנפרד |
העלות מחושבת בנפרד לאחר ניתוח הדרישות הטכניות וזמינות הנכסים המוכנים.
הניסיון שלנו: סיפקנו למעלה מ-10 פרויקטי תלת-ממד על SceneKit, כולל יישומי AR בעלי ביצועים גבוהים. כל הפרויקטים עברו את בדיקות ה-App Store ללא דחיות.
צור קשר — נבחן את הפרויקט שלך תוך יום עסקים אחד. פיתוח מלא מאפס ועד פרסום. תיעוד Apple SceneKit.







