Adding collectibles to the game level

Running on platforms is not enough for the prototype; we need to provide a player with a goal. Let's say that our prototype level is complete once the player has gathered a number of collectibles that we randomly scatter in the level.

To achieve that, we add a few lines to the PlatManager script and create a new prefab to be instantiated as our collectible game object.

Getting ready

Open the PlatManager script in Monodevelop and be ready to add the lines described here.

How to do it...

  1. We need two extra variables to make the collectibles: a public Transform to store the reference to the collectible prefab and a private one to instantiate it. Do this by adding the following lines to the script:
    public Transform collectPref;
    private Transform collectible;
  2. Next we create a new function called TossCollectible() that casts a random result to decide whether to instantiate a collectible on the next platform to be created in the level. Add the following lines to the script:
    void TossCollectible(){
      float f = Random.Range(0f,1f);
      Debug.Log(f);
      if (f > 0.5){
        Vector3 v = new Vector3 (nextPos.x, nextPos.y + delta, 0);
        collectible = (Transform)Instantiate(collectPref, v, Quaternion.identity);
      }
    }
  3. Now we can add a call to TossCollectible() when we instantiate a new platform in the level. What follows is the complete updated FixedUpdate() function, with the new lines highlighted:
    void FixedUpdate(){
      UpdatePos();
      if(actualPlat != null && charX > actualPlat.transform.position.x + delta){float strict = actualPlat.transform.position.x; 
        prevPlat = actualPlat;
        actualPlat = null;
        SetScalesAndGaps();
        nextPos = new Vector3(strict + platScale.x + gap, yGap, charZ); 
        nextPlat = (Transform)Instantiate(platBrick, nextPos, 	 Quaternion.identity );
        nextPlat.localScale = platScale; 
        TossCollectible();
      }
      if(actualPlat != null && charX < actualPlat.transform.position.x - delta){
        float strict = actualPlat.transform.position.x;
        prevPlat = actualPlat;
        actualPlat = null;
        SetScalesAndGaps();
        nextPos = new Vector3(strict - platScale.x - gap, yGap, charZ);
        nextPlat = (Transform)Instantiate(platBrick, nextPos, Quaternion.identity );
        nextPlat.localScale = platScale;
        TossCollectible();
      }
      if(prevPlat != null){
        float strict = prevPlat.transform.position.x; 
        if(charX > strict - delta && charX < strict + delta){ 
          Destroy(nextPlat.gameObject);
          nextPlat = null;
          actualPlat = prevPlat;
          prevPlat = null;
        }
      }
      if(nextPlat != null){
        float strict = nextPlat.transform.position.x;
        if(charX > strict - delta && charX < strict + delta){ 
          actualPlat = nextPlat;
          nextPlat = null;
          Destroy(prevPlat.gameObject);
        }
      }
    }
  4. Next we need to edit the Runner script to manage the collisions between the character and the collectibles. Open the script in Monodevelop. We begin with declaring a new public int variable to store the number of items collected so far. We will display this data in the GUI, later. Add the following declaration at the top of the script:
    public int collected;
  5. In the Start() function, we initialize collected to 0, with one simple instruction. To make things more clear, we add the full Start() function as follows:
    void Start () {
      charAnimator = GameObject.Find("runner").GetComponent<Animator>();
      horAcceleration = 4f;
      bIsTouch = false;
      jumpVel = new Vector3 (0,10,0);
      collected = 0;
    }
  6. Finally, we modify the OnCollisionEnter() function by adding a check for a second tag, named collectible, that we will create pretty soon. If we get a positive check with the tag, we can destroy the collectible instance and add 1 to the number of collected items. What follows is the updated OnCollisionEnter() function:
    void OnCollisionEnter(Collision c){
      if(c.gameObject.tag == "platform"){
        bIsTouch = true;
        charAnimator.SetBool("bJump",false);
      }
      if(c.gameObject.tag == "collectible"){
        Destroy(c.gameObject);
        collected += 1;
      }
    }
  7. Now back to Unity, we need to create the prefab to be instantiated as the collectible. Let's start by adding Sphere GameObject to the scene. Scale it down to .35 on all axes and be sure that its position is reset to 0 on all axes.
  8. Add any material you like to the sphere. We picked a red material, but anything you like will do the task.
  9. Next, create a new prefab in the Prefabs folder of your project and name it coll_prefab. Then drag the sphere onto the prefab, as shown in the following screenshot:
    How to do it...
  10. You can now delete Sphere from the scene. Select coll_prefab in the Project panel, then move to Inspector. In the Tag field, open the scrolling menu and add a new tag called collectible, as we did before, and set that tag for coll_prefab. You can refer to the following screenshot:
    How to do it...
  11. Last step: select plat_manager in Scene, then drag coll_prefab to the empty Collect Pref field, which represents the public variable we added to the PlatManager script. The following screenshot shows the operation:
    How to do it...
  12. You can now run the prototype and run around to collect items that appear above the platforms.

How it works...

The collectible objects are spawned with a random chance on platforms that get instantiated at runtime. Upon collision with the game character, they get destroyed and their count is increased by one.

There's more...

In the previous script, we used the OnCollisionEnter() function to detect when the character hits a collectible. Unity offers another method called OnTriggerEnter() that detects when two objects collide without generating a collision. The OnTriggerEnter() function is useful when you don't want two colliding objects to physically react upon collision. You can check out this link for a description of the difference between OnCollisionEnter() and OnTriggerEnter(): http://answers.unity3d.com/questions/790724/what-is-the-difference-between-oncollisionenter-an.html.

To complete our working prototype we need to add a control for the game camera so it follows the character. There is already a camera in the scene called Main Camera, so we will take advantage of it.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.137.167.195