gpt4 book ai didi

快速添加按钮到 SCNNode

转载 作者:可可西里 更新时间:2023-11-01 00:39:19 26 4
gpt4 key购买 nike

我正在研究 ARKit 和图像检测。现在我有一个应用程序可以检测图像并将平面放置在屏幕上检测到的对象所在的位置。

我怎样才能在飞机上添加一个像按钮一样的可点击元素。我想在每个检测到的对象上都有一个点击事件。

这是我的渲染器函数的样子:

func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
guard let imageAnchor = anchor as? ARImageAnchor else { return }
let referenceImage = imageAnchor.referenceImage
updateQueue.async {
let plane = SCNPlane(width: referenceImage.physicalSize.width,
height: referenceImage.physicalSize.height)
let planeNode = SCNNode(geometry: plane)

planeNode.opacity = 0.25
planeNode.eulerAngles.x = -.pi / 2
planeNode.runAction(self.imageHighlightAction)
node.addChildNode(planeNode)
}

DispatchQueue.main.async {
let imageName = referenceImage.name ?? ""
self.statusViewController.cancelAllScheduledMessages()
// self.statusViewController.showMessage("Detected image “\(imageName)”")
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let second = storyboard.instantiateViewController(withIdentifier: "InfoViewController")as! InfoViewController
second.myStringValue = imageName
// self.navigationController?.pushViewController(second, animated: true)
}
}

最佳答案

有几种方法可以解决这个问题:

1:标准方法:

在您的 delegate 方法中,按照以下方式为每个节点分配一个名称(很明显,如果您有很多节点,您可能希望根据需要将它们存储在数组或字典中):

 func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {

//1. Check We Have The Image Anchor
guard let imageAnchor = anchor as? ARImageAnchor else { return }

//2. Get The Reference Image
let referenceImage = imageAnchor.referenceImage

//1. Create The Plane Geometry With Our Width & Height Parameters
let planeGeometry = SCNPlane(width: referenceImage.physicalSize.width,
height: referenceImage.physicalSize.height)

//2. Create A New Material
let material = SCNMaterial()

material.diffuse.contents = UIColor.red

//3. Create The Plane Node
let planeNode = SCNNode(geometry: planeGeometry)

planeNode.geometry?.firstMaterial = material

planeNode.opacity = 0.25

planeNode.eulerAngles.x = -.pi / 2

//4. Add A Name To The Node
planeNode.name = "I Was Clicked"

//5. Add It To The Scene
node.addChildNode(planeNode)

}

然后使用 touchesBegan,执行 hitTest 并相应地处理您的触摸:

   override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

/*
1. Get The Current Touch Location
2. Check That We Have Touched A Valid Node
3. Check If The Node Has A Name
4. Handle The Touch
*/

guard let touchLocation = touches.first?.location(in: augmentedRealityView),
let hitNode = augmentedRealityView?.hitTest(touchLocation, options: nil).first?.node,
let nodeName = hitNode.name
else {
//No Node Has Been Tapped
return

}
//Handle Event Here e.g. PerformSegue
print(nodeName)

}

2:一个有趣的方法:

UIKit 元素实际上可以添加为 SCNGeometry 的 Material 。我个人还没有看到很多人使用这种方法,但它可能对任何想要将 UIKitARKit 合并的人有用。

创建自定义 UIButton 例如:

/// Clickable View
class ClickableView: UIButton{

override init(frame: CGRect) {

super.init(frame: frame)

self.addTarget(self, action: #selector(objectTapped(_:)), for: .touchUpInside)

self.backgroundColor = .red

}

required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

/// Detects Which Object Was Tapped
///
/// - Parameter sender: UIButton
@objc func objectTapped(_ sender: UIButton){

print("Object With Tag \(tag)")

}

}

然后在您的委托(delegate)方法中执行以下操作:

  func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {

//1. Check We Have The Image Anchor
guard let imageAnchor = anchor as? ARImageAnchor else { return }

//2. Get The Reference Image
let referenceImage = imageAnchor.referenceImage

//1. Create The Plane Geometry With Our Width & Height Parameters
let planeGeometry = SCNPlane(width: referenceImage.physicalSize.width,
height: referenceImage.physicalSize.height)

//2. Create A New Material
let material = SCNMaterial()

DispatchQueue.main.async {
//3. Create The New Clickable View
let clickableElement = ClickableView(frame: CGRect(x: 0, y: 0,
width: 300,
height: 300))
clickableElement.tag = 1

//4. Add The Clickable View As A Materil
material.diffuse.contents = clickableElement
}

//5. Create The Plane Node
let planeNode = SCNNode(geometry: planeGeometry)

planeNode.geometry?.firstMaterial = material

planeNode.opacity = 0.25

planeNode.eulerAngles.x = -.pi / 2

//6. Add It To The Scene
node.addChildNode(planeNode)
}

这应该让你开始......

关于快速添加按钮到 SCNNode,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49058411/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com