CloudCanards World Planner

For the past 2-3 weeks, I’ve been making an internal tool to plan out the world map for CloudCanards.

WorldPlanner

For those of you who don’t know, CloudCanards is a game development project that me and my team have been working on for the past two years. It has a 2D pixel art aesthetic, but level design wise, it is a 3D Metroidvania with interconnected regions. We needed a way to efficiently plan out the open world while keeping track of which areas the player could visit with specific powerups. This led to the creation of our World Planner tool.

The entire world is represented by a graph where each node is an area and each edge is a connection between two areas. These connections might have requirements that that player needs to acquire before being able to traverse through.

What’s interesting is that the entire tool is heavily integrated into Google Firebase, allowing all of us to edit the graph concurrently. It’s pretty fun to fly around the world planning specific regions together.

Tokei is telling me that I wrote around 4,000 lines of code for this project, which is pretty low compared to the main CloudCanards repository. I was pretty surprised at how intuitive it was to implement Firebase Realtime Database into the project.

Unstoppable Spider

Last weekend, my friends and I participated in the Game Maker’s Toolkit Jam 2018, where the goal was to create a game that follows a genre while leaving out a core mechanic. Within 48 hours, we created Unstoppable Spider, a stealth game with no breaks.

afxxwx

Here’s the link if you’d like to check it out:

https://creativitry.itch.io/unstoppable-spider

Continue reading

Unity 2.5D Tilemap Depth

Hello, Gahwon here. Here’s another Unity tutorial!

Have you ever tried to make a 2.5D world, only to realize that your trees are rendering behind the player all the time? Well, fear not!

Although many sources exist on creating this feature using sprites, this tutorial instead uses the new Unity Tilemap to apply depth.

For those who want the whole source code, here it is.

https://github.com/creativitRy/TilemapHeightTest

Feel free to use this anywhere (probably not the sprites since I drew them and I’m not an artist).

Here’s a TL;DR version of the system: Each tile contains a height property. This height is compared with the player’s height every frame to see if the tile should overlap or not. Overlapping tiles are moved to a new Tilemap layer that is always rendered in front of the player. This layer is cleared at the start of every frame.

Continue reading

Unity Dropdown Slider

Hello, Gahwon here. Let’s start off this blog with a tutorial!

For one of my Unity projects, I was prompted to make a slider that expands from and retracts into a button. Here’s how I made it.

hierarchy

Here’s how each of them looks in the hierarchy. As a basic overview, the Mask hides anything outside its region. Meanwhile, the RockSlider moves anything within DropDown up or down when the Button is pressed.

Let’s get started. Create a canvas an put a Panel inside. This will be the parent object for all other components.
Create a new panel and put a mask component. Now, create another panel as a child object. This will be the dropdown that is shown. Make the mask a child of the parent panel.
Put a button as a child object. This button will be in charge of opening and closing the dropdown.
Let’s write code to toggle the visibility of the dropdown object.

public class DropdownSlider : MonoBehavior
{
	public RectTransform Dropdown;

	private bool _opened;

	public bool Opened
	{
		get { return _opened; }
		set
		{
			_opened = value;

			Dropdown.gameObject.SetActive(value);
		}
	}

	public void OnClick()
	{
		Opened = !Opened;
	}
}

You can put this DropdownSlider component within the parent panel and select the dropdown object for the Dropdown field. On the button, add a new function for the On Click () event. Select the parent, and select DropdownSlider.OnClick().

If you run the game now, you can toggle the visibility of the dropdown. But we want it to be more gradual. So lets update our code. Add these lines to DropdownSlider.

// what percentage of the dropdown is visible
private float _percentage;

// how the dropdown animation will play
public AnimationCurve Animation = AnimationCurve.EaseInOut(0, 0, 1, 1);

// length of the total dropdown animation (from completely retracted to fully expanded)
public float AnimationDuration = 1f;

// y position of the dropdown when either fully retracted or expanded
public float RetractedY = 0f;
public float ExpandedY = 100f;

private void Update()
{
	// all animation finished playing
	if (_percentage = 1 && Opened)
		return;

	// update how much is visible
	_percentage += (Opened ? 1 : -1) * Time.unscaledDeltaTime / AnimationDuration;

	if (_percentage = 1)
	{
		_percentage = 1;
	}

	PositionSlider(_percentage);
}

private void PositionSlider(float percentage)
{
	// move the dropdown itself
	var pos = Dropdown.anchoredPosition;
	pos.y = Mathf.Lerp(RetractedY, ExpandedY, Animation.Evaluate(percentage));
	Dropdown.anchoredPosition = pos;
}

Change the setter for the Opened property.

public bool Opened
{
	get { return _opened; }
	set
	{
		_opened = value;

		if (value)
		{
			Dropdown.gameObject.SetActive(true);
		}
	}
}

Now the dropdown should be fully functional.

If you want to change whether the dropdown starts retracted or expanded, use this code:

[SerializeField]
[Tooltip("Whether to start retracted (false) or expanded (true)")]
private bool _opened;

private void Start()
{
	if (!Opened)
	{
		UpdateDropdownVisibility(false);
		PositionSlider(0f);
	}
	else
	{
		UpdateDropdownVisibility(true);
		PositionSlider(1f);
		_percentage = 1f;
	}
}

Here’s the final code:

public class DropdownSlider : MonoBehavior
{
	public RectTransform Dropdown;

	private bool _opened;

	public bool Opened
	{
		get { return _opened; }
		set
		{
			_opened = value;

			if (value)
			{
				Dropdown.gameObject.SetActive(true);
			}
		}
	}

	// what percentage of the dropdown is visible
	private float _percentage;

	// how the dropdown animation will play
	public AnimationCurve Animation = AnimationCurve.EaseInOut(0, 0, 1, 1);

	// length of the total dropdown animation (from completely retracted to fully expanded)
	public float AnimationDuration = 1f;

	// y position of the dropdown when either fully retracted or expanded
	public float RetractedY = 0f;
	public float ExpandedY = 100f;

	private void Start()
	{
		if (!Opened)
		{
			Dropdown.gameObject.SetActive(false);
			PositionSlider(0f);
		}
		else
		{
			Dropdown.gameObject.SetActive(true);
			PositionSlider(1f);
			_percentage = 1f;
		}
	}

	private void Update()
	{
		// all animation finished playing
		if (_percentage = 1 && Opened)
			return;

		// update how much is visible
		_percentage += (Opened ? 1 : -1) * Time.unscaledDeltaTime / AnimationDuration;

		if (_percentage = 1)
		{
			_percentage = 1;
		}

		PositionSlider(_percentage);
	}

	private void PositionSlider(float percentage)
	{
		// move the dropdown itself
		var pos = Dropdown.anchoredPosition;
		pos.y = Mathf.Lerp(RetractedY, ExpandedY, Animation.Evaluate(percentage));
		Dropdown.anchoredPosition = pos;
	}

	public void OnClicked()
	{
		Opened = !Opened;
	}
}

Thanks for reading! Please let me know if any of this was helpful or if I made any mistakes. Also let me know if you would like more images/gifs.