Adding custom game logic to Scene Kit (Swift)
When you assign:
gameView.delegate = self
This requires that self
be a class that declares conformance to the SCNSceneRendererDelegate
protocol. To make your view controller class declare protocol conformance, use the syntax described in the Swift book:
class ViewController: UIViewController, SCNSceneRendererDelegate {
// ~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~ ^
// ^- superclass ^- protocol |
// more protocols if you conform to them --/
// ... rest of class definition ...
}
How to create game menu ui (i.e. buttons, scroll views) with Scene Kit?
Depending on your requirements for a title screen, pause and even HUD elements, UIKit could work. I would not recommend UIKit if you need any fancy stuff like shaders, particle effects or a lot of heavy animations. In that case I would go with Sprite Kit as suggested by David Rönnqvist.
But if your needs are menu screens, simple HUD elements, dialogs etc. there are no problems too use UIKit with any needed custom views, and just treat the SCNView like any other UIKit view. The up side is of course that UIKit does a great job for common UI tasks and user interaction, and is very easy and simple to use. Sprite Kit can some times feel a bit heavy for UI in my opinion.
SCNCamera made programmatically not in the correct position
After a while, I discovered that you can actually add empty nodes directly within the Scene Builder. I originally only wanted a programmatic answer, as I wanted to make a camera orbit node like the questions I linked to. Now I can add an empty node, I can make the child of the orbit the camera.
This requires no code, unless you want to access the nodes (e.g. changing position or rotation):
gameCameraNode = gameView.pointOfView // Use camera object from scene
gameCameraOrbitNode = gameCameraNode.parent // Use camera orbit object from scene
Here are the steps to create an orbit node:
1) Drag it in from the Objects Library
:
2) Setup up your Scene Graph
like so:
SceneKit game architecture
I will explain a real game design that I am actually working on and was based on the design of the sample codes provided by Apple for SceneKit.
As @HalMuelller correctly points out, you need to extract the game logic into a platform independent layer, and that is a good idea even if you are writing the game for one platform as that will help you in testing.
As you can see in the class diagram above:
On the right side is the entire game logic starting with a Game
class which actually works as the scene and physics delegate. This is just a plain old ObjC or Swift class.
One of the main responsibility of the Game
class is to build scenes SCNScene
either from files supported by SceneKit/Model IO or programmatically as your case may be.
The Game
class also refers to other Model
classes such as Animation
which loads 3D skeletal animations and Player
class which contains the player data such as his statistics, the Player
in here refers to some player like a baseball player in the game.
You can also see that there is a PlayerEntity
class which is made up of BatterComponent
, this is based off the Entity-Component design from GamePlayKit
. Now the BatterComponent
has a StateMachine
which handles the batter's transitions between various states.
The other important component is BatterControlComponent
which you add to the entity only when the user is batting. This is also a platform dependent component, so you can write this independently in your macOs/iOS targets. Again the batter control component is backed by a state machine as State machine can also be used for handling controls transitions. This control is implemented as a SpriteKit
scene as an overlay on top of the SCNScene
.
If you are pitching, then you configure the player entity with the PitcherComponent
backed by another state machine and so on.
On the left side of the class diagram, you can see sits a GameViewController
which sets up an SCNView
and also instantiates a Game
object and this game object's scene is what your game view controllers scene view renders. You also ensure that you set the scene view delegate to be the game object.
You must seriously refer to the Apple sample codes for SceneKit and the samples for GameKit. In Apple developer, Sample Code section search for: SceneKit
and GameplayKit
.
Overall you must design a platform independent game logic layer using plain old Swift/ObjC classes and the appropriate patterns from GamePlayKit
based on your game requirements.
A note on production usage. See this memory leak issue and animation issues, so I am not really sure if SceneKit is yet ready for prime time, but Google is your friend. Having said that, SceneKit is really great if you are already working on Apple platform so the turn around time vis a vis learning a new game engine is lesser if you have not used any game engine and are writing games as a hobby or to learn game programming. I believe that SceneKit has been improving every year and in the next 2 releases (WWDC 17, 18) it should be a really polished game engine for Apple platforms. These are my 2$ based on my experience, YMMV.
how to make vehicle or train move across the scene in iOS Sprite Kit Game with swift
You can add the wheels and all pieces of the train as children of a main SKNode
which represents the whole train. You can move that across the screen and simply handle rotation on the wheels.
let train = SKNode() // add move actions to this
let wheel = SKSPriteNode(imageNamed: "wheel") // add rotation actions to this
train.addChild(wheel)
Related Topics
How to Add Interactive Uilabels on Top of a Uiimageview
How to Calculate a Random Cgpoint Which Does Not Touch a Uiview
How to Use Multiple Protocols in Swift with Same Protocol Variables
Converting an Existing Project into Customizable Framework
Traverse View Controller Hierarchy in Swift
Cannot Convert Value of Type 'String.Type' to Expected Argument Type 'String!'
How to Change the Nstimeinterval of an Nstimer After X Seconds
How to Share Published Model Between Two View Models in Swiftui
Playing an Audio File Repeatedly with Avaudioengine
Share Attachment from Mail App with Share Extension in iOS
Audiokit - How to Get Real Time Floatchanneldata from Microphone
What Are the First Two Columns in Scnmatrix4
Swift - Parse a String Which Contains a Url
iOS Swift. How to Get a Gps Metadata from Just a Uiimage (Nsurl)
Didbegincontact Passed Pkphyicsobject
Swift Get Specific Value from Firebase Database
What am I Doing Wrong with Allowsfractionalunits on Nsdatecomponentsformatter