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-Based movement question

Discussion in 'Getting Started' started by Suomiboy, Oct 16, 2015.

  1. Suomiboy

    Suomiboy

    Joined:
    Oct 6, 2015
    Posts:
    6
    Hello again!

    I am making a grid-based game and I'd like to ask questions about it.


    Here is how it works right now:
    - I don't use anykind of physics.
    - I use raycasts to check collisions in 4 directions from player position, and 4 raycasts to check if there is floor that player can move to.
    - There currently are 3 scripts; 1 for player input, 1 for grid movement and 1 that handles the raycasts, is this good? I plan to use grid movement and raycast scripts for somekind of AI.
    - Raycasts are cast only when player presses Horizontal or Vertical axis buttons
    - Raycasts change boolian values in a struct.
    - Each of the four possible directions have 3 boolians now - can move, climb up, climb down.
    - Moving is made by lerp in a while loop.


    Questions:
    Is using a lot of raycasts efficient?
    Is using a lot of "if - else if - else" statements efficient, is there ways to avoid them?
    I'd like to add jump to this game - height of blocks varies, there might be gaps in stage... Should I make more raycasts, or is my way of doing this "wrong"? The way I'm doing this would need maybe 8 raycasts more for all possible jump positions.
    What about player attacking enemy? Player pressing button - do a raycast in player's direction - if it hits, kill enemy?
    Are there better ways of doing grid-based games? I haven't looked up guides, so I am kinda proud of what I have made so far. :)

    Here is quick video my current project:
    http://tinypic.com/player.php?v=2ry4isy>&s=8#.ViEVKCuHS1F
     
  2. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,848
    OK, first you say you're not using any kind of physics, but then you say you're using raycasts. Raycasts are physics.

    And that's fine if it works for you — you shouldn't be worrying too much about efficiency at this stage (when you're just learning Unity and how to code). You should be worried primarily about getting something to work!

    But yeah, since it's a grid-based game, using raycasts (or any other kind of physics) is both more difficult and less efficient than simply checking a 2D array that keeps track of what is in each cell of the grid. If you don't know how to make and manipulate a 2D array, this might be a good starting point.

    Good luck,
    - Joe
     
  3. Suomiboy

    Suomiboy

    Joined:
    Oct 6, 2015
    Posts:
    6
    By saying that I don't use physics I meant that I don't use rigidbody etc to make player fall down, collide with objects etc, I know raycasts being physics.

    About arrays, I know how to use them but what about using them as "level" for 3D game? What if I want to change something in the level, I'd have to edit some arrays instead of just making new cube as a ground? How can simple array store if there are enemies moving randomly in the level? What about possible obstacles in level, and some of them are breakable?

    If you give me a link to tutorial about grid based 3D game using arrays instead of raycasts, I'll gladly use them instead.
     
    Last edited: Oct 17, 2015
  4. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,848
    I assumed you were talking about a 2D grid — even if you're using 3D objects, your game is essentially 2D if things can only move in two dimensions. So, a 2D array would work fine. (If you meant a 3D grid, then you'd need to use a 3D array.)

    And in the long run you will probably find it easier to define your levels in a text file than in the editor. At the start of the game, a script would read this file, instantiate the appropriate prefabs, and also update the 2D array that keeps track of what's where.

    When enemies (or the player) move around, you just update the array — clear the entry for where they were coming from, and set the entry for where they are now.

    However, here's a bit of more general advice that will really step up your programming game. Code in such a way that implementation decisions like this don't matter to the rest of your code. Hide the details.

    In this case, that would mean you have some sort of "GridManager" class that's responsible for telling the rest of the code where things are. And here's the key bit: the rest of the code should not know or care how GridManager comes up with its answers.

    So for starters, since it's what you're doing already, have it produce those answers by ray-casting. Later, if you decide you like the 2D array idea better, you just change GridManager to manage a 2D array. The rest of the code doesn't change, because it never knew how GridManager did its work anyway.
     
  5. Suomiboy

    Suomiboy

    Joined:
    Oct 6, 2015
    Posts:
    6
    That sounds interesting approach, I'll make a note about that tip.

    To be honest, I don't think that my solution should be called "grid movement" at all, because it is just an illusion. Player just presses button and character lerps 1 point in X or Z axis from one location to another. There is no grid - it just feels like it :D
     
  6. Suomiboy

    Suomiboy

    Joined:
    Oct 6, 2015
    Posts:
    6
    Hello again, I'm not sure if I should start new thread but here it goes.

    I am now doing jump with Slerp.
    I found a "boomerang" example somewhere and used it as starting point for curved "Jump".
    The code works fine only when player's x y z position is 0, anywhere else it behaves weirdly. Why is this?

    Here are some mad paint skillz:
    asdasdasdsaddsadsa.png

    Code (CSharp):
    1.  
    2.     public float moveDuration = 0.25f; // how long the move takes in seconds
    3.  
    4.     public Vector3 beginPoint; //Movements start position
    5.     public Vector3 finalPoint; //End position
    6.     public Vector3 farPoint; //I don't quite understand this
    7.  
    8.     float startTime; //Time the movement starts
    9.  
    10.     bool isJumping = false;
    11.  
    12.     public void Update()
    13.     {
    14.         if(isJumping)
    15.         {
    16.             Vector3 center = (beginPoint + finalPoint) * 0.5F;
    17.             center -= farPoint;
    18.  
    19.             Vector3 riseRelCenter = beginPoint - center;
    20.             Vector3 setRelCenter = finalPoint - center;
    21.  
    22.             transform.position = Vector3.Slerp(riseRelCenter, setRelCenter, (Time.time - startTime) / duration);
    23.             transform.position += center;
    24.  
    25.             //Rounding the position of player so that it isn't 23.2532141251235 which can cause problems
    26.             Vector3 roundedPos = transform.position;
    27.             roundedPos.x = (float)Math.Round(roundedPos.x, 3);
    28.             roundedPos.y = (float)Math.Round(roundedPos.y, 3);
    29.             roundedPos.z = (float)Math.Round(roundedPos.z, 3);
    30.             transform.position = roundedPos;
    31.  
    32.  
    33.             if (transform.position == finalPoint)
    34.             {
    35.                 isJumping = false;
    36.             }
    37.         }
    38.     }
    39.  
    40.         //Example of my jump function
    41.     public void jumpExample()
    42.     {
    43.         startTime = Time.time; //starting time
    44.         beginPoint = new Vector3(transform.position.x, transform.position.y, transform.position.z); //starting position
    45.         finalPoint = new Vector3(transform.position.x, transform.position.y, transform.position.z + 3); //player moves 3 points in Z axis
    46.         farPoint = new Vector3(transform.position.x, transform.position.y + 2.5f, transform.position.z); //should make curve?
    47.         isJumping = true;
    48.     }
     
    Last edited: Oct 18, 2015