Search Unity

just a maths problem that I can't wrap my head around

Discussion in 'Scripting' started by BubyMB, Feb 12, 2017.

  1. BubyMB

    BubyMB

    Joined:
    Jun 6, 2016
    Posts:
    140
    hey guys, I am making a wave system for an array of blocks; for example, If one block is at 2, and the origin point is 0, it will calculate how many blocks it will take to slowly decline to the origin point, sort of like stairs.
    Here is my script:
    Code (csharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5. using System;
    6.  
    7. public class MobMentality : MonoBehaviour {
    8.  
    9.     public float moveIncrement = .2f;
    10.     public float MoveSize = 1f;
    11.     [Space]
    12.     private float offset;
    13.     private Grid highlightedGrid;
    14.     private Vector3 startPos = new Vector3 (1, 0, 1);
    15.  
    16.     public GameObject cubePrefab;
    17.     [Space]
    18.     public float size;
    19.     public float spacing;
    20.     [Serializable]
    21.     public sealed class Grid{
    22.         public GameObject Object;
    23.         public int column;
    24.         public int height;
    25.     }
    26.     [Space]
    27.     [HideInInspector]
    28.     public List<Grid> Grids = new List<Grid>();
    29.  
    30.     public int width;
    31.     public int height;
    32.  
    33.     void Start(){
    34.         for (int i = 0; i < width; i++) {
    35.             for (int j = 0; j < height; j++) {
    36.                 createCube (i, j);
    37.             }
    38.         }
    39.     }
    40.  
    41.     void createCube(int width, int height){
    42.         Vector3 pos;
    43.         offset = size + spacing;
    44.  
    45.         GameObject Cube = Instantiate (cubePrefab, new Vector3 (0, 0, 0), Quaternion.identity);
    46.         float x = offset * width;
    47.         float z = offset * height;
    48.         pos = new Vector3(x,0,z) + startPos;
    49.         Cube.transform.position = pos;
    50.         Cube.GetComponent<CubeUpdate> ().number = Grids.Count + 1;
    51.         Cube.GetComponent<CubeUpdate> ().GameManager = this.gameObject;
    52.  
    53.         Grid _CubeGrid = new Grid ();
    54.         _CubeGrid.Object = Cube;
    55.         _CubeGrid.height = height;
    56.         _CubeGrid.column = width;
    57.  
    58.         Grids.Add (_CubeGrid);
    59.     }
    60.  
    61.     public void MovementUpdate(GameObject _object){
    62.         if (_object.transform.position.y > 0f)
    63.             getGrid (_object.transform.position.x, _object.transform.position.z);
    64.     }
    65.  
    66. //    void Update(){
    67. //        foreach (Grid _grid in Grids) {
    68. //            if (_grid.Object.transform.position.y != 0f) {
    69. //                getGrid (_grid.Object.transform.position.x, _grid.Object.transform.position.z);
    70. //            }
    71. //        }
    72. //    }
    73.  
    74.  
    75.     void getGrid(float posZ, float posX){
    76.         int column = (int)((posX / offset) + .1f);
    77.         int _height = (int)((posZ / offset) + .1f);
    78.         int number = column + (width * (_height-1));
    79.         highlightedGrid = Grids [number - 1];
    80.         moveNeighbour (highlightedGrid, number);
    81.         Debug.Log (number + "");
    82.     }
    83.  
    84.     void moveNeighbour(Grid _grid, int blockNumber){
    85.         GameObject gridObject = _grid.Object;
    86.         float blocksToAffect = (gridObject.transform.position.y / moveIncrement);
    87.         //MoveAll Left
    88.         for (int i = 1; i < blocksToAffect; i++) {
    89.             Grids [blockNumber - i].Object.transform.position = new Vector3(Grids[blockNumber - i].Object.transform.position.x,(_grid.Object.transform.position.y + 1 - (i * moveIncrement)),Grids[blockNumber - i].Object.transform.position.z);
    90.             Debug.Log ("Move Neighbour: " + (blockNumber - i) + " From Origin Point: " + blockNumber + " To Point: " + Grids[blockNumber - i].Object.transform.position.y);
    91.             Debug.Log ("Origin Point: " + blockNumber);
    92.             Debug.Log ("Blocks to affect: " + blocksToAffect);
    93.         }
    94.     }
    95. }
    96.  
    97.  
    Focus is on moveNeighbour. So in the function, blocks to affect is the calculation that determines how many blocks need to be affected, if the block is at 2, it should be 15 since the move increment is 0.2; but no matter how high it is, it only shows 5.
    I did the math and it should work no matter what. E.G 5 / .2 = 25; 2 / .2 = 10
    and also; in movementUpdate, it only runs when the block is > 2. I want it to include 1 aswell. with the for loop, it also affects the middle block which i call origin point. which I tried to fix by starting i at 1 but it still doens't work.
    Thanks in advance!

    --Edit

    For reference, as you can see the origin point is the block that says (2.8); this should be 3 but the loop affects it for some reason, and it only goes down to 1.6, when it should have (1.4, 1.2, 1, .8 etc)
     
    Last edited: Feb 12, 2017
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,745
    Without studying what you're trying to do too closely, the first thing that leaps out at me is, do you just need to copy over the grid of height values all at once, THEN apply your computation from the copy to the original? It seems that the order in which your squares are processed might be impacting your outcome.
     
  3. BubyMB

    BubyMB

    Joined:
    Jun 6, 2016
    Posts:
    140
    I am applying them one at a time, and I doubt the way they are processed would make much a difference.
     
  4. takatok

    takatok

    Joined:
    Aug 18, 2016
    Posts:
    1,496
    From reading the code I assume what you want is some block is up in the air. And you want all the blocks to its left to make a small hill that goes up a little and then downwards. (the +1 in the y position means the first block to the left will be higher than your pivot block.. then the blocks will slope downwards till the last block is at +1 above the ground)
    If that is the case then you don't need a backup grid to do what you want. Since all the blocks are looking at the pivot block for their new position and that pivot block doesn't actually change.

    *Quick Note on Naming*: It was very confusing that you called the sealed class Grid and the List Grids. Grid to me implies well an entire grid. It might have been better to name it GridLoc or something similiar since that would imply one location in the grid. Once I figured out that Grid was just one location became easier to read the code :)

    So there are a number of problems in the code, and could be any of them or a mixture that is giving you the errors:

    First you building you list column by column. 0,0 gets added, 0,1 gets added, 0,2, 0,3 ... 1,0, 1,1 and so on. Because the X is the outer loop. However in GetGrid here:
    Code (CSharp):
    1.  int column = (int)((posX / offset) + .1f);
    2.         int _height = (int)((posZ / offset) + .1f);
    3.         int number = column + (width * (_height-1));
    You are unwinding it as if you layed it out row by row. So whatever object is being passed into MovementUpdate, when you pass that guy's x,z co-ordinates to GetGrid.. its coming up with the wrong object. You can fix this in three ways:
    1. swamp the x,z loop when you initially create the cubes. So your laying it out row by row
    2. switch your code in GetGrid so its _height+(height*col)
    3. Just use Find method to Get the exact object you want
    Code (CSharp):
    1. void getGrid(GameObject _gameObject){
    2.         highlightedGrid = Grids.Find(go=>go.Object==_gameObject);
    3.         moveNeighbour (highlightedGrid, number);
    4.         Debug.Log (number + "");
    5.     }
    So if you are wanting to keep unwinding your list using the x,y pos. Why is this code multiplying by height-1?
    Code (CSharp):
    1. int number = column + (width * (_height-1))
    If you create a cube at 0,0 then your GetGrid code will reverse its x,z positions to 0,0 but your index number will be = 0+(width*(0-1)) = -width index will which be bad. This will happen on any cube on the top row. Additionally even if you don't get an index out of range. you will always be accessing the cube one row above the one whose Y Height > 0.

    Then even if you were getting the right cube whose height > 0 this line backs it up by 1
    Code (CSharp):
    1. highlightedGrid = Grids [number - 1];
    So your pivot cube in the moveNeighbor function that your adjusting all the heights off of, is one cube to the left of the actual cube whose height was > 0. Which will affect the blocksToAffect and so on.

    There is also some issues with boundary checking. I don't know if there is some sanity checking in the Class that calls MovementUpdate? But what if a cube is called whose height is 4 and whose position in the grid is 2,2. it will cause a wave to wrap around to the line above it. If thats ok then no problem. but you might need to adjust blocksToAffect to cap out at the end of line.