How to click objects in a specific order to change scene
Hello, I'm a beginner with Unity but very interested in learning on making simple games with it. I would like to click three objects in a specific order and then if that order is correct to go to another scene. I found older posts with this subject but the code there does not work for me or I am more than a beginner and could not make it work :-) Can someone share a code to help me with this? Thanks! Adrian
Answer by Hellium · Dec 10, 2017 at 01:19 PM
The community is not supposed to make the job for you. The asker is supposed to provide what he has tried so far. But since I'm in good mood, I've made something for you.
1st step : Setting up your scene
1. Select your camera and click on Add component in the inspector and type physics in the search bar.
• If you want to click on 3D models, select the Physics Raycaster
• If you want to click on 2D sprites, select the Physics 2D Raycaster
• If you want to click on UI elements, don't add any component
2. Click on the GameObject menu option at the top of the Unity window, and select UI > Event System
3. Create an empty gameobject called ClicksManager
for instance (use the GameObject menu)
2nd step : The clickable objects
In your scene, create the elements which will be clicked.
• If you want to click on 3D models (such as a cube, a sphere, ...), they must have a Collider
component
• If you want to click on 2D sprites, they must have a 2D collider
component
• If you want to click on UI elements, the image / raw images must have Raycast target
checked
3rd step : The scripts
1. Create a new C# script called ClickTarget.cs
and put the following code inside.
using UnityEngine;
using UnityEngine.EventSystems;
public class ClickTarget : MonoBehaviour, IPointerClickHandler
{
// Define the function signature used to invoke a specific event
public delegate void OnTargetClickedEventHandler( ClickTarget target );
// Define the event invoked when the target will be clicked
// The event will warn the entities subscribing to this event that the target has been clicked
public event OnTargetClickedEventHandler OnTargetClickedEvent;
// Detect when the Event System of Unity has detected a click on the target
public void OnPointerClick( PointerEventData eventData )
{
// Invoke the event
if ( OnTargetClickedEvent != null )
OnTargetClickedEvent( this );
}
}
2. Create a new C# script called ClicksManager.cs
and put the following code inside.
using UnityEngine;
using UnityEngine.SceneManagement;
public class ClicksManager : MonoBehaviour
{
// Drag & Drop the objects with the `ClickTarget` component
[SerializeField]
private ClickTarget[] targets;
// Each target will have an index (based on its position in the previous array)
// This variable will indicate which target must be clicked
private int expectedTargetIndex;
// Called when the scene starts
private void Start()
{
expectedTargetIndex = 0;
// For each target, call a function when they are clicked
for ( int i = 0 ; i < targets.Length ; i++ )
{
// You have to declare a temporary index to prevent the "closure problem"
int closureIndex = i;
targets[closureIndex].OnTargetClickedEvent += ( target ) => OnTargetClicked( target, closureIndex );
}
}
// Function called when a target is clicked
private void OnTargetClicked( ClickTarget target, int index )
{
Debug.Log( target.name + " has been clicked!" );
if ( index == expectedTargetIndex )
{
Debug.Log( "The correct target has been clicked" );
expectedTargetIndex++;
if ( expectedTargetIndex == targets.Length )
{
Debug.Log( "The last target has been clicked : Loading next scene" );
// Load next scene
SceneManager.LoadScene( SceneManager.GetActiveScene().buildIndex + 1 );
}
}
else
{
Debug.Log( "The wrong target has been clicked" );
expectedTargetIndex = 0;
}
}
}
4th step : Attaching and configuring the scripts
1. Select the objects which must be clicked. Click on Add component in the inspector, and add the ClickTarget
component
2. Select the ClicksManager object and add the ClicksManager
component
3. In the inspector, you should see the Targets
array. Drag & Drop, one by one the objects with the ClickTarget
script. The order you assign those objects will determine the order they must be clicked when the game runs
5th step : Run the game and enjoy!
1. Click on the Play button of Unity
2. Click on the objects and you will see the messages in the Console tab of Unity (if you don't see it, click on Window > Console in the top menu of Unity)
hi, how I can unsubscribe from the events after I destroy the game object( clickable object) in OnTargetClicked.
if I introduce new sequence order I can't update the index (I try to unsubscribe from the old clickable objects and subscribe to the new sequence. but I can't
for (int i = 0; i < targets.Length; i++)
{
int closureIndex = i;
targets[closureIndex].OnTargetClickedEvent -= (target) => OnTargetClicked(target, closureIndex);
}
thanks
You will need to save the callbacks in an array in order to remove them afterwards
public class Clicks$$anonymous$$anager : $$anonymous$$onoBehaviour { // Drag & Drop the objects with the ClickTarget
component [SerializeField] private ClickTarget[] targets;
// Each target will have an index (based on its position in the previous array)
// This variable will indicate which target must be clicked
private int expectedTargetIndex;
private OnTargetClickedEventHandler[] callbacks;
// Called when the scene starts
private void Start()
{
expectedTargetIndex = 0;
callbacks = new OnTargetClickedEventHandler[targets.Length];
// For each target, call a function when they are clicked
for ( int i = 0 ; i < targets.Length ; i++ )
{
// You have to declare a temporary index to prevent the "closure problem"
int closureIndex = i;
callbacks[closureIndex] = ( target ) => OnTargetClicked( target, closureIndex );
targets[closureIndex].OnTargetClickedEvent += callbacks[closureIndex];
}
}
// ...
This way, you will be able to remove the callbacks at runtime
public void RemoveCallbacks()
{
if( callbacks == null ) return;
for ( int i = 0 ; i < targets.Length ; i++ )
{
targets[i].OnTargetClickedEvent -= callbacks[i];
callbacks[i] = null;
}
}
Answer by matheosx · Jan 29, 2018 at 05:02 PM
Hi there, thank you for your answer (effort) because I have the same problem. Unfortunately I am even bigger beginner than the guy who asked this. So, if you are still ok with helping, would you give me 2 clues:
Could you attach the script as a file, cause I don`t know how to write it in Unity. That way I can import it and place it inside of scene directly.
Could you change one line in script so that is: a) fired up-event is not "next level" but just next event inside the same scene triggered with the last click (on the last object). b) has 4 (not 3) objects involved Also, Is it possible to covert this script so that is visible in Playmaker through FSM-s ?
Thank you so much, so so so much!!!!!!!! Peace&Love
Your answer
Follow this Question
Related Questions
Click on specific object to win game and move to next level please help! 1 Answer
How to change sprite after several clicks? 1 Answer
C# 2D Click on Object touching trigger 1 Answer
Get click position on gameobject from OnPointerClicks PointerEventData 1 Answer
Accessing public variable with the On Click() function list in Inspector 1 Answer