How to change levels after task is completed

Hi,

I am new to coding and I am struggling to overcome a problem.

I am currently building a game where the player must answer a question, before they are able to move a piece of the rocket. This will be repeated to build the rocket. In game place, the rocket pieces attach to empty game objects, creating a snapping effect.

I am currently struggling to create a next level option. I would like the player to click a game object (ie alien) to move on to the next level however, they must build the rocket first. I am unsure of how to script this.

Any help will be appreciated.

Thank you,
Kaajal

Well, whatever code is snapping pieces on to the rocket will need to either calculate when the rocket is done, or invoke some event that another script uses to check whether the rocket is done.

In either case, it should then set a flag — perhaps a static bool variable somewhere, so that other code can check this simply by using ClassName.flagName (without needing a reference to a particular instance of the class).

Then you’ll have a script that handles the button click. This should check the flag, and either load the next level, or do whatever should happen when the rocket isn’t built (perhaps nothing).

Hi JoeStrout,

The DragObject script is the code that allows the snapping pieces together. Would the ClassName.flagname = The empty game objects? (in my script this is called trigger).

Change Level script - is currently the code I have on the Alien to change levels on Mouse down which works.

I am unsure of how the code must be written to stop the change level until the rocket has been built.

Thank you.

6622930–754624–DragObject.cs (1.47 KB)
6622930–754633–ChangeLevel.cs (478 Bytes)

To post code on these forums, use the “Code:” button in the editing toolbar.
6623740--754762--upload_2020-12-15_7-21-46.png

What does it mean for a rocket to be “built”? Does that mean at least one part has been added, or what?

Hi,

Oh sorry - I’ll do this now. I have now made changes to my codes and have split my responses to explain this better.

The Drag object script is attached to the rocket parts (in this scene/level there are 5). The aim is to move the pieces of the rocket around and attach to the game object after answering the question (this works).

using System.Collections;
using System.Collections.Generic;
using UnityEngine;


public class DragObject : MonoBehaviour
{

    private Vector3 mOffset;
    private float mZCoord;
    public GameObject target;
    public bool draggable = true;
    public bool correctAnswer = false;


    //I used the Mouse down on each box - so that when the player clicks and holds the mouse down
    //They are able to drag the box
    void OnMouseDown()
    {
        mZCoord = Camera.main.WorldToScreenPoint(gameObject.transform.position).z;

        // Store offset = gameobject world pos - mouse world pos
        mOffset = gameObject.transform.position - GetMouseAsWorldPoint();
    }

    private Vector3 GetMouseAsWorldPoint()
    {
        // Pixel coordinates of mouse (x,y)
        Vector3 mousePoint = Input.mousePosition;

        // z coordinate of game object on screen
        mousePoint.z = mZCoord;

        // Convert it to world points
        return Camera.main.ScreenToWorldPoint(mousePoint);
    }

    void OnMouseDrag()
    {
        if (!draggable) return;
        if (!correctAnswer) return;
        transform.position = GetMouseAsWorldPoint() + mOffset;
    }

    void OnTriggerEnter(Collider other)
    {
        Debug.Log("boom");
        if (other.gameObject  == target)
        {
            transform.position = target.transform.position;
            Debug.Log("attached");
            draggable = false;
        } 
    }
}

The count script is attached to the empty game objects - It is supposed to count when the rocket pieces attach the empty game objects. The draggable bool determines if the rocket piece has successfully attached to the empty game object.

Currently, this script doesn’t count when the rocket pieces attach. But does count if the draggable bool is false.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Count : MonoBehaviour
{
    public int piecesCount;
    private float noPieces;
    public bool draggable;

    DragObject dragObj;

    void Start()
    {
        //calling Drag object script
        dragObj = GetComponent<DragObject>();
    }

    void Update()
    {
        if (draggable == false)
        {
            Debug.Log("I am not counting");
        }
        else if (draggable == true)
        {
            Debug.Log("I  counting");
            piecesCount = piecesCount + 1;
            noPieces = piecesCount;
            Debug.Log("I  counting + 1");
        }
    }
}

