【问题标题】:Is there a way to create a curve when launching a gameobject to the player?有没有办法在向玩家启动游戏对象时创建曲线?
【发布时间】:2020-08-06 12:32:31
【问题描述】:

这是我迄今为止尝试过的: 我创建了一个光线投射,如果它击中第 8 层(需要将对象发射到玩家的层)上的对象,我调用 SlerpToHand() 函数。

    private void Update()
    {
        if(Physics.Raycast(transform.position, transform.forward * raycastLength, out hit))
        {
            if(hit.collider.gameObject.layer == 8)
            {
                // Launch object to player
                SlerpToHand(hit.collider.transform);
            }
        }
    }

在 SlerpToHand() 内部,我将对象的位置设置为 Vector3.Slerp(),该向量是根据命中对象中的值创建的。

    private void SlerpToHand(Transform hitObj)
    {
        Vector3 hitObjVector = new Vector3(hitObj.transform.position.x, hitObj.transform.position.y, hitObj.transform.position.z);

        hitObj.position = Vector3.Slerp(hitObjVector, transform.position, speed);
    }

但这一切的结果都是错误的,物体只是被传送到了玩家的手中。 Vector3.Slerp() 不是向玩家弯曲对象的好方法吗?对于上下文,我正在尝试重新创建半条命:Alyx 的抓握手套。手势还有一些工作要做,但我只是想降低对象曲线。非常感谢您的帮助,如果需要更多信息,请告诉我。

【问题讨论】:

    标签: c# unity3d


    【解决方案1】:

    见团结docs

    public static Vector3 Slerp(Vector3 a, Vector3 b, float t);

    这里,t 是两个输入值之间的归一化位置。这意味着,如果 t = 0,结果将恰好是第一个值。如果 t = 1,结果将恰好是第二个值。如果 t = 0.5,结果将是两个值的中间值。

    因此,通常,您需要在每次更新时调用 Slerp,逐步将 t 从 0 增加到 1。为此,通常使用 Time.deltaTime(等于更新之间的时间)。对于速度控制,请将您的速度乘以 Time.deltaTime。

    Update()
    {
        if (t < 1)
        {
            t += Time.deltaTime * speed;
            hitObj.position = Vector3.Slerp(startPosition, endPosition, t);
        }
    }
    

    ...在这种情况下,要开始移动,您只需要设置 t = 0。可能,您必须在这里实现自己的逻辑,但这应该说明这个想法。

    另外:

    • Slerp 用于在向量方向之间进行插值,位置使用 Lerp。
    • 考虑使用 DOTween 插件 - 对于此类情况,它免费且功能强大。

    【讨论】:

    • 嗨,是的,这行得通。谢谢您的回答。为什么要使用 DOTween?
    • DOTween 是一款强大的工具,适用于各种动画,由您的代码制作而成。想搬东西吗?旋转?弹跳,跳跃?淡入淡出,以及针对不同组件的许多特定操作——这一切都可以通过 DOTween 轻松完成。被称为“补间”的动画是可控的——您可以暂停、停止、重新启动、重用它们。有一个强大的路径工具,它允许您从点动态创建路径,并在这些路径上启动对象。基于动画曲线的大量不同缓动选项,包括自定义缓动选项。性能非常好。
    • 例如,在你的情况下,你不应该存储任何额外的 t 变量,并且每次更新都调用一些函数 - 你只需要一行代码就可以以给定的速度将某个对象移动到某个位置和缓动,然后你有一个回调,当它完成时。
    • 类似这样的东西:myObjectTransform.DOMove(endPosition, duration).SetEase(Ease.InOutSine).OnComplete(() =&gt; Debug.Log("Object arrived to destination"));
    • 这听起来很有用。我想它在动画 UI 中也可能非常有用!谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-07
    • 1970-01-01
    • 2021-01-23
    相关资源
    最近更新 更多