![](/img/trans.png)
[英]How do I make Rigidbody2D.MovePosition move a gameobject in local space?
[英]How do I make a Rigidbody 2D move in the direction the user swiped in?
使用 Unity 2D 和 c#,我试图让手机游戏中的游戏对象能够在用户滑动的方向上连续平滑地移动。下面的代码是我一直在尝试开始工作的代码我运行它,没有任何反应。 每当我滑动时,游戏对象就会保持原位。 我对这种东西很陌生,所以我很难找出问题所在。 我认为这与第 38 到 62 行的 if 和 else 语句有关,但我不完全确定。 非常感谢你的帮助。
private Vector3 fp; //First touch position
private Vector3 lp; //Last touch position
private float dragDistance; //minimum distance for a swipe to be registered
private float speed = 10;
private Rigidbody2D rb;
private Vector2 moveVelocity;
void Start() {
dragDistance = Screen.height * 5 / 100; //dragDistance is 5% height of the screen
rb = GetComponent<Rigidbody2D>();
}
void Update() {
if (Input.touchCount == 1) // user is touching the screen with a single touch
{
Touch touch = Input.GetTouch(0); // get the touch
if (touch.phase == TouchPhase.Began) //check for the first touch
{
fp = touch.position;
lp = touch.position;
}
else if (touch.phase == TouchPhase.Moved) // update the last position based on where they moved
{
lp = touch.position;
}
else if (touch.phase == TouchPhase.Ended) //check if the finger is removed from the screen
{
lp = touch.position; //last touch position. Ommitted if you use list
//Check if drag distance is greater than ?% of the screen height
if (Mathf.Abs(lp.x - fp.x) > dragDistance || Mathf.Abs(lp.y - fp.y) > dragDistance)
{//It's a drag
//check if the drag is vertical or horizontal
if (Mathf.Abs(lp.x - fp.x) > Mathf.Abs(lp.y - fp.y))
{ //If the horizontal movement is greater than the vertical movement...
if ((lp.x > fp.x)) //If the movement was to the right)
{ //Right swipe
Vector2 moveInput = new Vector2(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical"));
moveVelocity = moveInput.normalized * speed;
}
else
{ //Left swipe
Vector2 moveInput = new Vector2(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical"));
moveVelocity = moveInput.normalized * speed;
}
}
else
{ //the vertical movement is greater than the horizontal movement
if (lp.y > fp.y) //If the movement was up
{ //Up swipe
Vector2 moveInput = new Vector2(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical"));
moveVelocity = moveInput.normalized * speed;
}
else
{ //Down swipe
Vector2 moveInput = new Vector2(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical"));
moveVelocity = moveInput.normalized * speed;
}
}
}
}
}
}
void FixedUpdate() {
rb.MovePosition(rb.position + moveVelocity * Time.fixedDeltaTime);
}
首先,您的情况完全相同:
if (Mathf.Abs(lp.x - fp.x) > Mathf.Abs(lp.y - fp.y))
{ //If the horizontal movement is greater than the vertical movement...
if ((lp.x > fp.x)) //If the movement was to the right)
{ //Right swipe
Vector2 moveInput = new Vector2(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical"));
moveVelocity = moveInput.normalized * speed;
}
else
{ //Left swipe
Vector2 moveInput = new Vector2(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical"));
moveVelocity = moveInput.normalized * speed;
}
}
else
{ //the vertical movement is greater than the horizontal movement
if (lp.y > fp.y) //If the movement was up
{ //Up swipe
Vector2 moveInput = new Vector2(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical"));
moveVelocity = moveInput.normalized * speed;
}
else
{ //Down swipe
Vector2 moveInput = new Vector2(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical"));
moveVelocity = moveInput.normalized * speed;
}
}
他们都使用完全相同的两行
Vector2 moveInput = new Vector2(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical"));
moveVelocity = moveInput.normalized * speed;
我的猜测是Input.GetAxisRaw("Horizontal")
和Input.GetAxisRaw("Vertical")
始终为0
,因此根本不会发生任何移动。 据我所知,它仅适用于键盘和鼠标输入,不适用于触摸。
你不是宁愿根据你的滑动方向而是做例如
if (Mathf.Abs(lp.x - fp.x) > Mathf.Abs(lp.y - fp.y))
{
//If the horizontal movement is greater than the vertical movement...
if (lp.x > fp.x) //If the movement was to the right)
{ //Right swipe
moveVelocity = Vector2.right;
}
else
{ //Left swipe
moveVelocity = Vector2.left;
}
}
else
{ //the vertical movement is greater than the horizontal movement
if (lp.y > fp.y) //If the movement was up
{ //Up swipe
moveVelocity = Vector2.up;
}
else
{ //Down swipe
moveVelocity = Vector2.down;
}
}
进而
void FixedUpdate()
{
rb.MovePosition(rb.position + moveVelocity * speed * Time.deltaTime);
}
请注意,而不是Time.fixedDeltaTime
为了读取增量时间,建议使用
Time.deltaTime
代替,因为如果您在FixedUpdate
函数或Update
函数中,它会自动返回正确的增量时间。
或者你也可以直接分配rb.velocity
if (Mathf.Abs(lp.x - fp.x) > Mathf.Abs(lp.y - fp.y))
{
//If the horizontal movement is greater than the vertical movement...
if (lp.x > fp.x) //If the movement was to the right)
{ //Right swipe
rb.velocity = Vector2.right * speed;
}
else
{ //Left swipe
rb.velocity = Vector2.left * speed;;
}
}
else
{ //the vertical movement is greater than the horizontal movement
if (lp.y > fp.y) //If the movement was up
{ //Up swipe
rb.velocity = Vector2.up * speed;;
}
else
{ //Down swipe
rb.velocity = Vector2.down * speed;;
}
}
没有FixedUpdate
。 由于您在此处仅更改 Rigidbody 的velocity
并且不直接移动它,因此可以在Update
执行此操作。
一般注意事项:
您应该使用switch-case
代替
switch(touch.phase)
{
case TouchPhase.Began:
fp = touch.position;
// No need to assign lp here actually
// lp = touch.position;
break;
case TouchPhase.Ended:
// lp could actually be a local variable - no need to make it a field
var lp = touch.position;
...
break;
}
由于您不使用在TouchPhase.Moved
分配的lp
值,因此您实际上可以完全跳过此块。
您可以通过引入一个额外的变量来使您的if-else
检查移动方向更具可读性/更好地维护:
var lp = touch.position;
var difference = lp - fp;
if (difference.x > dragDistance || difference.y > dragDistance)
{
if (Mathf.Abs(difference.x) > Mathf.Abs(difference.y))
{
if (difference.x > 0)
{
// Right swipe
}
else
{
// Left swipe
}
}
else
{
if (difference.y > 0)
{
// Up swipe
}
else
{
// Down swipe
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.