Goals/Missions/Objective System

hi everyone!

How do i make goals in my game?What would be the most preferred way to do it?
Examples are:

  1. Collect 200 coins
  2. Kill 30 Enemies in One Game

How do I start this? Thank you!

class Goal : Monobehaviour
{
 public event System.Action completed;
 protected void GoalCompleted()
 {
    if(completed!=null)
       completed();
 }
}

class CollectCoins : Goal
{
   ...
}
...

etc…

If that doesn’t answer the question, I’m not sure I have understood it

1 Like

This is a very broad topic.

  • To keep track of goals, you can store data and methods on a GameObject. I’ll sketch out the code below. If you need something more sophisticated, examine the design of quest systems available on the Asset Store.
  • If you want to show the progress onscreen, you need some kind of HUD (heads-up display). Goals need to be aware of each other so they can position themselves correctly onscreen. Otherwise, if every goal tries to draw itself in the same location (e.g., upper left corner), they’ll overlap.
  • If you want to keep track of goal progress between play sessions, you need to save the game. To do this, you need to implement a save system – for example, saving a small amount of information in PlayerPrefs, or more information to a local file or network database.

Say you have a GameObject named GoalManager. Riffing on A.Killingbeck’s code, you could do this:

// Add this script to the GoalManager GameObject. It keeps track of all goals.
public class GoalManager : MonoBehaviour {

    public Goal[] goals;

    void Awake() {
        goals = GetComponents<Goal>();
    }

    void OnGUI() {
        foreach (var goal in goals) {
            goals.DrawHUD();
        }
    }

    void Update() {
        foreach (var goal in goals) {
            if (goal.IsAchieved()) {
                goal.Complete();
                Destroy(goal);
            }
        }
    }
    }
}


// This is the abstract base class for all goals:
public abstract class Goal : MonoBehaviour {
    public abstract bool IsAchieved();
    public abstract void Complete();
    public abstract void DrawHUD();
}


// Add this to GoalManager to run a "collect the coins" goal:
public class CollectCoins : Goal {

    public int coins = 0;
    public int requiredCoins = 50;

    public override bool IsComplete() {
        return (coins >= requiredCoins);
    }

    public override void Complete() {
        ScoreSingleton.score += 10;
    }

    public override void DrawHUD() {
        GUILayout.Label(string.Format("Collected {0}/{1} coins", coins, requiredCoins));
    }

    public OnTriggerEnter(Collider other) {
        if (string.Equals(other.tag, "Coin")) {
            coins++;
            Destroy(other.gameObject);
        }
    }
}


// Add this to GoalManager to run a "kill the enemies" goal:    
public class KillEnemies : Goal {

    public int requiredKills= 50;
    public AudioClip trumpetSound;

    private PlayerStats playerStats;

    void Awake() {
        playerStats = GameObject.Find("Player").GetComponent<PlayerStats>();
    }

    public override bool IsAchieved() {
        return (playerStats.kills >= requiredKills);
    }

    public override void Complete() {
        ScoreSingleton.score += 50;
        audio.Play(trumpetSound);
    }

    public override void DrawHUD() {
        GUILayout.Label(string.Format("Killed {0}/{1} enemies", playerStats.kills, requiredKills));
    }
}

Thank you TonyLi… tried this and it works… Will try to experiment integrating it on NGUI too… and for other goals… Thanks you so much!

Happy to help! I based my example off A.Killingbeck’s response, so credit goes there, too! :slight_smile:

Anyone still folowing this thread ?
I have a similar problem but I don’t really understand the answers.
I need to put a goal on my game (the game is basicly the space shooter tutorial code).
I would like to have a WIN screen après aavoir détruit 100 asteroid.
I finished the basic tutorial so I have the HUD (GUItext), the Game over and restart fuction to.
Thanks

Since you only have the one goal (destroy 100 asteroids), it’s probably easiest to write a simple script for that. Here’s one way.

  1. Make a WIN scene. Let’s say it’s called “WIN”.

  2. Add a C# script named AsteroidGoal to an empty GameObject in your gameplay scene:

using UnityEngine;
using UnityEngine.SceneManagement;

public class AsteroidGoal : MonoBehaviour {
    public int goal = 100; // Player must destroy this many asteroids.
    private int destroyed = 0; // Counts how many asteroids destroyed so far.

    public void AsteroidDestroyed() { // Called by asteroids when they're destroyed.
        destroyed++;
        if (destroyed >= goal) SceneManager.LoadScene("WIN");
    }
}
  1. Add a C# script named Asteroid to your asteroids:
using UnityEngine;

public class Asteroid : MonoBehaviour {
    void OnDestroy() {
        FindObjectOfType<AsteroidGoal>().AsteroidDestroyed();
    }
}

Thanks
Actually I used the score count to trigger the win sequence, I use a small part of the code of the first tutorial (with the sphere) and some stuff online but in the end the code was 3 or 4 line long :slight_smile: :

if (score >= 300)
            {
                winText.text = "Systeme nettoye \r\n avec succes";
                break;

With a GUItext to display the “winning” phrase

Thank anyway, I’m new to this stuff (i’m a 3D graphic designer) and coding is quite frustrating because I don’t understand half of the stuff I put together so I’ just patching things up, like a patchwork.
I guess practice will make this more natural …

Thanks

PEACE

1 Like