Click here to Skip to main content
15,885,546 members
Articles / Game Development

Unity3D - Easily Handling Player's Objectives

Rate me:
Please Sign up or sign in to vote.
5.00/5 (1 vote)
1 Jan 2015CPOL1 min read 11.1K   4  
Unity3D - Easily Handling Player's Objectives

A really easy way to handle player's objectives in Unity3D is by taking advantage of these features:

  • Game Object hierarchy
  • Using public fields in scripts
  • Drag and Drop objects into public fields

With that said, this is what we can do:

  1. Create an empty game object
  2. Create a new child object per objective we want to represent
  3. Move each objective to the corresponding position (To make it easier, you can click on the cube in the inspector once you have selected the objective, this will show the icon and name of the object in the Scene view)
  4. Attach a collider marked with trigger so that it does not block the player movement.
  5. Create a custom Objective script which will contain its Name, Description, and other aspects required to handle its behavior, including the action to perform when collider is reached. One of the important keys here is that each objective would have a "NextObjective" field, which is of the same type of the script (Objective). This helps in reducing harcoded logic strings to go into the next objective.
  6. Create a Objectives script, which will contain a field for CurrentObjective and internally retrieves the list of all of the objectives in the hierarchy.
  7. Attach the Objectives script into the player's object, and drag your initial objective into the CurrentObjective field.

Image 1

Image 2

These are the sample scripts:

Objective.cs

using UnityEngine;
using System.Collections;
using System.Linq;
using System.Linq.Expressions;

public class Objective : MonoBehaviour
{

    public enum ObjectiveType
    {
        Reach = 0,
        Talk = 1,
        Defeat = 2,
    }

    public enum ObjectiveStatus
    {
        Pending = 0,
        Achieved = 1,
    }

    public enum ActionOnReach
    {
        MarkAsAchieved = 0,
        PlayCinematic = 1,
        PlayAnimation = 2,
        SetTrigger = 3,
    }

    public string Name;
    [Multiline(10)]
    public string Description;
    public ObjectiveType Kind;
    public ObjectiveStatus Status;
    public GameObject Target;
    public Objective NextObjective;
    public ActionOnReach[] ActionsOnReach;
    public Animator animator;
    public MovieTexture ClipToPlay;
    public string TriggerName;

    private void OnReach()
    {
        if (this.ActionsOnReach.Contains(ActionOnReach.MarkAsAchieved))
            this.Status = ObjectiveStatus.Achieved;
        if (this.ActionsOnReach.Contains(ActionOnReach.PlayCinematic))
            this.PlayCinematic();
        if (this.ActionsOnReach.Contains(ActionOnReach.PlayAnimation))
            this.PlayAnimation();
        if (this.ActionsOnReach.Contains(ActionOnReach.SetTrigger))
            this.NextObjective.Target.GetComponentInParent<animator>().SetTrigger(this.TriggerName);

        ParentScript.CurrentObjective = this.NextObjective;

    }

    private void PlayAnimation()
    {
        Debug.Log("On PlayAnimation: Not implemented yet");
    }

    private void PlayCinematic()
    {
        Debug.Log("On PlayCinematic: Not implemented yet ");
    }

    void OnTriggerEnter2D(Collider2D other)
    {
        if (other.tag == "Player" && this.ParentScript.CurrentObjective.name == this.name)
        {
            OnReach();
        }
    }

    public Objectives ParentScript { get; set; }
}

Objectives.cs

using UnityEngine;
using System.Collections;
using UnityEngine.UI;

public class Objectives : MonoBehaviour {

    public Objective CurrentObjective;
    private Objective[] PlayerObjectives;
    public Image CurrentObjectiveArrow;

    public Text CurrentObjectiveDescription; 

    void Start()
    {
        var objectiveParentGameObject = this.CurrentObjective.transform.parent.gameObject;
        if (objectiveParentGameObject != null)
        {
            this.PlayerObjectives = objectiveParentGameObject.GetComponentsInChildren<Objective>();
            if (this.PlayerObjectives != null)
            {
                Debug.Log("Successfully found all player objectives");
                foreach (Objective singleObjective in PlayerObjectives)
                {
                    if (singleObjective != null)
                    {
                        singleObjective.ParentScript = this;
                    }
                }
            }
            else
                Debug.LogError("Unable to find objectives");
        }
    }

    void OnGUI()
    {
        this.CurrentObjectiveDescription.text = this.CurrentObjective.Description;
    }
}

This is just one way to do it, although it is not the only way, there are always other ways, some easier, some more complex, and complexity would be based on your game specific needs.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
CEO PTI Costa Rica
Costa Rica Costa Rica
Eduardo is an individual with knowledge is multiple academic fields,
where the two main are System Engineering and Psychology.
This not only allows Eduardo to work in the IT fields, but also give him the knowledge and abilities required to understand people behavior, and the factors involved that could affect a person, and even more than understand them, his Psychology studies give him the tools to help the individuals that require it.

Eduardo has also some knowledge in he videogame development field, and using tools such as
3ds max and Unity 3d.

Eduardo's main goal is actually to become a videogame profesional.

Profile:
* Bachellor in System Ingeneering
* 8+ years of experience

Linkedin profile: https://cr.linkedin.com/in/pticostarica

Comments and Discussions

 
-- There are no messages in this forum --