美文网首页游戏设计&游戏开发程序员
SceneKit教程03 - 搭建game scene

SceneKit教程03 - 搭建game scene

作者: Xtuphe | 来源:发表于2018-05-06 15:52 被阅读61次

    前面两篇主要在做一些准备工作, 这一篇就有趣了, 开始搭建游戏场景.

    我们在之前已经在game scene创建了一个巨大的草坪, 现在我们要补上其余的细节: 两条拥挤的高速公路, 漂亮的树, 和我们的主角猪大哥.

    添加主角

    首先先来添加我们的主角Mr. Pig到game scene, 这样有助于将其作为参照物来放置其他的物体.

    首先选中MrPig.scnassets/ GameScene.scn, 在Media Library找到Mr. Pig reference, 将其拖动到scene, 并确保Position跟Euler都为0; Mr. Pig reference

    然后到ViewController.swift, 添加这条属性, 用来持有Mr.Pig的实例:

    var pigNode: SCNNode!
    

    添加下面这行到setupNodes():

    pigNode = gameScene.rootNode.childNode(withName: "MrPig", recursively:
                true)!
    

    这个方法会在GameScene.scn加载完成后调用, 所以是一个安全的方法来绑定game scene里实际的对象到pigNode.
    (虽然Mr. Pig是一个reference node, 你仍可以在game scene中像正常node一样访问它)

    设置镜头和灯光

    跟前面一样, 这里仍使用"自拍杆"原则, 即通过创建empty node来作为camera 或 light的焦点 - 这样可以简化很多数学问题, 你应该不会介意的. :]

    创建跟随镜头

    返回MrPig.scnassets/GameScene.scn, 首先确保Scene graph上没有东西被选中, 然后点左下角 + 创建empty node. 将其命名为Follow Camera, Position值为0, Euler:(x:-45, y:20, z:0).

    然后把之前的camera拖动到新建的Follow Camera下面, 将camera的Position设置为(x:0, y:0, z:14), Euler为0;

    点击Perspective 选中camera, 你的视角应该是上图的样子.

    选中ViewController.swift, 添加这两个属性:

        var cameraNode: SCNNode!
        var cameraFollowNode: SCNNode!
    

    这用来持有camera和Follow Camera的实例

    添加下面代码到setupNodes():

            // 1 将camera绑定到cameraNode
            cameraNode = gameScene.rootNode.childNode(withName: "camera", recursively: true)!
            // 2 将hud作为子node添加给camera, 这样玩家可以始终看到游戏内需要展示的信息
            cameraNode.addChildNode(game.hudNode)
            // 3 将Follow Camera绑定到cameraFollowNode, 这样你仅仅需要更新cameraFollowNode的position就可以使我们的镜头时刻跟随猪大哥
            cameraFollowNode = gameScene.rootNode.childNode(withName: "Follow Camera", recursively: true)!
    

    创建跟随光源

    这里会用到和上面镜头差不多的步骤, 我们需要两个基础光源, 一个环境光来填充, 一个平行光来模拟阳光照射和它产生的阴影.

    首先确保Scene graph没有东西被选中, 点击左下 + , 命名为Follow Light并将Position 和 Euler 设置为0.

    从Object Library拖动Ambient Light和Directional Light到Follow Light下, 选中ambient, 确保Position 和 Euler 均为0, 点击Attributes Inspector, 颜色选择Aluminum, 这会让整个场景稍微亮一些. 选中directional, 设置Position : (x:-5, y:5, z:5), Euler : (x:-45, y:-60, z:0), 这会把平行光放置在scene的左上方, 很好的照亮了大地. 然后点击Attributes Inspector开始设置阴影. 选中Casts shadows, 设置Sample count为0, 取消Auto Adjust并设置Scale 和 Clipping如下图所示.

    因为阴影是个相对比较消耗性能的操作, 所以你并不想在玩家看不到的地方计算阴影.

    接下来是一些代码工作, 将下面属性添加到ViewController.swift

    var lightFollowNode: SCNNode!
    

    这用来持有FollowLight的实例

    添加下面的代码到setupNodes():

    lightFollowNode = gameScene.rootNode.childNode(withName: "Follow Light", recursively: true)!
    

    这将Follow Light与lightFollowNode绑定, 你可以将lightFollowNode的position设置为与Follow Camera相同来使玩家可视区域投射出漂亮的阴影.

    command + R来验证一下你的成果:



    看起来像一个阳光明媚的好天气, 注意一下你的阴影, 简直闻到了烤肉的香气 :]

    添加高速公路与车流

    首先, 确保你的game scene的scene graph没东西被选中, 点击左下角 + 添加empty node, 将其命名为Highway. 这个node用来作为两条高速公路的容器node来使用.

    然后在Media Library拖动两个Road到Highway下, 选中第一个, 设置Position:(x:0, y:0, z:-4.5), Euler为0.

    选中第二个, 设置Position:(x:0, y:0, z:-11.5), Euler : 0. Perspective处选中camera, 应该看起来像这样

    (我这里Xcode又出了问题, scene editor的马路被阳光照射成了白色, 但实际运行起来是ok的, Xcode的bug真是多啊)


    看道路与上图的区别

    添加车流

    跟前面类似, 创建一个empty node并命名为Traffic作为容器, 然后从Media Library拖动Bus到Traffic下, 并设置position : (x:0, y:0, z:-4), Euler: (x:0, y:-90, z:0).

    重复类似步骤, 再从Media Library拖动Mini 与 SUV到Traffic下, 并设置Mini :position (x:3, y:0, z:-5). Euler (x:0, y:-90, z: 0); SUV: position (x:-3, y:0, z:-5)Euler (x:0, y:-90, z:0).
    完美! 接下来添加下面属性到ViewController.swift,
    var trafficNode: SCNNode!
    

    因为路上车会很多, 不需要给每个引用添加一个属性, 而是通过这个属性来持有所有车辆.
    添加下面代码到setupNodes():

    trafficNode = gameScene.rootNode.childNode(withName: "Traffic", recursively: true)!
    

    这会绑定Traffic到trafficNode, 你可以访问它所有的子node来是车辆动起来.

    下面是挑战内容, 你可以尝试自己添加很多很多很多的车辆来使公路变得热闹起来. 当你完成时差不多应该是这样的:


    Challenge

    添加时你应该注意如下事项:

    • 确保道路左侧为大巴路线, 右侧为跑的更快的小车.
    • 确保两条公路的车流方向是相反的
    • 摆放车的位置时记着按着command键, 这样可以确保位置都为整数.
    • 当你完成一条公路时, 可以选中路上的所有车, 然后按着option键的同时拖动到另外一跳公路上, 这样你可以将所有的车复制过去, 然后, 修改Euler 180°即可将其朝向另一个方向.
    • 同样的, 修改旋转角度时长按command键可以使角度都为整数.

    当你完成后, command + R来验证一下你的成果.


    你的猪大哥不再孤单

    添加树🌲

    目前看起来像是有人在足球场上建了两条路, 我们要的效果是在公园里有两条路, 所以现在要加树 :]

    接下来你要添加两组不同的树: 树线, 和 树组... 树线用来勾勒整个公园的边界, 树组用来装饰, 使足球场变公园.

    创建树线TreeLine

    比起一棵棵的栽树, 你会采用一个更聪明的方法: 创建一个由很多树构成的可复用的scene, 然后在game scene把这些作为reference node来使用.

    首先在File Template Library拖动一个SceneKit Scene File到Project Navigator. 将其命名为TreeLine, 并放在MrPig.scnassets目录下. 选中, 删除里面自带的camera因为你不会用到, 在里面再创建一个empty node 并命名为TreeLine. 然后按照下面的模式来搭建TreeLine:

    这个表是啥意思呢? 每个白色方块代表一棵树的位置.

    • 行: 代表树Position的x值
    • 列: 代表树Position的z值
    • S: SmallTree reference node
    • M: MediumTree reference node
    • L: LargeTree reference node
      举个例子, 第一行第一个, 需要从Media Library拖动一个SmallTree到scene, 并设置其position 为 (x:-5, y:0, z:-1). y = 0确保其一直在草地的表面.
      你可以通过长按option + command并拖动相应的node来加速你的工作.
      当你完成的时候应该看起来是这样的:


    创建树组TreePatch

    这根上面几乎是完全一样的, 除了模式换成了这样的:
    当你完成时应该看起来是这样:

    添加数线

    终于, 我们的reference node准备完毕, 是时候把它们扔进game scene了.

    选中GameScene.scn并确保Scene graph上没有东西被选中, 创建一个empty node命名为Trees. 接下来从Media Library 拖动一个TreeLine到scene, 然后开始复制并调整位置, 直到你的game scene看起来差不多这个样子:



    我个人习惯按着option + command一个一个拖动来布局, 当然, 你也可以直接复制一堆TreeLine, 然后在Node Inspector直接修改Position, 如果你选择后者, 可以这样修改:
    猪先生前面
    • Position:(x:0,y:0,z:7),Euler:(x:0,y:0,z:0).
    • Position:(x:-7, y:0, z:3), Euler: (x:0, y:90, z:0).
    • Position:(x:7,y:0,z:3),Euler:(x:0,y:90,z:0).
    • Position:(x:-14,y:0,z:-1),Euler:(x:0,y:0,z:0).
    • Position:(x:14,y:0,z:-1),Euler:(x:0,y:0,z:0).
    道路两侧
    • Position:(x:-14,y:0,z:-8),Euler:(x:0,y:0,z:0).
    • Position:(x:14,y:0,z:-8),Euler:(x:0,y:0,z:0).
    后面
    • Position:(x:18,y:0,z:-19),Euler:(x:0,y:90,z:0).
    • Position:(x:-18,y:0,z:-19),Euler:(x:0,y:90,z:0).
    • Position:(x::-11,y:0,z:-23),Euler:(x:0,y:0,z:0).
    • Position: (x:0, y:0, z:-23), Euler: `(x:0, y:0, z:0).
    • Position:(x:11,y:0,z:-23),Euler:(x:0,y:0,z:0).

    添加树组

    这个就简单多了, 只有三个
    • Position:(x:10,y:0,z:-17),Euler:(x:0,y:0,z:0).
    • Position:(x:-10,y:0,z:-17),Euler:(x:0,y:0,z:0).
    • Position:(x:0,y:0,z:-17),Euler:(x:0,y:90,z:0).
    完成后大概是这样的:



    最后, 再次确认你的树node都在Trees容器node下面.

    添加金币

    听说🐷都爱金币 :] , 所以现在我们要添加些金币到我们的game scene.

    先创建一个名为Coins的empty node, 然后从Media Library拖动一个coin到里面, 再复制3个, 设置位置如下:
    • Position:(x:0,y:0.5,z:-8).
    • Position:(x:0,y:0.5,z:-21).
    • Position:(x:-14,y:0.5,z:-20).
    • Position:(x:14,y:0.5,z:-20).


    完美! 最后comman + R来验证一下本章的成果.


    现在, 你有一个漂亮的启动页面Splash Scene, 然后有个漂亮的转场动画让你的Mr.Pig出现在你刚搭建的有着拥挤车流的漂亮的公园, 一切都是那么的漂亮. 应该给自己一个掌声了.

    然而, 我们猪大哥跟车流都是静止的, 如何让他们动起来呢? 我们下篇见!

    目录 (不定期更新中 :] )

    1 准备工作、创建项目、Splash Scene
    2 过场动画 Transition
    3 搭建游戏场景 Game Scene
    4 用场景编辑器添加动作
    5 用代码添加动作

    相关文章

      网友评论

        本文标题:SceneKit教程03 - 搭建game scene

        本文链接:https://www.haomeiwen.com/subject/eqzyrftx.html