游戏引擎学习第75天

news2025/1/8 13:53:29

仓库:https://gitee.com/mrxiao_com/2d_game_2

Blackboard: 处理楼梯通行

为了实现楼梯的平滑过渡和角色的移动控制,需要对楼梯区域的碰撞与玩家的运动方式进行优化。具体的处理方式和遇到的问题如下:

  1. 楼梯区域的过渡

    • 在三维空间中,楼梯的形状是一个从下到上的坡道,通常用两个关键点表示:底部楼梯和顶部楼梯。玩家在进入楼梯区域时,系统需要根据玩家的位置和楼梯的高度变化,平滑调整玩家的高度,使其能够顺利上升或下降楼梯。
    • 当玩家从楼梯的底部向上移动时,需要调整玩家的高度,使其按比例增加,直到达到楼梯的最高点;而当玩家从楼梯的顶部向下移动时,调整高度使其逐渐下降,直到到底部。
  2. 楼梯区域的具体实现

    • 玩家进入楼梯区域时,系统会检测玩家当前的位置,并根据楼梯的几何形状调整玩家的高度,使其沿着楼梯平滑移动。假设楼梯是斜坡形状,玩家的高度会根据位置变化而调整。
    • 这种调整虽然在理论上可以实现平滑过渡,但在实际执行中遇到了一些问题。特别是当玩家速度较快时,玩家可能会“跳过”楼梯,即快速通过楼梯区域而未能正确地下降,这导致了物理上不真实的行为,像是“曲线跳跃”现象。
  3. 楼梯的速度和角色大小问题

    • 当前角色的速度和体型没有被很好地调整到与楼梯的比例上,这意味着角色在楼梯上的运动速度过快,导致未能准确地与楼梯的高度变化匹配。因此需要对角色的速度和大小进行调整,以便能够更精确地适应楼梯的大小。
  4. 玩家碰撞处理的问题

    • 现有的碰撞处理方式存在问题,主要是当玩家接近楼梯时,会由于地面检测的方式(即不断将玩家位置调整到地面)造成玩家位置被错误地处理。例如,玩家可能会一直被推到楼梯的下方,再被推回地面,这会导致玩家“卡住”或者始终无法正确进入楼梯区域。
    • 这个问题的根本原因是,当前楼梯区域的碰撞检测并没有正确扩展到玩家进入区域的深度,因此玩家有时会被错误地放置在楼梯下方,导致无法进入楼梯。
  5. 实体边界的处理

    • 为了解决这些问题,需要对玩家实体的边界进行调整。实体的边界需要考虑到楼梯的具体尺寸和玩家与楼梯之间的交互方式。通过精确计算和调整边界,可以避免玩家进入楼梯时发生的不合理行为,确保碰撞检测和运动过渡更加流畅和自然。

sed

在这里插入图片描述

Blackboard: Z轴上的碰撞检测

当前的碰撞检测只在二维空间中进行,这意味着当玩家在移动时,如果有物体位于玩家的上方或下方,玩家仍然会与其发生碰撞。为了实现更自然的碰撞处理,需要对碰撞检测进行优化,确保物体在玩家上方或下方时不会与玩家发生碰撞,从而允许玩家能够通过物体的下方或上方自由移动。

具体的优化方案包括:

  1. 排除上下方物体的碰撞

    • 需要调整碰撞检测机制,使其能够区分物体是否位于玩家的上下方。对于位于玩家上方或下方的物体,应该将其排除在碰撞检测之外,这样玩家就可以自由地穿越它们,无论是从下方经过还是从上方通过。
  2. 改进工程实现

    • 需要对工程实现进行调整,确保碰撞检测不仅仅限于二维,而是能够在考虑上下方向的情况下进行。这样可以避免不必要的碰撞检测,从而提高系统的效率和准确性。

这种调整的目的是为了让玩家的运动更加流畅和自然,同时避免因不合适的碰撞检测导致的卡顿或不合理的行为。

Blackboard: 合理绘制

除了碰撞检测之外,还希望能够加入一些功能,使得绘制更加合理。这意味着需要改进渲染部分,使其能够根据场景和物体的实际位置进行更准确的绘制。这可能涉及到更精细的图形表现,确保物体在游戏世界中的显示效果更加真实和一致。

运行游戏展示多个可见楼层

目前,碰撞检测存在问题,导致两个楼层堆叠在一起,这在视觉上显得很混乱,很难理解。虽然还没有完成游戏的渲染部分,但需要提前规划一下如何在渲染中解决这个问题。当前的效果是,玩家进入楼梯时会碰到地面然后被弹回,这种情况看起来不自然,需要改善。

考虑到这一点,应该从基础的楼梯碰撞和地面处理做起。需要避免玩家进入地面并弹回的现象,思考如何让角色在楼梯上移动时显得更加平滑和合理。在这方面,还需要进一步的实验和调整,以确保碰撞和运动的处理更符合实际需求。

另外,尽管目前对游戏的渲染处理还没有进行很深入的设计,但至少需要思考如何在最终实现时让画面更加清晰,避免两个楼层在视觉上的重叠和混淆。

目前的关键挑战是如何处理玩家与楼梯之间的交互,并改善碰撞检测机制,使其能够更自然地处理楼梯上的上升和下降。

game_sim_region.cpp: 防止实体在地面上被重力加速

希望能够实现一个机制,当角色站在地面上时,不会因为重力而加速进入地面。换句话说,当角色站在地面时,应该有一个正常的力阻止角色向下加速,避免出现角色陷入地面的问题。角色应该能够平稳地沿着地面移动,只有在地面低于角色时,才会受到重力加速度的影响。

