Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Unity刚体碰撞无法正常工作_C#_Unity3d_Collision Detection - Fatal编程技术网

C# Unity刚体碰撞无法正常工作

C# Unity刚体碰撞无法正常工作,c#,unity3d,collision-detection,C#,Unity3d,Collision Detection,我有很多关于我的刚体碰撞的奇怪问题。我有一个玩家控制器脚本,它允许我移动我的玩家,但当它与楼梯碰撞时,就会出现小故障。当它与一扇门碰撞时,会出现小故障,当它在斜行时与地图边缘的两个nvisible box碰撞器碰撞时,它会穿过其中一个。我到处找了不少,但什么也没找到。我知道这没什么大不了的,但这里有一些东西可能会有所帮助: 字符控制器代码: 我的播放器对象的重要组件的屏幕截图: 另外,代码中有一些奇怪的变化部分。这是游戏剩下的部分,但对这个问题来说并不重要。希望你们能帮助我。我很乐意提

我有很多关于我的刚体碰撞的奇怪问题。我有一个玩家控制器脚本,它允许我移动我的玩家,但当它与楼梯碰撞时,就会出现小故障。当它与一扇门碰撞时,会出现小故障,当它在斜行时与地图边缘的两个nvisible box碰撞器碰撞时,它会穿过其中一个。我到处找了不少,但什么也没找到。我知道这没什么大不了的,但这里有一些东西可能会有所帮助:

  • 字符控制器代码:
  • 我的播放器对象的重要组件的屏幕截图:
另外,代码中有一些奇怪的变化部分。这是游戏剩下的部分,但对这个问题来说并不重要。希望你们能帮助我。我很乐意提供您可能需要的任何其他信息:)谢谢您提前抽出时间


编辑:根据第一个答案注释掉一个部分,但这并不能修复它。首先,你移动你的播放器“两次”,首先进入你拥有的
movePlayer
功能:

//移动播放器
if(输入!=矢量3.0){
body.velocity=输入;
}
然后在每个
固定更新中

body.MovePosition(body.position+输入*速度*时间.固定时间);
body.MovePosition
移动您的播放器,但不将速度归零(您在
movePlayer
功能中设置)

通过这种方式移动玩家,你们可以“超越”太小的colider,这样物体就会通过


你可以在刚体上增加更多的阻力,使物体减速一点。

好的,对于有类似问题的人,我找到了答案:

问题是我使用的是body.moveposition,实际上应该是body.addforce

这意味着您必须更改一些代码。如果您因遇到类似问题而需要进一步解释,请与我联系,但以下是我的改进代码,以帮助您开始:

using System;
using UnityEngine;

public class PlayerController : MonoBehaviour{
    public Rigidbody body;

    //player movement
    private float speed = 12f;
    private float walkSpeed = 10;
    private float runSpeed = 15;
    public float gravity = -9.81f;
    public float jumpHeight = 2f;
    private Vector3 inputs;

    //player rotation
    private float targetAngle = 0f;
    private float angle = 0f;
    public float turnSmoothTime = .1f;
    public float turnSmoothVelocity;

    //player jump
    public Transform groundCheck;
    public float groundDistance = 0.4f;
    public LayerMask groundMask;
    private bool isGrounded;

    //there are 6 possible directions for gravity; positive and negative x, y and z. The direction can therefore be -3, -2, -1, 1, 2 or 3 where 1=y, 2=x, 3=z
    public int direction = 1;

    public void movePlayer(Vector2 movement){

        float horizontal = movement.x;
        float vertical = movement.y;
        
        //check if the player is standing on the ground
        isGrounded = Physics.CheckSphere(groundCheck.position, groundDistance, groundMask);

        Quaternion rotation = new Quaternion();

        body.freezeRotation = true;

        if (Mathf.Abs(direction) == 1){
            //gravity in y direction
            //set the direction of the gravity
            Physics.gravity = new Vector3(0f, direction * gravity, 0f);

            //set the direction the inputs should work in
            inputs.x = horizontal;
            inputs.z = vertical;
            inputs.y = 0;

            //calculate the angle with which the player has to be rotated and make the rotation smooth (smoothing is only possible in this orientation)
            targetAngle = Mathf.Atan2(inputs.x, inputs.z) * Mathf.Rad2Deg;
            angle = Mathf.SmoothDampAngle(transform.eulerAngles.y, targetAngle, ref turnSmoothVelocity, turnSmoothTime);

            //set the characters rotation
            rotation = Quaternion.Euler(0f, angle, 0f);
        }
        else if (Mathf.Abs(direction) == 2){
            //gravity in x direction
            Physics.gravity = new Vector3((direction / 2) * gravity, 0f, 0f);

            inputs.y = -horizontal;
            inputs.z = vertical;
            inputs.x = body.velocity.x;
            
            targetAngle = Mathf.Atan2(-inputs.y, inputs.z) * Mathf.Rad2Deg;

            rotation = Quaternion.Euler(targetAngle, 0f, (direction / 2) * -90f);
        }
        else if (Mathf.Abs(direction) == 3){
            //gravity in z-direction

            Physics.gravity = new Vector3(0f, 0f, (direction / 3) * -gravity);

            inputs.x = horizontal;
            inputs.y = vertical;
            inputs.z = body.velocity.z;
            
            targetAngle = Mathf.Atan2(inputs.x, inputs.y) * Mathf.Rad2Deg;

            //set the rotation in the correct order of the axis (90 degrees first and then around the correct axis)
            rotation = Quaternion.AngleAxis((direction / 3) * -90f, Vector3.right) *
                       Quaternion.AngleAxis(0f, Vector3.forward) *
                       Quaternion.AngleAxis(targetAngle, Vector3.up);
        }
        else{

            direction = 1;
        }

        //rotate the player in the move direction as long as they are moving
        if (inputs.magnitude >= 0.1f){
            transform.rotation = rotation;
        }
        
    }

