无法转换“[String : Any] 类型的值?”到预期的参数类型 'Float'

Cannot convert value of type '[String : Any]?' to expected argument type 'Float'

我正在尝试做一个除法来计算放大或缩小我的 AR 项目节点的比例。但是我遇到了 Cannot convert value of type '[String : Any]?' to expected argument type 'Float'.

的编译错误

我知道错误发生是因为数字是一个可选参数,我尝试了几种不同的方法,但我无法将它解包为浮点类型。我该如何打开它?

guard let touchPositionInFrontOfCamera = getPosition(ofPoint: indexTip2, atDistanceFromCamera: self.distance, inView: self.sceneView) else { return }

for node in sceneView.scene.rootNode.childNodes{
    let distance = SCNVector3(
        touchPositionInFrontOfCamera.x - node.position.x,
        touchPositionInFrontOfCamera.y - node.position.y,
        touchPositionInFrontOfCamera.z - node.position.z
    )
    let radius: Float = sqrtf(distance.x * distance.x + distance.y * distance.y + distance.z * distance.z)
    print(node.geometry?.dictionaryWithValues(forKeys: ["radius"]), radius)
    let number = node.geometry?.dictionaryWithValues(forKeys: ["radius"])
    print(radius / number)
}

dictionaryWithValues(forKeys returns [String:Any] 你不能用Float

guard let res = node.geometry?.dictionaryWithValues(forKeys: ["radius"]), let number = res["radius"] as? Float else { return } 
print(radius / number)

顺便说一句,根据你的几何你可以很容易地得到半径见

if let sphere = node.geometry as? SCNSphere { 
    print(sphere.radius) 
}

你走错了路。方法 NSObject.dictionaryWithValues(forKeys:) 的存在是为了 明确目的 从接收者对象的 属性 值(对于给定的 属性 名称)创建字典。你已经问过这个,现在你想知道“我如何摆脱这些字典的东西?”。

答案很简单:首先不要制作您需要的词典!直接访问属性即可。

在这种情况下,它只是有点棘手,因为 SCNNode.geometry returns 一个通用的 SCNGeometry 类型,它没有半径(想一想,如果它是一个立方体,什么它的半径是多少?这是无意义的)。所以在这种情况下,您需要将一般的 SCNGeometry 类型缩小为更窄的类型,可能是 SCNSphere.

for node in sceneView.scene.rootNode.childNodes {
    let distance = SCNVector3(
        touchPositionInFrontOfCamera.x - node.position.x,
        touchPositionInFrontOfCamera.y - node.position.y,
        touchPositionInFrontOfCamera.z - node.position.z
    )
    let radius: Float = sqrtf(distance.x * distance.x + distance.y * distance.y + distance.z * distance.z)
    let number = (node.geometry as? SCNSphere).radius
    print(number, radius)
    print(radius / number)
}

你这里也有很多样板,你应该自己做一些辅助函数和运算符来清理它:

extension SCNVector3 {
    func distance(to target: other) -> SCNFloat {
        (target - self).magnitude()
    }

    static func - (a: SCNVector3, b: SCNVector3) -> SCNVector3 {
        SCNVector3(a.x - b.x, a.y + b.y, a.z + b.z)
    }

    var magnitude: SCNFloat {
        (x*x + y*y + z*z).squareRoot()
    }
}

for node in sceneView.scene.rootNode.childNodes {
    guard let sphere = (node.geometry as? SCNSphere) else {
       // FIXME: the geometry wasn't a sphere, after all! Handle it.
       fatalError()
    }

    let radius = node.distance(to: touchPositionInFrontOfCamera)
    let number = sphere.radius
    print(number, radius, radius / number)
}

看看这变得多么简单。