So, I've trying to make a 2D roguelike in Unity, I want to implement a pixel shadow based on sprites (I have a tile set containing all shadow tiles I may need), So I made that each Shadow had a "shadowType", to define either the shadow is coming from the top, bottom, etc. and I add them all to a Dictionary, with the keys being a 2x2 array (I had to declare a new class for the array), but when I try to call the ShadowType from the dictionary it gives a KeyNotFound Exception, I'd appreciate if I could get some help
ShadowObject script (apllied to all shadow prefabs):
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ShadowObject : MonoBehaviour {
public ShadowType shadowType;
}
public enum ShadowType
{
BottomEnd, Bottom, OutterCorner, Right, RightEnd, InnerConner, None
}
BoardObject script (for now only defines wether a object should cast shadows or not):
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BoardObject : MonoBehaviour {
public bool castShadow = false;
}
GameManager script (calls the board initialization):
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameManager : MonoBehaviour {
GameManager instance = null;
BoardManager boardManager;
void Awake () {
if (instance == null)
instance = this;
else if (instance != this)
Destroy (this);
DontDestroyOnLoad (this);
boardManager = GetComponent<BoardManager> ();
}
void Start () {
boardManager.SetupsScene ();
}
}
BoardManager script (Builds the Board, set ups the floor, walls and shadows):
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using Random = UnityEngine.Random;
public class BoardManager : MonoBehaviour {
public int width, height;
Camera cam;
public GameObject[] floorTiles;
public GameObject mainFloorTile;
public GameObject[] wallTiles;
public List<GameObject> shadowTiles;
Transform boardHolder;
List<Vector3> gridPositions = new List<Vector3>();
Dictionary<Vector3, GameObject> boardObjects = new Dictionary<Vector3, GameObject>();
#region ShadowHandler
//for handling 2x2 spaces, needed to know which shadow to instantiate
class Matrix2 <T> {
public T[,] elements = new T[2,2];
public Matrix2 () {}
public Matrix2 (T m00, T m01, T m10, T m11){
elements[0,0] = m00;
elements[0,1] = m01;
elements[1,0] = m10;
elements[1,1] = m11;
}
}
//I tought that using this with the dictionary could solve the problem, it didn't
class Matrix2EqualityComparer <T>: IEqualityComparer<Matrix2<T>> {
public bool Equals (Matrix2<T> m1, Matrix2<T> m2){
if (m1 == null && m2 == null)
return true;
else if (m1 == null || m2 == null)
return false;
else if (m1.elements == m2.elements)
return true;
else
return false;
}
public int GetHashCode (Matrix2<T> mat){
return base.GetHashCode ();
}
}
static Matrix2EqualityComparer<bool> mat2EqC = new Matrix2EqualityComparer<bool> ();
Dictionary<Matrix2<bool>, ShadowType> shadowListOrganizer = new Dictionary<Matrix2<bool>, ShadowType>(mat2EqC);
//adds all 16 posible states of the boardObjects to the dictioanry, with the shadowType that should be instantiate in that case
void SetupShadowListOrganizer () {
shadowListOrganizer.Clear ();
shadowListOrganizer.Add (new Matrix2<bool> (false, false, false, false), ShadowType.None);
shadowListOrganizer.Add (new Matrix2<bool> (false, false, false, true), ShadowType.None);
shadowListOrganizer.Add (new Matrix2<bool> (false, false, true, false), ShadowType.RightEnd);
shadowListOrganizer.Add (new Matrix2<bool> (false, false, true, true), ShadowType.None);
shadowListOrganizer.Add (new Matrix2<bool> (false, true, false, false), ShadowType.BottomEnd);
shadowListOrganizer.Add (new Matrix2<bool> (false, true, false, true), ShadowType.None);
shadowListOrganizer.Add (new Matrix2<bool> (false, true, true, false), ShadowType.InnerConner);
shadowListOrganizer.Add (new Matrix2<bool> (false, true, true, true), ShadowType.None);
shadowListOrganizer.Add (new Matrix2<bool> (true, false, false, false), ShadowType.OutterCorner);
shadowListOrganizer.Add (new Matrix2<bool> (true, false, false, true), ShadowType.None);
shadowListOrganizer.Add (new Matrix2<bool> (true, false, true, false), ShadowType.Right);
shadowListOrganizer.Add (new Matrix2<bool> (true, false, true, true), ShadowType.None);
shadowListOrganizer.Add (new Matrix2<bool> (true, true, false, false), ShadowType.Bottom);
shadowListOrganizer.Add (new Matrix2<bool> (true, true, false, true), ShadowType.None);
shadowListOrganizer.Add (new Matrix2<bool> (true, true, true, false), ShadowType.InnerConner);
shadowListOrganizer.Add (new Matrix2<bool> (true, true, true, true), ShadowType.None);
}
#endregion
void Awake () {
cam = Camera.main;
cam.orthographicSize = height > width ? ( height + 2) / 2 + 1: ( width + 2 ) / 2 + 1;
cam.transform.position = new Vector3(width / 2, height / 2, -10f);
}
void InitialiseList() {
gridPositions.Clear ();
for (int y = 0; y < height; y++){
for (int x = 0; x < width; x++){
gridPositions.Add (new Vector3 (x, y, 0f));
}
}
}
void BoardSetup () {
boardHolder = Instantiate (new GameObject ("BoardHolder").transform);
for (int y = -1; y <= height; y++){
for (int x = -1; x <= width; x++){
GameObject toInstantiate = ( x == -1 || y == -1 || x == width || y == height ) ?
wallTiles[Random.Range (0, wallTiles.Length)] :
Random.Range(0, 101) <= 66 ?
mainFloorTile :
floorTiles[Random.Range (0, floorTiles.Length)];
GameObject instance = Instantiate (toInstantiate, new Vector3 (x, y, 0f), Quaternion.identity) as GameObject;
instance.transform.SetParent (boardHolder);
boardObjects.Add (new Vector3 (x, y, 0f), instance);
}
}
}
void SetupShadow () {
SetupShadowListOrganizer ();
for (int y = 0; y <= height; y++){ //this loop will go on for a 2x2 grid, with the (x, y) tile being the right bottom corner of that grid
for (int x = 0; x <= width; x++){
bool m00 = boardObjects[new Vector3 (x - 1, y + 1, 0f)].GetComponent<BoardObject>().castShadow;
bool m01 = boardObjects[new Vector3 (x, y + 1, 0f)].GetComponent<BoardObject>().castShadow;
bool m10 = boardObjects[new Vector3 (x - 1, y, 0f)].GetComponent<BoardObject>().castShadow;
bool m11 = boardObjects[new Vector3 (x, y, 0f)].GetComponent<BoardObject>().castShadow;
GameObject toInstantiate = shadowTiles.SingleOrDefault (shadow => shadow.GetComponent<ShadowObject> ().shadowType == shadowListOrganizer[new Matrix2<bool> (m00, m01, m10, m11)]);
if (toInstantiate == null)
continue;
GameObject instance = Instantiate (toInstantiate, new Vector3 (x, y, 0f), Quaternion.identity);
instance.transform.SetParent (boardHolder);
}
}
}
public void SetupsScene () {
InitialiseList ();
BoardSetup ();
SetupShadow ();
}
}