So I’ve been getting into the habit of creating more modular reusable tools so that my artist/designer can set things like this up in scene.
And this can be done without a queue or any really complicated code. But instead follow a basic logic chain.
Here are my scripts:
A simple OnTriggerEnter2D script that signals a UnityEvent. I allow for a tag mask, and 2 states based on if the ‘SignalShouldPass’ boolean toggle.
using UnityEngine;
using UnityEngine.Events;
public class t_OnTriggerEnter2D : MonoBehaviour {
public string TagMask;
public bool SignalShouldPass;
public UnityEvent OnEnterPass;
public UnityEvent OnEnterFail;
public void SetIfSignalPass(bool value)
{
this.SignalShouldPass = value;
}
void OnTriggerEnter2D(Collider2D collision)
{
if (!this.enabled) return;
if (!string.IsNullOrEmpty(TagMask) && !collision.gameObject.CompareTag(TagMask)) return;
if (this.SignalShouldPass)
this.OnEnterPass.Invoke();
else
this.OnEnterFail.Invoke();
}
}
Then I have the result of the sequence. What should happen if the player succeeds or fails:
using UnityEngine;
public class SequenceCompleteResult : MonoBehaviour {
public void OnSequenceFail()
{
Debug.Log("PLAYER LOST!");
//here we can reset the puzzle
}
public void OnSequenceSucceeded()
{
Debug.Log("PLAYER SUCCEEDED!!");
//here we can do what we do on success
}
}
I don’t really do much, that’s up for you.
And lastly I created a very simple motion script. Mine just moves some object to the mouse position. You can have whatever motion script you want:
using UnityEngine;
public class MotionScript : MonoBehaviour {
private void Update()
{
var plane = new Plane(Vector3.forward, Vector3.zero);
var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
float dist;
plane.Raycast(ray, out dist);
this.transform.position = ray.GetPoint(dist);
}
}
Then a scene. I start with a player sphere and 2 cubes that have to be hovered order in the order bottom first, then top second (note adding more entries is mostly trivial):
Then on the ‘First’ I attached my t_OnEnterTrigger2D script:
It’s configured to singal as pass because it’s the first entry, it should pass by default.
In it’s on pass event I target the ‘Second’ cube in the sequence and set it’s ‘SignalShouldPass’ to true.
Then on Second:
Here it’s set to fail by default. This way if you entered it before entering ‘First’ it’ll play the ‘Fail’ event. But if ‘First’ was already entered, it’ll be toggled, and run its ‘Pass’ event.
Then in the pass and fail we target the ‘Result’ object. In ‘Pass’ I call ‘OnSequenceSucceeded’ and in ‘Fail’ I call ‘OnSequenceFailed’.
Done.
…
If we wanted to insert a third entry into the sequence well we just set up the 3rd the same way 2nd is, and we make 2nd toggle the thirds ‘SignalPass’ boolean: