Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/334.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/unity3d/4.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jsp/3.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# Unity2D:Can';平衡壁面跳跃力_C#_Unity3d - Fatal编程技术网

C# Unity2D:Can';平衡壁面跳跃力

C# Unity2D:Can';平衡壁面跳跃力,c#,unity3d,C#,Unity3d,我的意图是让我的角色在墙壁上跳跃/攀爬/滑动,我让滑动部分工作得很好,但是如果他在墙壁滑动时跳跃,他应该“反弹”到墙壁上,问题是我无法平衡力量。在我看到的所有教程中,这只是一个简单的问题,即检测角色是否在滑动墙壁,如果他在滑动,并且他在跳跃,则向墙壁添加一个力 这对我不起作用,因为如果我增加足够的力量让他跳,他跳得太快了,玩家几乎看不到他跳了,他只是看到角色现在在墙上更高了。如果我再加上一点力,这还不足以做出一个相当大的跳跃,玩家必须打一千次空格才能让他在墙上上升几厘米 感谢您的帮助,我已经尝试

我的意图是让我的角色在墙壁上跳跃/攀爬/滑动,我让滑动部分工作得很好,但是如果他在墙壁滑动时跳跃,他应该“反弹”到墙壁上,问题是我无法平衡力量。在我看到的所有教程中,这只是一个简单的问题,即检测角色是否在滑动墙壁,如果他在滑动,并且他在跳跃,则向墙壁添加一个力

这对我不起作用,因为如果我增加足够的力量让他跳,他跳得太快了,玩家几乎看不到他跳了,他只是看到角色现在在墙上更高了。如果我再加上一点力,这还不足以做出一个相当大的跳跃,玩家必须打一千次空格才能让他在墙上上升几厘米

感谢您的帮助,我已经尝试了很多方法,甚至尝试冻结控件,将重力比例设置为0,并使用MoveToward将角色fo设置到正确的点,这就是我的绝望

我对Unity也很陌生,所以我可能错过了一些非常简单的东西

以下是显示角色行为的gif:

