我的基本代码几乎就是这个教程: https://code.tutsplus.com/tutorials/an-introduction-to-scenekit-fundamentals--cms-23847
我想做一个日出行为。像lightNode这样的东西在与受约束的cubeNode相同的高度上开始并向上移动,以便阴影随着时间的推移变小。 因此,我尝试通过SCNAction.move(to ...)移动节点。
对lightNode采取行动 - >没有任何反应
对受约束的cubeNode采取行动 - >阴影开始闪烁,但没有变化
我尝试使用shadowModes。我想我误解了这一点。没有出现有用的结果。
有人知道如果scenekit支持动态改变阴影吗?
答案 0 :(得分:1)
我找到了一种方法来实现它。我的主要错误是:
以某种方式它无法访问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
没有帮助。如果有人有想法,我们非常感激。
答案 1 :(得分:1)
是。你可以制作一个美丽动人的影子。如果您的聚光灯没有移动,可能是因为教程已经对它施加了约束。尝试删除它。
// lightNode.constraints = [constraint]