    void FixedUpdate(){
        body.AddForce(inputs * speed * Time.fixedDeltaTime);
    }

    public void flip(int changedDirection){
        inputs = Vector3.zero;
        angle = 0f;
        targetAngle = 0f;
        direction = changedDirection;
    }

    public void walk(){
        if (isGrounded){
            speed = walkSpeed;
        }
    }

    public void run(){
        if (isGrounded){
            speed = runSpeed;
        }
    }

    public void jump(){
        if (isGrounded){
            if (direction == 1){
                body.AddForce(new Vector3(0, jumpHeight, 0));
            }
            else if (direction == 2){
                body.AddForce(new Vector3(jumpHeight, 0, 0));
            }
            else if (direction == 3){
                body.AddForce(new Vector3(0,0 , jumpHeight));
            }
        }
    }
}

对我来说,这给跳跃带来了一些额外的问题,例如,这里是需要调整的值来解决这些问题:刚体质量和阻力,以及玩家控制器重力和跳跃高度。

感谢您的回答!你是对的,这是不正确的,但我修复了它(新的和改进的代码se post)的广告,我仍然得到相同的问题。有些已经不那么糟糕了,但我仍然可以穿过角落、楼梯和门,所以肯定还是有问题:(
using System;
using UnityEngine;

public class PlayerController : MonoBehaviour{
    public Rigidbody body;

    //player movement
    private float speed = 12f;
    private float walkSpeed = 10;
    private float runSpeed = 15;
    public float gravity = -9.81f;
    public float jumpHeight = 2f;
    private Vector3 inputs;

    //player rotation
    private float targetAngle = 0f;
    private float angle = 0f;
    public float turnSmoothTime = .1f;
    public float turnSmoothVelocity;

    //player jump
    public Transform groundCheck;
    public float groundDistance = 0.4f;
    public LayerMask groundMask;
    private bool isGrounded;

    //there are 6 possible directions for gravity; positive and negative x, y and z. The direction can therefore be -3, -2, -1, 1, 2 or 3 where 1=y, 2=x, 3=z
    public int direction = 1;

    public void movePlayer(Vector2 movement){

        float horizontal = movement.x;
        float vertical = movement.y;
        
        //check if the player is standing on the ground
        isGrounded = Physics.CheckSphere(groundCheck.position, groundDistance, groundMask);

        Quaternion rotation = new Quaternion();

        body.freezeRotation = true;

        if (Mathf.Abs(direction) == 1){
            //gravity in y direction
            //set the direction of the gravity
            Physics.gravity = new Vector3(0f, direction * gravity, 0f);

            //set the direction the inputs should work in
            inputs.x = horizontal;
            inputs.z = vertical;
            inputs.y = 0;

            //calculate the angle with which the player has to be rotated and make the rotation smooth (smoothing is only possible in this orientation)
            targetAngle = Mathf.Atan2(inputs.x, inputs.z) * Mathf.Rad2Deg;
            angle = Mathf.SmoothDampAngle(transform.eulerAngles.y, targetAngle, ref turnSmoothVelocity, turnSmoothTime);

            //set the characters rotation
            rotation = Quaternion.Euler(0f, angle, 0f);
        }
        else if (Mathf.Abs(direction) == 2){
            //gravity in x direction
            Physics.gravity = new Vector3((direction / 2) * gravity, 0f, 0f);

            inputs.y = -horizontal;
            inputs.z = vertical;
            inputs.x = body.velocity.x;
            
            targetAngle = Mathf.Atan2(-inputs.y, inputs.z) * Mathf.Rad2Deg;

            rotation = Quaternion.Euler(targetAngle, 0f, (direction / 2) * -90f);
        }
        else if (Mathf.Abs(direction) == 3){
            //gravity in z-direction

            Physics.gravity = new Vector3(0f, 0f, (direction / 3) * -gravity);

            inputs.x = horizontal;
            inputs.y = vertical;
            inputs.z = body.velocity.z;
            
            targetAngle = Mathf.Atan2(inputs.x, inputs.y) * Mathf.Rad2Deg;

            //set the rotation in the correct order of the axis (90 degrees first and then around the correct axis)
            rotation = Quaternion.AngleAxis((direction / 3) * -90f, Vector3.right) *
                       Quaternion.AngleAxis(0f, Vector3.forward) *
                       Quaternion.AngleAxis(targetAngle, Vector3.up);
        }
        else{

            direction = 1;
        }

        //rotate the player in the move direction as long as they are moving
        if (inputs.magnitude >= 0.1f){
            transform.rotation = rotation;
        }
        
    }

    void FixedUpdate(){
        body.AddForce(inputs * speed * Time.fixedDeltaTime);
    }

    public void flip(int changedDirection){
        inputs = Vector3.zero;
        angle = 0f;
        targetAngle = 0f;
        direction = changedDirection;
    }

    public void walk(){
        if (isGrounded){
            speed = walkSpeed;
        }
    }

    public void run(){
        if (isGrounded){
            speed = runSpeed;
        }
    }

    public void jump(){
        if (isGrounded){
            if (direction == 1){
                body.AddForce(new Vector3(0, jumpHeight, 0));
            }
            else if (direction == 2){
                body.AddForce(new Vector3(jumpHeight, 0, 0));
            }
            else if (direction == 3){
                body.AddForce(new Vector3(0,0 , jumpHeight));
            }
        }
    }
}