简体   繁体   English

Unity Collider预制件无法在一侧使用

[英]Unity collider prefab doesn't work on one side

I have a collider prefab (a cube, with a box collider the size of the cube). 我有一个对撞机预制件(一个立方体,盒子的对撞机的大小等于立方体)。 In one scene, my player collides perfectly with it, but in another scene, the player glitches and phases through one side of the collider but not the other. 在一个场景中,我的玩家与它完美碰撞,但在另一个场景中,玩家在对撞机的一侧出现毛刺并逐步移动,但在另一侧则没有。 Rotating it changes the side that it glitches out on, so it always faces the same global direction. 旋转它会改变其出现毛刺的一侧,因此它始终面向相同的全局方向。

What could be causing this? 是什么原因造成的? I've made sure the prefab for both the player and collider object are exactly the same across scenes, and nothing effects the collisions besides the player controller script which moves the player and has a condition for OnCollisionExit that sets the rigidbody's velocity to 0. 我确保了播放器和碰撞器对象的预制在场景之间完全相同,除了播放器控制器脚本移动了播放器并具有将刚性体的速度设置为0的条件OnCollisionExit之外,没有影响碰撞的因素。

Added the code below. 添加了以下代码。 The input is with joysticks (think the joysticks in a helicopter). 输入带有操纵杆(以直升飞机上的操纵杆为例)。 Like I said, the collision works perfectly usually, but for some reason only in this scene it doesn't. 就像我说的那样,碰撞通常正常进行,但由于某种原因,仅在此场景中不起作用。 I suspect it's some kind of hierarchy or rigidbody problem but I've checked seemingly everything. 我怀疑这是某种层次结构或刚体问题,但似乎已经检查了所有内容。

https://github.com/ben-humphries/FRC-Driving-Simulation 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");
    }
}

When GameObject has Rigidbody and Collider and you want collision, do not move the Object by transform.Translate or rotate it with transform.Rotate or transform.RotateAround . 当GameObject具有Rigidbody和Collider并且想要碰撞时,请不要通过transform.Translate移动对象。请使用transform.Rotatetransform.RotateAround对其进行transform.Rotate或旋转。 When you do this there will be no collision. 当您这样做时,将不会有碰撞。

The right way to move GameObject with a Rigidbody and Collision is with the Rigidbody.MovePosition function. 使用Rigidbody和Collision移动GameObject的正确方法是使用Rigidbody.MovePosition函数。

The correct way to rotate it is to use the Rigidbody.MoveRotation function. 旋转它的正确方法是使用Rigidbody.MoveRotation函数。


Example of Rigidbody.MovePosition : Rigidbody.MovePosition示例:

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

Example of Rigidbody.MoveRotation : Rigidbody.MoveRotation示例:

Quaternion deltaRotation = Quaternion.Euler(eulerAngleVelocity * Time.deltaTime);
rb.MoveRotation(rb.rotation * deltaRotation);

You need to replace transform.Translate , transform.Rotate and transform.RotateAround with these. 您需要用这些替换transform.Translatetransform.Rotatetransform.RotateAround

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

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