我在 SpriteKit 场景中遇到节点 zPosition 的问题。
我正在构建一个管理器节点,它支持节点 zPosition 的“层式”管理,本质上使您能够摆脱 zPosition 属性的手动管理,而是使用类似addNodeUnder(node:SKNode)和 创建组的方法添加节点。
问题是,根据我所做的操作,绿色和黄色节点应该位于红色节点之上 。
我制作了自己的小调试器,以分层顺序显示 SceneKit“场景图”:
Node of type LMManagerNode has zPosition = 0.0 and has children :
Node of type LMWarpperNode has zPosition = 0.0 and has children :
Node of type SKSpriteNode ('Red node') has zPosition = 0.0.
Node of type LMWarpperNode has zPosition = -100.0 and has children :
Node of type SKSpriteNode ('Blue node') has zPosition = 0.0.
Node of type LMWarpperNode has zPosition = 100.0 and has children :
Node of type LMGroupNode ('Test group') has zPosition = 0.0 and has children :
Node of type LMWarpperNode has zPosition = -150.0 and has children :
Node of type SKSpriteNode ('Yellow node') has zPosition = 0.0.
Node of type LMWarpperNode has zPosition = -200.0 and has children :
Node of type SKSpriteNode ('Green node') has zPosition = 0.0.
Run Code Online (Sandbox Code Playgroud)
如你看到的 :
zPosition = 0zPosition = -100zPosition = 100既然包含红色节点的节点有zPosition = 0,并且包含绿色和黄色节点的节点有zPosition = 100,那么这两个节点不应该在红色节点的 顶部吗?
顺便说一句,ignoresSiblingOrder我的SKView设置为...false
编辑:这很奇怪:yellowNode.zPosition = 1000 确实使黄色节点位于红色节点之上。怎么可能?
编辑#2 这是我的调试功能的代码:
func renderNodeHieararchyForNode(node:SKNode, index:Int) {
var i = 0
var beginning = ""
while i != index {
beginning += " "
i++
if i == index {
beginning += " "
}
}
print("\(beginning)Node of type \(node.dynamicType) \(node.name != nil ? "('\(node.name!)')" : "") has zPosition = \(node.zPosition)\(node.children.count > 0 ? " and has children :" : ".")")
for (i,child) in node.children.enumerate() {
renderNodeHieararchyForNode(child, index: index+1)
if i == node.children.count-1 {
print("")
}
}
}
func renderNodeHiearchyForNode(node:SKNode) {
renderNodeHieararchyForNode(node, index: 0)
}
Run Code Online (Sandbox Code Playgroud)
如您所见,我仅使用 SpriteKit 框架方法来显示它,因此我的调试器的输出绝对是正确的。
从苹果的文档来看,
\n\n\nz 位置是 node\xe2\x80\x99s 相对于其父节点的高度,就像 node\xe2\x80\x99s 位置属性表示其相对于父\xe2\x80\x99s 位置的 x 和 y 位置一样。因此,您可以使用 z 位置将节点放置在 Parent\xe2\x80\x99s 位置的上方或下方。
\n
和
\n\n\n当您考虑 z 位置时,节点树的渲染方式如下:\n
\n\n
\n- 计算每个节点\xe2\x80\x99的全局z位置。
\n- 节点按从最小 z 值到最大 z 值的顺序绘制。
\n- 如果两个节点共享相同的 z 值,则先渲染祖先节点,然后按子节点顺序渲染兄弟节点。
\n
在哪里
\nnode's global z position = node's z position + node's parent's z position + node's parent's parent's z position + ...\nRun Code Online (Sandbox Code Playgroud)\n使用此公式,节点的全局 z 位置为
\nred is 0 (0 + 0 + 0)\nblue is -100 (0 + -100 + 0)\nyellow = -50 (-150 + 0 + 100 + 0)\ngreen = -100 (-200 + 0 + 100 + 0)\nRun Code Online (Sandbox Code Playgroud)\n从最高到最低的全局 z 位置(基于规则 1 和 2),节点在场景中出现的顺序为
\nred\nyellow\ngreen / blue\nRun Code Online (Sandbox Code Playgroud)\n其中红色出现在黄色之上,黄色出现在绿色/蓝色之上。由于绿色和蓝色具有相同的全局 z 值,因此使用兄弟顺序(规则 3)来确定绘制顺序。在本例中,绿色的顶级LMWarpperNode节点(即,其曾祖父母)被添加到LMManagerNode蓝色LMWarpperNode节点之后的节点,因此首先绘制蓝色,然后在蓝色上绘制绿色。
这是最终的(相反的)抽签顺序
\nred 0\nyellow -50\ngreen -100\nblue -100 (parent was added to scene before green's great grandparent)\nRun Code Online (Sandbox Code Playgroud)\n