为了实现这个目标,考虑引入一个能量存储的机制,比如使用一个标志来表示角色是否当前处于地面上。这意味着在上一个时间步骤结束时,如果角色是站在地面上的,那么就不会应用重力加速度。这是一个简单有效的方案。

为了避免频繁地进行重叠检查,决定尽量减少重叠检查的次数,尤其是避免在每帧的开始和结束时都进行这些检查,因为这样做会浪费性能。可以通过快速检查的方式来确定角色是否接触到地面,从而决定是否需要应用重力。这种方法对于当前的游戏需求来说,应该是足够的,毕竟该游戏并没有过多依赖于重叠检查。

在这里插入图片描述

game_sim_region.h: 引入 EntityFlag_ZSupported

可以引入一个标志,例如“在地面上”(onground)或者“受支持”(supported),表示角色是否在垂直方向上受到支持。这个标志意味着如果角色在Z轴方向上有支持(即接触到地面),则不再应用重力。

具体来说,可以通过一个简单的标志检查来实现这一点,判断角色是否处于“受支持”状态。如果是受支持状态,就不应用重力;如果不是,则正常应用重力。这个标志检查可以通过一个设置好的标志进行处理,确保在角色没有接触地面时才会受到重力影响。

在这里插入图片描述

game_sim_region.cpp: 使用 EntityFlag_ZSupported

在这个实体的处理上,如果角色是Z轴受支持的状态,则不需要处理重力;如果没有Z轴支持,则正常应用重力。可以使用一个标志来表示是否受Z轴支持(例如“z supported”),并根据角色是否接触地面来调整这个标志。

每当角色接触到地面时,就会设置这个标志,表示角色已站在地面上;如果角色处于自由下落状态,则清除该标志。这样可以避免角色“下沉”到地面下,确保角色能够正确地沿地面运动。

这个方法通过设置和清除标志来帮助角色与地面交互,解决了角色穿透地面的问题,同时也避免了角色“掉进”地面的问题。接下来,检查这种方法是否能够解决之前遇到的楼梯问题,即是否需要调整楼梯的大小才能让角色正确地走上楼梯。

在这里插入图片描述

game.cpp: 移除楼梯高度填充

暂时移除这个标志后,问题仍然没有得到解决,导致结果并没有预期的那样工作。接下来需要检查具体的问题所在,可能是因为某些细节没有正确处理,因此还是没有达到预期的效果。为了解决这个问题,计划设置一个断点,专门调试角色(英雄)部分,看看是否能找到更具体的原因,从而确保实现正确的行为。

在这里插入图片描述

game_sim_region.cpp: 在 MoveEntity 中添加 BreakHere 变量

为方便调试,决定给自己设置一个简单的方法,以便随时在代码中设置断点。具体做法是,如果实体类型等于“英雄”,就能够触发断点,这样可以帮助更好地定位问题。
在这里插入图片描述

调试: 步入 MoveEntity 中的这一点

为了调试方便,使用了一种技巧,通过设置特定条件来触发断点,确保在调试版本中能够暂停代码执行,查看变量值等调试信息。这些条件在优化后的构建版本中会被编译器移除,不会影响性能。当前的调试目的是查看英雄角色的移动情况。通过检查重叠测试,确认了重力是否被正确跳过,且Z轴位置为零。发现角色的X、Y和Z坐标都为零,原因是摄像机一直在移动,并且角色位置被设置为零,始终位于摄像机的中心。因此,角色实际位置并未反映在调试中。
在这里插入图片描述

调试: 注意到 EntityFlag_ZSupported 仅在我们处于地面下方时被设置

问题在于,当角色不在地面下时,清除了“ZSupported”标志。这个清除操作导致了标志没有正确反映角色的地面状态,从而影响了重力的应用。
在这里插入图片描述

game_sim_region.cpp: 更改该 if 语句以包含地面

当前的问题是,当角色仍然站在地面上时,应该将角色视为“地面支撑”。之前的逻辑错误在于清除了这个标志,而当角色在地面上时,应该保留该标志。修正后的逻辑是,只有当角色的高度小于或等于地面时,才认为角色处于地面支撑状态。
在这里插入图片描述

调试: 步入这一点在 MoveEntity 中

问题出在角色和楼梯的碰撞检测上,发现角色的碰撞体积(entity)没有正确地设置高度,导致其在Z轴上没有深度。楼梯的碰撞体积也没有延伸到地面,造成无法正确检测到碰撞。这表明在处理三维碰撞时,缺少对Z轴深度的考虑,需要修复角色的Z轴设置,并确保楼梯碰撞体积正确地延伸到地面。
在这里插入图片描述

game.cpp: 给楼梯增加一些 Z 轴深度

发现问题的根源在于楼梯的碰撞体积(stairwell)没有正确设置Z轴深度,导致无法进行有效的碰撞检测。原本应该设置的代码行被意外删除了,造成楼梯区域没有正确包含需要检测的Z轴空间。
在这里插入图片描述

运行游戏并跳跃穿越楼层,发现现在我们与楼梯发生碰撞

目前存在的问题是角色可以通过跳跃无限向上浮动,导致楼梯区域的行为异常。这种现象与平台层的设计有关,平台层的处理方式导致了这种“漂浮”效果。为了修复这个问题,首先需要确保角色在上升和下降时更符合预期行为,特别是在上升时需要更加准确地把角色保持在楼梯的正确位置,而不是让角色漂浮下来。

