0

我的基本代码在该教程中几乎是这样的: https ://code.tutsplus.com/tutorials/an-introduction-to-scenekit-fundamentals--cms-23847

我想做一个日出行为。像 lightNode 这样的东西从与受约束的 cubeNode 相同的高度开始并将其向上移动,以便阴影随着时间的推移变得更小。因此我尝试通过 SCNAction.move(to...) 移动节点。

lightNode 上的操作 -> 没有任何反应

受约束的 cubeNode -> shadow 上的操作开始闪烁,但没有变化

我尝试了shadowModes。我想我误解了这一点。没有出现有用的结果。

有谁知道scenekit是否支持动态变化的阴影之类的东西?

4

2 回答 2

1

我找到了一种方法。我的主要错误是:

  1. 不知何故,它无法访问 lightNode(当lightNode调用 a 的操作时,它只是没有效果)

  2. 我试图通过SCNAction.move(to...). 答案是使用旋转而不是纵向运动。

答案是访问约束节点(而不是 lightNode)。在此代码中, cubeNode 被替换为不可见的(作为必须查看centerPoint的约束节点)。已添加lightNodeA用于制作阴影画布。必须添加到 中,boxNode而不是添加到场景中。lightNodecenterPoint

有修改的viewDidLoad方法。如果你想检查一下,打开 Xcode,启动一个新项目作为 SceneKit Game 并将其替换viewDidLoad为以下代码。

    override func viewDidLoad() {
    super.viewDidLoad()

    // create a new scene
    let scene = SCNScene(named: "art.scnassets/ship.scn")!

    // create and add a camera to the scene
    let cameraNode = SCNNode()
    cameraNode.camera = SCNCamera()
    scene.rootNode.addChildNode(cameraNode)

    // place the camera
    cameraNode.position = SCNVector3(x: 0, y: 0, z: 15)

    // create and add a light to the scene
    let centerPoint = SCNNode.init()
    centerPoint.position = SCNVector3Make(0, 0, 0)
    scene.rootNode.addChildNode(centerPoint)

    let light = SCNLight()
    light.type = SCNLight.LightType.spot
    light.spotInnerAngle = 30
    light.spotOuterAngle = 80
    light.castsShadow = true
    light.color = UIColor.init(colorLiteralRed: 0.95, green: 0.8, blue: 0.8, alpha: 1)
    light.zFar = 200

    let lightNode = SCNNode()
    lightNode.light = light
    lightNode.position = SCNVector3Make(20, 100, 50)

    let constraint = SCNLookAtConstraint(target: centerPoint)
    constraint.isGimbalLockEnabled = true
    lightNode.constraints = [constraint]
    centerPoint.addChildNode(lightNode)

    let ambientLight = SCNLight.init()
    ambientLight.type = SCNLight.LightType.ambient
    ambientLight.color = UIColor.darkGray

    scene.rootNode.light = ambientLight

    // retrieve the ship node
    let material = SCNMaterial.init()
    material.diffuse.contents = UIColor.yellow
    material.lightingModel = SCNMaterial.LightingModel.phong
    material.locksAmbientWithDiffuse = true

    let boxNode = SCNNode.init(geometry: SCNBox.init(width: 10, height: 0.1, length: 10, chamferRadius: 0))
    boxNode.geometry?.firstMaterial = material
    boxNode.position = SCNVector3Make(0, -2, 0)

    scene.rootNode.addChildNode(boxNode)

    // animate spot light rotation
    centerPoint.runAction(SCNAction.repeatForever(SCNAction.rotateBy(x: CGFloat(M_PI), y: 0, z: CGFloat(M_PI), duration: 5)))

    // animate color light change
    let lightColorChange: CABasicAnimation = CABasicAnimation.init(keyPath: "color")
    lightColorChange.fromValue = UIColor.init(colorLiteralRed: 0.95, green: 0.8, blue: 0.8, alpha: 1)
    lightColorChange.toValue = UIColor.init(colorLiteralRed: 0, green: 0, blue: 0.4, alpha: 1)
    lightColorChange.duration = 5.0
    lightColorChange.autoreverses = true
    lightColorChange.repeatCount = Float.infinity
    light.addAnimation(lightColorChange, forKey: "changeLight")

    // retrieve the SCNView
    let scnView = self.view as! SCNView

    // set the scene to the view
    scnView.scene = scene

    // allows the user to manipulate the camera
    scnView.allowsCameraControl = true

    // show statistics such as fps and timing information
    scnView.showsStatistics = true

    // configure the view
    scnView.backgroundColor = UIColor.black

    // add a tap gesture recognizer
    let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTap(_:)))
    scnView.addGestureRecognizer(tapGesture)
}

还考虑了光的颜色变化。使用 CABasicAnimation 可以light.color随时间更改 - 属性。它不像具有所有颜色步骤的完美日出,但也有一种方法可以链接这些动画以使其更加复杂。(为此搜索“wenderlich 如何创建复杂的加载动画”。

但是我没有找到改变阴影颜色的方法。晚上有白色阴影,白天有黑色阴影可能是一个很好的效果。light.shadowColor还没有帮助。如果有人有想法,将不胜感激。

于 2017-03-11T01:36:05.767 回答
1

是的。你可以制作一个美丽的移动阴影。如果您的聚光灯没有移动,可能是因为教程让您对其进行了限制。尝试删除它。

// lightNode.constraints = [constraint]
于 2017-03-11T01:43:50.113 回答