只能移动放置在场景中的最后一个对象
Can move only the last object placed in Scene
喂!我只能移动放置在场景中的最后一个虚拟对象。当我添加另一个对象时,之前添加的对象保持静态,我无法对其执行任何操作。你能给我一个解决方案来移动、缩放、旋转我想要的对象吗?
鉴于您还没有发布任何代码,因此很难提供准确的答案。
但是,为了跟踪您希望使用的当前 SCNNode
,当您加载模型等时,您可以将其存储为变量,例如:
var currentNode: SCNNode!
您还可以在加载模型时使用节点的 name
属性 以保持对它的更具体引用。
这是一个这样做的例子:
/// Example Of Loading An SCNScene & Setting It As The Current Node
func loadModel(){
let modelPath = "Character.scn"
//1. Get The Reference To Our SCNScene & Get The Model Root Node
guard let model = SCNScene(named: modelPath),
let modelObject = model.rootNode.childNode(withName: "Root", recursively: false) else { return }
//2. Scale It
modelObject.scale = SCNVector3(0.4, 0.4, 0.4)
//3. Add It To The Scene & Position It 1.5m Away From The Camera
augmentedRealityView.scene.rootNode.addChildNode(modelObject)
modelObject.position = SCNVector3(0, 0, -1.5)
//4. Set It As The Current Node & Assign A Name
currentNode = modelObject
currentNode.name = "Character"
}
您还可以使用 SCNHitTest
其中:
Looks for SCNGeometry objects along the ray you specify. For each
intersection between the ray and and a geometry, SceneKit creates a
hit-test result to provide information about both the SCNNode object
containing the geometry and the location of the intersection on the
geometry’s surface.
这可用于区分哪些节点被击中,例如:
/// Detects A Tap On An SCNNode
///
/// - Parameter gesture: UITapGestureRecognizer
@objc func detectTap(_ gesture: UITapGestureRecognizer){
//1. Get The Current Touch Point
let currentTouchPoint = gesture.location(in: self.augmentedRealityView)
//2a. Perform An SCNHitTest To Detect If An SCNNode Has Been Touched
guard let nodeHitTest = self.augmentedRealityView.hitTest(currentTouchPoint, options: nil).first else { return }
if nodeHitTest.node == currentNode{
print("The Current Node Has Been Touched")
}
//Or To See Which Node Has Been Touched
if nodeHitTest.node.name == "The Model"{
print("The Model Has Been Touched")
}
}
另一种处理此问题的方法是将 UITapGestureRecognizer 添加到视图中,并根据结果启用交互,例如以这种方式设置 currentNode 例如:
/// Detects A Tap On An SCNNode & Sets It As The Current Node
///
/// - Parameter gesture: UITapGestureRecognizer
@objc func detectTap(_ gesture: UITapGestureRecognizer){
//1. Get The Current Touch Point
let currentTouchPoint = gesture.location(in: self.augmentedRealityView)
//2a. Perform An SCNHitTest To Detect If An SCNNode Has Been Touched
guard let nodeHitTest = self.augmentedRealityView.hitTest(currentTouchPoint, options: nil).first else { return }
//2b. Set It As The Current Node
currentNode = nodeHitTest.node
}
然后您可以应用逻辑来确保只有 currentNode
移动等:
/// Moves An SCNNode
///
/// - Parameter gesture: UIPanGestureRecognizer
@objc func moveNode(_ gesture: UIPanGestureRecognizer) {
//1. Get The Current Touch Point
let currentTouchPoint = gesture.location(in: self.augmentedRealityView)
//2. If The Gesture State Has Begun Perform A Hit Test To Get The SCNNode At The Touch Location
if gesture.state == .began{
//2a. Perform An SCNHitTest To Detect If An SCNNode Has Been Touched
guard let nodeHitTest = self.augmentedRealityView.hitTest(currentTouchPoint, options: nil).first else { return }
//2b. Get The SCNNode Result
if nodeHitTest.node == currentNode{
//3a. If The Gesture State Has Changed Then Perform An ARSCNHitTest To Detect Any Existing Planes
if gesture.state == .changed{
//3b. Get The Next Feature Point Etc
guard let hitTest = self.augmentedRealityView.hitTest(currentTouchPoint, types: .existingPlane).first else { return }
//3c. Convert To World Coordinates
let worldTransform = hitTest.worldTransform
//3d. Set The New Position
let newPosition = SCNVector3(worldTransform.columns.3.x, worldTransform.columns.3.y, worldTransform.columns.3.z)
//3e. Apply To The Node
currentNode.simdPosition = float3(newPosition.x, newPosition.y, newPosition.z)
}
}
}
}
这应该足以为您指明正确的方向...
喂!我只能移动放置在场景中的最后一个虚拟对象。当我添加另一个对象时,之前添加的对象保持静态,我无法对其执行任何操作。你能给我一个解决方案来移动、缩放、旋转我想要的对象吗?
鉴于您还没有发布任何代码,因此很难提供准确的答案。
但是,为了跟踪您希望使用的当前 SCNNode
,当您加载模型等时,您可以将其存储为变量,例如:
var currentNode: SCNNode!
您还可以在加载模型时使用节点的 name
属性 以保持对它的更具体引用。
这是一个这样做的例子:
/// Example Of Loading An SCNScene & Setting It As The Current Node
func loadModel(){
let modelPath = "Character.scn"
//1. Get The Reference To Our SCNScene & Get The Model Root Node
guard let model = SCNScene(named: modelPath),
let modelObject = model.rootNode.childNode(withName: "Root", recursively: false) else { return }
//2. Scale It
modelObject.scale = SCNVector3(0.4, 0.4, 0.4)
//3. Add It To The Scene & Position It 1.5m Away From The Camera
augmentedRealityView.scene.rootNode.addChildNode(modelObject)
modelObject.position = SCNVector3(0, 0, -1.5)
//4. Set It As The Current Node & Assign A Name
currentNode = modelObject
currentNode.name = "Character"
}
您还可以使用 SCNHitTest
其中:
Looks for SCNGeometry objects along the ray you specify. For each intersection between the ray and and a geometry, SceneKit creates a hit-test result to provide information about both the SCNNode object containing the geometry and the location of the intersection on the geometry’s surface.
这可用于区分哪些节点被击中,例如:
/// Detects A Tap On An SCNNode
///
/// - Parameter gesture: UITapGestureRecognizer
@objc func detectTap(_ gesture: UITapGestureRecognizer){
//1. Get The Current Touch Point
let currentTouchPoint = gesture.location(in: self.augmentedRealityView)
//2a. Perform An SCNHitTest To Detect If An SCNNode Has Been Touched
guard let nodeHitTest = self.augmentedRealityView.hitTest(currentTouchPoint, options: nil).first else { return }
if nodeHitTest.node == currentNode{
print("The Current Node Has Been Touched")
}
//Or To See Which Node Has Been Touched
if nodeHitTest.node.name == "The Model"{
print("The Model Has Been Touched")
}
}
另一种处理此问题的方法是将 UITapGestureRecognizer 添加到视图中,并根据结果启用交互,例如以这种方式设置 currentNode 例如:
/// Detects A Tap On An SCNNode & Sets It As The Current Node
///
/// - Parameter gesture: UITapGestureRecognizer
@objc func detectTap(_ gesture: UITapGestureRecognizer){
//1. Get The Current Touch Point
let currentTouchPoint = gesture.location(in: self.augmentedRealityView)
//2a. Perform An SCNHitTest To Detect If An SCNNode Has Been Touched
guard let nodeHitTest = self.augmentedRealityView.hitTest(currentTouchPoint, options: nil).first else { return }
//2b. Set It As The Current Node
currentNode = nodeHitTest.node
}
然后您可以应用逻辑来确保只有 currentNode
移动等:
/// Moves An SCNNode
///
/// - Parameter gesture: UIPanGestureRecognizer
@objc func moveNode(_ gesture: UIPanGestureRecognizer) {
//1. Get The Current Touch Point
let currentTouchPoint = gesture.location(in: self.augmentedRealityView)
//2. If The Gesture State Has Begun Perform A Hit Test To Get The SCNNode At The Touch Location
if gesture.state == .began{
//2a. Perform An SCNHitTest To Detect If An SCNNode Has Been Touched
guard let nodeHitTest = self.augmentedRealityView.hitTest(currentTouchPoint, options: nil).first else { return }
//2b. Get The SCNNode Result
if nodeHitTest.node == currentNode{
//3a. If The Gesture State Has Changed Then Perform An ARSCNHitTest To Detect Any Existing Planes
if gesture.state == .changed{
//3b. Get The Next Feature Point Etc
guard let hitTest = self.augmentedRealityView.hitTest(currentTouchPoint, types: .existingPlane).first else { return }
//3c. Convert To World Coordinates
let worldTransform = hitTest.worldTransform
//3d. Set The New Position
let newPosition = SCNVector3(worldTransform.columns.3.x, worldTransform.columns.3.y, worldTransform.columns.3.z)
//3e. Apply To The Node
currentNode.simdPosition = float3(newPosition.x, newPosition.y, newPosition.z)
}
}
}
}
这应该足以为您指明正确的方向...