【问题标题】:SceneKit and SpriteKit togetherSceneKit 和 SpriteKit 一起使用
【发布时间】:2018-06-21 05:27:02
【问题描述】:

我正在使用 SceneKit 构建一个 3D 游戏场景,我想在顶部构建一个“hud”,为了让它工作,我使用子视图和overlaySKScene 构建了我的 ViewController,如下所示:

class ViewController:UIViewController {
  var sceneView: SCNView!
  var mainScene = MainScene() // <- SCNScene
  var spriteScene: OverlayScene! // <- SKScene 

  override func viewDidLoad() {
    super.viewDidLoad()

    self.sceneView = SCNView(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height))
    self.sceneView.scene = mainScene
    self.sceneView.backgroundColor = UIColor.clear
    self.view.addSubview(self.sceneView)

    self.spriteScene = OverlayScene(size: self.view.bounds.size)
    self.sceneView.overlaySKScene = self.spriteScene
  }
}

我有几个问题应该如何正确地完成,因为我遇到了一些看起来不寻常的事情。

首先,假设我需要进行转场,我似乎不清楚如何实际观察OverlayScene 中的一个 SpriteKit 节点上的点击然后更改主父 ViewController 的控制器。我没有在网上找到任何描述类似情况的资源。

这是我的OverlayScene 的精简版:

import UIKit
import SpriteKit

class OverlayScene: SKScene {

  var actionBarNode: SKSpriteNode!

  override init(size: CGSize) {
    super.init(size: size)

    self.backgroundColor = UIColor.clear

    self.actionBarNode = SKSpriteNode()
    self.actionBarNode.size = CGSize(width: size.width, height: 100)
    self.actionBarNode.position = CGPoint(x: size.width / 2, y: 50)
    self.actionBarNode.color = .white
    self.addChild(self.actionBarNode)
  }
}

【问题讨论】:

  • "如何将 IBAction 连接到精灵场景中的节点?"您的问题与我如何将 IBAction 连接到位于 UIView 对象上的 UIKit 控件之一几乎相同。

标签: swift sprite-kit scenekit


【解决方案1】:

我不会直接回答您的两个问题,而是会处理您的更大问题,即您想要在游戏中使用 HUD。一个用户界面。我从未制作过Scenekit 游戏,但我确实制作了Spritekit 游戏,而且HUD 是一个聪明的把戏。让我解释一下。

想象一下,您站在相机后面,通过镜头查看相机所看到的内容。你看到它前面的场景。现在拿一张纸,在中间剪出一个矩形框,在剩余的外围画上。将这张纸贴在相机的前面并查看。您仍然可以看到场景(现在小一点),但现在您还可以看到带有图纸的纸张。这就是 HUD 在游戏中的工作方式。

我做了一些搜索,SpriteKitSceneKit 都有一个 camera。在 sceneKit 中,您创建一个 camera node 并将场景的视点设置为该相机。这代表玩家向外看场景。

我不确定它在SceneKit 中的工作方式是否相同,但在SpriteKit 中,您可以将节点添加到将被锁定的摄像机。这些成为您的 HUD 元素(按钮、分数等)。由于这些都是camera 的子节点,因此它们会在您移动相机时移动,因此感觉它们就像是静态 HUD。这就是您实现 HUD 的方式。阅读SceneKit 相机的文档,因为这将帮助您了解如何实现相同的效果。

我曾经也想过按照你现在的方式来做,事实证明混合SceneKitSpriteKit是一种非常痛苦的经历,所以我会告诫不要这样做。

此外,虽然您可以混合使用 Interface Builder 和 SpriteKit,但我会提醒您不要这样做。它基本上把我的第一场比赛毁得一团糟。如果您决定使用 Interface Builder,请尝试将其限制为菜单屏幕和选项屏幕。但是,我发现以编程方式创建所有内容可以让您获得更流畅、更清洁和无错误的体验。

希望这会有所帮助!

【讨论】:

  • 感谢您对 @Aleksandr 的见解,我会在构建此内容时考虑您的想法。
【解决方案2】:

我为任何可能遇到同样问题的人找到了解决我的问题的方法(我认为这很可能是因为许多示例都展示了以我的方式添加为子视图的叠加场景。

首先,我在viewController 中的tapHandler 需要将属性cancelsTouchesInView 设置为false。这将允许手势被底层视图接收。

let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTap(_:)))
tapGesture.cancelsTouchesInView = false
sceneView.addGestureRecognizer(tapGesture)

并非所有子视图都发生这种情况的原因是,我依赖于一个大小为 100% 帧的视图,它覆盖了底层视图,而不是仅仅让视图占据更小的屏幕区域,比如如示例文档中所示的按钮或记分牌。

【讨论】:

    猜你喜欢
    • 2016-02-17
    • 1970-01-01
    • 2014-12-01
    • 2018-02-07
    • 2017-04-12
    • 2020-07-12
    • 2014-11-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多