c# - 我需要关于这个 lerping 问题的帮助。我正在尝试制作平台游戏
问题描述
(一旦到达 B 点,它会平稳有序地到达 A 点并返回 B 点)。出于某种原因,平台拒绝移动并保持原状。我已经尝试了很多东西,比如使用vector3.movetowards
等等,但没有什么能让它动起来。
这是代码。(A 点和 B 点是不属于平台的空游戏对象)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MoveTwoTransforms : MonoBehaviour
{
public Transform pointA;
public Transform pointB;
bool HeadingtowardsB;
bool HeadingtowardsA;
public float speed = 10;
// Start is called before the first frame update
void Start()
{
transform.position = pointA.position;
HeadingtowardsB = true;
HeadingtowardsA = false;
GlideAround();
}
// Update is called once per frame
void Update()
{
}
public IEnumerator GlideAround()
{
while (true)
{
while ((Mathf.Abs((pointB.position.x - transform.position.x) + (pointB.position.y - transform.position.y)) > 0.05f) && HeadingtowardsB == true && HeadingtowardsA==false )
{
yield return new WaitForEndOfFrame();
transform.position = Vector2.Lerp(transform.position, pointB.position, speed * Time.deltaTime);
if(Mathf.Abs((pointB.position.x - transform.position.x) + (pointB.position.y - transform.position.y)) > 0.05f)
{
HeadingtowardsB = false;
HeadingtowardsA = true;
}
}
HeadingtowardsB = false;
HeadingtowardsA = true;
while (Mathf.Abs((pointA.position.x - transform.position.x) + (pointA.position.y - transform.position.y)) > 0.05f && HeadingtowardsA==true && HeadingtowardsB==false)
{
yield return new WaitForEndOfFrame();
transform.position=transform.position=Vector3.Lerp(transform.position, pointA.position, speed*Time.deltaTime);
}
}
}
}
没有错误消息,平台不会移动。平台仍在碰撞,它的行为似乎与普通平台一样。
解决方案
GlideAround()
是一个IEnumerator
并且不能像方法一样被调用。你必须使用它来启动它StartCoroutine
StartCoroutine(GlideAround());
另请注意,speed * Time.deltaTime
在Lerp
. 在您的情况下,您通常需要一个介于 0-1 之间的常数值(因为您将当前位置重新用作第一个参数)。
例如,0.5 的值意味着:每一帧都将新位置设置为当前位置和目标位置之间的中心。
由于您使用此阈值捕获它0.05f
应该没问题,但通常我不会Lerp
像这样使用......使用非常小的值,您可能永远不会真正到达目标位置。
因此,我宁愿控制恒定速度并使用
bool isHeadingA = true;
while(true)
{
// if it was intended you can ofourse also again use
// Vector2.Distance(transform.position, isHeadingA ? pointA.position : pointB.position) <= 0.05f)
while (transform.position != (isHeadingA ? pointA.position : pointB.position))
{
yield return new WaitForEndOfFrame();
transform.position = Vector2.MoveTowards(transform.position, isHeadingA ? pointA.position : pointB.position, speed * Time.deltaTime);
}
// flip the direction
isHeadingA = !isHeadingA;
}
!=
精度为0.00001
并且在这里很好,因为MoveTowards
它避免了过冲,所以在某些时候它肯定会到达 if 的位置speed != 0
。
或者,如果您更愿意使用平滑的进出速度来控制运动的持续时间,您可以使用 Lerp,例如作为因素和缓进和缓出Mathf.PingPong
Mathf.SmoothStep
while(true)
{
yield return new WaitForEndOfFrame();
// linear pingpong between 0 and 1
var factor = Mathf.PingPong(Time.time, 1);
// add easing at the ends
factor = Mathf.SmoothStep(0, 1, factor);
// optionally add even more easing ;)
//factor = Mathf.SmoothStep(0, 1, factor);
transform.position = Vector2.Lerp(pointA.position, pointB.position, factor);
}
推荐阅读
- javascript - Javascript模仿Chrome“+”按钮
- php - 如果值在 foreach 循环 + php 中不匹配,则跳过步骤
- c# - Oracle dB 自动检索新记录
- java - 检查一维数组是否是另一个二维数组的每一行的子集
- svn - svn 合并基于 xml 的文件
- class - 在另一个类中使用类对象?还是只使用字段?
- java - 如何在使用spring和@Transaction时将全局变量从一个类发送到另一个类?
- ruby - XML 解析破碎的文本
- hyperledger-fabric - 如果提交节点与网络断开连接,其他背书节点和提交节点会提交交易吗?
- javascript - 在 Node JS 中创建 API 下载日志文件