Unity对撞机预制件不能在一侧工作

时间:2017-06-07 15:13:12

标签: c# unity3d

我有一个对撞机预制件(一个立方体,与立方体大小的盒子对撞机)。在一个场景中,我的玩家与它完美碰撞,但在另一个场景中,玩家在对撞机的一侧出现故障并相位而不是另一侧。旋转它会改变它出现故障的一侧,因此它总是面向相同的全局方向。

可能导致这种情况的原因是什么?我已确保播放器和对撞机对象的预制件在场景中完全相同,除了移动播放器的播放器控制器脚本以及具有将刚体的速度设置为0的OnCollisionExit条件之外,没有任何影响碰撞。 / p>

添加了以下代码。输入是用操纵杆(想想直升机中的操纵杆)。就像我说的那样,碰撞通常是完美的,但由于某些原因,只有在这个场景中它不会。我怀疑它是某种层次结构或严格的问题,但我已经检查了所有的东西。

https://github.com/ben-humphries/FRC-Driving-Simulation

using UnityEngine;
using UnityEngine.UI;

public class ChassisController : MonoBehaviour {

    public UIController uiController;

    public Canvas PauseCanvas;

    public float speedLinear = 10f;
    public float speedAngular = 100f;
    public float joyDeadZone = 0.5f;

    public float rotationOffset = 3f;

    public bool squaredMovement = false;

    public DriveModes driveMode = DriveModes.Tank;

    [HideInInspector]
    public bool paused = false;


    private Rigidbody rigidbody;

    Vector3 lastLinearPosition;
    float lastAngularPosition;



    void Start () {

        rigidbody = GetComponent<Rigidbody> ();

        lastLinearPosition = Vector3.zero;
        lastAngularPosition = 0f;
        paused = false;

    }

    void FixedUpdate () {

        if (!paused) {

            /*
         * INPUT
         */

            if (driveMode == DriveModes.Tank) {


                if (Mathf.Abs (Input.GetAxis ("VerticalLeft")) > joyDeadZone) {


                    Vector3 rotatePoint = (transform.position) + transform.TransformDirection (Vector3.right) * rotationOffset;
                    Vector3 rotateAxis = transform.TransformDirection (Vector3.up);

                    Debug.DrawRay (rotatePoint, rotateAxis * 10f, Color.red);

                    transform.RotateAround (rotatePoint, rotateAxis, -speedAngular * Input.GetAxis ("VerticalLeft") * Time.fixedDeltaTime * (squaredMovement ? Mathf.Abs (Input.GetAxis ("VerticalLeft")) : 1));

                }
                if (Mathf.Abs (Input.GetAxis ("VerticalRight")) > joyDeadZone) {
                    Vector3 rotatePoint = (transform.position) + transform.TransformDirection (Vector3.left) * rotationOffset;
                    Vector3 rotateAxis = transform.TransformDirection (Vector3.up);

                    Debug.DrawRay (rotatePoint, rotateAxis * 10f, Color.red);


                    transform.RotateAround (rotatePoint, rotateAxis, speedAngular * Input.GetAxis ("VerticalRight") * Time.fixedDeltaTime * (squaredMovement ? Mathf.Abs (Input.GetAxis ("VerticalRight")) : 1));

                }


            } else if (driveMode == DriveModes.Mecanum) {


                if (Mathf.Abs (Input.GetAxis ("VerticalRight")) > joyDeadZone) {
                    transform.Translate (Vector3.forward * -speedLinear * Input.GetAxis ("VerticalRight") * Time.fixedDeltaTime * (squaredMovement ? Mathf.Abs (Input.GetAxis ("VerticalRight")) : 1));
                }

                if (Mathf.Abs (Input.GetAxis ("HorizontalRight")) > joyDeadZone) {
                    transform.Translate (Vector3.right * speedLinear / 5f * Input.GetAxis ("HorizontalRight") * Time.fixedDeltaTime * (squaredMovement ? Mathf.Abs (Input.GetAxis ("HorizontalRight")) : 1));
                }

                if (Mathf.Abs (Input.GetAxis ("TwistRight")) > joyDeadZone) {
                    transform.Rotate (0, speedAngular * Input.GetAxis ("TwistRight") * Time.fixedDeltaTime * (squaredMovement ? Mathf.Abs (Input.GetAxis ("TwistRight")) : 1), 0);

                }

            }

            float linearVelocity = Mathf.Round (((transform.position - lastLinearPosition) / Time.fixedDeltaTime).magnitude * 100f) / 100f;
            lastLinearPosition = transform.position;

            float angularVelocity = Mathf.Round ((transform.eulerAngles.y - lastAngularPosition) / Time.fixedDeltaTime * Mathf.Deg2Rad  * 100f) / 100f;
            lastAngularPosition = transform.eulerAngles.y;

            uiController.UpdateVelocities (linearVelocity, angularVelocity);


        }
    }

    void OnCollisionExit(Collision col){

        rigidbody.isKinematic = true;

        rigidbody.velocity = Vector3.zero;
        rigidbody.angularVelocity = Vector3.zero;

        rigidbody.isKinematic = false;

    }
    public enum DriveModes{
        Tank,
        Mecanum
    }

    public void setDriveMode(){

        int index = PauseCanvas.transform.GetChild (1).GetComponent<Dropdown> ().value;

        if (index == 0) {
            driveMode = DriveModes.Tank;
        } else if (index == 1) {
            driveMode = DriveModes.Mecanum;
        }

        uiController.UpdateDriveMode (index == 0 ? "Tank" : "Mecanum");
    }
}

1 个答案:

答案 0 :(得分:0)

当GameObject有Rigidbody和Collider并且你想要碰撞时,transform.Translate移动对象,或者用transform.Rotate或{{1}将其旋转}。当你这样做时,不会发生碰撞。

使用transform.RotateAround和碰撞移动GameObject的正确方法是使用Rigidbody.MovePosition函数。

旋转它的正确方法是使用Rigidbody.MoveRotation功能。

Rigidbody.MovePosition的示例:

Rigidbody

Rigidbody.MoveRotation的示例:

float h = Input.GetAxisRaw("Horizontal");
float v = Input.GetAxisRaw("Vertical");

Vector3 tempVect = new Vector3(h, 0, v);
tempVect = tempVect.normalized * speed * Time.deltaTime;
rb.MovePosition(transform.position + tempVect);

您需要将Quaternion deltaRotation = Quaternion.Euler(eulerAngleVelocity * Time.deltaTime); rb.MoveRotation(rb.rotation * deltaRotation); transform.Translatetransform.Rotate替换为这些。