The change level script I have attached to the Alien - it is supposed to change the level when the player clicks on the level - This works.

But what it is supposed to do is be a game loop. So the player has to build the rocket before the alien lets the player move to the next level - Which I’m struggling to achieve.

I hope I have explained this properly.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
using System.Linq;

public class ChangeLevel : MonoBehaviour
{

    public string levelName;

    Count countItems;

    void Start()
    {
        //calling Drag object script
        countItems = GetComponent<Count>();
    }

    void OnMouseDown()
    {
            SceneManager.LoadScene(levelName);

    }

}

I don’t quite understand what you mean there. But I can see that this script is “sus” as the young people say.

What this script does is increment both piecesCount and noPieces on every frame that its draggable bool is true. I’m not sure why that would be a useful thing to do.

If you want to count how many times an object was successfully attached, why not do that in your DragObject script, where you are logging “attached”?

Hi Joe,

I have different levels in the game and not all the levels have 5 pieces to the rocket. I wanted to create a script that could be adapted to each of these levels.

So I want this count script to:

  • See there are 5 or 4 or 3 empty game objects.
  • Count when a piece has been connected to the empty game object.
  • Know when all pieces have been connected to all the game objects.

Then in the change level script:

  • It will see all pieces are connected to the game objects. This may be 3, 4 or 5.
  • Then the player is able to click on the alien to change levels.

I hope I have explained it better … Its a little difficult as I cannot show you what I mean.

I am trying to understand how to use tags to do this - Currently, this is the script I currently have. But I still cannot get this to count or detect when it has been connected.


using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Count : MonoBehaviour
{
    public int piecesCount;
    public float noPieces;
    private GameObject target;

    DragObject dragObj;

    void Start()
    {
        target = GameObject.FindGameObjectWithTag("Target");
    }

    void Update()
    {
        if (GameObject.FindGameObjectsWithTag("Target").Length < 5)
        {
            piecesCount++;
            Debug.Log("I am counting");
        }
        else
        {
            piecesCount = 0;
            Debug.Log("I am not counting");
        }

    }

OK, take it one step at a time. For now let’s just say you need to add 3 pieces to consider it completed. And the Count script is the right way to focus. But we will also need to look at DragObject.

First, I don’t think you need anything in the Update method of the Count script. Update is for doing things on every frame; you will never need to change the piecesCount on every frame. Instead, you want to do it on certain events, namely when a piece is dropped (right?). So delete Update. I think you can also delete target, and all references to it, including the Start method.

Now let’s turn to DragObject. Are the “boom!” and “attached” debug messages appearing when you think it should? If so, that means you can identify the “a piece was dropped/attached” event correctly. So the next step is to turn that into an actual UnityEvent, so that other scripts can respond do it. Go watch this video to learn more about that.

Then add using UnityEngine.Events; to the top of DragObject, and add a public UnityEvent onDropped; property to your script. Finally, where the “attached” debug message is logged, add: onDropped.Invoke();

Now your DragObject is a properly event-friendly component that notifies interested parties when something interesting happens — namely, that a piece has been attached.

Now your Count script simply needs a public method to increment the count.

public void IncrementCount() {
    piecesCount++;
    Debug.Log("piecesCount is now: " + piecesCount);
}

Now, using the inspector, hook up the onDropped event of DragObject to the IncrementCount method of Count on each of your draggable objects. (Probably Count should live on one object in the scene, rather than on each draggable object… think that through, or experiment and see what works.)

When that’s working, then we can deal with firing another event when the count gets high enough, and using that to load the next level or whatever.

Hi JoeStrout,

Hope you are well.

I am really sorry I have just seen this response now. I have managed to get the code working, my friend from my course has helped me. I was just missing a few lines of code which we had figured out.

Thank you for assisting me with this query, much appreciated. If you would like my code for a future query, I can send this to you.