game_sim_region.cpp: 指定另一个标准来确定何时希望保持固定在地面

在当前的设计中,当角色在地面上时,如果角色处于地面以下并且标记显示角色处于支持状态(例如“z支持”标记被激活),则会将角色“固定”在地面上,不允许它通过跳跃或其他动作离开地面。这样做的目的是确保角色在地面上时能够保持稳定,防止意外的漂浮或错误的加速度行为。这种方法能够帮助修复跳跃行为不当的问题,尤其是在上下楼梯时,角色应该始终保持在预定的地面位置,避免出现不必要的漂浮或跳跃。
在这里插入图片描述

game.cpp: 停止伙伴跟随我们

当前的设计中,角色(如伙伴)并不会主动进行碰撞检测或找到其他物体,而是保持在其当前的位置。此行为不包括角色主动寻找到达某些目标的位置,而是更多地依赖于角色在游戏世界中的静态表现,保持在预定的区域内。
在这里插入图片描述

在楼梯上上下行走

目前在楼梯系统中,角色的高度是根据其在楼梯中的水平位置来确定的。如果角色进入楼梯的最顶部,角色会立即上升到顶端。这种方式可能会导致玩家在接触到楼梯顶端时瞬间被推到最高点,进而影响游戏的流畅性。解决这个问题的思路之一是控制角色与楼梯的互动方式,避免这种“直接碰撞”导致的突然上升,可能考虑通过一些限制措施让玩家能够更自然地与楼梯进行交互。但也有可能为了游戏性,直接允许角色碰到楼梯顶部时立刻上升。

game.cpp: 让楼梯稍微长一点

为了更好地观察楼梯的互动效果,决定将楼梯的长度增加一些,并将其位置稍微调整。楼梯的高度增加到两块砖的长度,位置也调整到了更低的地方。调整过程中遇到了一些问题,比如楼梯被放置在门的上面,导致了冲突,因为系统不允许物体重叠在门的位置上。经过修正后,楼梯被调整为单块砖宽度,并且重新定位后可以顺利放置。

现在,楼梯长度增加后,角色可以顺利走上去,且在中间位置时,楼梯的高度层级会发生变化。整体来看,楼梯系统运行正常,效果也较为可靠。
在这里插入图片描述

运行游戏并演示传送到楼梯顶部

目前正在考虑改进楼梯系统的设计,以便让角色更自然地上楼而不是直接瞬移到顶部。可以通过将楼梯构建成由多个实体组成的方式来实现。具体来说,可以将楼梯设计成一个主实体,并为楼梯两侧添加两个额外的实体,一个用来阻止角色从下方穿过楼梯,另一个用来阻止角色从上方通过。这样做的目的是让角色能够从楼梯的中间进入,同时防止角色穿过楼梯的上下部分。

然而,问题在于,如果将这些实体设为墙壁,可能会导致角色的头部碰撞,因此需要对这些阻挡实体进行调整,使它们在适当的位置形成隐形墙,从而避免不必要的碰撞。

尽管这种方法看起来可以解决问题,但也有些矛盾之处,因为这种设计可能会过度增加楼梯系统的复杂性,使其需要特别的处理。最终是否采取这种方案仍在考虑中。

Blackboard: 考虑用多个组件构建楼梯

为了改善楼梯的设计,考虑将楼梯构建为由多个实体组成,其中包括一个主楼梯实体,以及两个其他实体,一个用于阻止角色从楼梯下方通过,另一个用于阻止角色从楼梯上方通过。这样可以避免角色直接穿越楼梯两侧,同时允许角色进入楼梯的中间部分。虽然这种设计可能会导致角色的头部与楼梯碰撞,但可以通过设置不可见的墙壁来避免这一问题。不过,是否采用这种方案还有些犹豫,因为这样会增加楼梯处理的复杂性,需要权衡是否值得这样做。

game_sim_region.cpp: 考虑在楼梯上进行预测碰撞测试

考虑在角色进入楼梯时限制其z轴高度变化。可以在角色移动过程中,通过碰撞检测来决定是否允许角色继续变化z轴高度。具体思路是,在每次碰撞检测中判断角色与楼梯的高度差,如果差距较小,允许角色继续移动,如果差距较大,则阻止角色继续上升或下降。

这种方式要求在每次碰撞检测后,计算角色和楼梯的高度差,并决定是否允许角色继续移动。虽然这个方法可以解决问题,但可能会使楼梯的碰撞检测逻辑更加复杂,需要评估是否值得增加这样的高度判断。

这个方法并不难实现,但仍需要考虑它是否是最合适的解决方案。

game_sim_region.cpp: 引入 TestWallNormal, TestHitEntity 和 SpeculativeCollide 来进行这些预测测试

