当前位置:   GIT > 正文

Unity 2d游戏中奇怪的碰撞错误

c#,collision-detection,unity3d,git,算法,编辑器,DevBox,在线流程图,编程,编程问答,程序员,开发者工具,开发工具,json解析,二维码生成,unix时间戳,在线开发工具,前端开发工具,开发人员工具,站长工具

Github Repository(Scripts文件夹,包含.cs文件中的所有代码)

我在团结中有这个奇怪的碰撞错误,这里是它的一个gif:

GIF

重新创建:例如,在gif中,我按两个Left arrowUp arrow直到速度正常化,然后我得到一些为什么卡在一个块中.

当我在XNA中进行游戏时,我之前已经使用了自己的碰撞算法,希望在Unity中不会发生这种情况.

这是播放器脚本PlayerMovement:

using UnityEngine;
using UnityEngine.UI;

namespace Assets.Scripts
{
    public enum Directions
    {
        Back,
        Left,
        Front,
        Right,
        Idle = -1
    }

    public class PlayerMovement : MonoBehaviour
    {
        #region Public Members

        /// 
        /// Maximum speed of the player (Accelerated to over a period of time)
        /// 
        public float speed;

        /// 
        /// Debug UI.Text element
        /// 
        public Text debugText;

        #endregion

        #region Constants

        /// 
        /// Constant for decaying the velocity on updates
        /// 
        private const float VELOCITY_DECAY_FACTOR = 0.85f;

        /// 
        /// Constant to convert normal speed sizes to fit the scale
        /// Of UnityEngine.Vector2
        /// 
        private const float HUMAN_TO_VECTOR_SCALE_FACTOR = 850f;

        /// 
        /// Constant to set the base speed of the player animation
        /// 
        private const float BASE_ANIM_SPEED = 0.7f;

        /// 
        /// Constant to slightly reduce the animation speed after 
        /// It is multiplied by the velocity of the player
        /// 
        private const float POST_VELOCITY_MULTIPLICATION_ANIM_SPEED_FACTOR = 0.5f;

        /// 
        /// Constant to set the animation speed
        /// 
        private const float ANIM_SPEED_MODIFIER = BASE_ANIM_SPEED * POST_VELOCITY_MULTIPLICATION_ANIM_SPEED_FACTOR;

        /// 
        /// Epsilon before velocity zerofication
        /// 
        private const float VELOCITY_EPSILON = 0.1f;

        #endregion

        #region Private Members

        private Rigidbody2D rb2D;
        private Vector2 velocity;
        private Animator animator;
        private Directions dir = Directions.Idle;

        #endregion

        #region Game Loop Methods

        private void Awake()
        {
            animator = GetComponent();
            rb2D = GetComponent();
        }

        private void FixedUpdate()
        {
            float vertical = Input.GetAxisRaw("Vertical");
            float horizontal = Input.GetAxisRaw("Horizontal");
            UpdateVelocity(horizontal, vertical);
            UpdateAnimation(horizontal, vertical);
            UpdateMovment();
        }

        #endregion

        #region Animation Methods

        private void UpdateAnimation(float horizontal, float vertical)
        {
            UpdateAnimation(new Vector2(horizontal, vertical));
        }

        private void UpdateAnimation(Vector2 input)
        {
            Directions direction;

            if (input.y > 0)
                direction = Directions.Back;
            else if (input.y < 0)
                direction = Directions.Front;
            else if (input.x > 0)
                direction = Directions.Right;
            else if (input.x < 0)
                direction = Directions.Left;
            else
                direction = Directions.Idle;

            SetDirection(direction);
        }

        private void SetDirection(Directions value)
        {
            animator.SetInteger("Direction", (int)value);
            dir = value;
        }

        #endregion

        #region Movement Methods

        private void UpdateMovment()
        {
            rb2D.MovePosition(rb2D.position + velocity * Time.fixedDeltaTime);
            KinematicsDebugPrints();
            ApplySpeedDecay();
        }

        private string GetDebugPrintDetails()
        {
            return string.Format("HOR : {0}\nVER : {1}\nDIR : {2}:{3}\nX : {4}\nY : {5}",
                velocity.x,
                velocity.y,
                animator.GetInteger("Direction").ToString().PadLeft(2),
                (Directions)animator.GetInteger("Direction"),
                rb2D.position.x,
                rb2D.position.y);
        }

        private void KinematicsDebugPrints()
        {
            var details = GetDebugPrintDetails();
            debugText.text = details;
            Debug.Log(details);
        }

        private void UpdateVelocity(float horizontal, float vertical)
        {
            if (vertical != 0)
                velocity.y += Mathf.Sign(vertical) * speed / HUMAN_TO_VECTOR_SCALE_FACTOR;
            if (horizontal != 0)
                velocity.x += Mathf.Sign(horizontal) * speed / HUMAN_TO_VECTOR_SCALE_FACTOR;
            animator.speed = ANIM_SPEED_MODIFIER * velocity.MaxOfXandY() ;
        }

        private void ApplySpeedDecay()
        {
            if (velocity == Vector2.zero) return;

            velocity *= VELOCITY_DECAY_FACTOR;
            velocity = velocity.ZerofiyTinyValues(0.1f);
        }

        #endregion
    }
}

这是目前的玩家对象:

播放机

这是墙体物体(除了图像之外,所有墙壁的预制都是相同的:

壁

这是我的另一个bug的gif:

错误二

这是碰撞框和圆圈的样子:

新的碰撞盒

这是检查员的详细信息

新检查员


所以在与Hamza Hasan交谈之后,他帮我把所有的外墙箱式对撞机变成了四个连续的对撞机,每侧一个(顶部,底部,左侧,右侧).

它的代码BoardManagerCreateWallsColliders方法的脚本上.

这是场景编辑器中当前场景的样子:

新的场景编辑器



1> Tamas Hegedu..:

您遇到的现象是由角色的矩形对撞机与下一个墙砖的底边碰撞引起的.这个'bug'在物理引擎中很常见.它是由一些计算错误引起的,应该是预期的.这就是为什么大多数游戏都有字符的边界椭圆,因为椭圆没有角或边.

摆脱这种突然停止的一种方法是确保所有连续的墙面砖都表示为单个对撞机(矩形或多边形).这需要一个单独的逻辑,在加载关卡后从障碍物中创建碰撞器,并且必须在每次改变关卡后更新碰撞器(打开门等......)

解决问题的一种更简单的方法是更改​​角色的对撞机.如果角色的矩形形状不是必需的,我建议您使用以下形状的对撞机:

胶囊形状的对撞机

或者如果矩形形状是必不可少的,您可以用圆圈扩展角落:

在此输入图像描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/blog/GIT/detail/13090
推荐阅读
相关标签
  

闽ICP备14008679号