我的基本代码几乎是那个教程: https://code.tutsplus.com/tutorials/an-introduction-to-scenekit-fundamentals--cms-23847
我想做出日出行为。类似于 lightNode 的东西从与受约束的立方体节点相同的高度开始,并将其向上移动,以便阴影随着时间的推移而变小。 因此,我尝试通过SCNAction.move(to...)移动节点。
对 lightNode 执行操作 ->什么也没发生
对受约束的 cubeNode -> 阴影开始闪烁,但没有变化
我尝试了阴影模式。我想我误解了这一点。没有出现有用的结果。
有没有人知道场景套件是否支持动态变化的阴影之类的东西?
是的。你可以制作一个美丽的移动阴影。如果你的聚光灯没有移动,可能是因为教程让你对它施加了约束。尝试将其删除。
// lightNode.constraints = [constraint]
我找到了一种方法来做到这一点。我的主要错误是:
-
不知何故,访问 lightNode 不起作用(当调用
lightNode
的操作时,它只是没有效果) -
我试图通过
SCNAction.move(to...)
.答案是使用旋转而不是纵向运动。
答案是访问约束节点(而不是 lightNode)。在此代码中,cubeNode 被替换为不可见的centerPoint
(作为lightNode
必须查看的约束节点)。添加了用于为阴影制作画布的boxNode
。lightNode
必须添加到centerPoint
,而不是场景。
有修改后的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
还没有帮助。如果有人有想法,我们将不胜感激。