Project Overview

Tool Info

Roles: Programmer

Date: May 2020 - June 2020

Team Size: Solo project

Engine: Unity

Version Control: Git

Code Language: C#

My Role

I worked on this project while interning at House of How. Me and another intern was tasked with generating Minecraft parkour maps by improving the Unity tool DunGen to give more creative freedom to the game designers using it.

Collider bounds

DunGen already had basic bounds restriction implemented but to improve that I was tasked with making a new restriction rule. In scene colliders would count as the restriction area and the dungeon should only be able to generate tiles within that. This rule made it possible to generate the tiles within multiple boxes and in more interesting shapes by moving the colliders.

dungencolliderbounds

The restriction can find any collider but will only use the bounds for said collider. Since unitys bounds is always represented as a box that means the tiles can be generated outside of the collider if the tile is still within the collider bounds.

dungencolliderboundscirlce
dungencolliderboundscirlcesquare

//Find all the colliders that are meant to be the restriction area.
//These have to be on a certain layer.
List FindGameObjectsWithLayer(int layer) 
  { 
    GameObject[] goArray = GameObject.FindObjectsOfType(typeof(GameObject)) as GameObject[];
    List goList = new List(); 
    for (int i = 0; i < goArray.Length; i++) 
    { 
        if (goArray[i].layer == layer) 
        goList.Add(goArray[i]); 
    } 
    if (goList.Count == 0) 
        return null; 

    return goList; 
}

//Do collision check here with all colliders on layer RestrictColliderBounds
if (RestrictDungeonToColliderBounds && DungeonRestrictColliders != null && DungeonRestrictColliders.Count > 0 && TempRestrictToColliderBounds)
{
    int containedIn = 0;
    foreach (GameObject collider in DungeonRestrictColliders)
    {
        Collider restrictCollider = collider.GetComponent();
        Bounds newProxyBounds = restrictCollider.bounds;
        if (newProxyBounds.Contains(proxyBounds))
            containedIn++;
    }

    if(containedIn <= 0)
    {
        Debug.LogWarning("Tile was placed outside of restriction. Removing and retrying");
        return TilePlacementResult.OutOfBounds;
    }
}
            

Repeat modes

Repeat modes in DunGen is the rules for how a tile is allowed to generate e.g "Allow tiles to be placed in a row". To extend these options I implemented two more repeat modes for tiles.

Allow X tiles in a row

Allow X tiles in a row makes sure that only x tiles can be placed in a row.

Allow X tiles maximum to generate in a dungeon

Allow X tiles maximum does not generate any more of that tile once X amount has been placed.

X can be set separetely for each tile using repeat modes where relevant by using the custom tile inspector fields that was added.

dungencolliderbounds

In the picture above, the red tiles are set to "allow maximum 3 tiles in a row" the yellow to "allow 4 maximum in dungeon" and the green ones follow the standard "allow anywhere". Both tile types can still be generated less than the rules say.

switch (repeatMode)
{
    //Standard
    case TileRepeatMode.Allow:							
        allowTile = true;
        break;
    //Allow X tiles in a row
    case TileRepeatMode.AllowXInRow:
        if (potentialNextTile.PrefabTile.AllowedAmount <= 0)
            allowTile = false;
        else if (UsedAmounts < potentialNextTile.PrefabTile.AllowedAmount)
            allowTile = true;
        else
            allowTile = false;
        break;
    //Allow X total of tile in dungeon
    case TileRepeatMode.AllowXTotalOfTile:
        if (potentialNextTile.PrefabTile.AllowedAmount <= 0)
            allowTile = false;
        else if (potentialNextTile.PrefabTile.TotalAmountPlaced < potentialNextTile.PrefabTile.AllowedAmount)
            allowTile = true;
        else
            allowTile = false;
        break;
    //Standard
    case TileRepeatMode.DisallowImmediate:
        allowTile = !isImmediateRepeat;
        break;
     //Standard
    case TileRepeatMode.Disallow:
        allowTile = !proxyDungeon.AllTiles.Where(t => t.Prefab == potentialNextTile.Prefab).Any();
        break;
    default:
        throw new NotImplementedException("TileRepeatMode " + repeatMode + " is not implemented");
}

//Reset UsedAmounts & ForceXInRow if new tile != last tile
if (lastTile != null && (createdTile.Prefab != lastTile.Prefab))
    UsedAmounts = 0;

//Add to counters if neccessary
switch (createdTile.PrefabTile.RepeatMode)
{
    case TileRepeatMode.AllowXInRow:
        UsedAmounts++;
        break;
    case TileRepeatMode.AllowXTotalOfTile:
        createdTile.PrefabTile.TotalAmountPlaced++;
        break;
    default:
        break;
}