Author | SHA1 | Message | Date |
---|---|---|---|
DESKTOP-B4ME9GF\Joshua Reason | a447a350a7 | Made the clicked cell also use styles | 6 years ago |
DESKTOP-B4ME9GF\Joshua Reason | 4871b8f942 | Re-working Gui to use contants and no longer use guilayout + created board class | 6 years ago |
Joshua Reason | 1742e5b032 | Added colors and clicking on nothing opens everything | 6 years ago |
Joshua Reason | a2df77f3ab | Merge branch 'feature/HideInPrefabAttribute' into develop | 6 years ago |
Joshua Reason | 4e9bb9c71f | Commented Code | 6 years ago |
DESKTOP-B4ME9GF\Joshua Reason | b0e7e1f753 | Implemented feature, but needs commenting before finishing | 6 years ago |
@ -1,5 +1,5 @@ | |||
fileFormatVersion: 2 | |||
guid: d2ef7c61cf0a63a439bf63d461541ce3 | |||
guid: 7a8bfbd0555f21048abd1415f2c47893 | |||
folderAsset: yes | |||
DefaultImporter: | |||
externalObjects: {} |
@ -1,5 +1,5 @@ | |||
fileFormatVersion: 2 | |||
guid: 1eba5231ebd032b4db5d58d699e0f0de | |||
guid: 040e0c0ec80bb52409744b03671df838 | |||
folderAsset: yes | |||
DefaultImporter: | |||
externalObjects: {} |
@ -0,0 +1,8 @@ | |||
fileFormatVersion: 2 | |||
guid: f134e8ccabae44c45b14bad67978a30b | |||
folderAsset: yes | |||
DefaultImporter: | |||
externalObjects: {} | |||
userData: | |||
assetBundleName: | |||
assetBundleVariant: |
@ -0,0 +1,8 @@ | |||
fileFormatVersion: 2 | |||
guid: affc4046c2a5111479cf285e82bedb4f | |||
folderAsset: yes | |||
DefaultImporter: | |||
externalObjects: {} | |||
userData: | |||
assetBundleName: | |||
assetBundleVariant: |
@ -0,0 +1,22 @@ | |||
using System.Collections; | |||
using System.Collections.Generic; | |||
using UnityEngine; | |||
/// <summary> | |||
/// Example of a script using [HideInPrfab] | |||
/// </summary> | |||
public class HideInPrefabExample : MonoBehaviour { | |||
[Header ("Drag Me into scene to show hidden properties.")] | |||
[HideInPrefab] | |||
public float HiddenFloat = 5; //Hidden in prefab inspector | |||
public float ShownFloat = 6; //Not hidden in prefab inspector | |||
[HideInInspector] | |||
public float AlwaysHiddenFloat = 7; //Always hidden (Unity's default implementation) | |||
[HideInPrefab] | |||
public GameObject HiddenGameObject; //Hidden in Prefab inspector | |||
public GameObject ShownGameObject; //NotHidden in Prefab inspector | |||
} |
@ -0,0 +1,11 @@ | |||
fileFormatVersion: 2 | |||
guid: b3a8b00c985891a448737258d9b09ede | |||
MonoImporter: | |||
externalObjects: {} | |||
serializedVersion: 2 | |||
defaultReferences: [] | |||
executionOrder: 0 | |||
icon: {instanceID: 0} | |||
userData: | |||
assetBundleName: | |||
assetBundleVariant: |
@ -0,0 +1,58 @@ | |||
%YAML 1.1 | |||
%TAG !u! tag:unity3d.com,2011: | |||
--- !u!1001 &100100000 | |||
Prefab: | |||
m_ObjectHideFlags: 1 | |||
serializedVersion: 2 | |||
m_Modification: | |||
m_TransformParent: {fileID: 0} | |||
m_Modifications: [] | |||
m_RemovedComponents: [] | |||
m_ParentPrefab: {fileID: 0} | |||
m_RootGameObject: {fileID: 1839211675386134} | |||
m_IsPrefabParent: 1 | |||
--- !u!1 &1839211675386134 | |||
GameObject: | |||
m_ObjectHideFlags: 0 | |||
m_PrefabParentObject: {fileID: 0} | |||
m_PrefabInternal: {fileID: 100100000} | |||
serializedVersion: 5 | |||
m_Component: | |||
- component: {fileID: 4904693562653106} | |||
- component: {fileID: 114800799608557334} | |||
m_Layer: 0 | |||
m_Name: HideInPrefabExample | |||
m_TagString: Untagged | |||
m_Icon: {fileID: 0} | |||
m_NavMeshLayer: 0 | |||
m_StaticEditorFlags: 0 | |||
m_IsActive: 1 | |||
--- !u!4 &4904693562653106 | |||
Transform: | |||
m_ObjectHideFlags: 1 | |||
m_PrefabParentObject: {fileID: 0} | |||
m_PrefabInternal: {fileID: 100100000} | |||
m_GameObject: {fileID: 1839211675386134} | |||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} | |||
m_LocalPosition: {x: 0, y: 0, z: 0} | |||
m_LocalScale: {x: 1, y: 1, z: 1} | |||
m_Children: [] | |||
m_Father: {fileID: 0} | |||
m_RootOrder: 0 | |||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} | |||
--- !u!114 &114800799608557334 | |||
MonoBehaviour: | |||
m_ObjectHideFlags: 1 | |||
m_PrefabParentObject: {fileID: 0} | |||
m_PrefabInternal: {fileID: 100100000} | |||
m_GameObject: {fileID: 1839211675386134} | |||
m_Enabled: 1 | |||
m_EditorHideFlags: 0 | |||
m_Script: {fileID: 11500000, guid: b3a8b00c985891a448737258d9b09ede, type: 3} | |||
m_Name: | |||
m_EditorClassIdentifier: | |||
HiddenFloat: 5 | |||
ShownFloat: 6 | |||
AlwaysHiddenFloat: 7 | |||
HiddenGameObject: {fileID: 0} | |||
ShownGameObject: {fileID: 0} |
@ -0,0 +1,8 @@ | |||
fileFormatVersion: 2 | |||
guid: 3e4c28a2ff8a30f4da1d96c254a14fc5 | |||
NativeFormatImporter: | |||
externalObjects: {} | |||
mainObjectFileID: 100100000 | |||
userData: | |||
assetBundleName: | |||
assetBundleVariant: |
@ -0,0 +1,8 @@ | |||
fileFormatVersion: 2 | |||
guid: 5629afcda35004c4d99c76bde4f4eeb7 | |||
folderAsset: yes | |||
DefaultImporter: | |||
externalObjects: {} | |||
userData: | |||
assetBundleName: | |||
assetBundleVariant: |
@ -0,0 +1,53 @@ | |||
using UnityEngine; | |||
#if UNITY_EDITOR | |||
using UnityEditor; | |||
#endif | |||
/// <summary> | |||
/// Class for the Hide in Prefab Attribute | |||
/// </summary> | |||
/// <remarks> | |||
/// Class is empty because we have no parameters needed for this attribute | |||
/// </remarks> | |||
public class HideInPrefabAttribute : PropertyAttribute | |||
{ | |||
} | |||
#if UNITY_EDITOR | |||
/// <summary> | |||
/// Override for the Property Drawer which draws the GUI | |||
/// </summary> | |||
[CustomPropertyDrawer(typeof(HideInPrefabAttribute))] | |||
public class HideInPrefabDrawer : PropertyDrawer | |||
{ | |||
//On GUI override | |||
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) | |||
{ | |||
//get the type of the object this property is attched to | |||
PrefabType type = PrefabUtility.GetPrefabType(property.serializedObject.targetObject); | |||
//if the type isn't a perfab then draw the property | |||
if (type != PrefabType.Prefab) | |||
EditorGUI.PropertyField(position, property, label); | |||
} | |||
//Override GetPropertyHeight | |||
public override float GetPropertyHeight(SerializedProperty property, GUIContent label) | |||
{ | |||
//get the type of the object this property is attched to | |||
PrefabType type = PrefabUtility.GetPrefabType(property.serializedObject.targetObject); | |||
//if type prefab return zero height (because it won't be drawn) | |||
if (type == PrefabType.Prefab) | |||
return 0; | |||
//else return normal height | |||
return base.GetPropertyHeight(property, label); | |||
} | |||
} | |||
#endif |
@ -0,0 +1,11 @@ | |||
fileFormatVersion: 2 | |||
guid: 7ffee7f5af11da344ae52c6c92cce67c | |||
MonoImporter: | |||
externalObjects: {} | |||
serializedVersion: 2 | |||
defaultReferences: [] | |||
executionOrder: 0 | |||
icon: {instanceID: 0} | |||
userData: | |||
assetBundleName: | |||
assetBundleVariant: |
@ -0,0 +1,8 @@ | |||
fileFormatVersion: 2 | |||
guid: d4bd0c05ca2429b43bfc7f02fe4a9101 | |||
folderAsset: yes | |||
DefaultImporter: | |||
externalObjects: {} | |||
userData: | |||
assetBundleName: | |||
assetBundleVariant: |
@ -0,0 +1,161 @@ | |||
using System.Collections; | |||
using System.Collections.Generic; | |||
using UnityEngine; | |||
using UnityEditor; | |||
public class MineSweeperEditor : EditorWindow { | |||
public int MineCount = 10; | |||
Board board; | |||
// Add menu named "My Window" to the Window menu | |||
[MenuItem("Addon/Mine Sweeper")] | |||
static void Init() | |||
{ | |||
// Get existing open window or if none, make a new one: | |||
MineSweeperEditor window = (MineSweeperEditor)EditorWindow.GetWindow(typeof(MineSweeperEditor)); | |||
window.Show(); | |||
} | |||
private void Awake() | |||
{ | |||
board = new Board(new Vector2Int(10, 10)); | |||
} | |||
void OnGUI() | |||
{ | |||
HeaderGUI(); | |||
board.OnGUI(); | |||
board.OnClick(); | |||
} | |||
private void Update() | |||
{ | |||
Repaint(); | |||
} | |||
private void HeaderGUI() | |||
{ | |||
GUIStyle style = GUI.skin.label; | |||
style.normal.textColor = Color.red; | |||
style.normal.background = MineSweeperConstants.CELL_CLICKED; | |||
GUILayout.BeginHorizontal(); | |||
GUILayout.Label("000", style); | |||
GUILayout.FlexibleSpace(); | |||
GUILayout.EndHorizontal(); | |||
} | |||
public static Color getColor(int count){ | |||
switch (count) { | |||
case 0: | |||
return new Color(0.75f, 0.75f, 0.75f); | |||
case 1: | |||
return Color.blue; | |||
case 2: | |||
return Color.green; | |||
case 3: | |||
return Color.red; | |||
case 4: | |||
return new Color(0, 0, 0.54f); | |||
case 5: | |||
return new Color(0.64f, 0.16f, 0.16f); | |||
case 6: | |||
return Color.cyan; | |||
case 7: | |||
return Color.grey; | |||
case 8: | |||
return Color.black; | |||
default: | |||
return Color.black; | |||
} | |||
} | |||
} | |||
public class Cell { | |||
public bool isOpen = false; | |||
public bool containsMine = false; | |||
public int adjacentMines = 0; | |||
public Board board; | |||
private Rect rect; | |||
Vector2Int coords; | |||
public bool isMarked = false; | |||
public Cell(Board board, Vector2Int coords) | |||
{ | |||
this.board = board; | |||
this.coords = coords; | |||
rect = new Rect(coords.x * MineSweeperConstants.CELL_SIZE + 1, coords.y * MineSweeperConstants.CELL_SIZE + 1, MineSweeperConstants.CELL_SIZE, MineSweeperConstants.CELL_SIZE); | |||
} | |||
public void DrawCell() | |||
{ | |||
if (!isOpen) { | |||
if (isMarked) | |||
GUI.Label(rect, "!",MineSweeperConstants.STYLE_CELL_BUTTON); | |||
else | |||
{ | |||
GUI.Label(rect, "", MineSweeperConstants.STYLE_CELL_BUTTON); | |||
} | |||
} else { | |||
if (containsMine) | |||
GUI.Label(rect, "X",MineSweeperConstants.STYLE_CELL_CLICKED); | |||
else { | |||
MineSweeperConstants.STYLE_CELL_CLICKED.normal.textColor = MineSweeperEditor.getColor(adjacentMines); | |||
GUI.Label(rect,adjacentMines.ToString(), MineSweeperConstants.STYLE_CELL_CLICKED); | |||
MineSweeperConstants.STYLE_CELL_CLICKED.normal.textColor = Color.black; | |||
} | |||
} | |||
} | |||
public void OnClick(int button, Vector2 mousePos) | |||
{ | |||
if (rect.Contains(mousePos)) { | |||
if (button == 0) | |||
DoLeftClick(); | |||
else if (button == 1) | |||
DoRightClick(); | |||
} | |||
} | |||
private void DoLeftClick() | |||
{ | |||
if (isOpen) | |||
return; | |||
isOpen = true; | |||
Cell[] adjacentCells = board.AdjacentCells(coords); | |||
foreach (Cell cell in adjacentCells) { | |||
if (cell.containsMine) | |||
adjacentMines++; | |||
} | |||
if (adjacentMines == 0 && !containsMine) | |||
foreach (Cell cell in adjacentCells) | |||
if (!cell.isOpen) | |||
cell.DoLeftClick(); | |||
} | |||
private void DoRightClick() | |||
{ | |||
isMarked = !isMarked; | |||
} | |||
} |
@ -0,0 +1,11 @@ | |||
fileFormatVersion: 2 | |||
guid: b2427cb8299c3ea4c9acc48e65e85e4d | |||
MonoImporter: | |||
externalObjects: {} | |||
serializedVersion: 2 | |||
defaultReferences: [] | |||
executionOrder: 0 | |||
icon: {instanceID: 0} | |||
userData: | |||
assetBundleName: | |||
assetBundleVariant: |
@ -0,0 +1,303 @@ | |||
using System.Collections; | |||
using System.Collections.Generic; | |||
using UnityEngine; | |||
using UnityEditor; | |||
public static class MineSweeperConstants | |||
{ | |||
private static Texture2D Cell_Button; | |||
private static Texture2D Cell_Clicked; | |||
private static GUIStyle Button_Style; | |||
private static GUIStyle Clicked_Style; | |||
/// <summary> | |||
/// Height and Width of a Cell in Pixels | |||
/// </summary> | |||
public static int CELL_SIZE { get { return 20; } } | |||
/// <summary> | |||
/// Texture of Cell when it hasn't been clicked | |||
/// </summary> | |||
public static Texture2D CELL_BUTTON | |||
{ | |||
get | |||
{ | |||
if (Cell_Button == null) | |||
{ | |||
Cell_Button = CreateButtonTexture(Color.white, new Color(0.75f, 0.75f, 0.75f), Color.black); | |||
Debug.Log("Generating CELL_BUTTON"); | |||
} | |||
return Cell_Button; | |||
} | |||
} | |||
/// <summary> | |||
/// Texture of Cell when it has been clicked | |||
/// </summary> | |||
public static Texture2D CELL_CLICKED | |||
{ | |||
get | |||
{ | |||
if (Cell_Clicked == null) | |||
{ | |||
Cell_Clicked = CreateButtonTexture(new Color(0.2f, 0.2f, 0.2f), new Color(0.75f, 0.75f, 0.75f), new Color(0.8f, 0.8f, 0.8f)); | |||
Debug.Log("Generating CELL_CLicked"); | |||
} | |||
return Cell_Clicked; | |||
} | |||
} | |||
/// <summary> | |||
/// Style to use with a Cell_Button | |||
/// </summary> | |||
public static GUIStyle STYLE_CELL_BUTTON | |||
{ | |||
get | |||
{ | |||
if (Button_Style == null) | |||
{ | |||
Debug.Log("Creating Cell Style"); | |||
Button_Style = new GUIStyle(); | |||
Button_Style.alignment = TextAnchor.MiddleCenter; | |||
Button_Style.normal.background = CELL_BUTTON; | |||
} | |||
return Button_Style; | |||
} | |||
} | |||
/// <summary> | |||
/// Style to use with a Cell_Button | |||
/// </summary> | |||
public static GUIStyle STYLE_CELL_CLICKED | |||
{ | |||
get | |||
{ | |||
if (Clicked_Style == null) | |||
{ | |||
Debug.Log("Creating Cell Style Clicked"); | |||
Clicked_Style = new GUIStyle(); | |||
Clicked_Style.alignment = TextAnchor.MiddleCenter; | |||
Clicked_Style.normal.background = CELL_CLICKED; | |||
} | |||
return Clicked_Style; | |||
} | |||
} | |||
private static Texture2D CreateButtonTexture(Color highLight, Color mainColor, Color lowLight) | |||
{ | |||
Texture2D retval = new Texture2D(CELL_SIZE, CELL_SIZE); | |||
for (int i = 0; i < CELL_SIZE; i++) | |||
{ | |||
for (int j = 0; j < CELL_SIZE; j++) | |||
{ | |||
if (i == 0 || j == CELL_SIZE - 1) | |||
{ | |||
retval.SetPixel(i, j, highLight); | |||
} | |||
else if (i == CELL_SIZE - 1 || j == 0) | |||
{ | |||
retval.SetPixel(i, j, lowLight); | |||
} | |||
else | |||
retval.SetPixel(i, j, mainColor); | |||
} | |||
} | |||
retval.Apply(); | |||
return retval; | |||
} | |||
} | |||
public class Board | |||
{ | |||
private Cell[,] Cells; | |||
private int MineCount = 10; | |||
public Board(Vector2Int Size) | |||
{ | |||
Cells = new Cell[Size.x, Size.y]; | |||
for (int i = 0; i < Size.x; i++) | |||
for (int j = 0; j < Size.y; j++) | |||
Cells[i, j] = new Cell(this, new Vector2Int(i, j)); | |||
PlaceMines(new Vector2Int(0, 0)); | |||
} | |||
public void OnGUI() | |||
{ | |||
foreach (Cell cell in Cells) | |||
cell.DrawCell(); | |||
} | |||
public void OnClick() | |||
{ | |||
Event e = Event.current; | |||
if (e.type == EventType.MouseUp) | |||
{ | |||
foreach (Cell cell in Cells) | |||
cell.OnClick(e.button, e.mousePosition); | |||
} | |||
} | |||
public Cell[] AdjacentCells(Vector2Int coords) | |||
{ | |||
List<Cell> retVal = new List<Cell>(); | |||
for (int i = -1; i <= 1; i++) | |||
{ | |||
if (coords.x + i < 0 || coords.x + i >= Cells.GetLength(0)) | |||
continue; | |||
for (int j = -1; j <= 1; j++) | |||
{ | |||
if (coords.y + j < 0 || coords.y + j >= Cells.GetLength(0)) | |||
continue; | |||
if (i == 0 && j == 0) | |||
continue; | |||
retVal.Add(Cells[coords.x + i, coords.y + j]); | |||
} | |||
} | |||
return retVal.ToArray(); | |||
} | |||
public void PlaceMines(Vector2Int startPos) | |||
{ | |||
int placedMines = 0; | |||
while (placedMines < MineCount) | |||
{ | |||
int x = Random.Range(0, Cells.GetLength(0) - 1); | |||
int y = Random.Range(0, Cells.GetLength(1) - 1); | |||
if (!Cells[x, y].containsMine || startPos != new Vector2Int(x,y)) | |||
{ | |||
Cells[x, y].containsMine = true; | |||
Debug.Log("Mine at: (" + x + ", " + y + ")"); | |||
placedMines++; | |||
} | |||
} | |||
} | |||
} | |||
public class Cell | |||
{ | |||
public enum Mark { None,Flag,Question} | |||
public bool isClicked = false; | |||
public bool containsMine = false; | |||
public int adjacentMines = 0; | |||
public Board board; | |||
private Rect rect; | |||
Vector2Int coords; | |||
public bool isMarked = false; | |||
public Cell(Board board, Vector2Int coords) | |||
{ | |||
this.board = board; | |||
this.coords = coords; | |||
rect = new Rect(coords.x * MineSweeperConstants.CELL_SIZE + 1, coords.y * MineSweeperConstants.CELL_SIZE + 1, MineSweeperConstants.CELL_SIZE, MineSweeperConstants.CELL_SIZE); | |||
} | |||
public void DrawCell() | |||
{ | |||
if (!isClicked) | |||
{ | |||
if (isMarked) | |||
GUI.Label(rect, "!", MineSweeperConstants.STYLE_CELL_BUTTON); | |||
else | |||
{ | |||
GUI.Label(rect, "", MineSweeperConstants.STYLE_CELL_BUTTON); | |||
} | |||
} | |||
else | |||
{ | |||
if (containsMine) | |||
GUI.Label(rect, "X", MineSweeperConstants.STYLE_CELL_CLICKED); | |||
else | |||
{ | |||
MineSweeperConstants.STYLE_CELL_CLICKED.normal.textColor = MineSweeperEditor.getColor(adjacentMines); | |||
GUI.Label(rect, adjacentMines.ToString(), MineSweeperConstants.STYLE_CELL_CLICKED); | |||
MineSweeperConstants.STYLE_CELL_CLICKED.normal.textColor = Color.black; | |||
} | |||
} | |||
} | |||
public void OnClick(int button, Vector2 mousePos) | |||
{ | |||
if (rect.Contains(mousePos)) | |||
{ | |||
if (button == 0) | |||
DoLeftClick(); | |||
else if (button == 1) | |||
DoRightClick(); | |||
} | |||
} | |||
private void DoLeftClick() | |||
{ | |||
if (isClicked) | |||
return; | |||
isClicked = true; | |||
Cell[] adjacentCells = board.AdjacentCells(coords); | |||
foreach (Cell cell in adjacentCells) | |||
{ | |||
if (cell.containsMine) | |||
adjacentMines++; | |||
} | |||
if (adjacentMines == 0 && !containsMine) | |||
foreach (Cell cell in adjacentCells) | |||
if (!cell.isClicked) | |||
cell.DoLeftClick(); | |||
} | |||
private void DoRightClick() | |||
{ | |||
isMarked = !isMarked; | |||
} | |||
} | |||
public struct Vector2Int | |||
{ | |||
public int x; | |||
public int y; | |||
public Vector2Int(int x, int y) | |||
{ | |||
this.x = x; | |||
this.y = y; | |||
} | |||
public override bool Equals(System.Object obj) | |||
{ | |||
return obj is Vector2Int && this == (Vector2Int)obj; | |||
} | |||
public override int GetHashCode() | |||
{ | |||
return x.GetHashCode() ^ y.GetHashCode(); | |||
} | |||
public static bool operator ==(Vector2Int x, Vector2Int y) | |||
{ | |||
return x.x == y.x && x.y == y.y; | |||
} | |||
public static bool operator !=(Vector2Int x, Vector2Int y) | |||
{ | |||
return !(x == y); | |||
} | |||
} |
@ -0,0 +1,11 @@ | |||
fileFormatVersion: 2 | |||
guid: 3e07fb6972ad4834d89d7b7dd378fbd1 | |||
MonoImporter: | |||
externalObjects: {} | |||
serializedVersion: 2 | |||
defaultReferences: [] | |||
executionOrder: 0 | |||
icon: {instanceID: 0} | |||
userData: | |||
assetBundleName: | |||
assetBundleVariant: |