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 | fileFormatVersion: 2 | ||||
guid: d2ef7c61cf0a63a439bf63d461541ce3 | |||||
guid: 7a8bfbd0555f21048abd1415f2c47893 | |||||
folderAsset: yes | folderAsset: yes | ||||
DefaultImporter: | DefaultImporter: | ||||
externalObjects: {} | externalObjects: {} |
@ -1,5 +1,5 @@ | |||||
fileFormatVersion: 2 | fileFormatVersion: 2 | ||||
guid: 1eba5231ebd032b4db5d58d699e0f0de | |||||
guid: 040e0c0ec80bb52409744b03671df838 | |||||
folderAsset: yes | folderAsset: yes | ||||
DefaultImporter: | DefaultImporter: | ||||
externalObjects: {} | 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: |