以下是我角色剧本的相关部分:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TheBot : MonoBehaviour {

    public float speed;
    public int jumpForce;
    public Transform groundCheck;
    public Transform meleeCheck;
    public Transform bulletSpawner;
    public LayerMask layerGround;
    public float meleeCoolDown;
    public float meleeDamage;

    private Rigidbody2D body;
    private Animator anim;
    private Dash dashController;
    private Shooter shotController;
    private float unloadWaitingTime = 3;
    private float idleGunTime = 0;

    private bool facingRight = true;
    private bool onGround = true;
    private bool jumping = false;
    private bool attacking = false;
    private bool dead = false;
    private bool isGunLoaded = false;
    private bool isGunLoading = false;
    private bool isGunUnloading = false;
    private bool takingDamage = false;
    private bool dashing = false;
    private bool isWallSliding = false;

    private float wallJumpTime = 0f;
    private Vector3[] wallJumpControlPoint;

    // Use this for initialization
    void Start () {
        body = GetComponent<Rigidbody2D>();
        anim = GetComponent<Animator>();
        dashController = GetComponent<Dash>();
        shotController = GetComponent<Shooter>();
    }

    // Update is called once per frame
    void Update () {
        PlayAnimations();
        CheckIfGrounded();
        checkIfWallSliding();
        dashing = dashController.IsDashing();

        if (Input.GetButtonDown("Jump") && (onGround || isWallSliding)  && !isGunLoading && !jumping && !takingDamage){
            jumping = true;
            wallJumpControlPoint = new Vector3[3];
            wallJumpControlPoint[0] = body.position;
            wallJumpControlPoint[1] = new Vector3(body.position.x +4, body.position.y + 2);
            wallJumpControlPoint[2] = new Vector3(body.position.x, body.position.y + 4);
        }
        if (Input.GetButtonDown("Melee") && !attacking && !isGunLoading){
            Attack();
        }
        if(Input.GetButtonDown("Ranged") && !attacking  && !isGunLoading && onGround){
            Shoot();
        }

        if(Input.GetButtonDown("Dash") && !attacking && !isGunLoading && onGround){
            dashController.DashTo(facingRight? Dash.RIGHT : Dash.LEFT);
        }


        if(isGunLoaded){
            idleGunTime += Time.deltaTime;
            if (idleGunTime >= unloadWaitingTime){
                UnloadGun();
            }
        }

    }

    void FixedUpdate(){
        if(!takingDamage){

            float move = Input.GetAxis("Horizontal");

            //while charachter is wall sliding, slowly fall
            if (isWallSliding){
                body.velocity = new Vector2(body.velocity.x, -0.7f);
            }

            if(!dashing){
                if(onGround){
                    //if not dashing on on ground, walk with normal speed
                    body.velocity = new Vector2(move * speed, body.velocity.y);
                } else {
                    //if character is not on ground, reduce the speed so he doesn't jump too far away
                    body.velocity = new Vector2(move * (speed * 0.7f), body.velocity.y);
                }
            }

            if((move < 0 && facingRight) || (move > 0 && !facingRight) ){
                //control direction character is facing
                Flip();
            }

            if (jumping){

                if(isWallSliding){
                    body.velocity = new Vector2(30, 20);
                } else {
                    body.AddForce(new Vector2(0f, jumpForce), ForceMode2D.Impulse);
                }

                if(Input.GetKey(KeyCode.RightArrow) || Input.GetKey(KeyCode.LeftArrow)){
                    //if is moving while jumping, reduce jump height
                    body.velocity = new Vector2(body.velocity.x, body.velocity.y*0.8f);
                }
                onGround = false;
                jumping = false;
            }       
        }
    }

    void CheckIfGrounded(){
        onGround = false;
        Collider2D[] collisionResults = new Collider2D[2];
        int objectsBeneath = Physics2D.OverlapBoxNonAlloc(groundCheck.position, new Vector2(0.9f, 0.3f), 0.0f, collisionResults, layerGround);
        for (int i=0; i <objectsBeneath; i++ ){
            if (!GameObject.ReferenceEquals(gameObject, collisionResults[i].gameObject)){
                onGround = true;
            }
        }
    }

    void checkIfWallSliding(){
        if (!onGround){
            RaycastHit2D[] ray = new RaycastHit2D[1];
            int totalRayHits = Physics2D.LinecastNonAlloc(bulletSpawner.position, body.position, ray, 1 << LayerMask.NameToLayer("SolidGround"));
            bool wallFound = totalRayHits > 0 && ray[0].collider.gameObject.tag == "SolidGround";

            isWallSliding = wallFound && ( (facingRight && Input.GetKey(KeyCode.RightArrow)) ||  (!facingRight && Input.GetKey(KeyCode.LeftArrow))) ;
        } else {
            isWallSliding = false;
            if (body.velocity.y > 10){
                body.velocity = new Vector2(body.velocity.x, 5);
            }
        }
    }


    public void Die(){
        dead = true;
    }

}
使用系统集合;
使用System.Collections.Generic;
使用UnityEngine;
公共类TheBot:单一行为{
公众浮标速度;
公共安全部队;
公开审查;
公共交通检查;
公共产卵器;
公共层屏蔽层环绕;
公共浮球冷却;
公共交通混乱;
私人刚体2D机构;
私人动画师;
专用仪表盘控制器;
私人射击控制器;
私有浮动unloadWaitingTime=3;
私有float idleGunTime=0;
私有bool-facingRight=true;
private bool onGround=真;
私人布尔跳跃=假;
私有布尔攻击=假;
二等兵布尔死=假;
private bool isgunload=假;
私有bool isGunLoading=假;
私有bool=false;
私人楼宇损坏=错误;
private bool dashing=假;
private bool IswallSlideing=假;
私有浮动时间=0f;
专用矢量3[]控制点;
//用于初始化
无效开始(){
body=GetComponent();
anim=GetComponent();
dashController=GetComponent();
shotController=GetComponent();
}
//每帧调用一次更新
无效更新(){
播放动画();
checkifground();
checkIfWallSliding();
dashing=dashController.IsDashing();
如果(输入.GetButtonDown(“跳跃”)&&(onGround | | | IsWallSlideing)&&!isGunLoading&!跳跃和承受伤害){
跳跃=正确;
wallJumpControlPoint=新矢量3[3];
wallJumpControlPoint[0]=body.position;
wallJumpControlPoint[1]=新矢量3(body.position.x+4,body.position.y+2);
wallJumpControlPoint[2]=新矢量3(body.position.x,body.position.y+4);
}
if(Input.GetButtonDown(“近战”)&&!攻击&&!isGunLoading){
攻击();
}
if(Input.GetButtonDown(“Ranged”)&&&!攻击&&!isGunLoading&&onGround){
射击();
}
if(Input.GetButtonDown(“Dash”)&&&!攻击&&!isGunLoading&&onGround){
dashController.DashTo(朝向右侧?Dash.RIGHT:Dash.LEFT);
}
如果(带枪){
idleGunTime+=Time.deltaTime;
if(idleGunTime>=卸载等待时间){
解锁枪();
}
}
}
void FixedUpdate(){
如果(!承受损坏){
float move=Input.GetAxis(“水平”);
//当charachter在墙壁上滑动时,缓慢下降
如果(Iswall滑动){
body.velocity=新矢量2(body.velocity.x,-0.7f);
}
如果(!破折号){
如果(每轮){
//如果没有在地面上冲刺,则以正常速度行走
body.velocity=新矢量2(移动*速度,body.velocity.y);
}否则{
//如果角色不在地面上,降低速度,这样他就不会跳得太远
body.velocity=新矢量2(移动*(速度*0.7f),body.velocity.y);
}
}
if((移动<0&&朝向右侧)| |(移动>0&&朝向右侧)){
//控制方向字符所面对的方向
翻转();
}
如果(跳跃){
如果(Iswall滑动){
body.velocity=新矢量2(30,20);
}否则{
body.AddForce(新矢量2(0f,跳跃力),ForceMode2D.Pulse);
}
if(Input.GetKey(KeyCode.RightArrow)| | Input.GetKey(KeyCode.LeftArrow)){
//如果在跳跃时移动,降低跳跃高度
body.velocity=新矢量2(body.velocity.x,body.velocity.y*0.8f);
}
onGround=假;
跳跃=错误;
}       
}
}
void CheckIfGrounded(){
onGround=假;
CollizedR2d[]碰撞结果=新的碰撞r2D[2];
int objectsBeneath=Physics2D.overlappeboxNonaloc(groundCheck.position,新矢量2(0.9f,0.3f),0.0f,碰撞结果,层轮);
对于(int i=0;i 10){
body.velocity=新矢量2(body.velocity.x,5);
}
}
}
公共空间(){
死=真;
}
}

