The code in the presentation code ////// comment. I want to complete the process when climbing up the slope with an if statement

Question 1 I'd like to know how to implement the process of "when going down the hill".
Question 2 I want to know the implementation method of the branch that separates the processing when climbing up and down the hill, and I want to know the implementation method of processing that also considers the side because it can not move when going diagonally on the hill
Question 4 I want to know the reason why I can't climb when I try to climb up the slope from the flat

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player: MonoBehaviour
const float walk_speed_max = 20.0f;
    Rigidbody rb;
    Vector3 move;
    float input_h;
    float input_v;
    Vector3 move_x;
    Vector3 move_z;
    public GameObject gGround;
    ground spt_g;
    bool isJump;
    bool isDush;
    bool isRay;
    bool isGround = false;
    float jump_force = 200.0f;
    float move_speed = walk_speed_max;
    Animator ani;
    private Transform StepHit;
    private RaycastHit downRay;
    private Transform Hit;
    private RaycastHit ray;
    const float ray_range = 0.3f;/// Distance to fly ray
    // Ascending steps
    private float stepOffset = 0.3f;
    // Climb the slope
    private float slopeLimit = 65f;
    // distance of the ray to fly from the position of the rising step
    private float slopeDistance = 0.1f;
    private Vector3 v;
    // GameObject go = GameObject.Find ("GameObject");
    private Transform prev;
    void move_step ()
    {// y axis is reversed plus down
        Debug.DrawLine (StepHit.position, StepHit.position + StepHit.right * ray_range, Color.red);
        Debug.DrawLine (StepHit.position, StepHit.position + StepHit.forward * ray_range, Color.blue);
        float s = Mathf.Sqrt ((move.x * move.x) + (move.z * move.z));
        if (s>0&&isGround == true)
            if (Physics.Linecast (StepHit.position, StepHit.position + StepHit.forward * ray_range, out ray, LayerMask.GetMask ("Slope")))
// if (Physics.Linecast (StepHit.position, StepHit.position + StepHit.forward * ray_range, out ray))
                //Debug.Log(Vector3.Angle(transform.up, ray.normal));
                if (Vector3.Angle (transform.up, ray.normal)<= slopeLimit)
                    v = new Vector3 (0f, (Quaternion.FromToRotation (Vector3.up, ray.normal) * transform.forward * s) .y, 0f)
                                            + transform.forward * s;
                    Debug.Log ("Up" + v.y);
                    move.y + = v.y;
                ////////////////////////////////////////////////// ////////////////////////////////////////////////// //
            } else if (Physics.Linecast (StepHit.position, StepHit.position + StepHit.right * ray_range, out downRay, LayerMask.GetMask ("Slope")))
            {Debug.Log (Vector3.Angle (transform.up, downRay.normal));
                if (Vector3.Angle (transform.up, downRay.normal)<= slopeLimit)
                    Debug.Log ("down");
                    v = new Vector3 (0f, (Quaternion.FromToRotation (Vector3.up, ray.normal) * transform.forward * s) .y, 0f)
                                    + transform.up * s;
                    Debug.Log ("Go down:" + v.y);
                    move.y + = -v.y;
              // Debug.Log ("When going down");
            ////////////////////////////////////////////////// ////////////////////////////////////////////////// //

    // Start is called before the first frame update
    void Start ()
        rb = GetComponent<Rigidbody>();
        spt_g = gGround.GetComponent<ground>();
        ani = GetComponent  ();
        isJump = false;
        isDush = false;
        StepHit = transform.Find ("StepRay");
    // Update is called once per frame
    void Update ()
// Debug.Log (transform.right);
        isGround = spt_g.isGround;
       // Debug.Log (isGround);
        // input_h = Input.GetAxis ("Horizontal");
        // input_v = Input.GetAxis ("Vertical");
        if (Input.GetKey (KeyCode.LeftArrow))
            input_h = -1;
        } else if (Input.GetKey (KeyCode.RightArrow))
            input_h = 1;
            input_h = 0;

        if (Input.GetKey (KeyCode.UpArrow))
            input_v = 1;
        else if (Input.GetKey (KeyCode.DownArrow))
            input_v = -1;
            input_v = 0;
        move_z = Vector3.Scale (Camera.main.transform.forward, new Vector3 (1, 0, 1)). normalized * input_v;
        move_x = Camera.main.transform.right * input_h;
        move = move_x + move_z;
        move.x * = move_speed;move.z * = move_speed;
    // Debug.Log (isRay);
        if (move! = Vector3.zero)
            transform.rotation = Quaternion.LookRotation (move.normalized);
        if (Input.GetKey (KeyCode.RightControl))
            isDush = true;
            move_speed = 15.0f;
            isDush = false;
            move_speed = walk_speed_max;
        if (Input.GetKey (KeyCode.Space))
            if (isGround == true&&isJump == false)
                isJump = true;
        move_step ();
        Animation_Mng ();
    / * Animation management * /
    void Animation_Mng ()
        float speed = Mathf.Sqrt ((move.x * move.x) + (move.z * move.z));
        ani.SetFloat ("Move_Speed", speed);
        ani.SetBool ("isDush", isDush);
        //ani.speed = 2;

    private void FixedUpdate ()
        if (isGround == false)
            rb.AddForce (new Vector3 (0, -30.0f, 0));
            rb.velocity = new Vector3 (move.x, rb.velocity.y, move.z);
            rb.velocity = new Vector3 (move.x, move.y, move.z);

    private void OnCollisionEnter (Collision c)
        // isGround = true;

    private void OnCollisionExit (Collision c)
        // isGround = false;
 // Debug.Log ("Player collision false");
  • Answer # 1

    void In move_step (), there seems to be a comment out even though there is a trace of trying to tamper with the y-axis speed when on a slope.

    As a result, the movement in the y direction is only messing with AddForce even though the x and z directions are directly changing the speed. (Sorry if it is different)
    If so, that is probably the cause.

    Explain what is happening and what is happening.

    When trying to climb a hill, the speed of x and z is directly messed up even though there is a hill. is.

    As a result, the sinking disappears at the moment when it stops, and it looks like it has gone up.

    When trying to go down the hill, the speed in the y-axis direction is initially 0, and only the speeds of x and z are suddenly made constant.
    Although it is AddForce also in the y direction, this is only accelerated by applying force.

    If you don't apply too much force, you won't be able to reach that speed in an instant, as if you were messing with the speed value directly.

    By doing this, the x and z velocities are constant, the y-axis speed is accelerated from 0, hits the slope, and returns to 0.

    Therefore, it will be a gradual movement as if going down the stairs.

    Is it consistent with the questioner's symptoms?

    The solution is to tweak the y-axis speed, or tweak the y-coordinate directly to the slope.

    We use the move as it is because we get information on whether or not there is a slope at move_step ().
    When you are on a slope, calculate from the angle and direction of movement, and then add the necessary y-axis speed or coordinates.

    What is the commented out process?

    (Other than that, if you search on Saka Unity, there are many things that you can check out, please check it yourself)

    As an aside, there are cases like this, so it may be said that playing with RigidBody directly is not recommended.

    You can do everything with AddForce.
    However, in that case, it can cause problems, or it can be a dull movement that doesn't do very well.

    So, if you want to take care of the laws of physics, all are unified with AddForce, but if you want to cherish the game's uniqueness such as response, it is appropriate to change the RigidBody.verocity and transform.position.

Related articles