0

Hey i have imported my character animation in xcode and i want to move it with touch in scenekit let suppose from point A to another point B . but it is not moving i have the following code. don,t know why it is not working please help....thanks

//character imported from blender
var scene = SCNScene(named: "art.scnassets/hero.dae")!
// touches for movement 
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
    var taps = event!.allTouches()
    touchCount = taps?.count
}

override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
    touchCount = 0


}

func positionCameraWithHero() {
    let hero = heroNode.presentationNode
    var heroPosition = hero.position
    let cameraDamping:Float = 0.3
    var targetPosition = SCNVector3Make(heroPosition.x, 30.0, heroPosition.z + 20.0)
    var cameraPosition = camera.position
    var cameraXPos = cameraPosition.x * (1.0 - cameraDamping) + targetPosition.x *
cameraDamping
    var cameraYPos = cameraPosition.y * (1.0 - cameraDamping) + targetPosition.y *
cameraDamping
    var cameraZPos = cameraPosition.z * (1.0 - cameraDamping) + targetPosition.z *
cameraDamping
    cameraPosition = SCNVector3(x: cameraXPos, y: cameraYPos, z: cameraZPos)
    camera.position = cameraPosition
    light.position = SCNVector3(x: heroPosition.x, y: 90, z: heroPosition.z +
    40.0)
    light.rotation = SCNVector4(x: 1, y: 0, z: 0, w: Float(-M_PI/2.8))

}

func renderer(aRenderer: SCNSceneRenderer, didSimulatePhysicsAtTime time: NSTimeInterval) {
    let moveDistance = Float(10.0)
    let moveSpeed = NSTimeInterval(1.0)
    let currentX = heroNode.position.x
    let currentY = heroNode.position.y
    let currentZ = heroNode.position.z

    if touchCount == 1{
        let action = SCNAction.moveTo(SCNVector3Make(currentX, currentY, currentZ -
        moveDistance), duration: moveSpeed);
        heroNode.runAction(action)
    }
    else if touchCount == 2 {
        let action = SCNAction.moveTo(SCNVector3Make(currentX, currentY, currentZ +
        moveDistance), duration: moveSpeed)
        heroNode.runAction(action)
    }
Luca D'Alberti
  • 4,749
  • 3
  • 25
  • 45
Sipa
  • 383
  • 1
  • 13

1 Answers1

2

Your code is attempting to create and run a new SCNAction each time a frame is rendered. That's likely not what you want.

Instead, create one SCNAction when the touch is received, with a duration of, say 10 seconds. Run that. That code belongs in touchesBegan() (or maybe touchesEnded()).

You can make your code a bit shorter by using SCNAction.moveBy(_:duration:) or SCNAction.moveByX(_:y:z:duration:) instead of moveTo(). What you're calling moveSpeed is really a time interval, not a speed, and that terminology could be confusing to future maintainers.

I don't see that positionCameraWithHero() is ever called. It should be invoked from renderer(didSimulatePhysicsAtTime:).

Note: in your current implementation, renderer(didSimulatePhysicsAtTime{) will never be invoked. That's because you have no animations running (see SKScene becomes unresponsive while being idle). Also be aware of an apparent bug in the playing property being ignored on OS X (see SceneKit SCNSceneRendererDelegate - renderer function not called). However, once you've corrected the creation of the SCNAction, you won't have this issue.

Community
  • 1
  • 1
Hal Mueller
  • 7,019
  • 2
  • 24
  • 42