为了处理楼梯的碰撞检测问题,首先提出了一个推测性的碰撞处理方法。基本的思路是通过模拟检测在碰撞发生时,角色是否能够通过楼梯。如果角色的高度差不大,且符合一定的步高限制,允许角色通过楼梯。如果步高差异太大,则阻止角色移动。

  1. 推测性检测

    • 在每次碰撞检测时,首先计算一个“测试位置”(TestP),这是角色在假设某个时间点上,如果发生碰撞时,会到达的位置。
    • 然后通过一个名为 SpeculativeCollide 的函数来检查角色是否能通过这个测试位置与楼梯发生碰撞。如果检测到碰撞,就会更新当前的碰撞信息,如时间点 tMin 和墙面法线 WallNormal,以及发生碰撞的实体 HitEntity
  2. 高度差检测

    • 在处理楼梯时,需要检查角色的高度差。如果角色的高度差小于一个设定的最大步高(例如 0.1 米),则允许角色通过楼梯。
    • 计算方法是,通过比较角色当前的 Z 值与楼梯的地面高度差值,如果差值小于或等于步高,就允许角色通过。
  3. 碰撞规则的调整

    • 目前楼梯没有设置碰撞标志(即楼梯和角色之间只有重叠检测,而没有实际的碰撞检测)。为了允许角色通过楼梯,需要在楼梯对象中添加一个碰撞标志。
    • 这样在处理碰撞时,如果遇到楼梯,会根据设定的碰撞规则判断是否允许角色通过。
  4. 停止碰撞处理

    • 在碰撞处理的过程中,如果角色与楼梯发生碰撞,应该允许角色继续通过,而不是停止。为此,需要在碰撞处理逻辑中添加一个特殊条件,识别是否是楼梯。如果是楼梯,则忽略碰撞停止的逻辑,允许角色通过。
  5. 遇到的问题

    • 在实际运行时,发现角色可以正常上下楼梯,但问题在于角色能否正确地进入楼梯。这个问题出在游戏开始时没有设置好楼梯的碰撞标志,导致检测时出现问题。
    • 因此,需要确保在游戏开始时,楼梯对象已经具备正确的碰撞标志,以确保碰撞检测的正确性。

总结而言,通过增加推测性碰撞检测,调整楼梯的碰撞标志,改进步高判断等方法,可以让角色正确地在楼梯上移动,避免不合适的碰撞和阻止移动的问题。
在这里插入图片描述

调试: 步入 SpeculativeCollide,发现我们没有与楼梯发生碰撞

考虑对楼梯的碰撞处理进行改进,目标是限制角色在进入楼梯时的Z轴高度变化。为了实现这一点,可以在碰撞检测中加入一种“猜测性”碰撞逻辑,通过预计算角色在碰撞发生时可能的坐标位置,来判断是否允许角色继续移动。

具体实现步骤是:

  1. 碰撞测试:在碰撞检测循环中,首先进行一次“猜测性”碰撞计算,确定角色碰撞后可能到达的坐标。
  2. 高度差判断:在计算完成后,如果角色的Z轴高度变化较小(例如小于某个设定的“步高”值),则允许角色通过楼梯,否则阻止角色继续上升或下降。
  3. 标记碰撞:在完成碰撞检测后,调整角色的最终位置,确保角色只会在允许的条件下进入楼梯。
  4. 优化和调整:虽然这种方法可以限制不合理的高度变化,但它的实现比较复杂,需要针对不同情况进行适当调整。

这个方法可以解决角色进入楼梯时出现的Z轴跳跃问题,但实现时可能需要考虑楼梯的特殊碰撞逻辑,确保角色在移动过程中始终符合游戏的物理规则。

在这里插入图片描述

game_sim_region.cpp: 翻转 SpeculativeCollide 的逻辑

实际上,问题出在步幅设置的高度过高,导致了碰撞。最终的目标是要判断是否发生了碰撞,答案是当步幅过高时发生了碰撞。
在这里插入图片描述

运行游戏并发现楼梯表现符合预期,除了我们没有沿着楼梯滑行,以及现在我们没有与墙壁碰撞

现在应该能够上下走动,但不能直接走到顶部,这是不允许的。只允许在最底部和最顶部走动,这一部分工作得很好。然而,问题在于无法沿着它滑行,似乎还有一些怪异的现象,不确定具体原因。可能是碰撞检测出了问题,无法正常滑行。看起来现在不再与墙壁发生碰撞,这可能是一个bug。
在这里插入图片描述

在这里插入图片描述

game_sim_region.cpp: 调整 SpeculativeCollide 的逻辑

看起来,猜测性碰撞通常是有效的,但在楼梯这种情况下需要特殊处理。问题出在猜测性碰撞导致所有碰撞检测都无法正常工作,尽管在其他表面上滑行正常。现在无法滑行的原因可能与楼梯的特殊性有关。可能是因为在某些情况下,碰撞处理没有按预期进行,尤其是当碰撞标志被设置为false时,可能会停止处理碰撞。
在这里插入图片描述

法向量设置错误

在这里插入图片描述

在这里插入图片描述

上下楼梯并注意到感觉很好

game.h: 处理待办事项列表

其实,处理这些碰撞检测问题相对简单。首先,想要做的是清理碰撞检测中的谓词,使规则更加简洁明了,方便理解。希望能够创建一套干净、清晰的标志和规则集,使特殊处理更容易理解。这可能涉及到将迭代过程集中处理,而不是在外部处理重叠等问题。

虽然目前已经解决了上下楼梯的问题,但渲染部分仍然需要处理。接下来,也许可以尝试在接下来的时间里做一些碰撞检测的工作。

game_sim_region.cpp: 在 sim_region 中添加 DefaultGroundLevel

问题在于,地面的位置依赖于相机的高度,z=0 只是相机所在的位置,这显然不对。正确的做法是将地面定义为始终处于一个固定的z平面上。这个平面可以是堆叠在一起的多个z平面,取决于不同的地面层级。虽然目前还不确定如何准确地确定地面的具体位置,但可以设定一个地面高度的参数,使得模拟区域中的地面始终按照这个参数来定义,并为其设置一个默认的地面高度。
在这里插入图片描述

game_sim_region.cpp: 根据 BeginSim 中的信息计算 DefaultGroundLevel

