Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Grid movement with different heights and ramps

Discussion in 'Scripting' started by darryldonohoe, Feb 11, 2017.

  1. darryldonohoe

    darryldonohoe

    Joined:
    Jan 10, 2012
    Posts:
    55
    Hey there,

    I have a problem and was hoping someone could help me, i want to create a grid based movement, but with different heights and ramps.

    So right now i use the GridMove from the Wiki. I thought about converting it to use a rigidbody.(but i got weird problems whenever you hit a ramp, you start floating)
    But i still don't know how to tackle the problem whenever you come across a ramp-tile.

    The idea should be that the player walks up the ramp, automatically updating the Y position but reaching the X or Z position.

    Can anybody share some insight on this? It would greatly help me.

    I already tried looking on google, so far i saw some great tips. But none of them wanted to use a system with different heights or ramps.

    Thanks in advance! Meanwhile i will start thinking of a possible solution.

    Cheers,
    Darryl
     
  2. darryldonohoe

    darryldonohoe

    Joined:
    Jan 10, 2012
    Posts:
    55
    Okay, so i thought about some methods to tackle this and i came up with this:

    Cast a ray downwards, and store the hit Y position.

    The code now looks like this:

    Code (CSharp):
    1. using System.Collections;
    2. using UnityEngine;
    3.  
    4. class PlayerController : MonoBehaviour
    5. {
    6.     public float moveSpeed = 3f;
    7.     public float gridSize = 1f;
    8.  
    9.  
    10.     private Vector2 input;
    11.     private bool isMoving = false;
    12.     private Vector3 startPosition;
    13.     private Vector3 endPosition;
    14.     private float t;
    15.     private float factor;
    16.  
    17.     public Vector3 groundPosition;
    18.     RaycastHit hit;
    19.  
    20.     Transform myTransform;
    21.  
    22.     void Start()
    23.     {
    24.         myTransform = transform;
    25.     }
    26.  
    27.     public void Update()
    28.     {
    29.         if(Physics.Raycast(myTransform.position, Vector3.down, out hit, 2f))
    30.         {
    31.             groundPosition = hit.point;
    32.  
    33.             groundPosition += new Vector3(0, myTransform.localScale.y, 0);
    34.  
    35.         }
    36.  
    37.         if (!isMoving)
    38.         {
    39.             input = new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"));
    40.             if (Mathf.Abs(input.x) > Mathf.Abs(input.y))
    41.             {
    42.                 input.y = 0;
    43.             }
    44.             else
    45.             {
    46.                 input.x = 0;
    47.             }
    48.  
    49.             if (input != Vector2.zero)
    50.             {
    51.                 StartCoroutine(move(myTransform));
    52.             }
    53.         }
    54.     }
    55.  
    56.     public IEnumerator move(Transform myTransform)
    57.     {
    58.         isMoving = true;
    59.         startPosition = myTransform.position;
    60.         t = 0;
    61.  
    62.         endPosition = new Vector3(startPosition.x + System.Math.Sign(input.x) * gridSize,
    63.         groundPosition.y, startPosition.z + System.Math.Sign(input.y) * gridSize);
    64.  
    65.         factor = 1f;
    66.  
    67.         while (t < 1f)
    68.         {
    69.             t += Time.deltaTime * (moveSpeed / gridSize) * factor;
    70.             myTransform.position = Vector3.Lerp(startPosition, endPosition, t);
    71.             yield return null;
    72.         }
    73.  
    74.         isMoving = false;
    75.         yield return 0;
    76.     }
    77. }
    78.  
    It is sort of working, but there is a delay in the groundPosition and the actual transform position.
    So when walking down ramps, you will float in the air or whenever you walk up a ramp, you will first walk through the ramp.

    However, i am a step closer.


    Cheers,
    Darryl
     
  3. darryldonohoe

    darryldonohoe

    Joined:
    Jan 10, 2012
    Posts:
    55
    Okay sorry for all the bumps. But i figured it out!
    The problem was, whenever you moved in a direction it only calculated the X and Z axis. Since it casted a Ray downwards from the players position.

    So i did a check in which direction the player is moving, casting a ray 1 block away downwards.

    And now it works!

    So if anyone is interested, here is the code:

    Code (CSharp):
    1. using System.Collections;
    2. using UnityEngine;
    3.  
    4. class PlayerController : MonoBehaviour
    5. {
    6.     public float moveSpeed = 3f;
    7.     public float gridSize = 1f;
    8.  
    9.     private Vector2 input;
    10.     private bool isMoving = false;
    11.     private Vector3 startPosition;
    12.     private Vector3 endPosition;
    13.     private float t;
    14.     private float factor;
    15.  
    16.     public Vector3 groundPosition;
    17.  
    18.     Vector3 rayPosition;
    19.     RaycastHit hit;
    20.  
    21.     Transform myTransform;
    22.  
    23.  
    24.     void Start()
    25.     {
    26.         myTransform = transform;
    27.     }
    28.  
    29.  
    30.     public void Update()
    31.     {
    32.         if (!isMoving)
    33.         {
    34.             input = new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"));
    35.  
    36.             if (Mathf.Abs(input.x) > Mathf.Abs(input.y))
    37.             {
    38.                 input.y = 0;
    39.  
    40.                 if(input.x  >0)
    41.                 {
    42.                     rayPosition = new Vector3(myTransform.position.x+1f, myTransform.position.y, myTransform.position.z);
    43.                 }
    44.                 else if(input.x < 0)
    45.                 {
    46.                     rayPosition = new Vector3(myTransform.position.x-1f, myTransform.position.y, myTransform.position.z);
    47.                 }
    48.             }
    49.             else
    50.             {
    51.                 input.x = 0;
    52.  
    53.                 if(input.y > 0)
    54.                 {
    55.                     rayPosition = new Vector3(myTransform.position.x, myTransform.position.y, myTransform.position.z + 1f);
    56.                 }
    57.                 else if(input.y < 0)
    58.                 {
    59.                     rayPosition = new Vector3(myTransform.position.x, myTransform.position.y, myTransform.position.z - 1f);
    60.                 }
    61.             }
    62.  
    63.             if (input != Vector2.zero)
    64.             {
    65.                 if (Physics.Raycast(rayPosition, Vector3.down, out hit, 2f))
    66.                 {
    67.                     groundPosition = hit.point;
    68.  
    69.                     groundPosition += new Vector3(0, myTransform.localScale.y, 0);
    70.  
    71.                 }
    72.  
    73.                 StartCoroutine(move(myTransform));
    74.             }
    75.         }
    76.     }
    77.  
    78.  
    79.     public IEnumerator move(Transform myTransform)
    80.     {
    81.         isMoving = true;
    82.         startPosition = myTransform.position;
    83.         t = 0;
    84.  
    85.  
    86.         endPosition = new Vector3(startPosition.x + System.Math.Sign(input.x) * gridSize,
    87.         groundPosition.y, startPosition.z + System.Math.Sign(input.y) * gridSize);
    88.  
    89.         factor = 1f;
    90.  
    91.         while (t < 1f)
    92.         {
    93.             t += Time.deltaTime * (moveSpeed / gridSize) * factor;
    94.             myTransform.position = Vector3.Lerp(startPosition, endPosition, t);
    95.             yield return null;
    96.         }
    97.  
    98.         isMoving = false;
    99.         yield return 0;
    100.     }
    101. }
    102.  
    If you have anything to add, or maybe some tips. I would still like to hear them!
    For now i am just happy for fixing this.


    Cheers,
    Darryl