Search Unity

How can i setup an infinite Wall coming down?

Discussion in 'World Building' started by PalDiaray, Mar 11, 2019.

  1. PalDiaray

    PalDiaray

    Joined:
    Mar 18, 2018
    Posts:
    22
    Hello,

    is it possible to make an infinite Wall coming down? (everytime a part of a wall reaches a specific y position, it spawn a new one top of the walltower).
    I would like that my player can jump back and forth between these two walls (infinetly). They also need to increase the speed over time (with acceleration). I do not want to pre-build the wall. Hope it can be solved by a code or something else. Maybe sprite change speed over time or so?

    Hope you know what i mean,
    PalDiaray

     

    Attached Files:

  2. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    Yes, it certainly can. Exactly like you said: every time a part of a wall goes off the bottom of the screen, move it up above the previously-highest wall part.
     
  3. PalDiaray

    PalDiaray

    Joined:
    Mar 18, 2018
    Posts:
    22
    Hey, thanks for your answer! I've checked that already in other forums and videos, but i don't get it to work. Do i have to calculate exactly all xyz positions? In this case only the y, or is there a easier way to do that? And if it is, how i can implement this?

    Greetings,
    PalDiaray
     
  4. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    Yes, you have to calculate the Y. Make it slightly easier on yourself by keeping your wall sections some nice round number in height, like 100 units or whatever. Then when one goes off the screen, you just have to move it up by some multiple of that, say 400 units if you have 4 wall sections.

    If still stuck, posting "I tried but couldn't get it to work" is not helpful. Show the code from your best attempt, and describe (possibly with screen shots) what it does, and how that differs from what you want it to do. If you want a specific answer, ask a specific question.
     
  5. PalDiaray

    PalDiaray

    Joined:
    Mar 18, 2018
    Posts:
    22
    Hello Joe,

    Thanks for your answer. For sure i can show my work in here to recieve an exactly answer.
    I did what you said, but I am not satisfied with my work.

    Here is my code for creating the walls:

    Code (CSharp):
    1. public void Update()
    2.     {
    3.         if (movingWalls.sideWallCounter <= 6)
    4.         {
    5.             Instantiate(leftWall, new Vector3(328, 1000, -7813), Quaternion.Euler(new Vector3(0, 0, 0)));
    6.             Instantiate(rightWall, new Vector3(-362, 1000, -7813), Quaternion.Euler(new Vector3(0, 0, 0)));
    7.         }
    8.     }
    In combination with the walls themselves so that they move and are destroyed:

    Code (CSharp):
    1. public void Start()
    2.     {
    3.         sideWallCounter = 8;
    4.     }
    5.  
    6. void Update()
    7.     {
    8.  
    9.         movementSpeed += Time.deltaTime * 1.8f;
    10.  
    11.         transform.position += Vector3.down * Time.deltaTime * movementSpeed;
    12.  
    13.         if (transform.position.y <= -500)
    14.         {
    15.             sideWallCounter = sideWallCounter - 1;
    16.             Destroy(gameObject);
    17.         }
    18.     }
    Every wall is exactly 500x500x500 big.
    I tried to solve the problem with a counter and it worked... somehow.

    However, the instantiated walls didn't spawn exactly on the top of the other walls and leave some space behind. The speed and the acceleration is so far okay.

    wall.PNG

    wall2.PNG
     
  6. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    OK, the approach you're using is going to be very hard to get right. The walls do not move down the exact same amount every frame; how much they move depends on Time.deltaTime. So when one gets destroyed, you don't know exactly where the top wall is. Yet you create your new wall at the exact same position every time. Thus, there are small random gaps.

    So try this:
    1. Delete that first Update method you posted above. You will no longer need it.
    2. Delete your sideWallCounter property, and any code that uses it.
    3. Change your "if I am off the screen" code to this:
    Code (CSharp):
    1. if (transform.position.y <= -500)
    2.         {
    3.             transform.position += Vector3.up * 2000;
    4.         }
    So when a wall moves off screen, it moves itself back up above the top of the screen, by exactly 2000 meters relative to where it was before. You didn't tell me how big your wall blocks are, but if they are 500 units tall, and there are four them, then when this code runs, there will be a block 500 units higher than this one, and 1000 units higher, and 1500 units higher. And so when this one jumps 2000 units higher, it will fit perfectly with the one 1500 units higher. No gap.

    If your wall blocks are not 500 units high, or you don't have four of them at any given time, then just change that 2000 to the block height times the number of blocks.
     
  7. PalDiaray

    PalDiaray

    Joined:
    Mar 18, 2018
    Posts:
    22
    Never thought it would be that easy, thank you a lot! Why do I always have to think so complicated?
    I made the changes you said and it works. Now I've to think about the acceleration without getting those spaces between the walls.

    Code (CSharp):
    1. acceleration += acceleration * 0.0005f;
    2.         transform.position += Vector3.down * acceleration;
    Do you think this code is perfekt for a working acceleration or is there also a better way to do it? FYI this code works quite well with your solution.

    Greetings and thanks,
    PalDiaray
     
  8. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    That could work. You should probably use a larger value, and then multiply by Time.deltaTime on both lines, so that it is framerate-independent.
     
  9. PalDiaray

    PalDiaray

    Joined:
    Mar 18, 2018
    Posts:
    22
    Hey tried to implement Time.deltaTime with my two variables, but there are still some spaces (every 2nd Wall)

    Code (CSharp):
    1.  
    2. float acceleration = 0.5f;
    3.         float movementSpeed = 50f;
    4.  
    5.         movementSpeed += acceleration * 0.45f * Time.deltaTime;
    6.         transform.position += Vector3.down * movementSpeed * Time.deltaTime;
    But if i remove "Time.deltaTime", then it worked perfekt. is there an other way to do it or do i miss something?
    And is there a way to get the same speed/acceleration on other objects like small obstacles on the wall? Because if i implement the code to some other objects, they are too fast (Maybe because of the size? Or Colliders? There are no rigid bodys fyi).

    Greetings
    wall3.PNG wall4.PNG
     
  10. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    Hmm. OK, I don't know why that's causing gaps. All I can think of is floating-point precision issues, but that seems unlikely.

    It's also very strange that the same code on other objects causes them to go at a different rate. Clearly something is not the same there.

    I wonder if perhaps you should refactor a bit. Have just one object that acts as the WallManager or whatever. In its Update method, it should compute an amountToMove (taking into account acceleration and the frame time), and provide this as a public property. Then all other objects that should be moving as/with the wall have code in LateUpdate, which simply gets the amountToMove from the WallManager and moves by that amount (with doing their move-to-top-when-I-go-off-the-bottom trick).

    This should ensure that everybody always moves by exactly the same amount.
     
  11. PalDiaray

    PalDiaray

    Joined:
    Mar 18, 2018
    Posts:
    22
    Hey, i created the wallManager and it works very good. But the gaps are still there. I also implement the amountToMove into the wallManager. But i think it depends on the acceleration or?

    Code (CSharp):
    1. wallManager.allMovementSpeed += wallManager.allAcceleration * 1.5f * 0.02f;// * Time.deltaTime;
    2.         transform.position += Vector3.down * wallManager.allMovementSpeed * 0.02f;// * Time.deltaTime;
    I also commented out Time.deltaTime and inserted some similair values to it. But still gaps.
    Is there something else i have to looking for?

    Greetings
     
  12. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    Hold on. Is the code above in the same class? Do you have every class that's using the wallManager, also updating the wallManager's allMovementSpeed?!

    If so, please go back and re-read my suggestion. :) You should only be updating wallManager.allMovementSpeed in one place (the wall manager's own Update method). Everything else should simply use that (without multiplying by anything) in LateUpdate.
     
  13. PalDiaray

    PalDiaray

    Joined:
    Mar 18, 2018
    Posts:
    22
    Okay well sorry for that :confused:

    The movementSpeed is now Updating in the wallManager. And it seems to work. Hopefully.
    Thank you, for your help. I come back (or open a new thread) if i find the next problems i cant answer.

    Greetings
     
    JoeStrout likes this.