简体   繁体   English

使用Rigidbody2D movePosition来回移动

[英]Back and forth movement using Rigidbody2D movePosition

I have two force fields I & II (Image here - https://i.stack.imgur.com/yXAhQ.png ). 我有两个力场I和II(图像在这里-https://i.stack.imgur.com/yXAhQ.png )。 They both have an attached script with a bool 'repel', which is toggled on MouseDown(). 它们都有一个带有bool'repel'的附加脚本,可以在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. 所有游戏对象都是运动学的。

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. 通过使用transform.Translate移动船,这可以很好地工作。 However, collisions were buggy, so I decided to use Rigidbody2D.MovePosition instead. 但是,碰撞是越野车,因此我决定改用Rigidbody2D.MovePosition。

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. 现在,该船可以向ForceField I移动,并且当它检测到ForceField II时,它将沿着垂直线更改航向,这正是我想要的。 BUT, it can no longer move towards or away from ForceField I when it detects it along the X axis ray. 但是,当它沿着X轴射线检测到它时,它就无法再向ForceField I移动或离开它。 So, the ship can now only move up and down. 因此,船现在只能上下移动。 How do I keep the ship moving between the force fields? 如何保持船舶在力场之间移动?

Here's the code attached to the ship - 这是船上附带的代码-

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

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. 显然, Rigidbody.MovePosition()存储传递的值并在帧上进行插值,每次调用都会覆盖先前的值,在此期间Rigidbody.position不会更改。 This isn't noted in the documentation at all (or at least not well), but there's the rub. 这一点在文档中根本没有指出(或至少不是很好),但是存在麻烦。

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() . 要解决此问题,您需要创建一个变量来自己保留所需的新位置,并将其作为逻辑流程添加到该位置,并且仅在最后调用MovePosition()添加到该位置。

So you'd have to set things up like this: 因此,您必须像这样设置:

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM