Search code examples
c#unity-game-enginecontrolsraycasting

why is every second "if input.axis" statement is failing without error when trying to detect a RayCastHit?


I am creating a 3D top-down game and I am wanting to make a character move around though i am using ray casts to make sure that when the characters collides it does continue to change it's position when the character is trying to move against it.

I have create code such as:

[SerializeField] private float speed = 5;


    public float XMovement;
    public float ZMovement;
    public Vector3 RotationY;

    void FixedUpdate()
    {

        MovementSetting();
        

        var dir = new Vector3(XMovement, 0, ZMovement);
        transform.Translate(dir * speed * Time.deltaTime);
    }

    
    void MovementSetting()
    {
        var ray = new Ray();
        RaycastHit hit;

        // If input is "a"
        if (Input.GetAxis("Horizontal") < 0)
        {
            RotationY = transform.TransformDirection(Vector3.left);
            ray = new Ray(this.transform.position, RotationY);

            if (Physics.Raycast(ray, out hit, 0.6f)) { XMovement = 0; }
            else { XMovement = Input.GetAxis("Horizontal"); }
        }
        else { XMovement = 0; }

        // If input is "d"
        if (Input.GetAxis("Horizontal") > 0)
        {
            RotationY = transform.TransformDirection(Vector3.right);
            ray = new Ray(this.transform.position, RotationY);

            if (Physics.Raycast(ray, out hit, 0.6f)) { XMovement = 0; }
            else { XMovement = Input.GetAxis("Horizontal"); }
        }
        else { XMovement = 0; }

        // If input is "s"
        if (Input.GetAxis("Vertical") < 0)
        {
            RotationY = transform.TransformDirection(Vector3.back);
            ray = new Ray(this.transform.position, RotationY);

            if (Physics.Raycast(ray, out hit, 0.6f)) { ZMovement = 0; }
            else { ZMovement = Input.GetAxis("Vertical"); }
        }
        else { ZMovement = 0; }

        // If input is "w"
        if (Input.GetAxis("Vertical") > 0)
        {
            RotationY = transform.TransformDirection(Vector3.forward);
            ray = new Ray(this.transform.position, RotationY);

            if (Physics.Raycast(ray, out hit, 0.6f)) { ZMovement = 0; }
            else { ZMovement = Input.GetAxis("Vertical"); }
        }
        else { ZMovement = 0; }

        
    }

in theory this is meant to work though, only every second "if input" statement 100% works

I find that as soon as it reaches if (Physics.Raycast(ray, out hit, 0.6f)) for every odd "if input", it stops working, though doesn't throw an error code

I tried using debug.log to see if there was any response in the "if physics" respone which I didn't get.

I also tried (dumb idea) seeing if I double the "if input" statements twice, therefore every second one should work, that didn't work either


Solution

  • They are not failing. But the second if-statement may revert the XMovement the first one sets:

    // Let's assume the horizontal axis is < 0 ...
    if (Input.GetAxis("Horizontal") < 0) {
        XMovement = ...; // ... then a value will be assigend here.
    } else {
        XMovement = 0;
    }
    
    if (Input.GetAxis("Horizontal") > 0) {
        // We said it's < 0, so this code will not be executed
    } else {
        XMovement = 0; // however, this one will
                       // and thus the value we assigned earlier will be cleared!
    }
    

    Let's re-organize the code

    float horizontalAxis = Input.GetAxis("Horizontal");
    if (horizontalAxis < 0) {
        XMovement = ...;
    } else if (horizontalAxis > 0) {
        XMovement = ...;
    } else { // horizontalAxis == 0
        XMovement = 0;
    }
    

    Now, always exactly one branch will ever be executed.