Search Unity

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