|
思路
给定:起点、终点、“速度”、“高度”。
做法
根据“速度”算得运动总时长:运动总时长 = 起点到终点的距离 / 速度让物体在运动总时长内,坐标从起点变到终点(Lerp的方式)
- 在上述过程中,要修改物体的PosY(加一个Offset):Offset = 高度 * y
根据指定函数算得:该函数的自变量取值范围为0~1,在0和1时因变量值(y,高度系数值)为0。如:y = 1 - 4 *(x-0.5)^2
也可以直接使用AnimationCurve画出期望的y在该过程中变化的曲线,同样要求在0和1时因变量值为0。
实现
效果
模拟抛物运动.gif
配置
image.png
示意代码
using System.Collections;using System.Collections.Generic;using UnityEngine;// 物体沿弧线移动测试public class Fan_ThrowTest : MonoBehaviour{ [SerializeField] private GameObject _go; [SerializeField] private Transform _beginPosTrans; private Vector3 BeginPos{ get { return _beginPosTrans.position; } } [SerializeField] private Transform _endPosTrans; private Vector3 EndPos{ get { return _endPosTrans.position; } } [SerializeField] private float _moveSpeed; [SerializeField] private AnimationCurve _posYCurve; [SerializeField] private float _height; private IEnumerator _moveCoroutine; private void Start() { Init(); } private void Update() { if (Input.GetKeyDown(KeyCode.Space)) { Move(); } } private void OnDestroy() { Destroy(); } public void Init() { } public void Destroy() { } private void Move() { if (_moveCoroutine != null) { StopCoroutine(_moveCoroutine); _moveCoroutine = null; } _moveCoroutine = MoveCoroutine(); StartCoroutine(_moveCoroutine); } private IEnumerator MoveCoroutine() { float distance = Vector3.Distance(BeginPos, EndPos); float duration = distance / _moveSpeed; float timer = 0f; // 若是rigidbody,可以使用rigidbody.MovePostion(_beginPos),下同 _go.transform.position = BeginPos; while (timer < duration) { float x = timer / duration; Vector3 nextPos = Vector3.Lerp(BeginPos, EndPos, timer / duration); // float y = 1 - 4 * (x - 0.5f) * (x - 0.5f); float y = _posYCurve.Evaluate(x); nextPos.y += y * _height; _go.transform.LookAt(nextPos, transform.forward); _go.transform.position = nextPos; timer += Time.deltaTime; yield return null; } _go.transform.position = EndPos; }} |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
×
|