SceneKit 相关

SceneKit

SCNNode 结构图

SCNNode 1.png

SCNNode 2.png

通过两张图片,更好地了解SCNNode的结构

一个渲染循环

渲染循环内做的事


Render Cycle.png

SCNGeometry 的内建对象

内建对象1.jpg
内建对象2.jpg
内建对象3.jpg

.dae 文件全称Data Asset Exchange,是Collada 的输出文件

Collada file specifies.jpg

上帝说有光,于是SCNLight亮了

四种光照效果
1.jpg

2.jpg
光照的规则
光照规则.jpg
亮起来
func setupLighting(scene:SCNScene) {
        
        let ambientLight = SCNNode()
        ambientLight.light = SCNLight()
        ambientLight.light!.type = SCNLightTypeAmbient
        ambientLight.light!.color = UIColor(white: 0.3, alpha: 1.0)
        scene.rootNode.addChildNode(ambientLight)
        
        let lightNode = SCNNode()
        lightNode.light = SCNLight()
        lightNode.light!.type = SCNLightTypeSpot
        lightNode.light!.castsShadow = true
        lightNode.light!.color = UIColor(white: 0.8, alpha: 1.0)
        lightNode.position = SCNVector3Make(0, 80, 30)
        lightNode.rotation = SCNVector4Make(1, 0, 0, Float(-M_PI/2.8))
        lightNode.light!.spotInnerAngle = 0
        lightNode.light!.spotOuterAngle = 50
        lightNode.light!.shadowColor = UIColor.blackColor()
        lightNode.light!.zFar = 500
        lightNode.light!.zNear = 50
        scene.rootNode.addChildNode(lightNode)
        
        //Save for later
        spotLight = lightNode
    }

老板,你是土豪金的么SCNMaterial

八种不同的材质
蓝色贴图
pyramidNode.geometry?.firstMaterial?.diffuse.contents = UIColor.blueColor()
pyramidNode.geometry?.firstMaterial?.specular.contents = UIColor.blueColor()
pyramidNode.geometry?.firstMaterial?.shininess = 1.0
地球贴图
globeNode.geometry?.firstMaterial?.diffuse.contents = UIImage(named: "earthDiffuse")
globeNode.geometry?.firstMaterial?.ambient.contents = UIImage(named: "earthAmbient")
globeNode.geometry?.firstMaterial?.specular.contents = UIImage(named: "earthSpecular")
globeNode.geometry?.firstMaterial?.normal.contents = UIImage(named: "earthNormal")
globeNode.geometry?.firstMaterial?.diffuse.mipFilter = SCNFilterMode.Linear

相机走起 -- SCNCamera

添加一个cameraNode

cameraNode = SCNNode()
cameraNode.camera = SCNCamera()
cameraNode.camera!.zFar = 500
cameraNode.position = SCNVector3Make(0, 30, 200)
cameraNode.rotation  = SCNVector4Make(1, 0, 0, Float(-M_PI_4*0.75))
scene.rootNode.addChildNode(cameraNode)
SCNCamera.jpg

添加动画

用CoreAnimation就好啦

直接上代码,绕y轴旋转

// Spin around the Y-Axis
rotation.fromValue = NSValue(SCNVector4:SCNVector4Make(0, 0, 0, 0))
rotation.toValue =  NSValue(SCNVector4:SCNVector4Make(0, 1, 0, Float(2.0*M_PI)))
rotation.duration = 5
rotation.repeatCount = .infinity
pyramidNode.addAnimation(rotation, forKey: "rotation")```
#####添加SCNAction 实现动画
实现上下跳动
```swift
//上下跳动
let moveGlobeUp = SCNAction.moveByX(0.0, y: 10.0, z: 0.0, duration: 1.0)
let moveGlobeDown = SCNAction.moveByX(0.0, y: -10.0, z: 0.0, duration: 1.0)
let sequence = SCNAction.sequence([moveGlobeUp, moveGlobeDown])
let repeateSequence = SCNAction.repeatActionForever(sequence)
globeNode.runAction(repeateSequence)

放大缩小

let scaleToZero = SCNAction.scaleTo(0.0, duration: 0)
let scaleUp = SCNAction.scaleTo(1.0, duration: 5)
let opacityToZero = SCNAction.fadeOutWithDuration(5)
let sequence = SCNAction.sequence([scaleToZero, scaleUp, opacityToZero])
let repeateSequence = SCNAction.repeatAction(sequence, count: 10)
cylinderNode.runAction(repeateSequence)

动起来

镜头动作

让镜头跟着移动

//follow the camera
let spaceman =  spaceManNode.presentationNode
let spacemanPosition = spaceman.position
let cameraDamping:Float = 0.05
let targetPosition =  SCNVector3Make(spacemanPosition.x, 30.0, spacemanPositio
var cameraPosition =  cameraNode.position
cameraPosition = SCNVector3Make(cameraPosition.x * (1.0 - cameraDamping) + tar
* cameraDamping,
    cameraPosition.y * (1.0 - cameraDamping) + targetPosition.y * cameraDampin
    cameraPosition.z * (1.0 - cameraDamping) + targetPosition.z * cameraDampin
cameraNode.position = cameraPosition
添加.dae 文件到scene
func setupEnemy(scene:SCNScene) -> SCNNode {
    
    let enemyScene = SCNScene(named: "art.scnassets/Enemy.dae")
    let enemyNode = enemyScene!.rootNode.childNodeWithName("enemy", recursively: false)
    enemyNode!.name = "enemy"
    enemyNode!.position = SCNVector3Make(40, 10, 30)
    enemyNode!.rotation = SCNVector4Make(0, 1, 0, Float(M_PI))
    scene.rootNode.addChildNode(enemyNode!)
    
    return enemyNode!
}
碰撞检测SCNPhysicsBody

三种碰撞体

三种碰撞体.jpg

在SceneKit 里面使用SpriteKit

绘制2d效果

import SpriteKit
import SceneKit
class GameOverlay: SKScene {
    required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
}

碰撞这一块实现的不是很好,暂时先不研究了


以上代码图像来自:Beginning Swift Games Development for iOS 一书,没搜到中文翻译版,建议做3D开发的童鞋自行下载此书,查词典看完(本书提供的source code 不太全,得配合着书进行完善)


Scenekit内容很丰富,后续应该还会继续补充...
待续...

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 111. [动画系统]如何将其他类型的动画转换成关键帧动画? 动画->点缓存->关键帧 112. [动画]Unit...
    胤醚貔貅阅读 14,531评论 3 89
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 14,223评论 4 61
  • iOS 苹果官方Demo合集 字数10517阅读21059评论18喜欢144 其实, 开发了这么久, 不得不说, ...
    bingo居然被占了阅读 13,491评论 2 31
  • 更新:【面试题含答案】http://bbs.9ria.com/thread-288394-1-1.html 高频问...
    好怕怕阅读 10,317评论 3 52
  • AndroidManifest.xml文件中可以设置 android:largeHeap="true" 分配更多的...
    waven阅读 3,392评论 0 0