【问题标题】:Following other object with delay in Unity在 Unity 中延迟跟随其他对象
【发布时间】:2018-04-11 16:13:00
【问题描述】:

我正在 Unity 中制作 2D 游戏,并试图让一个角色接连移动以攻击他们。为了使这个动作看起来自然,我想添加一个延迟,即角色遵循其他角色所走的确切路径,但落后 0.5 秒。

由于我将状态模式用于我的角色行为,因此移动逻辑位于可编写脚本的对象中。这意味着我不能直接访问 Update() 或 IEnumerator,但我通过传入对附加到 characterGameObject 的 MonoBehaviour 脚本的引用来解决这个问题(不确定这部分是否相关,但包括在内以防万一一些我不知道的奇怪副作用)。

我首先尝试使用 IEnumerator,每次对可编写脚本对象的 Execute() 调用(每个游戏周期发生一次)都会启动一个协同程序,它首先等待一段时间,然后移动对象。

void Execute(StateController stateController){

Vector3 movementVector = 
Vector3.MoveTowards(actor.transform.position,targetWithOffset,
Time.deltaTime);

stateController.StartCoroutine(stateController.MoveTorwards(movementVector, 
    delay));

}

public IEnumerator MoveTorwards(Vector3 movementVector, float delay)
{
yield return new WaitForSeconds(delay);
gameObject.transform.position = movementVector;
}

然而,这导致了一个极其奇怪的故障运动,角色在向目标移动时不断地在自己周围传送。

有人对此有所了解吗?我是否错过了一个基本简单的实现,或者我的方法是否正确并且故障运动来自副作用(值得怀疑,因为代码在没有 IEnumerator 的情况下完美运行,并且当延迟 var 设置为零时故障仍然发生。

【问题讨论】:

  • 您需要使用列表或队列以及每个动作之间的位置、旋转和时间结构来执行此操作。然后,您可以在其他对象上使用它。使用每个结构后,将其移除。如果您尝试执行我上面所说的操作但遇到问题,请使用该代码编辑您的问题。
  • @Programmer 不需要录制时间;给“追随者”一个speed 需要更少的数据并且更灵活。另外,假设“跟随者”在路径中总是看起来“向前”,那么也不需要旋转,因为它可以从当前位置或最后一个节点的方向算出,到下一个节点的位置。
  • 上面的帖子是我用来实现记录和回放功能的技术,它比不记录旋转和时间效果更好。我总是移动另一个对象的旋转,不知道 OP 是否也需要旋转它,但我认为这是为了节省更多的 cmets。此外,从记录的时间中减去速度。您只需获得更准确的结果,尤其是在延迟时间较长(1 秒及以上)的情况下。
  • @AlmightyR “给“追随者”一个速度需要更少的数据并且更灵活”...是的,但是如果你需要延迟另一个对象1 秒或更长的时间,它不会很好地工作。另一个对象将跳过位置/旋转。它看起来像切割一条线,而不是你所期望的。 这实际上可能导致以下对象穿过其他对象,这不是一个好主意,除非 OP 对此很好。
  • “另一个对象将跳过位置/旋转。” - 如何?我不是在说让“跟随者”假设每帧“跟随”的记录位置(有延迟);更好的算法是让“跟随者”实际上跟随路径作为路径,而不是作为一组点。点对点算法不允许 “跳过” 那样的行为。 --- 此外,AFAIK,无需进一步检查,任何一种算法都可能产生您描述的 “幽灵穿透” 效果;事实上,在设置(没有物理)而不是跟随(可以做物理)的情况下,它甚至更更糟

标签: c# unity3d


【解决方案1】:

角色遵循其他角色所走的确切路径,但 0.5 秒 后面。


第1步:定义“确切路径”是什么。

实现一个 "consumable" 点对点path 结构(即Queue<Vector3>),并通过记录第一个字符在更新时的当前位置来继续记录第一个字符的路径循环(即Update(),直接或间接)。


第 2 步:尝试“使用”从最旧节点到最新节点的路径。

现在,忽略延迟的想法;只需确保路径系统正常工作,并且移动看起来正确。

在跟随实体的每次更新(Update() 或间接)时,向路径中的下一个节点移动,直到到达;当它是,“消费”那个节点(从“路径”中删除,即.Dequeue()),以及任何下一个如此接近以至于被认为是“到达”的节点;如果还有任何“未到达”节点,这显然会使实体开始走向下一个节点。


第 3 步:在开始时和路径为空之后延迟路径的跟踪(和/或基于事件和触发器,如果​​您需要更多)。

当路径从<=1 个节点的长度/计数变为>1 个节点时,在开始跟踪第一个(或下一个)段之前,请执行延迟;这将创建您正在寻找的效果。

如果路径的长度再次变为<=1,则意味着它在创建时立即被消耗,这意味着“追随者”实体已到达“被追随”实体。在这种情况下,根据您的描述,“关注者”实体攻击“关注者”实体;意味着游戏不会立即结束;在这种情况下,为了让“跟随者”在开始移动后再次与自己保持距离(暗示应该是这种情况),在“跟随者”开始跟随之前再次应用延迟。 --- 这种实现延迟的方法使这种行为自动发生在这种情况下,因为它与在“开始”时所做的检查相同(实际上是一个循环);无需二次检查。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多