美文网首页
Unity 抛物线运动

Unity 抛物线运动

作者: NightChord | 来源:发表于2023-09-06 11:04 被阅读0次

在Unity中实现平滑抛物线移动

在游戏开发中,经常需要控制物体以一种平滑的方式从一个点移动到另一个点。本博客将介绍如何使用Unity引擎和C#编程来实现这样的平滑抛物线移动效果,其中可以设置抛物线高度、起始点、落点和移动速度参数

效果展示

步骤 1: 创建一个新的Unity项目

首先,打开Unity并创建一个新的3D项目。确保已经有一个场景,并将要移动的物体添加到场景中。

步骤 2: 创建一个C#脚本

在项目资源管理器中,右键单击“Assets”文件夹,选择“Create” > “C# Script”来创建一个新的C#脚本。为脚本命名,例如"ParabolicMovement"。

步骤 3: 编写代码

打开刚刚创建的脚本并编写以下代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ParabolicMotion : MonoBehaviour
{

    [Header("开始位置的Transform")]
    public Transform startTransform;
    [Header("结束位置的Transform")]
    public Transform endTransform;

    [Header("抛物线的高度")]
    public float parabolaHeight = 5f;
    [Header("移动速度")]
    public float speed = 5f;

    private Vector3 startPoint;
    private Vector3 endPoint;


    private float distanceToTarget;
    private float startTime;

    private bool isBool = true;

    private void Start()
    {
        startPoint = startTransform.position;
        endPoint = endTransform.position;

        // 设置物体的初始位置
        transform.position = startPoint;

        // 计算起始点到落点的距离
        distanceToTarget = Vector3.Distance(startPoint, endPoint);

        // 计算移动的起始时间
        startTime = Time.time;
    }

    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.S))
        {
            Debug.Log("重置");
            transform.position = startPoint;
            startTime = Time.time;
            isBool = true;
        }
    }

    private void FixedUpdate()
    {
        if (isBool)
        {
            // 计算已经经过的时间
            float elapsedTime = Time.time - startTime;

            // 计算当前位置
            float journeyFraction = elapsedTime * speed / distanceToTarget;
            Vector3 currentPos = Vector3.Lerp(startPoint, endPoint, journeyFraction);

            // 计算抛物线高度
            currentPos.y += Mathf.Sin(journeyFraction * Mathf.PI) * parabolaHeight;

            // 移动物体
            transform.position = currentPos;

            // 如果已经到达目标点,结束移动
            if (journeyFraction >= 1f)
            {
                // 确保物体在落点位置
                transform.position = endPoint;
                isBool=false;
            }
        }
    }
}

步骤 4: 将脚本附加到物体上

将编写好的脚本附加到你想要移动的物体(Move)上。在物体(Move)的Inspector窗口中,你可以设置起始点、落点、抛物线高度和速度参数。


步骤 5: 调试和微调

你可以在Unity编辑器中进行调试和微调。根据需要,你可能需要更改抛物线高度、速度参数或其他变量来获得最佳效果。

拓展

设置的参数变成:抛物线高度、起始点、落点和移动时间参数也能同样达到一样效果。

代码变为

using UnityEngine;

public class ParabolicMotion : MonoBehaviour
{
    [Header("开始位置的Transform")]
    public Transform startTransform;
    [Header("结束位置的Transform")]
    public Transform endTransform;

    [Header("抛物线的高度")]
    public float throwHeight = 2.0f; 

    [Header("移动总时间")]
    public float totalTime = 2.0f;

    private Vector3 startPoint;
    private Vector3 endPoint;
    private float elapsedTime = 0.0f;

    private void Start()
    {
        startPoint= startTransform.position;
        endPoint= endTransform.position;

        transform.position = startPoint;
    }


    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.S))
        {
            Debug.Log("重置");
            transform.position = startPoint;
            elapsedTime = 0.0f;
        }
    }

    private void FixedUpdate()
    {
        // 在FixedUpdate中更新位置
        if (elapsedTime <= totalTime)
        {
            TimeAndHeightMove();
        }
    }


    /// <summary>
    /// 时间和高度决定移动过程,移动速度无关
    /// </summary>
    private void TimeAndHeightMove()
    {
        // 计算当前时间占总时间的比例
        float t = elapsedTime / totalTime;

        // 计算抛物线高度
        float height = Mathf.Lerp(startPoint.y, endPoint.y, t) +
                       throwHeight * Mathf.Sin(t * Mathf.PI);

        // 计算平面上的位置
        Vector3 currentPosition = Vector3.Lerp(startPoint, endPoint, t);
        currentPosition.y = height;

        // 更新物体的位置
        transform.position = currentPosition;

        // 更新已经经过的时间
        elapsedTime += Time.fixedDeltaTime;
    }


}

相关文章

网友评论

      本文标题:Unity 抛物线运动

      本文链接:https://www.haomeiwen.com/subject/pjykvdtx.html