C# Unity3D-在2.5D跑步游戏中,让角色在跷跷板上顺利前进

C# Unity3D-在2.5D跑步游戏中,让角色在跷跷板上顺利前进,c#,unity3d,C#,Unity3d,我想做的是在Unity中制作一个2.5D跑步者游戏,角色的所有三个旋转轴都被冻结,Z轴上的位置也被冻结。我不知道如何让角色在跷跷板上顺利前进。(我使用HingeJoint创建跷跷板。) 我使用Physics.Raycast()函数创建了一个结构来检测CapsuleColleder的状态,效果很好 private struct ColliderStatus { public bool headed; //colliding up public bool

我想做的是在Unity中制作一个2.5D跑步者游戏,角色的所有三个旋转轴都被冻结,Z轴上的位置也被冻结。我不知道如何让角色在跷跷板上顺利前进。(我使用HingeJoint创建跷跷板。)

我使用Physics.Raycast()函数创建了一个结构来检测CapsuleColleder的状态,效果很好

 private struct ColliderStatus
    {
        public bool headed;  //colliding up
        public bool footed;  //colliding down
        public bool onPlane; //colliding down && the obstacle colliding does not have slope angle
        public bool lefted;  //colliding left
        public bool righted; //colliding right
        public bool inAir;   //not colliding anything
    }
我试过以下方法:

  • 对刚体施加力使其向前移动

    //To move character rigidbody move forward automatically in runner game 
    //when the speed is lower than the minimum speed and it's on plane or in air.
    if (rigidbody.velocity.x < minForwardSpeed && (colliderStatus.onPlane || colliderStatus.inAir))
    {
        rigidbody.AddForce(20f * Vector3.right);
    }
    
    //Add gravity to player
    Vector3 gravityForce = new Vector3(0f, -gravityOnPlayer, 0f);
    rigidbody.AddForce(gravityForce);
    
  • 我不知道为什么我不能这样写,因为这会导致速度反应不正确:

        //Use transform.Translate() to move forward
        if (!colliderStatus.righted && rigidbody.velocity.x < minForwardSpeed)
        {
             transform.Translate(new Vector2(minForwardSpeed, 0f) * Time.deltaTime);
        }
    
    然后我通过计算坡度向量上的重力投影来添加重力:

        private void AddGravity()
        {
        Vector3 gravityForce = new Vector3(0f, -gravityOnPlayer, 0f);
        //my character could be collided by the long vertical wall(colliderStatus.righted)
        //so I set the condition as "!colliderStatus.footed"
        //otherwise, I would use "colliderStatus.inAir"
        if (!colliderStatus.footed)
        {
            gravityForce = new Vector3(0f, -gravityOnPlayer, 0f);
        }
        else
        {
            gravityForce = Vector3.Project(Vector3.down * gravityOnPlayer, SlopeAngleVector());
        }
        rigidbody.AddForce(gravityForce);
        }
    
    现在我的角色可以从跷跷板上滑下来,但它会一直向后。当在低坡度的跷跷板上时,它无法通过


    如何在跷跷板上为跑步者制作一个好的行为脚本?

    我建议查看一些Unity standard asset角色控制器,我相信它们在角色移动时会考虑坡度。它可能会给你一些想法

    我还建议修改代码计算坡度角度的方式。光线投射命中将返回曲面法线,然后您应该能够使用矢量3.Cross来计算坡度的角度

    它类似于:Vector3.Cross(法线,(指向远离屏幕的向量))

    您可能需要调整它以使其正常工作,但这可以在一个光线投射中为您提供坡度角度。它还可以消除你的位置在跷跷板下方的潜在问题


    作为一般提示,尽量不要将变换和刚体内容混合在一起,如果要移动刚体,请直接移动刚体,而不是通过变换间接移动刚体

    你试过改变速度而不是增加力吗?
        private Vector3 SlopeAngleVector()
        {
        Vector3 nextStepPositon = new Vector3(transform.position.x + 0.01f, transform.position.y, 0f);
        Ray nextPosRay = new Ray(nextStepPositon, Vector3.down);
        Ray nowPosRay = new Ray(transform.position, Vector3.down);
        RaycastHit nextPosHit;
        RaycastHit nowPosHit;
        Vector3 slopeAngle = Vector3.zero;
    
        Physics.Raycast(nowPosRay, out nowPosHit, 5f, obstaclesLayerMask);
        if (Physics.Raycast(nextPosRay, out nextPosHit, 5f, obstaclesLayerMask))
        {
            slopeAngle = new Vector3(nextPosHit.point.x - nowPosHit.point.x, nextPosHit.point.y - nowPosHit.point.y, 0f).normalized;
        }
        return slopeAngle;
        }
    
        private void AddGravity()
        {
        Vector3 gravityForce = new Vector3(0f, -gravityOnPlayer, 0f);
        //my character could be collided by the long vertical wall(colliderStatus.righted)
        //so I set the condition as "!colliderStatus.footed"
        //otherwise, I would use "colliderStatus.inAir"
        if (!colliderStatus.footed)
        {
            gravityForce = new Vector3(0f, -gravityOnPlayer, 0f);
        }
        else
        {
            gravityForce = Vector3.Project(Vector3.down * gravityOnPlayer, SlopeAngleVector());
        }
        rigidbody.AddForce(gravityForce);
        }