如何防止 SceneKit 中的 SpriteKit 覆盖拉伸?
Posted
技术标签:
【中文标题】如何防止 SceneKit 中的 SpriteKit 覆盖拉伸?【英文标题】:How to prevent SpriteKit overlay in SceneKit to stretch? 【发布时间】:2017-12-24 18:07:35 【问题描述】:在 WWDC 2017 SceneKit 会议中,他们建议使用 overlaySKScene 将 SpriteKit 层覆盖在 SceneKit 上用于 HUD 等。在我旋转 iPhone/iPad 之前它似乎工作正常。现在 SpriteKit 中的文本都被拉伸(如果从纵向变为横向)或缩小(如果从横向变为纵向)。无论如何,无论方向如何,都可以使文本或图形保持相同的大小?
sceneView.overlaySKScene = SKScene(size: sceneView.frame.size)
我以非常简单的方式解决了这个问题。只需调整 overlaySKScene 的大小并将所有内容重新定位在
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator)
let width = sceneView.frame.height
let height = sceneView.frame.width
sceneView.overlaySKScene?.size = CGSize(width:width, height:height)
...
希望这可以帮助其他面临类似问题的人。
【问题讨论】:
【参考方案1】:你需要看看 SKScene 是如何工作的:
这意味着将叠加层设置为给定方向的 iphone 屏幕大小:
sceneView.overlaySKScene = SKScene(size: sceneView.frame.size)
现在我假设没有其他任何变化,这意味着您的 scaleMode
设置为 .fill
,这意味着拉伸图形直到所有边都被填充。
坐在纵向模式时,您不会注意到任何东西,因为它是 1:1 比例。
现在您将其翻转为横向。
系统将尝试将您的纵向屏幕尺寸转换为横向尺寸。
这意味着你会得到粗短的图形,因为它会拉伸你的两侧,并缩小你的顶部和底部以填充所有边缘。
这就是为什么编写像sceneView.overlaySKScene = SKScene(size: sceneView.frame.size)
这样的代码不好的原因。你最终会让自己感到困惑。
我总是建议使用 SKS 文件,或者设置恒定的场景大小,所以sceneView.overlaySKScene = SKScene(size: CGSize(750,1334))
然后,根据我想要显示叠加层的方式,我使用适当的缩放模式。
在我希望叠加层占据屏幕空间的确切百分比的游戏中,我使用.aspectFill
在我希望叠加层占用确切数量的像素空间的游戏中,我使用.resizeFill
通过查看scaleMode
,我现在知道我的场景应该如何表现。
使用.aspectFill
,我将需要检测方向何时翻转,届时要么呈现与方向对应的SKS,要么移动与方向对应的节点。
对于.resizeFill
,我需要创建一个在方向翻转时遵守的调整大小方法,并根据新大小按比例移动节点。
您可以在ViewController
中检测方向何时翻转
override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator)
然后使用视图进入场景以调用您的调整大小功能/加载新场景。
【讨论】:
以上是关于如何防止 SceneKit 中的 SpriteKit 覆盖拉伸?的主要内容,如果未能解决你的问题,请参考以下文章
SceneKit:如何将节点的移动限制在本地的一个轴上,而不是整个世界
如何从 SceneKit 中的 .dae 文件访问文本元素?
带有 SceneKit 的 SwiftUI:如何使用视图中的按钮操作来操作底层场景