当获取到世界位置时,需要根据该位置来计算默认的地面高度。基于这些信息,应该根据地面高度来进行角色的移动。这样可以确保地面高度的正确性并根据当前位置进行调整。不过,这里可能会有一些复杂的情况,需要仔细处理。
在这里插入图片描述

Blackboard: 指定给定 sim 区域中的地面水平

问题的关键在于,地面高度并非统一的默认值,而是需要根据不同角色所在的具体地面层级来确定。在同一个区域内,不同角色可能处于不同的地面层级上,例如一个英雄站在高处,而怪物可能站在低处。因此,不能仅仅依赖默认的地面高度,而是需要根据每个角色的具体位置来确定他们的z值。

要做到这一点,需要一个基于z轴的基准,以便能够确定每个角色所在的地面层级。在这个基准上,可以计算角色在当前z平面上的位置,进而判断他们处于哪个层级。具体来说,需要能够识别每个层级的高度,并根据角色的z坐标判断他们的位置。这样才能正确处理每个角色的地面层级,并实现精确的碰撞和移动处理。

game_sim_region.cpp: 将 DefaultGroundLevel 重命名为 GroundZBase

核心思路是,需要一个类似“地面基准”的东西,来准确确定每个角色的地面层级。为了找出当前的地面高度,可以将角色当前位置的z坐标截断,得到一个新的z值,这个值代表角色所处的地面层级。通过这个“地面基准”,可以确定角色的底部支撑面,并据此确定其地面高度。这样就能清楚地知道角色站在哪个地面层级上,从而正确处理碰撞和移动。
在这里插入图片描述

Blackboard: 快速跳到正确的地面高度

在楼梯的处理上,简单的截断方法并不适用,因为当角色从楼梯上走下时,需要将其位置“吸附”到最近的地面层。对于这种情况,截断只对某些情况有效,但无法处理所有场景,特别是在角色走出楼梯时,地面高度应该根据具体情况进行调整。为了正确处理楼梯,应该在角色离开楼梯时,将其地面层级“吸附”到最近的地面层。如果角色走出楼梯或从楼梯顶部跳下来,我们希望角色的地面高度能够调整到接下来的有效地面,而不是简单地沿用旧的地面层级。

如果没有特殊的处理,角色可能会错误地“跳”到不合适的地面层,导致问题。因此,在处理楼梯时,需要加入智能的地面调整规则,确保当角色从楼梯顶端走下来时,能够正确地对接到下一个地面层。

game.h: 需要对地面高度进行概念化,以便相机可以自由地放置在 Z 轴上,并在一个 sim 区域中拥有多个地面高度

这部分处理确实很复杂,目前还没有找到一个理想的解决方案,而时间也所剩不多。因此,暂时先放下这个问题,将其作为待办事项。接下来的任务是需要明确地面层级的概念,确保相机可以自由地放置在z轴上,并且在同一个模拟区域内能够处理多个地面层级。这是当前需要解决的主要问题。
在这里插入图片描述

运行游戏并注意到熟悉物和怪物错误地被吸附到我们的 Z 轴位置

目前已经存在一个与地面层级相关的bug。具体来说,当熟悉的角色和怪物一起向上移动时,它们被错误地“吸附”到z=0,这意味着它们被认为是站在地面上。实际上,这两个角色应该保持在同一个z层级上,而不是随着地面高度变化。因此,在解决这个问题后,角色的z层级应该保持一致。这个问题非常重要,因为它影响到角色与环境的交互。除此之外,其他部分看起来都还好,没有特别奇怪的情况。

game.cpp: 根据 Z 轴高度调整实体位置

在渲染时,可以尝试通过调整z值来改变物体的xy坐标,以模拟不同层级之间的视觉效果。例如,可以为每个实体根据其z位置应用一个“偏移因子”(例如z * 常数),将这个因子应用到实体的xy坐标上。这样,实体在不同的高度层之间会有更明显的区分,帮助更好地理解物体的位置关系。

这种方法可以让多个平面上的物体看起来有明显的上下层次,尤其是在可以看到透视的情况下。此外,这种渲染方法能够帮助识别物体是否处于玩家的上方或下方。然而,由于当前缺乏3D碰撞检测,无法直接通过碰撞判断物体的遮挡和交互,但这种渲染调整为后续实现3D碰撞检测提供了直观的视觉反馈。
在这里插入图片描述

我猜你们的引擎会管理任意高度的地面水平?你们真的需要这样做吗?像是向下投射攻击到一个怪物下面,听起来挺有趣的

总结一下,用户正在确保引擎能够支持任意的地面高度,适应不同的游戏玩法,包括处理楼梯、地面上的洞以及其他地形特征。主要工作集中在碰撞检测和响应方面,因为绘制部分相对简单。目标是确保引擎足够灵活,可以处理涉及地面互动的各种游戏场景。

为什么不直接使用 X 和 Y 屏幕坐标来检测 sim 区域?

正在探索使用屏幕上的 x 和 y 坐标来检测模拟区域,但不确定具体的实现方法或如何处理这一问题。

你是否也应该检查楼梯顶部的“阶梯步骤”?看起来你可以比在楼梯底部提前退出

发现当前在处理楼梯的碰撞检测时存在问题。现有的处理方法只检查玩家是否踏上楼梯,但并没有检查玩家是否能够从楼梯上离开。为了修复这一点,用户建议在玩家离开楼梯时,检查其 z 坐标,以确保玩家不会在未到达楼梯底部时就离开楼梯,进而防止楼梯出口提前触发。

