I'm building an infinite runner and have to generate pillars on which the player jumps. There's a minimum and maximum value for how much gap can exist between two pillars. In addition to this, i want the pillars to move to the left with increasing velocity. All pillars need to have same velocity. So, i made a pillarHolder object which would have velocity that increases with time. The instantiated pillars would be made children of this pillarHolder. Code is:

 if ((Vector3.Distance (go.transform.position,transform.position)<25f)) {


                pos=new Vector2(tempx,-2.22f);

                go=Instantiate(pillar,pos,Quaternion.identity) as GameObject;
holder.GetComponent<Rigidbody2D> ().velocity=new Vector2(-10f,0);

The problem is, the pillarHolder keeps moving in the negative x direction and after a while, the pillars are not positioned properly. The gap between them exceeds the maxGap. I tried to solve the problem by resetting the pillarHolder's position once it went beyond position.x=-20f. But when it's position resets, child objects are reset too.

Any help please?

  • \$\begingroup\$ if you put the line: "holder.GetComponent<Rigidbody2D> ().velocity=new Vector2(-10f,0);" in the fixedupdate? \$\endgroup\$ – dnk drone.vs.drones May 8 '15 at 11:21
  • \$\begingroup\$ But the holder would still be moving infinitely. \$\endgroup\$ – SanSolo May 8 '15 at 11:32
  • \$\begingroup\$ Tried. Same problem. \$\endgroup\$ – SanSolo May 8 '15 at 11:38

If you're making an endless runner that means the inverse of your players' velocity should be driving the movement of all the other entities in the game - such as the backgrounds (dampened obviously) as well as the various obstacles and terrain for your player to traverse.

As such if you just instantiate a new pillar gameObject (based either on some mechanic such as a timer using predefined obstacle data lists etc) then it should just be driven by something simple like

transform.position = Vector2.MoveTowards(playerPos, targetPos, speed * Time.deltaTime);

in each Update() call. targetPos can just be a gameObject in your scene indicating a position to the left, just outside of the visible screen space (at which point you can kill/recycle your pillar). If you need objects which have their own speed then alter or add to the 'speed' variable for each required gameObject. For example a projectile being shot by a trap towards the player from right to left might be moving at playerSpeed + bulletSpeed etc.

On the topic of recycling objects : instead of instantiating a new gameObject for each obstacle such as pillars, especially in a tight loop or Update() function, instead investigate object pooling in Unity where you can just keep recycling from a pre-allocated list of gameObjects.

--- EDIT forgot you're using rigidBody ----

After you instantiate each pillar with an initial velocity (moving towards the player from right to left) then it sounds like you could then use an InvokeRepeating or something similar to fire off an increase in speed of each subsequent pillar by just adding force to the current velocity :

rididbody2D.AddForce(tranform.right * speed) // 'speed' in meters per second
| improve this answer | |
  • \$\begingroup\$ Cannot use AddForce. It might cause pillars to collide with each other. Object pooling is definitely something i should be doing. Thanks. \$\endgroup\$ – SanSolo May 8 '15 at 12:59
  • 1
    \$\begingroup\$ You could use Unity Layers to better manage your collision tests with other pillars in the OnCollisionEnter. You could also use RigidBody2D.MovePosition I guess although then it might not generate all the needed physics collisions with your players etc. \$\endgroup\$ – DanoThom May 8 '15 at 15:29
  • 1
    \$\begingroup\$ Why will they each have a different speed? You either all give them a uniform speed which you can increase or decrease globally, or you allow them to alter their own speeds (which it sounds like you don't want). I'm unclear of your overall objectives now so not exactly sure what you're attempting to solve. Why don't you post an edit of some points of what exactly you're trying to achieve. \$\endgroup\$ – DanoThom May 10 '15 at 9:27
  • 1
    \$\begingroup\$ I think you're overcomplicating this a bit. Just have 1 single global velocity value. Increase or decrease this global value whenever you want to change the speed of all the pillars. When you instantiate a pillar it sets it's starting velocity to the global value. \$\endgroup\$ – DanoThom May 10 '15 at 10:18
  • 1
    \$\begingroup\$ Sounds like a plan. A lot of endless runners use recycled, staggered scenery + object prefabs. If you keep 3 running in a row and just recycle the beginning and end ones you'll give the illusion of a continuous scene. \$\endgroup\$ – DanoThom May 10 '15 at 12:51

Your Answer