正如您之前尝试的那样,您需要降低跳跃时的水平跳跃加速度/速度

当你跳墙的时候,你会朝着墙挤。当你在空中时,你的水平速度被设置为你按下的方向。这使得任何水平运动从
if(!dashing){
    if(onGround){
        //if not dashing on on ground, walk with normal speed
        body.velocity = new Vector2(move * speed, body.velocity.y);
    } else {
        //if character is not on ground, reduce the speed so he doesn't jump too far away
        float airControlAccelerationLimit = 0.5f;  // Higher = more responsive air control
        float airSpeedModifier = 0.7f; // the 0.7f in your code, affects max air speed
        float targetHorizVelocity = move 
                * speed 
                * airSpeedModifier;  // How fast we are trying to move horizontally
        float targetHorizChange = targetHorizVelocity 
                - body.velocity.x; // How much we want to change the horizontal velocity
        float horizChange = Mathf.Clamp(
                targetHorizChange ,
                -airControlAccelerationLimit , 
                airControlAccelerationLimit ); // How much we are limiting ourselves 
                                               // to changing the horizontal velocity
        body.velocity = new Vector2(body.velocity.x + horizChange, body.velocity.y);
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TheBot : MonoBehaviour {

    public float speed;
    public int jumpForce;
    public Transform groundCheck;
    public Transform meleeCheck;
    public Transform bulletSpawner;
    public LayerMask layerGround;
    public float meleeCoolDown;
    public float meleeDamage;

    private Rigidbody2D body;
    private Animator anim;
    private Dash dashController;
    private Shooter shotController;
    private float unloadWaitingTime = 3;
    private float idleGunTime = 0;

    private bool facingRight = true;
    private bool onGround = true;
    private bool jumping = false;
    private bool attacking = false;
    private bool dead = false;
    private bool isGunLoaded = false;
    private bool isGunLoading = false;
    private bool isGunUnloading = false;
    private bool takingDamage = false;
    private bool dashing = false;
    private bool isWallSliding = false;

    private float wallJumpTime = 0f;
    private Vector3[] wallJumpControlPoint;

    // Use this for initialization
    void Start () {
        body = GetComponent<Rigidbody2D>();
        anim = GetComponent<Animator>();
        dashController = GetComponent<Dash>();
        shotController = GetComponent<Shooter>();
    }

    // Update is called once per frame
    void Update () {
        PlayAnimations();
        CheckIfGrounded();
        checkIfWallSliding();
        dashing = dashController.IsDashing();

        if (Input.GetButtonDown("Jump") && (onGround || isWallSliding)  && !isGunLoading && !jumping && !takingDamage){
            jumping = true;
            wallJumpControlPoint = new Vector3[3];
            wallJumpControlPoint[0] = body.position;
            wallJumpControlPoint[1] = new Vector3(body.position.x +4, body.position.y + 2);
            wallJumpControlPoint[2] = new Vector3(body.position.x, body.position.y + 4);
        }
        if (Input.GetButtonDown("Melee") && !attacking && !isGunLoading){
            Attack();
        }
        if(Input.GetButtonDown("Ranged") && !attacking  && !isGunLoading && onGround){
            Shoot();
        }

        if(Input.GetButtonDown("Dash") && !attacking && !isGunLoading && onGround){
            dashController.DashTo(facingRight? Dash.RIGHT : Dash.LEFT);
        }


        if(isGunLoaded){
            idleGunTime += Time.deltaTime;
            if (idleGunTime >= unloadWaitingTime){
                UnloadGun();
            }
        }

    }

    void FixedUpdate(){
        if(!takingDamage){

            float move = Input.GetAxis("Horizontal");

            //while charachter is wall sliding, slowly fall
            if (isWallSliding && !jumping && body.velocity.y < -0.7f){ 
                body.velocity = new Vector2(body.velocity.x, -0.7f)
            }

            if(!dashing){
                if(onGround){
                    //if not dashing on on ground, walk with normal speed
                    body.velocity = new Vector2(move * speed, body.velocity.y);
                } else {
                    //if character is not on ground, reduce the speed so he doesn't jump too far away
                    float airControlAccelerationLimit = 0.5f;  // Higher = more responsive air control
                    float airSpeedModifier = 0.7f; // the 0.7f in your code, affects max air speed
                    float targetHorizVelocity = move 
                            * speed 
                            * airSpeedModifier;  // How fast we are trying to move horizontally
                    float targetHorizChange = targetHorizVelocity 
                            - body.velocity.x; // How much we want to change the horizontal velocity
                    float horizChange = Mathf.Clamp(
                            targetHorizChange ,
                            -airControlAccelerationLimit , 
                            airControlAccelerationLimit ); // How much we are limiting ourselves 
                                                           // to changing the horizontal velocity
                    body.velocity = new Vector2(body.velocity.x + horizChange, body.velocity.y);
                }
            }

            if((move < 0 && facingRight) || (move > 0 && !facingRight) ){
                //control direction character is facing
                Flip();
            }

            if (jumping){

                if(isWallSliding){
                    body.velocity = new Vector2(body.velocity.x + 0.25f * jumpForce, jumpForce);
                } else {
                    body.AddForce(new Vector2(0f, jumpForce), ForceMode2D.Impulse);
                }

                if(Input.GetKey(KeyCode.RightArrow) || Input.GetKey(KeyCode.LeftArrow)){
                    //if is moving while jumping, reduce jump height
                    body.velocity = new Vector2(body.velocity.x, body.velocity.y*0.8f);
                }
                onGround = false;
                jumping = false;
            }       
        }
    }

    void CheckIfGrounded(){
        onGround = false;
        Collider2D[] collisionResults = new Collider2D[2];
        int objectsBeneath = Physics2D.OverlapBoxNonAlloc(groundCheck.position, new Vector2(0.9f, 0.3f), 0.0f, collisionResults, layerGround);
        for (int i=0; i <objectsBeneath; i++ ){
            if (!GameObject.ReferenceEquals(gameObject, collisionResults[i].gameObject)){
                onGround = true;
            }
        }
    }

    void checkIfWallSliding(){
        if (!onGround){
            RaycastHit2D[] ray = new RaycastHit2D[1];
            int totalRayHits = Physics2D.LinecastNonAlloc(bulletSpawner.position, body.position, ray, 1 << LayerMask.NameToLayer("SolidGround"));
            bool wallFound = totalRayHits > 0 && ray[0].collider.gameObject.tag == "SolidGround";

            isWallSliding = wallFound && ( (facingRight && Input.GetKey(KeyCode.RightArrow)) ||  (!facingRight && Input.GetKey(KeyCode.LeftArrow))) ;
        } else {
            isWallSliding = false;
        }
    }


    public void Die(){
        dead = true;
    }

}