你能否在黑板上做一个关于“实体位置系统”的概览吗?现在它已经“完成”了?我有些理解困难(希望你明白我的问题)

该系统的世界和实体位置管理采用了稀疏世界存储结构,目的是有效地存储和模拟一个大的世界。具体来说,世界被分割成不重叠的块(chunk),每块只包含实际存在的数据。这种方式避免了像传统的大型数组那样的存储浪费,使得即使世界呈现出长条或螺旋形等复杂形状,也能高效存储。

在进行模拟时,会选择一个特定的区域来进行处理,通常这个区域是围绕某个点,形成一个三维的框来模拟所有与之相关的实体和几何数据。这个框包含了摄像头当前可见的区域,并且还会包括一个更大范围的区域以进行模拟。实体在这些区域中的位置是以它们所在块的索引加上在该块内的偏移量来存储的。

模拟过程中,实体的位置是基于该块的中心点偏移来计算的,模拟结束后,将它们的位置数据重新写回世界。具体来说,实体的偏移量会根据新的块进行更新,如果实体迁移到新的块,需要将其从原来的块移除并放入新块,同时更新其相对于新块的偏移量。

总的来说,这种方法通过分块和偏移存储的方式,使得大世界能够高效存储和更新,同时保持较低的计算和存储成本。

为什么屏幕上绘制的东西的顺序有些杂乱(一些树木重叠,另一些则正常)?

问题出在屏幕上显示的顺序不正确,原因是尚未进行排序。

难道按照顺序绘制它们不是很简单吗——每一层从左到右,从上到下绘制实体?

虽然看起来按层次从左到右、从上到下绘制实体似乎很简单,但实际上还涉及到Z轴排序问题。绘制顺序不仅仅是按水平和垂直方向排序,还需要考虑实体的Z轴位置。当前的问题是,尚未进行排序,因此无法正确绘制。

排序的实现需要等到渲染阶段再进行,因为在那之前,必须先缓存所有实体的状态,之后才能进行排序。由于目前排序并不会影响其他工作进度,因此不急于实现排序,等到渲染阶段再处理更为合适。

不同楼层的东西看起来好像被上移了,是不是渲染时 Z 偏移造成的?

不同层次的实体在渲染时看起来有些偏移,是因为Z轴的偏移造成的。可以通过调整实体的偏移量来解决这个问题,避免实体在渲染时出现不必要的上移。如果不希望看到这种上移效果,可以通过修改偏移方式来实现,这样实体就不会被“推”上去。具体来说,通过调整Z轴的偏移量,可以控制实体的显示位置,从而避免这种问题。

这个问题的根源在于Z轴偏移量,因此可以通过调整来消除这种偏移效果,虽然目前尚未完全确定是否需要这样做,但这就是偏移现象的原因。

这会导致顶部的墙壁在相机锁定时被绘制在屏幕上方,而不是跟随角色吗?

这个问题可能会导致顶部的墙壁在摄像机固定时被绘制到屏幕上方,而不是跟随角色。虽然目前可能不完全确定如何处理,但可以通过调整相关设置来优化这一点。
至于墙壁的位置,确实还没有最终确定如何定位它们。随着更多世界构建工作的进行,应该能够更清楚地决定墙壁的正确位置和行为。

当你使用自定义内存分配器分配所有东西时,你仅将指针存储在栈上吗?

关于使用自定义内存分配器时,是否只使用栈来分配指针的问题,实际上,自定义内存分配器仍然可以用指针,只是分配的内存来源不同。栈内存和堆内存是两种不同的内存分配方式,栈内存通常用于局部变量,而堆内存则适用于动态分配的内存。自定义内存分配器的使用并不限制只能使用栈内存,它依然可以使用指针来操作自定义分配的内存。

你不担心三维会让实体的 AI 变得复杂,从而影响性能吗?

对于三维空间是否会使实体的AI变得复杂,进而影响性能的问题,实际上并不太担心。AI的调优通常相对简单,性能上也不会产生太大影响,尤其是当AI主要与玩家直接互动时。

问题的关键在于如何处理大规模的世界和其他不在玩家周围的实体。为了避免性能问题,如果需要模拟大量的其他实体,可以简化这些实体的AI。当玩家不与它们互动时,可以让它们执行更粗略的行为,不需要复杂的决策过程。这样可以在保证性能的同时,避免过多的计算负担。

你什么时候会切换回居中相机?看起来它没有出现在待办事项列表上

关于摄像机是否会切换回中心位置的问题,目前还没有明确的决定。已经展示过两种方式都能正常工作,因此不太需要再进行额外的测试。摄像机的对齐方式会根据游戏开发的进展进行调整,具体的设定将在游戏开发过程中通过实验来决定。

为什么要将块的原点设为块的中心,而不是设为其中一个角落?

将区块的原点设为区块中心而不是某个角落,并没有特别的理由。曾经使用过角落作为原点,但后来看不出任何非得使用其中一个的特别原因。一个可能的原因是,使用中心可以更容易地处理一些较大的实体。例如,如果实体跨越区块的边界或稍微插入区块内,使用中心作为参考点更直观,因为它不对称,而如果使用角落则更难以管理。总体来说,选择中心可能在某些情况下更方便,但从整体来看,这个选择可能是任意的。

抱歉让你不清楚。当你使用自定义内存分配器时,栈上除了指针之外还存储其他东西吗?

