Wednesday 27 January 2016

Moving platform in 2D


It often happens in 2D action games, to encounter the (in)famous moving platforms, likely to be harder to jump on than actually defeating the final boss.

I would like to show you a method I use when it comes to create moving platform that allows an easy placing of the platform actual travel path.

First of all, we create an empty game object called MovingPlatform. We then drag in whatever sprite we have for the platform and we child it to the MovingPlatform object we just created. Finally, we create another empty object, called Points, which will also be a child of MovingPlatform.

Your hierarchy should look like this:


The Points object is simply an empty object that acts as a parent object for all the child objects we will use as navigation points for the platform.

We can now create a few empty objects (which we cal call P1,P2,P3,...) and place the as children of Points. In order to see these empty objects in the scene, we give them an icon (Fig  1).

Fig 1
Our Platform object should now have only a Sprite renderer component. Let's add a Rigibody2D and set it to isKinematic.


Now, we create two C# script: one called MovingPlatform and the other one PointsHolder.

Let's start with the simpler one: PointsHolder. The sole purpose of this script is to count all the children of the Points object and return an array of Transform containing the children objects.

Here is the code:

public class PointsHolder : MonoBehaviour {

 Transform[] allPoints;

 // Use this for initialization
 void Awake () {

  allPoints = new Transform[transform.childCount];
 
 }
 
  public Transform[] getAllPoints()
 {

  for (int i=0; i<allPoints.Length; i++) {
   allPoints[i] = transform.GetChild(i);
  }


  return allPoints;
 }

Now, the other script, MovingPlatform
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
public class MovingPlatform : MonoBehaviour {

 public enum Modes
 {
  PING_PONG,
  LOOP
 }

 public Modes mode;

 public bool isMoving;
 public float speed;
 PointsHolder pointsHolder;
 Transform[] allPoints;
 
 int direction = 1;

 void Start()
 {
  pointsHolder = transform.parent.FindChild ("Points").GetComponent<PointsHolder> ();
                rb2d = GetComponent<RigidBody2D>();
  allPoints = pointsHolder.getAllPoints ();
 

  StartCoroutine (moveAround ());
 }

 IEnumerator moveAround()
 {
  transform.position = allPoints [0].position;

  int index = 1;

  while (isMoving) {

    while(rb2d.transform.position != allPoints[index].position)
   {
     rb2d.transform.position = Vector2.MoveTowards(rb2d.transform.position,allPoints[index].position,speed*Time.deltaTime);
    yield return null;
   }

   if(mode == Modes.PING_PONG)
    if(index == allPoints.Length-1 || index == 0)
     direction *=-1;

   if(mode == Modes.LOOP)
    if(index == allPoints.Length-1)
     index = -1;

   index+= direction;
   yield return null;
  }
 }

 
}

Let's break this one down.

First, I declare an enumeration which will determine the moving "mode" mode of the platform: PINGPONG means that the platform will travel backwards once it has reached the last point, while in LOOP  mode i will go back to the first point and iterate all the points again.

After declaring other needed variables, at line 23 we get the array of Transform from the PointsHolder script we wrote earlier. At his point, the coroutine can start (Line 35).

This coroutine is our moving function.It will start teleporting the platform to the first point (Line 40) and then it will iterate inside the array of Transform coming from the sibling object Points and the script PointsHolder, constantly moving the platform toward the next available Transform (Line 48). According to the "Moving mode" dictated by the enumeration Modes, the index for the array will be changed accordingly (Line 52 - 58).

At this point we can start creating empty objects and placed them as children of the parent object Points, and at the start of the scene the Platform object will begin it's movement, following the points one by one.

Here's a short video of the final result:




I will perhaps discuss how to get the character to jump on it and react properly (no falling through or sliding off) sometime later on, in another post. For now, let's enjoy our moving platform.

No comments:

Post a Comment