2017-06-30 46 views
1

我想規模和SCNNode使用實時的移動手勢縮放在運行時SCNNode:使用移動手勢

這是我當前的代碼

let pinchGestureRecognizer = UIPinchGestureRecognizer(target: self, action: #selector(handlePinch(from:))) 
sceneView.addGestureRecognizer(pinchGestureRecognizer) 

@objc 
func handlePinch(from recognizer: UIPinchGestureRecognizer){ 
    var pinchScale = recognizer.scale 
    pinchScale = round(pinchScale * 1000)/1000.0 

    sceneView.scene.rootNode.enumerateChildNodes { (node, stop) -> Void in 
    if(node.name == "Box01"){ 
     node.scale = SCNVector3(x: pinchScale, y: pinchScale, z: pinchScale) 
    } 
    }   
} 

然而,節點不結垢大或小?有人可以指出我的錯誤嗎?

的SCNNode被加載,並已申請像這樣的動畫,

sceneView.scene.rootNode.addChildNode(node) 
loadAnimation(animation: .Attack, sceneName: "art.scnassets/attack", animationIdentifier: "attackID"); 
+0

工作節點實際上名爲 'Box01的'?考慮在你的根節點上使用'childNode(withName:recursively:)'方法,這應該使這個更清晰。 – orangenkopf

+0

我很喜歡scenekit,而且很可怕。我會閱讀你提到的方法的文檔。但是,我仍然無法用它來擴展它的權利? –

回答

1

我用這個來處理規模:

@objc 
func handlePinch(from recognizer: UIPinchGestureRecognizer){ 
    var pinchScale = round(recognizer.scale * 1000)/1000000 
    let node_arm = sceneView.scene.rootNode.childNode(withName: "army", recursively: true) 
    node_arm?.runAction(.customAction(duration: 0, action: { node, progress in 
     node.physicsBody = nil 
     node.scale = SCNVector3(x: Float(pinchScale), y: Float(pinchScale), z: Float(pinchScale)) 
    })) 
} 
+0

這是否給你合理的東西?當我使用它時,物品剛開始變得非常小,然後我必須不斷捏它以使其變大。 –

+0

@AlanS你就是我所得到的。但這對我有效。如果你必須保持這個狀態,我恐怕沒有解決辦法。如果你找到一個我會很樂意接受一個答案:) –

+0

是的,我確實發現了一些工作得很好,我會發佈一個答案,但我很抱歉,我在Objective-C工作。 –

1

我發現這非常有效。我也使用兩個觸摸來嘗試和檢測我是否捏在一個物體上,所以你可以用任何一個手指抓住SCNNode。

請注意,復位規模的行是必要的,否則它的行爲真的很奇怪。我不能特別說明爲什麼這是事實。

-(void)scaleObject:(UIPinchGestureRecognizer *)recognizer { 
    if (recognizer.state == UIGestureRecognizerStateBegan) { 

     CGPoint tapPoint = [recognizer locationOfTouch:1 inView:_sceneView]; //Get tap location on the screen from the 2nd touch 
     NSArray <SCNHitTestResult *> *result = [self.sceneView hitTest:tapPoint options:nil]; //Get result array, checks on if we hit a SceneNode or not 

     if ([result count] == 0) { //If the first touch doesn't grap the SceneNode, try the second touch 
      tapPoint = [recognizer locationOfTouch:0 inView:_sceneView]; 
      result = [self.sceneView hitTest:tapPoint options:nil]; // Get the results 
      if ([result count] == 0) { 
       return; //No objects found, return 
      } 
     } 

     SCNHitTestResult *hitResult = [result firstObject]; //Get the first hitResult 
     scaledObject = [[hitResult node] parentNode]; 
     if (scaledObject) { 
      [NotificationView showNotificationWithText:@"Object has been selected for pinch"]; 
     } 
    } 
    if (recognizer.state == UIGestureRecognizerStateChanged) { //When pinch status is changing 
     if (scaledObject) { //If we have an object grabbed 
      CGFloat pinchScaleX = recognizer.scale * scaledObject.scale.x; 
      CGFloat pinchScaleY = recognizer.scale * scaledObject.scale.y; 
      CGFloat pinchScaleZ = recognizer.scale * scaledObject.scale.z; 
      [scaledObject setScale:SCNVector3Make(pinchScaleX, pinchScaleY, pinchScaleZ)]; 
     } 
     recognizer.scale = 1; //Reset the scale, skipping this line causes really weird behavior 
    } 
    if (recognizer.state == UIGestureRecognizerStateEnded) { 
     NSLog(@"Done pinching"); 
     scaledObject = nil; //Make sure that no object is set to scaledObject 
    } 
} 

希望這有助於

3

得到它在迅速

@objc func handlePinch(gesture: UIPinchGestureRecognizer){ 
    if(scnnodeSelected){ 

     if (gesture.state == .changed) { 
      let pinchScaleX = Float(gesture.scale) * tappedObjectNode.scale.x 
      let pinchScaleY = Float(gesture.scale) * tappedObjectNode.scale.y 
      let pinchScaleZ = Float(gesture.scale) * tappedObjectNode.scale.z 
      tappedObjectNode.scale = SCNVector3(pinchScaleX, pinchScaleY, pinchScaleZ) 
      gesture.scale=1 
     } 
    } 
}