使用Rigidbody2D movePosition来回移动 [英] Back and forth movement using Rigidbody2D movePosition

查看:893
本文介绍了使用Rigidbody2D movePosition来回移动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个力场I& II(图片在这里- https://i.stack.imgur.com/yXAhQ.png).它们都有一个带有bool'repel'的附加脚本,可以在MouseDown()上切换该脚本.这些力场需要直接在飞船的路径上吸引或排斥飞船.船舶的实际移动是通过右转和右转来完成的.从船上下来.这些射线广播检查力场的排斥力",然后将船移开或移向力场.所有游戏对象都是运动学的.

I have two force fields I & II (Image here - https://i.stack.imgur.com/yXAhQ.png). They both have an attached script with a bool 'repel', which is toggled on MouseDown(). These force fields need to either attract or repel a spaceship directly in its path. The actual movement of the ship is done by raycasting right & down from the ship. These raycasts check the 'repel' bool of the force fields and the ship is then either moved away or towards the force fields. All gameObjects are Kinematic.

我需要能够通过切换它们的排斥"布尔来在力场之间来回移动船.通过使用transform.Translate移动船,这可以很好地工作.但是,碰撞是越野车,因此我决定改用Rigidbody2D.MovePosition.

I need to be able to move the ship back and forth between the force fields by toggling their 'repel' bools. This was working fine by using transform.Translate to move the ship. However, collisions were buggy, so I decided to use Rigidbody2D.MovePosition instead.

现在,该船可以向ForceField I移动,当它检测到ForceField II时,它将沿着垂直线改变航向,这正是我想要的.但是,当它沿X轴射线检测到它时,它就不能再向ForceField I移动或离开它.因此,该船现在只能上下移动.如何保持船舶在力场之间移动?

Now, the ship can move towards ForceField I and when it detects ForceField II, it changes its course along a vertical line, which is what I want. BUT, it can no longer move towards or away from ForceField I when it detects it along the X axis ray. So, the ship can now only move up and down. How do I keep the ship moving between the force fields?

这是船上附带的代码-

using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;

 public class shipRays_test : MonoBehaviour {

             public float rayDistance = 100;
             public Vector2 Xspeed;
             public Vector2 Yspeed;

             private polarityScript polarityright;
             private polarityScript polaritydown;
             private Rigidbody2D rb;

             void Start()
             {
                 rb = GetComponent<Rigidbody2D>();
             }  

             void FixedUpdate ()
             {
                 Debug.DrawRay (transform.position, Vector2.right * rayDistance, Color.red);
                 RaycastHit2D rightHit = Physics2D.Raycast (transform.position, Vector2.right, rayDistance);

                 Debug.DrawRay (transform.position, Vector2.down * rayDistance, Color.green);
                 RaycastHit2D downHit = Physics2D.Raycast (transform.position, Vector2.down, rayDistance);

                 if (rightHit.collider != null) 
                 {
                     if (rightHit.collider.CompareTag ("forceField"))
                     {    
                         polarityright = rightHit.collider.gameObject.GetComponent<polarityScript > ();
                         if (polarityright.repel) 
                         {
                             rb.MovePosition (rb.position - Xspeed * Time.fixedDeltaTime);      
                         }
                         else if (!polarityright.repel)
                         {
                             rb.MovePosition (rb.position + Xspeed * Time.fixedDeltaTime);
                         }
                     }
                 }

                 if (downHit.collider != null)
                 {
                     if (downHit.collider.CompareTag ("forceField"))
                     {
                         polaritydown= downHit.collider.gameObject.GetComponent<polarityScript >();
                         if (polaritydown.repel)
                         {
                             rb.MovePosition (rb.position + Yspeed * Time.fixedDeltaTime);
                         }
                         else if (!polaritydown.repel)
                         {
                             rb.MovePosition (rb.position - Yspeed * Time.fixedDeltaTime);
                         }
                     }
                 }
             }
 }

推荐答案

显然Rigidbody.MovePosition()存储传递的值并在帧上进行插值,每次调用都覆盖先前的值,在此期间Rigidbody.position不变.在文档中根本没有指出(或至少不是很好),但是有麻烦.

Apparently Rigidbody.MovePosition() stores the value passed and interpolates over frames, each invocation overwriting the previous value, during which time Rigidbody.position does not change. This isn't noted in the documentation at all (or at least not well), but there's the rub.

要解决此问题,您需要创建一个变量来自己保留所需的新位置,并将其添加为逻辑流,并且仅在最后调用MovePosition()时添加.

To fix this you need to create a variable to hold the desired new position yourself, adding to it as your logic flow and only at the end calling MovePosition().

所以您必须这样设置:

Vector3 newPos = rb.position;
 if (rightHit.collider != null) 
 {
     //...
         {
             newPos -= Xspeed * Time.fixedDeltaTime;      
         }
     //...
 }

 if (downHit.collider != null)
 {
     //...
         {
             newPos += Yspeed * Time.fixedDeltaTime;      
         }
     //...
 }
 rb.MovePosition(newPos);

这篇关于使用Rigidbody2D movePosition来回移动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