关于是否只能在栈上存储指针,实际上,栈不仅仅存储指针,还存储许多其他内容,比如屏幕上显示的所有东西。例如,界面上的坐标、状态信息等,都会存储在栈上。栈用于存储线程中的所有局部变量及临时数据。所以,并不是所有东西都只存储指针,栈的作用是存储各种数据,而不仅仅是指针。对于问题本身,可能并没有完全理解其含义。

如果相机足够远离玩家,玩家是否会进入像其他实体一样更简单的例程?

如果摄像机离玩家足够远,玩家是否会进入类似其他实体的简化流程,实际上不太可能发生,因为摄像机是设定为始终跟随玩家的。所以,即使摄像机远离玩家,这种简化的行为也不会发生。

可能的碰撞测试是否应该使用 TestHitEntity 而不是 TestEntity,还是它们是相同的?你能简要回顾一下 HitEntity 更改的流程吗?

在碰撞测试中,TestHitEntityTestEntity 实际上是相同的。最初,碰撞检测只会直接设置被碰撞的实体,以标记是否发生了碰撞。然而,后来添加了一个中间步骤,通过“试探性碰撞”来检查碰撞是否有效,只有在验证通过后,才会正式记录碰撞结果。这样做是为了避免在初步检测到碰撞时立即确认结果,而是通过额外的检查来决定是否接受这一碰撞。

具体而言,当检测到初步碰撞时,会暂时记录这个碰撞,但不会立刻处理它。然后,系统会执行试探性碰撞,看看是否应该接受这个碰撞,如果试探性碰撞的结果表明可以继续处理,才会正式记录并处理这个碰撞。这种方式增加了一个层次,确保碰撞检测更为精确。

此外,对于楼梯的处理,当角色从楼梯上移动时,需要做进一步的处理。可以通过检查角色与楼梯的相对位置来判断是否允许角色上下楼梯。例如,只有当角色的Y坐标处于楼梯的开始和结束之间时,才能允许角色从楼梯上下。这种方式可以防止角色在楼梯的中间位置上或下楼,确保碰撞逻辑更合理。

然而,这样的处理需要额外的工作,尤其是楼梯的实际碰撞区域需要比绘制的宽度小,因为碰撞检测只会检查楼梯的内部区域。这个方法解决了在楼梯上或下楼时的行为问题,但仍然需要进一步改进,例如在楼梯的两端进行更多的限制,防止角色在不合适的位置上下楼。
在这里插入图片描述

你现在可以取消掉第一个 HitThis == true,避免进行其他检查

在讨论碰撞检测的优化时,有人建议可以通过在首次碰撞检查时直接跳过其他检查(即,如果HitThistrue,就不再做后续检查)。然而,这种优化并不成立,因为碰撞检测的目标是找到最早发生的碰撞。因此,不能跳过后续的碰撞检测,因为可能存在一个比当前碰撞更早发生的碰撞。为了确保计算最早碰撞,必须执行所有的检查,以确定最终哪个碰撞发生得更早。

总的来说,提前跳过碰撞检测的优化会导致结果不准确,因此这种优化不适用。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2272578.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

算法的学习笔记—不用常规控制语句求 1 到 n 的和

😀前言 在算法编程中,有时我们会遇到一些特殊的限制条件,这些限制会迫使我们跳出常规思维。本文讨论的问题就是一个典型案例:在不能使用基本控制语句的情况下,如何求解 1 到 n 的和。这个问题不仅考验编程技巧&#xf…

网络协议安全的攻击手法

1.使用SYN Flood泛洪攻击: SYN Flood(半开放攻击)是最经典的ddos攻击之一,他利用了TCP协议的三次握手机制,攻击者通常利用工具或控制僵尸主机向服务器发送海量的变源端口的TCP SYN报文,服务器响应了这些报文后就会生成大量的半连…

141.《mac m1安装mongodb详细教程》

文章目录 下载从官网下载安装包 下载后双击解压出文件夹安装文件名修改为 mongodb配置data存放位置和日志log的存放位置启动方式一方式二方式二:输入mongo报错以及解决办法 本人电脑 m2 pro,属于 arm 架构 下载 官网地址: mongodb官网 怎么查看自己电脑应该下载哪个版本,输入…

C++ operator = 返回void 会发生什么?

1.operator 正常情况 #include <iostream> using namespace std;class Box { public:Box(double L) : length(L) {}Box(const Box& b){}Box& operator (const Box&){return *this;}public:double length; // 长度 };int main() {Box box1(1.0);Box box2(…

Redis中字符串和列表的区别

在 Redis 中&#xff0c;字符串&#xff08;String&#xff09;和列表&#xff08;List&#xff09;是两种截然不同的数据类型&#xff0c;它们各自有着独特的特点和适用场景。 数据结构 • 字符串&#xff08;String&#xff09;&#xff1a; • 在 Redis 中&#xff0c;字符串…

Elasticsearch JavaRestClient版

文章目录 初始化RestHighLeveClient&#xff08;必要条件&#xff09;索引库操作1.创建索引库&#xff08;4步&#xff09;2.删除索引库&#xff08;3步&#xff09;3.判断索引库是否存在&#xff08;3步&#xff09;4.总结&#xff1a;四步走 文档操作1.创建文档&#xff08;4…

使用Dinky快速提交Flink operator任务

官网地址&#xff1a;K8s集成 | Dinky 1.目前使用版本 Dinky1.2.0、Flink1.18.1、Flink operator0.10.0 2.制作镜像 2.1创建DockerFile ARG FLINK_VERSION1.18.1 FROM flink:${FLINK_VERSION}-scala_2.12 RUN mkdir -p /opt/flink/usrlib COPY commons-cli-1.3.1.jar …

