I'm attempting to translate touches from SpriteKit to SceneKit and having a bit of difficulty. My intention is to move a 3D "monster" so that it appears as though its in the same location (though behind) a 2D crystal. 2D crystals are added to the SpriteKit-provided overlaySKScene
and positioned. Our "monster" is a full 3D SCNNode
sitting in a SCNScene
, as shown below.
I've tried a variety of approaches, the closest of which I've included below in the makeMonsterEatCrystalAtLocation
method, though I know it to be wrong, as it only acts within the SpriteKit world - it doesn't convert from SpriteKit to SceneKit. I've also looked into unprojectPoint
in the SCNSceneRenderer
protocol, but that method only works from within SceneKit itself. Any assistance would be greatly appreciated! I'm not partial to Objective-C or Swift, even though the below is in Obj-C.
- (void)setupSceneKit {
_sceneView = [[SCNView alloc] initWithFrame:[[UIScreen mainScreen] bounds] options:@{@"SCNPreferredRenderingAPIKey": @(SCNRenderingAPIOpenGLES2)}];
[self.view insertSubview:_sceneView aboveSubview:backgroundView];
_sceneView.scene = [SCNScene scene];
_sceneView.allowsCameraControl = YES;
_sceneView.autoenablesDefaultLighting = NO;
_sceneView.backgroundColor = [UIColor clearColor];
camera = [SCNCamera camera];
[camera setXFov:20];
[camera setYFov:20];
camera.zFar = 10000.0f;
cameraNode = [SCNNode node];
cameraNode.camera = camera;
cameraNode.position = SCNVector3Make(0, 3, 700);
[_sceneView.scene.rootNode addChildNode:cameraNode];
}
- (void)createMonster {
_monsterNode = [SCNNode node];
[self.sceneView.scene.rootNode addChildNode:_monsterNode];
[SCNTransaction begin];
[SCNTransaction setAnimationDuration:0.5f];
_monsterNode.position = SCNVector3Zero;
[SCNTransaction commit];
}
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
CGPoint crystalLocation = [[touches anyObject] locationInNode:self.sceneView.overlaySKScene];
SKNode *touchedCrystalNode = [self.sceneView.overlaySKScene nodeAtPoint:crystalLocation];
// determine that this is the SKNode touchedCrystalNode we're looking for...
[self makeMonsterEatCrystalAtLocation:crystalLocation];
}
- (void)makeMonsterEatCrystalAtLocation:(CGPoint)location {
// Attempt to move the "monster" (SCNNode in SceneKit) to appear as if its in the same
// location as the "crystal" (which is presented in the SpriteKit overlay: self.sceneView.overlaySKScene) and eventually
// play an animation of the monster eating the crystal.
CGPoint scnPoint = [self.sceneView.overlaySKScene convertPointToView:location];
[SCNTransaction begin];
[SCNTransaction setAnimationDuration:0.5f];
self.monsterNode.position = SCNVector3Make(scnPoint.x, scnPoint.y, 0);
[SCNTransaction commit];
// ...
}