使用Rigidbody2D movePosition进行来回移动

时间:2017-06-13 13:03:11

标签: c# unity3d unity5 unity3d-2dtools

我有两个力场I& II(图片在这里 - https://i.stack.imgur.com/yXAhQ.png)。它们都有一个带有bool'rev1'的附加脚本,它在MouseDown()上切换。这些力场需要直接在其路径上吸引或击退宇宙飞船。船舶的实际运动是通过光线投射来实现的。从船上下来。这些射线检查检查力场的“击退”布尔值,然后将船移开或朝向力场移动。所有游戏对象都是运动学。

我需要能够通过切换他们的'击退'布尔来在力场之间来回移动船。通过使用transform.Translate移动船只,这工作正常。但是,碰撞是错误的,所以我决定使用Rigidbody2D.MovePosition。

现在,船可以向ForceField I移动,当它检测到ForceField II时,它会沿垂直线改变路线,这就是我想要的。但是,当它沿着X轴射线检测到它时,它不能再朝向或远离ForceField I.所以,这艘船现在只能上下移动。如何让船在力场之间移动?

这是附在船上的代码 -

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);
                         }
                     }
                 }
             }
 }

1 个答案:

答案 0 :(得分:0)

显然Rigidbody.MovePosition()存储传递的值并在帧上插值,每次调用都会覆盖先前的值,在此期间Rigidbody.position不会改变。这根本没有在文档中注明(或者至少不是很好),但是还有一点。

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

所以你必须这样设置:

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

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