Search Unity

No Go Over O

Discussion in 'Editor & General Support' started by renman3000, Jul 25, 2014.

  1. renman3000

    renman3000

    Joined:
    Nov 7, 2011
    Posts:
    6,699
    Hi there,
    I am making a Pac Man like video game where the playing field is made up by an array of renderers that can variate in pattern each level. I will achieve the variance by turning some renderers on and some off. So, a level may look like this where x, is on, and o is off.


    xxxxxxooooxxxx
    xxxxooooxxxxxx
    xxxxooooxxxxxx



    My player can not travel over any o. I do not want to use triggers as to save engine cost. So, without using triggers, how can I prevent my player from crossing any o? Any ideas?


    Thanks.
     
    Last edited: Jul 25, 2014
  2. renman3000

    renman3000

    Joined:
    Nov 7, 2011
    Posts:
    6,699
    If I make the patterns to be like this instead....

    xxxioooixxx


    where i is a buffer to mark the edge, I could tell this renderer i, to run a call in Update() that will see if player is within its bounds. I could then tell player that it can not move in a direction. No?

    Overall I am doing this to save costs. This method would surely be less costly than triggers yes?
     
  3. Arowx

    Arowx

    Joined:
    Nov 12, 2009
    Posts:
    8,194
    Do you mean colliders, as triggers are more like, sensors.

    You can use the physics in Unity.

    Or you can use raycasts to see if your character can move in that direction.

    Or you line up the grid to 0,0 and each block to 1 unit in space then you can check moves against an array lookup.
     
  4. Arowx

    Arowx

    Joined:
    Nov 12, 2009
    Posts:
    8,194
    Unless you have a very low spec or are writing a turn based game then using colliders and physics should work fine.
     
  5. renman3000

    renman3000

    Joined:
    Nov 7, 2011
    Posts:
    6,699
    Yes, I am looking to avoid using them (the less colliders the better, mobile build). I think I found the solution in my second post.
    Cheers.
     
  6. Arowx

    Arowx

    Joined:
    Nov 12, 2009
    Posts:
    8,194
    Good.

    But an array lookup is faster and cheaper than having every edge do a bounds check on your player or characters.
     
  7. renman3000

    renman3000

    Joined:
    Nov 7, 2011
    Posts:
    6,699
    Fair enough, but the call would be temporary as it is only limited to when the player is moving and to the renderers who are i, border renderers.

    I think this would be better then using triggers. I have noticed collides can be very costly even when sitting idle. The difference between a 100 and 50 may be 10 fps on an older mobile model.
     
  8. Arowx

    Arowx

    Joined:
    Nov 12, 2009
    Posts:
    8,194
    You are missing my point if you are defining your level with an array then you just need to take the players position on the grid and check in the array to see if the new location is empty.

    You just need to calculate between the position of the player in game and their position in the array.
     
  9. renman3000

    renman3000

    Joined:
    Nov 7, 2011
    Posts:
    6,699
    I am not entirley sure what you are getting at?
    Can you explain further?
     
  10. Arowx

    Arowx

    Joined:
    Nov 12, 2009
    Posts:
    8,194
    Actually it was trickier than I thought it would be, add this code to a game object then you just need a cube and sphere or two other gameObjects to represent the walls and player.

    You also need to set up the camera to look at the grid.

    Note no colliders or bounds checking needed.

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. // GridRunner - Allan Rowntree - Arowx.com
    5. // Ultra basic retro maze game - No physics or bounds checking just an array
    6.  
    7. public class GridRunner : MonoBehaviour {
    8.  
    9.     public int[,] grid = {
    10.                          {1,1,1,1,1,1,1,1,1,1},
    11.                          {1,0,0,0,0,0,0,0,0,1},
    12.                          {1,0,1,1,0,0,1,1,0,1},
    13.                          {1,0,1,0,0,0,0,1,0,1},
    14.                          {1,0,0,0,1,1,0,0,0,1},
    15.                          {1,0,0,0,1,1,0,1,0,1},
    16.                          {1,0,1,0,0,0,0,1,0,1},
    17.                          {1,0,1,1,0,0,1,1,0,1},
    18.                          {1,0,0,0,0,0,0,0,0,1},
    19.                          {1,1,1,1,1,1,1,1,1,1}};
    20.  
    21.     public GameObject block;
    22.  
    23.     public Transform player;
    24.  
    25.     public Vector3 oldPos;
    26.     public Vector3 newPos;
    27.  
    28.     public float delta = 0f;
    29.  
    30.     public Vector3 nextMove;
    31.  
    32.     public float speed = 0.5f;
    33.  
    34.     public float inputDelay = 0.1f;
    35.     public bool inputDelayed = false;
    36.  
    37.     void Start () {
    38.         Vector3 pos = Vector3.zero;
    39.         Vector3 offsetX = Vector3.right;
    40.         Vector3 offsetY = Vector3.forward;
    41.  
    42.         Vector3 playerPos = Vector3.zero;
    43.  
    44.         for (int x = 0; x < 10; x++)
    45.         {
    46.             for (int y = 0; y < 10; y++)
    47.             {
    48.                 if (grid[x, y] > 0) Instantiate(block, pos, Quaternion.identity);
    49.                 else playerPos = pos;
    50.                 pos += offsetY;
    51.             }
    52.             pos.z = 0f;
    53.             pos += offsetX;
    54.         }
    55.  
    56.         player.position = playerPos;
    57.  
    58.         oldPos = playerPos;      
    59.     }
    60.        
    61.     void Update () {
    62.        
    63.         float dt = Time.deltaTime;
    64.  
    65.         float h = 0f;
    66.         float v = 0f;
    67.  
    68.         if (!inputDelayed)
    69.         {
    70.             h = Input.GetAxis("Horizontal");
    71.             v = Input.GetAxis("Vertical");
    72.         }
    73.  
    74.         Vector3 pos = player.position;
    75.  
    76.         int x = Mathf.FloorToInt(pos.x);
    77.         int y = Mathf.FloorToInt(pos.z);
    78.  
    79.         if (h != 0)
    80.         {
    81.             nextMove = new Vector3(Mathf.Sign(h), 0f, 0f);
    82.             InputDelay();
    83.         }
    84.         if (v != 0)
    85.         {
    86.             nextMove = new Vector3(0f, 0f, Mathf.Sign(v));
    87.             InputDelay();
    88.         }
    89.  
    90.         if (newPos != Vector3.zero)
    91.         {
    92.             delta += speed * dt;
    93.  
    94.             if (delta >= 1.0f) delta = 1f;
    95.  
    96.             if (delta > 0f)
    97.             {
    98.                 player.position = Vector3.MoveTowards(oldPos, newPos, delta);
    99.             }
    100.  
    101.             if (delta == 1f)
    102.             {
    103.                 delta = 0f;
    104.                 oldPos = newPos;
    105.                 newPos = Vector3.zero;
    106.             }
    107.         }
    108.  
    109.         if (delta == 0f)
    110.         {
    111.             if (nextMove != Vector3.zero)
    112.             {
    113.                 pos = oldPos + nextMove;
    114.  
    115.                 if (grid[(int)pos.x, (int)pos.z] == 0f)
    116.                 {
    117.                     newPos = pos;
    118.                 }
    119.                 nextMove = Vector3.zero;
    120.             }
    121.         }
    122.     }
    123.  
    124.     void InputDelay()
    125.     {
    126.         Invoke("EndInputDelay", inputDelay);
    127.     }
    128.  
    129.     void EndInputDelay()
    130.     {
    131.         inputDelayed = false;
    132.     }
    133. }
    134.  
     
  11. renman3000

    renman3000

    Joined:
    Nov 7, 2011
    Posts:
    6,699
    I actually figured it out.

    Cells can be active or !active, (0 or 1)

    If a cell is inactive, I get the cell beside it, via the common manager, and see if it is active or inactive. If it is active, I know that cell is a border piece. I then set that cell to limit player movement in a direction if player on it.

    It took me a little while but works like a charm.

    With 0 colliders I can set maps based on any size grid I want, with a tap guiding a player to the tapped cell, if a gsp I cures on the journey, the player stops at the cell, edge of playable area.
     
  12. renman3000

    renman3000

    Joined:
    Nov 7, 2011
    Posts:
    6,699
    ps. the issue with 2D arrays is that I can not access them in the inspector. I find that an issue in determining the values that make up the array.
     
  13. Arowx

    Arowx

    Joined:
    Nov 12, 2009
    Posts:
    8,194
    You could just use a single dimension array and work out the coordinates index = x + y * width;
     
  14. renman3000

    renman3000

    Joined:
    Nov 7, 2011
    Posts:
    6,699
    How I have done it is this.....

    Map script, holds 7 int[]'s. Each represents a row.

    Rows Mng gets the array held by any instance of map script. It then pases this two each of its members, row.

    Each row, then uses this passed array to set its members, cells. If a cell is inactive, I ask if the meber beside is active. If it is, I know the member beside it, is a border. Depending on which side this border is, I can say player can not move left or right from this cell.