我正在尝试为游戏添加功能,以使具有 containerTransform 的对象可以根据触摸输入向左或向右移动720f。我使用了 Vector3.MoveTowards(),但是无论何时向右或向左滑动,它都显示**来回晃动,而不是向右或向左正确过渡720f。我不确定我的逻辑哪里出了问题。这是完整的代码。我正在寻求您的帮助。谢谢
private Vector2 startPosition;
private Vector2 endPosition;
public Transform containerTransform;
public float speed;
public float SoftZone = 20f;
//soft zone is the distance upto which the swipe wont work, so swipe length less than it wont trigger the function;
private bool SwipeLeft;
private bool SwipeRight;
private bool boolean;
private Vector3 currentLocation;
private Vector3 endLocation;
void Start()
{
currentLocation = containerTransform.position;
endLocation = containerTransform.position;
}
void Update()
{
if(SwipeLeft) {
containerTransform.position = Vector3.MoveTowards(
currentLocation,
endLocation,
Time.deltaTime * speed
);
if(containerTransform.position == endLocation) {
SwipeLeft = false;
currentLocation = endLocation;
print("swipeleft ends");
}
}
if(SwipeRight) {
containerTransform.position = Vector3.MoveTowards(
currentLocation,
endLocation,
Time.deltaTime * speed
);
if(containerTransform.position == endLocation) {
SwipeRight = false;
currentLocation = endLocation;
print("swiperight ends");
}
}
SwipeCheck ();
}
void SwipeCheck () {
/*if (!SwipeConfirmed){*/
foreach (Touch touch in Input.touches)
{
if(touch.phase == TouchPhase.Began)
{
startPosition = touch.position;
endPosition = touch.position;
boolean = true;
}
if (touch.phase == TouchPhase.Moved)
{
endPosition = touch.position;
}
if (touch.phase == TouchPhase.Ended ||
touch.phase == TouchPhase.Canceled &&
boolean == true)
{
if (startPosition.x - endPosition.x >= SoftZone)
{
SwipeLeft = true;
print("left");
endLocation += new Vector3(
endLocation.x - 720f,
endLocation.y,
endLocation.z
);
}
else if(startPosition.x - endPosition.x <= -SoftZone)
{
SwipeRight = true;
print("right");
endLocation += new Vector3(
endLocation.x + 720f,
endLocation.y,
endLocation.z
);
boolean = false;
}
}
}
}
答案 0 :(得分:1)
首先,Touch.position给您
触摸在像素坐标中的位置。
为了将其用于transform.position
,您必须像使用Camera.ScreenToWorldPoint一样将它们转换为世界空间3D坐标
var worldPosition = Camera.main.ScreenToWorldPoint(new Vector3(touch.position.x, touch.position.y, distanceToCamera);
在distanceToCamera
是一个值的情况下,您必须定义/计算以确定该点应该在相机前面多远。
注意
如果您像在Update
中那样经常使用它,则应该存储Camera
并像这样重用引用:
private Camera cam;
private void Awake ()
{
cam = Camera.main;
}
//...
var worldPosition = cam.ScreenToWorldPoint( ... );
主要问题
您正在使用
Vector3.MoveTowards(currentLocation, endLocation, speed * Time.deltaTime);
这将始终从currentLocation
开始新的移动,因此您离currentLocation
的距离不得超过一个步骤/帧。
请使用对象的实际当前位置
containerTransform.position = Vector3.MoveTowards(containerTransform.position, endPosition, speed * Time.deltaTime);
您的代码SwipeLeft
和SwipeRight
实际上执行相同的操作,因此您只需删除其中一个块即可。
if (Swipe)
{
containerTransform.position = Vector3.MoveTowards(containerTransform.position, endPosition, speed * Time.deltaTime);
if (containerTransform.position == endLocation)
{
Swipe = false;
currentLocation = endLocation;
print("swipe ends");
}
}
并且仅设置Swipe = true;
但是,我建议您使用Coroutines而不是在Update
中做一些事情,因为使用StartCoroutine
和StopCoroutine
可以更好地控制它们,并在您不使用的情况下传递您的价值不需要局部变量currentLocation
和endLocation
。
看起来像
// Makes sure only one scrolling process is running at a time
private bool isScrolling;
private IEnumerator MoveTo(Vector3 targetPosition)
{
if (isScrolling) yield break;
isScrolling = true;
while (containerTransform.position != targetPosition)
{
containerTransform.position = Vector3.MoveTowards(containerTransform.position, endPosition, speed * Time.deltaTime);
yield return null;
}
isScrolling = false;
print("Swipe ends");
}
如果您想在一定时间内滑动,无论距离多远,都可以使用Vector3.Lerp
public float swipeDuration;
private IEnumerator MoveTo(Vector3 targetPosition)
{
if (isScrolling) yield break;
isScrolling = true;
var currentPosition = containerTransform.position;
var timePassed = 0.0f;
while (timePassed < swipeDuration)
{
var lerpFactor = timePassed / swipeDuration;
containerTransform.position = Vector3.Lerp(currentPosition, endPosition, lerpFactor);
yield return null;
}
// To be sure set a fixed end position
containerTransform.position = endPosition;
isScrolling = false;
print("Swipe ends");
}
在SwipeCheck()
中确认您的代码以使用新的协程。
StartCoroutine (MoveTo(endLocationWorldPoint));