Picking up 2D collectables in an order?
Hi Everyone,
I am creating a 2D platform game for children. Currently, the player can pick up objects in any order, however when the levels progress I wish for them to be picked up in a certain order.
An example of this would be: Not being able to pick up the orange block, before the green.
This my method for collecting objects. This is attached to the collectable game Objects within my game. This also checks that once all the items have been collected, then the next level can be loaded.
void OnTriggerEnter2D(Collider2D other)
{
if (other.tag == "Player")
{
++BlocksCollected;
Debug.Log(BlocksCollected);
gameObject.GetComponent<AudioSource>().Play();
Collect();
if (BlocksCollected == 4)
{
SceneManager.LoadScene("Level2");
}
}
}
}
If anyone could help me or guide me on how to do this, I would appreciate it!
Thanks!
Do the blocks have some sort of "BlockColor" enum-style property? If so, you could set up an array in the inspector to control the block order itself, then monitor the required next block that way?
You could consider adding something like this to the "player" doing the collecting:
Edit: be sure to build out the color array in your inspector.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public enum BlockType
{
Red = 0,
Blue = 1,
Yellow = 2,
Green = 3,
Black = 4,
White = 5,
}
public class BlockGrabber : $$anonymous$$onoBehaviour {
// Substitute your own enum for colors, this
// will just show the idea.
public BlockType[] colorOrder;
// Then keep track of your progress
private int nextColorIndex = 0;
// Check if a given block type would satisfy
// the order
public bool $$anonymous$$atchesNextBlock( BlockType b)
{
// The index is only being incremented here,
// so we shouldn't be getting any weird behavior
//
return b == this.colorOrder[this.nextColorIndex];
}
// Increment the index and see if that was the last
// color required
public bool IncrementandCheck()
{
// Add to our index
this.nextColorIndex++;
// Then return whether this exceeds our color array
return this.nextColorIndex >= this.colorOrder.Length;
}
}
Then adding a property with that enum onto your blocks themselves, adjusting the collision function appropriately:
public BlockType blockType;
void OnTriggerEnter2D(Collider2D other)
{
if (other.tag == "Player")
{
// We'll check the array on this object
BlockGrabber grabber = other.GetComponent<BlockGrabber>();
// See if this block's color is what the player
// wanted to grab next
bool match = grabber.$$anonymous$$atchesNextBlock( this.blockType);
// If this isn't the right block, break out here
if (!match)
return;
// If we're still here, then this block fits the bill, so
// check if we're actually done
bool done = grabber.IncrementandCheck();
// ++BlocksCollected;
// Debug.Log(BlocksCollected);
gameObject.GetComponent<AudioSource>().Play();
// Collect();
if (done)
{
Scene$$anonymous$$anager.LoadScene("Level2");
}
}
}
Hi @TreyH,
Thank you for your help! I now have added this into my code. However, I am getting the error 'array index is out of range'. Do you know why this may be?
Thanks again!
The example array there will need to be populated within the inspector, but, if you've already done that, then the player might need to have their collection index reset on a new scene.
By default, inspector arrays are of length 0, so any index will throw an exception.
Thank-you so much I got it working! I didn't set the size of the array on the BlockGrabber.
Thanks again!
Your answer
Follow this Question
Related Questions
Checking if the player jumps while not grounded 0 Answers
"Is Kinematic" required? 1 Answer
Adding sprites to same layer as bone in 2D animation rig 1 Answer
Change angle of player when changing slope angles 0 Answers
2D Runtime Editor for Platformer 0 Answers