在Unity中实现平滑抛物线移动
在游戏开发中,经常需要控制物体以一种平滑的方式从一个点移动到另一个点。本博客将介绍如何使用Unity引擎和C#编程来实现这样的平滑抛物线移动效果,其中可以设置抛物线高度、起始点、落点和移动速度参数。
![](https://img.haomeiwen.com/i3600990/52dfbc479b11b062.gif)
步骤 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窗口中,你可以设置起始点、落点、抛物线高度和速度参数。
![](https://img.haomeiwen.com/i3600990/66d8e90cdb176956.png)
步骤 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;
}
}
网友评论