如何返回用于设置SCNNode的球体几何体(SCNSphere)的半径。 我想在一个方法中使用radius,我将一些子节点相对于父节点移动。下面的代码失败,因为如果我没有将节点传递给方法,则半径对于结果节点来说是未知的?
此外,我的数组索引无法说Int不是Range。
我正在尝试从this
构建一些东西import UIKit
import SceneKit
class PrimitivesScene: SCNScene {
override init() {
super.init()
self.addSpheres();
}
func addSpheres() {
let sphereGeometry = SCNSphere(radius: 1.0)
sphereGeometry.firstMaterial?.diffuse.contents = UIColor.redColor()
let sphereNode = SCNNode(geometry: sphereGeometry)
self.rootNode.addChildNode(sphereNode)
let secondSphereGeometry = SCNSphere(radius: 0.5)
secondSphereGeometry.firstMaterial?.diffuse.contents = UIColor.greenColor()
let secondSphereNode = SCNNode(geometry: secondSphereGeometry)
secondSphereNode.position = SCNVector3(x: 0, y: 1.25, z: 0.0)
self.rootNode.addChildNode(secondSphereNode)
self.attachChildrenWithAngle(sphereNode, children:[secondSphereNode, sphereNode], angle:20)
}
func attachChildrenWithAngle(parent: SCNNode, children:[SCNNode], angle:Int) {
let parentRadius = parent.geometry.radius //This fails cause geometry does not know radius.
for var index = 0; index < 3; ++index{
children[index].position=SCNVector3(x:Float(index),y:parentRadius+children[index].radius/2, z:0);// fails saying int is not convertible to range.
}
}
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
答案 0 :(得分:4)
radius
的问题是parent.geometry
返回SCNGeometry
而不是SCNSphere
。如果您需要获取radius
,则需要先将parent.geometry
投射到SCNSphere
。为了安全起见,最好使用一些可选的绑定和链接来做到这一点:
if let parentRadius = (parent.geometry as? SCNSphere)?.radius {
// use parentRadius here
}
访问radius
节点上的children
时,您还需要这样做。如果你将所有这些放在一起并稍微清理一下,你会得到这样的东西:
func attachChildrenWithAngle(parent: SCNNode, children:[SCNNode], angle:Int) {
if let parentRadius = (parent.geometry as? SCNSphere)?.radius {
for var index = 0; index < 3; ++index{
let child = children[index]
if let childRadius = (child.geometry as? SCNSphere)?.radius {
let radius = parentRadius + childRadius / 2.0
child.position = SCNVector3(x:CGFloat(index), y:radius, z:0.0);
}
}
}
}
请注意,您使用2个孩子的数组调用attachChildrenWithAngle
:
self.attachChildrenWithAngle(sphereNode, children:[secondSphereNode, sphereNode], angle:20)
如果您这样做,那么在访问第3个元素时,您将在for
循环中获得运行时崩溃。每次调用该函数时,您都需要传递一个包含3个子节点的数组,或者更改for
循环中的逻辑。
答案 1 :(得分:0)
此时我只使用球体,因此半径很容易操作。但是,我认为您应该尝试查看SCNNode 的几何形状。除了您发布的代码片段之外,我还使用了此功能(两者配合使用对我来说很好)。
func updateRadiusOfNode(_ node: SCNNode, to radius: CGFloat) {
if let sphere = (node.geometry as? SCNSphere) {
if (sphere.radius != radius) {
sphere.radius = radius
}
}
}
此外,缩放因子(在半径处)也很重要。我使用 baseRadius 然后我将其与
相乘maxDistanceObserved / 2
如果 hitTest 有进一步的结果,总是更新最大距离。