探索数字化展馆:开启科技与文化的奇幻之旅

在科技飞速发展的当下&#xff0c;数字展馆作为一种新兴的展示形式&#xff0c;正逐渐走进大众的视野。数字展馆不仅仅是传统展馆的简单“数字化升级”&#xff0c;更是融合了多媒体、数字化技术以及人机交互等前沿科技的创新产物。 数字展馆借助VR、AR、全息投影等高科技手段&…

免费GEMINI模型使用及API调用

一、概述 谷歌最新发布的Gemini 2.0 FLASH模型为AI应用带来了新的可能性。该模型分为两个版本&#xff1a;gemini-2.0-flash-exp 和 gemini-2.0-flash-thinking-exp-1219。这两个模型目前限时免费使用&#xff0c;用户可以通过智匠MindCraft客户端或小程序直接体验&#xff0c;…

调整Python+Pytest+Allure+Yaml+Pymysql框架中需要执行的用例顺序

当pytest框架中有时时候会因为用例的前后关联关系需要调整用例执行顺序时则可以跟进具体的要求调整pytest.ini配置文件中执行用例文件夹的前后顺序 当如果是需要调整某个文件夹中用例的执行顺序时&#xff0c;则跟进具体的文件调整对应testcases中test_*.py文件中的执行顺序

容器技术思想 Docker K8S

容器技术介绍 以Docker为代表的容器技术解决了程序部署运行方面的问题。在容器技术出现前&#xff0c;程序直接部署在物理服务器上&#xff0c;依赖管理复杂&#xff0c;包括各类运行依赖&#xff0c;且易变&#xff0c;多程序混合部署时还可能产生依赖冲突&#xff0c;给程序…

系统思考—变革之舞

彼得圣吉在《变革之舞》中提到&#xff1a;变革的关键是持续学习。在这个变化万千的世界里&#xff0c;组织不能停留在过去的经验上&#xff0c;我们如何系统性的抛弃过去成功的经验&#xff0c;不断学习新技能&#xff0c;适应复杂的环境。每个人不仅要学会解决眼前的问题&…

OpenCV的人脸检测模型FaceDetectorYN

OpenCV的人脸检测模型FaceDetectorYN 1. 官网地址2. 如何使用2.1.到opencv_zoo下载模型文件和代码2.2. 下载文件展示2.3. 修改了demo支持读取视频文件&#xff0c;默认是图片和摄像头## 2.4 效果展示 1. 官网地址 https://docs.opencv.org/4.x/df/d20/classcv_1_1FaceDetector…

25/1/6 算法笔记<强化学习> 初玩V-REP

我们安装V-REP之后&#xff0c;使用的是下面Git克隆的项目。 git clone https://github.com/deep-reinforcement-learning_book/Chapter16-Robot-Learning-in-Simulation.git 项目中直接组装好了一个机械臂。 我们先来分析下它的对象树 DefaultCamera:摄像机&#xff0c;用于…

Linux驱动开发:深入理解I2C时序(二)

在Linux驱动开发中,I2C时序的理解和正确处理是保证I2C设备正常工作和通信的关键。I2C协议的时序特性决定了数据的有效传输和设备间的协作。因此,掌握I2C的时序细节,以及如何在Linux内核中进行时序处理,能够让开发者更好地处理设备通信问题。 本文将继续深入探讨I2C通信协议…

Java100道面试题

1.JVM内存结构 1. 方法区&#xff08;Method Area&#xff09; 方法区是JVM内存结构的一部分&#xff0c;用于存放类的相关信息&#xff0c;包括&#xff1a; 类的结构&#xff08;字段、方法、常量池等&#xff09;。字段和方法的描述&#xff0c;如名称、类型、访问修饰符…

《Python游戏编程入门》注-第9章8

2 游戏信息的显示 在游戏窗口的上部会显示游戏分数、游戏关卡、剩余砖块数以及剩余小球数等信息,如图12所示。 图12 游戏信息显示 使用如图13所示的代码实现以上功能。 图13 显示游戏信息的代码 其中,print_text()函数MyLibrary.

idea插件之 translation翻译插件

文章目录 1. translation翻译插件2. 效果图3. 延伸&#xff08;默认自动配置微软翻译&#xff09; 1. translation翻译插件 Settings 》Plugins 》Translation PS&#xff1a;安装后需要重启idea。 2. 效果图 右键选择插件&#xff0c;或者ctrlshifty 直接翻译代码。 3. 延伸…

Infineon PSoC 4 CapSense ModusToolbox IDE - 系统生态篇

本文档说明了 ModusToolbox 软体环境的 4 个层面&#xff0c;该环境为 CapSense 设备和生态系统提供支援。本文是 Infineon PSoC 4 CapSense ModusToolbox IDE-系统介绍的延伸篇 (Infineon PSoC 4 CapSense ModusToolbox IDE -系统介绍篇 - 大大通(简体站))。 什么是ModusToolb…

PyCharm+RobotFramework框架实现UDS自动化测试——(一)python-can 库的安装与环境配置

从0开始学习CANoe使用 从0开始学习车载测试 相信时间的力量 星光不负赶路者&#xff0c;时光不负有心人。 文章目录 1. 概述2.安装 python-can 库—基于pycharm在对应的工程下3. 在任意盘中安装环境4. 导入 can 模块语法5. 配置 CAN 接口6.CANoe设备连接语法 1. 概述 本专栏主…