작업 조건 분석 기능 개발
This commit is contained in:
281
Assets/Chart And Graph/Script/DataFillers/BarDataFiller.cs
Normal file
281
Assets/Chart And Graph/Script/DataFillers/BarDataFiller.cs
Normal file
@@ -0,0 +1,281 @@
|
||||
#define Graph_And_Chart_PRO
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System;
|
||||
using ChartAndGraph;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
#if UNITY_2018_1_OR_NEWER
|
||||
using UnityEngine.Networking;
|
||||
#endif
|
||||
|
||||
public class BarDataFiller : MonoBehaviour
|
||||
{
|
||||
[Serializable]
|
||||
public enum DataType
|
||||
{
|
||||
/// <summary>
|
||||
/// each category is an array of values. each value matches a group in the bar chart
|
||||
/// </summary>
|
||||
ValueArray,
|
||||
/// <summary>
|
||||
/// each category is an object containing a named object for each group
|
||||
/// </summary>
|
||||
ObjectForEachElement,
|
||||
}
|
||||
|
||||
public enum DocumentFormat
|
||||
{
|
||||
XML,
|
||||
JSON
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class CategoryData
|
||||
{
|
||||
public bool Enabled = true;
|
||||
|
||||
[ChartFillerEditor(DataType.ValueArray)]
|
||||
[ChartFillerEditor(DataType.ObjectForEachElement)]
|
||||
public string Name;
|
||||
|
||||
/// <summary>
|
||||
/// The way the data is stored in the object
|
||||
/// </summary>
|
||||
public DataType DataType;
|
||||
|
||||
[ChartFillerEditorAttribute(DataType.ValueArray)]
|
||||
public string DataObjectName;
|
||||
}
|
||||
|
||||
public BarChart BarObject;
|
||||
/// <summary>
|
||||
/// assign a graph chart prefab that will be used to copy category data
|
||||
/// </summary>
|
||||
public BarChart CategoryPrefab;
|
||||
|
||||
public DocumentFormat Format;
|
||||
public string RemoteUrl;
|
||||
public bool FillOnStart;
|
||||
public CategoryData[] Categories = new CategoryData[0];
|
||||
|
||||
private object[] mCategoryVisualStyle;
|
||||
delegate void CategoryLoader(CategoryData data);
|
||||
private Dictionary<DataType, CategoryLoader> mLoaders;
|
||||
private ChartParser mParser;
|
||||
|
||||
static BarDataFiller()
|
||||
{
|
||||
}
|
||||
|
||||
void EnsureCreateDataTypes()
|
||||
{
|
||||
if (mLoaders != null)
|
||||
return;
|
||||
mLoaders = new Dictionary<DataType, CategoryLoader>();
|
||||
mLoaders[DataType.ValueArray] = LoadValueArray;
|
||||
mLoaders[DataType.ObjectForEachElement] = LoadObjectForEachElement;
|
||||
}
|
||||
|
||||
|
||||
private double ParseItem(string item, string format)
|
||||
{
|
||||
if (String.IsNullOrEmpty(format) || format.Equals("none", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
double outputValueDouble;
|
||||
double.TryParse(string.Format(CultureInfo.InvariantCulture, "{0}", item), NumberStyles.Any, CultureInfo.InvariantCulture, out outputValueDouble);
|
||||
return outputValueDouble;
|
||||
}
|
||||
return ChartDateUtility.DateToValue(DateTime.ParseExact(item, format, CultureInfo.InvariantCulture));
|
||||
}
|
||||
|
||||
void LoadValueArray(CategoryData data)
|
||||
{
|
||||
BarChart bar = BarObject.GetComponent<BarChart>();
|
||||
var obj = mParser.GetObject(data.DataObjectName);
|
||||
int size = mParser.GetArraySize(obj);
|
||||
if (size < 0) // this is not an array , show warning
|
||||
{
|
||||
Debug.LogWarning("DataType " + data.DataType + " does not match category " + data.Name);
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
double val = ParseItem(mParser.GetItem(obj, i),null);
|
||||
string group = bar.DataSource.GetGroupName(i);
|
||||
bar.DataSource.SetValue(data.Name, group, val);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogWarning("Data for category " + data.Name + " does not match the specified format. Ended with exception : " + e.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
void LoadObjectForEachElement(CategoryData data)
|
||||
{
|
||||
BarChart bar = BarObject.GetComponent<BarChart>();
|
||||
var obj = mParser.GetObject(data.DataObjectName);
|
||||
int size = bar.DataSource.TotalGroups;
|
||||
if (size < 0) // this is not an array , show warning
|
||||
{
|
||||
Debug.LogWarning("DataType " + data.DataType + " does not match category " + data.Name);
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
|
||||
string group = bar.DataSource.GetGroupName(i);
|
||||
var groupObj = mParser.GetChildObject(obj, group);
|
||||
|
||||
double val = ParseItem(mParser.ObjectValue(groupObj), null);
|
||||
|
||||
bar.DataSource.SetValue(data.Name, group, val);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogWarning("Data for category " + data.Name + " does not match the specified format. Ended with exception : " + e.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
void Start()
|
||||
{
|
||||
if (FillOnStart)
|
||||
Fill();
|
||||
}
|
||||
|
||||
public void Fill()
|
||||
{
|
||||
Fill(null);
|
||||
}
|
||||
|
||||
public void Fill(WWWForm postData)
|
||||
{
|
||||
StartCoroutine(GetData(postData));
|
||||
}
|
||||
|
||||
void LoadCategoryVisualStyle(BarChart bar)
|
||||
{
|
||||
var prefab = CategoryPrefab;
|
||||
if (prefab == null)
|
||||
{
|
||||
if (bar is CanvasBarChart)
|
||||
prefab = ((GameObject)Resources.Load("Chart And Graph/DefualtBarCategoryStyle2D")).GetComponent<BarChart>();
|
||||
else
|
||||
prefab = ((GameObject)Resources.Load("Chart And Graph/DefualtBarCategoryStyle3D")).GetComponent<BarChart>(); // load default
|
||||
}
|
||||
if (prefab == null)
|
||||
Debug.LogError("missing resources for bar and chart, please reimport the package");
|
||||
else
|
||||
mCategoryVisualStyle = prefab.DataSource.StoreAllCategoriesinOrder();
|
||||
}
|
||||
|
||||
public void ApplyData(string text)
|
||||
{
|
||||
BarChart bar = BarObject.GetComponent<BarChart>();
|
||||
|
||||
if (Format == DocumentFormat.JSON)
|
||||
mParser = new JsonParser(text);
|
||||
else
|
||||
mParser = new XMLParser(text);
|
||||
|
||||
LoadCategoryVisualStyle(bar);
|
||||
EnsureCreateDataTypes();
|
||||
if (mCategoryVisualStyle.Length == 0)
|
||||
{
|
||||
Debug.LogWarning("no visual styles defeind for BarDataFiller, aborting");
|
||||
return;
|
||||
}
|
||||
|
||||
if (mCategoryVisualStyle.Length < Categories.Length)
|
||||
Debug.LogWarning("not enough visual styles in BarDataFiller");
|
||||
|
||||
|
||||
for (int i = 0; i < Categories.Length; i++)
|
||||
{
|
||||
var cat = Categories[i];
|
||||
if (cat.Enabled == false)
|
||||
continue;
|
||||
int visualIndex = Math.Min(i, mCategoryVisualStyle.Length - 1);
|
||||
object visualStyle = mCategoryVisualStyle[visualIndex];
|
||||
|
||||
if (bar.DataSource.HasCategory(cat.Name))
|
||||
bar.DataSource.RemoveCategory(cat.Name);
|
||||
bar.DataSource.AddCategory(cat.Name, (Material)null);
|
||||
bar.DataSource.RestoreCategory(cat.Name, visualStyle); // set the visual style of the category to the one in the prefab
|
||||
var loader = mLoaders[cat.DataType]; // find the loader based on the data type
|
||||
loader(cat); // load the category data
|
||||
}
|
||||
}
|
||||
|
||||
#if UNITY_2018_1_OR_NEWER
|
||||
UnityWebRequest CreateRequest(WWWForm postData)
|
||||
{
|
||||
if (postData == null)
|
||||
return UnityWebRequest.Get(RemoteUrl);
|
||||
return UnityWebRequest.Post(RemoteUrl, postData);
|
||||
}
|
||||
IEnumerator GetData(WWWForm postData)
|
||||
{
|
||||
using (UnityWebRequest webRequest = CreateRequest(postData))
|
||||
{
|
||||
yield return webRequest.SendWebRequest();
|
||||
#if UNITY_2020_1_OR_NEWER
|
||||
if (webRequest.result != UnityWebRequest.Result.Success)
|
||||
#else
|
||||
if (webRequest.isNetworkError)
|
||||
#endif
|
||||
Debug.LogError("Bar Data Filler : URL request failed ," + webRequest.error);
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
string text = webRequest.downloadHandler.text;
|
||||
ApplyData(text);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError("Bar Data Filler : Invalid document format, please check your settings , with exception " + e.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
IEnumerator GetData(WWWForm postData)
|
||||
{
|
||||
WWW request;
|
||||
if (postData != null)
|
||||
{
|
||||
request = new WWW(RemoteUrl, postData);
|
||||
}
|
||||
else
|
||||
request = new WWW(RemoteUrl);
|
||||
yield return request;
|
||||
if (String.IsNullOrEmpty(request.error))
|
||||
{
|
||||
try
|
||||
{
|
||||
string text = request.text;
|
||||
ApplyData(text);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError("Bar Data Filler : Invalid document format, please check your settings , with exception " + e.ToString());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("Bar Data Filler : URL request failed ," + request.error);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
void Update()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f832567015654b44eb7bafdc06dfa832
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
398
Assets/Chart And Graph/Script/DataFillers/GraphDataFiller.cs
Normal file
398
Assets/Chart And Graph/Script/DataFillers/GraphDataFiller.cs
Normal file
@@ -0,0 +1,398 @@
|
||||
#define Graph_And_Chart_PRO
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System;
|
||||
using ChartAndGraph;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
#if UNITY_2018_1_OR_NEWER
|
||||
using UnityEngine.Networking;
|
||||
#endif
|
||||
|
||||
public class GraphDataFiller : MonoBehaviour
|
||||
{
|
||||
[Serializable]
|
||||
public enum DataType
|
||||
{
|
||||
VectorArray,
|
||||
ArrayForEachElement,
|
||||
ObjectArray,
|
||||
}
|
||||
|
||||
public enum DocumentFormat
|
||||
{
|
||||
XML,
|
||||
JSON
|
||||
}
|
||||
|
||||
public enum VectorFormat
|
||||
{
|
||||
X_Y,
|
||||
Y_X,
|
||||
X_Y_SIZE,
|
||||
Y_X_SIZE,
|
||||
SIZE_X_Y,
|
||||
SIZE_Y_X,
|
||||
X_Y_GAP_SIZE,
|
||||
Y_X_GAP_SIZE
|
||||
}
|
||||
|
||||
class VectorFormatData
|
||||
{
|
||||
public int X, Y, Size, Length;
|
||||
public VectorFormatData(int x, int y, int size, int length)
|
||||
{
|
||||
X = x;
|
||||
Y = y;
|
||||
Size = size;
|
||||
Length = length;
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class CategoryData
|
||||
{
|
||||
public bool Enabled = true;
|
||||
|
||||
[ChartFillerEditor(DataType.ObjectArray)]
|
||||
[ChartFillerEditor(DataType.ArrayForEachElement)]
|
||||
[ChartFillerEditorAttribute(DataType.VectorArray)]
|
||||
public string Name;
|
||||
|
||||
/// <summary>
|
||||
/// The way the data is stored in the object
|
||||
/// </summary>
|
||||
public DataType DataType;
|
||||
|
||||
[ChartFillerEditorAttribute(DataType.VectorArray)]
|
||||
public VectorFormat DataFormat;
|
||||
|
||||
/// <summary>
|
||||
/// the amount of items to skip after each dataformat instance
|
||||
/// </summary>
|
||||
[ChartFillerEditorAttribute(DataType.VectorArray)]
|
||||
public int Skip = 0;
|
||||
|
||||
/// <summary>
|
||||
/// if this is empty then DataObjectName is not relative
|
||||
/// </summary>
|
||||
[ChartFillerEditor(DataType.ObjectArray)]
|
||||
[ChartFillerEditor(DataType.ArrayForEachElement)]
|
||||
public string ParentObjectName;
|
||||
|
||||
[ChartFillerEditorAttribute(DataType.VectorArray)]
|
||||
public string DataObjectName;
|
||||
|
||||
|
||||
[ChartFillerEditor(DataType.ObjectArray)]
|
||||
[ChartFillerEditor(DataType.ArrayForEachElement)]
|
||||
public string XDataObjectName;
|
||||
|
||||
[ChartFillerEditor(DataType.ObjectArray)]
|
||||
[ChartFillerEditor(DataType.ArrayForEachElement)]
|
||||
public string YDataObjectName;
|
||||
|
||||
[ChartFillerEditor(DataType.ObjectArray)]
|
||||
[ChartFillerEditor(DataType.ArrayForEachElement)]
|
||||
public string SizeDataObjectName;
|
||||
|
||||
/// <summary>
|
||||
/// set to empty null or "none" for numbers. Set to a date format for a date : https://docs.microsoft.com/en-us/dotnet/standard/base-types/custom-date-and-time-format-strings
|
||||
/// </summary>
|
||||
[ChartFillerEditor(DataType.ObjectArray)]
|
||||
[ChartFillerEditor(DataType.ArrayForEachElement)]
|
||||
public string XDateFormat = "";
|
||||
|
||||
[ChartFillerEditor(DataType.ObjectArray)]
|
||||
[ChartFillerEditor(DataType.ArrayForEachElement)]
|
||||
public string YDateFormat = "";
|
||||
|
||||
}
|
||||
|
||||
public GraphChartBase GraphObject;
|
||||
/// <summary>
|
||||
/// assign a graph chart prefab that will be used to copy category data
|
||||
/// </summary>
|
||||
public GraphChartBase CategoryPrefab;
|
||||
|
||||
public DocumentFormat Format;
|
||||
public string RemoteUrl;
|
||||
public bool FillOnStart;
|
||||
public CategoryData[] Categories = new CategoryData[0];
|
||||
|
||||
private object[] mCategoryVisualStyle;
|
||||
delegate void CategoryLoader(CategoryData data);
|
||||
private Dictionary<DataType, CategoryLoader> mLoaders;
|
||||
private static Dictionary<VectorFormat, VectorFormatData> mVectorFormats;
|
||||
private ChartParser mParser;
|
||||
|
||||
static GraphDataFiller()
|
||||
{
|
||||
CreateVectorFormats();
|
||||
}
|
||||
|
||||
void EnsureCreateDataTypes()
|
||||
{
|
||||
if (mLoaders != null)
|
||||
return;
|
||||
mLoaders = new Dictionary<DataType, CategoryLoader>();
|
||||
mLoaders[DataType.ArrayForEachElement] = LoadArrayForEachElement;
|
||||
mLoaders[DataType.ObjectArray] = LoadObjectArray;
|
||||
mLoaders[DataType.VectorArray] = LoadVectorArray;
|
||||
}
|
||||
|
||||
static void CreateVectorFormats()
|
||||
{
|
||||
mVectorFormats = new Dictionary<VectorFormat, VectorFormatData>();
|
||||
mVectorFormats[VectorFormat.X_Y] = new VectorFormatData(0, 1, -1, 2);
|
||||
mVectorFormats[VectorFormat.Y_X] = new VectorFormatData(1, 0, -1, 2);
|
||||
mVectorFormats[VectorFormat.X_Y_SIZE] = new VectorFormatData(0, 1, 2, 3);
|
||||
mVectorFormats[VectorFormat.Y_X_SIZE] = new VectorFormatData(1, 0, 2, 3);
|
||||
mVectorFormats[VectorFormat.SIZE_X_Y] = new VectorFormatData(1, 2, 0, 3);
|
||||
mVectorFormats[VectorFormat.SIZE_Y_X] = new VectorFormatData(2, 1, 0, 3);
|
||||
mVectorFormats[VectorFormat.X_Y_GAP_SIZE] = new VectorFormatData(0, 1, 3, 4);
|
||||
mVectorFormats[VectorFormat.Y_X_GAP_SIZE] = new VectorFormatData(1, 0, 3, 4);
|
||||
}
|
||||
|
||||
private double ParseItem(string item, string format)
|
||||
{
|
||||
if (String.IsNullOrEmpty(format) || format.Equals("none", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
double outputValueDouble;
|
||||
double.TryParse(string.Format(CultureInfo.InvariantCulture, "{0}", item), NumberStyles.Any, CultureInfo.InvariantCulture, out outputValueDouble);
|
||||
return outputValueDouble;
|
||||
}
|
||||
return ChartDateUtility.DateToValue(DateTime.ParseExact(item, format, CultureInfo.InvariantCulture));
|
||||
}
|
||||
|
||||
void LoadArrayForEachElement(CategoryData data)
|
||||
{
|
||||
GraphChartBase graph = GraphObject.GetComponent<GraphChartBase>();
|
||||
if (mParser.SetPathRelativeTo(data.ParentObjectName) == false)
|
||||
{
|
||||
Debug.LogWarning("Object " + data.ParentObjectName + " does not exist in the document");
|
||||
return;
|
||||
}
|
||||
var xObj = mParser.GetObject(data.XDataObjectName);
|
||||
var yObj = mParser.GetObject(data.YDataObjectName);
|
||||
object sizeObj = null;
|
||||
if (String.IsNullOrEmpty(data.SizeDataObjectName) == false)
|
||||
sizeObj = mParser.GetObject(data.SizeDataObjectName);
|
||||
int length = Math.Min(mParser.GetArraySize(xObj), mParser.GetArraySize(yObj));
|
||||
if (sizeObj != null)
|
||||
length = Math.Min(length, mParser.GetArraySize(sizeObj));
|
||||
try
|
||||
{
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
double x = ParseItem(mParser.GetItem(xObj, i), data.XDateFormat);
|
||||
double y = ParseItem(mParser.GetItem(yObj, i), data.YDateFormat);
|
||||
double pointSize = -1;
|
||||
if (sizeObj != null)
|
||||
pointSize = double.Parse(mParser.GetItem(sizeObj, i));
|
||||
graph.DataSource.AddPointToCategory(data.Name, x, y, pointSize);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogWarning("Data for category " + data.Name + " does not match the specified format. Ended with exception : " + e.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
void LoadObjectArray(CategoryData data)
|
||||
{
|
||||
GraphChartBase graph = GraphObject.GetComponent<GraphChartBase>();
|
||||
var parent = mParser.GetObject(data.ParentObjectName);
|
||||
if (parent == null)
|
||||
{
|
||||
Debug.LogWarning("Object " + data.ParentObjectName + " does not exist in the document");
|
||||
return;
|
||||
}
|
||||
|
||||
int length = mParser.GetArraySize(parent);
|
||||
try
|
||||
{
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
object item = mParser.GetItemObject(parent, i);
|
||||
double x = ParseItem(mParser.GetChildObjectValue(item, data.XDataObjectName), data.XDateFormat);
|
||||
double y = ParseItem(mParser.GetChildObjectValue(item, data.YDataObjectName), data.YDateFormat);
|
||||
double pointSize = -1;
|
||||
if (String.IsNullOrEmpty(data.SizeDataObjectName) == false)
|
||||
pointSize = double.Parse(mParser.GetChildObjectValue(item, data.SizeDataObjectName));
|
||||
graph.DataSource.AddPointToCategory(data.Name, x, y, pointSize);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogWarning("Data for category " + data.Name + " does not match the specified format. Ended with exception : " + e.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
void LoadVectorArray(CategoryData data)
|
||||
{
|
||||
GraphChartBase graph = GraphObject.GetComponent<GraphChartBase>();
|
||||
var obj = mParser.GetObject(data.DataObjectName);
|
||||
int size = mParser.GetArraySize(obj);
|
||||
VectorFormatData formatData = mVectorFormats[data.DataFormat];
|
||||
if (size < 0) // this is not an array , show warning
|
||||
{
|
||||
Debug.LogWarning("DataType " + data.DataType + " does not match category " + data.Name);
|
||||
return;
|
||||
}
|
||||
int itemLength = data.Skip + formatData.Length;
|
||||
try
|
||||
{
|
||||
for (int i = 0; i < size; i += itemLength)
|
||||
{
|
||||
double x = ParseItem(mParser.GetItem(obj, i + formatData.X), data.XDateFormat);
|
||||
double y = ParseItem(mParser.GetItem(obj, i + formatData.Y), data.YDateFormat);
|
||||
double pointSize = -1;
|
||||
if (formatData.Size >= 0)
|
||||
pointSize = double.Parse(mParser.GetItem(obj, i + formatData.Size));
|
||||
graph.DataSource.AddPointToCategory(data.Name, x, y, pointSize);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogWarning("Data for category " + data.Name + " does not match the specified format. Ended with exception : " + e.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
void Start()
|
||||
{
|
||||
if (FillOnStart)
|
||||
Fill();
|
||||
}
|
||||
|
||||
public void Fill()
|
||||
{
|
||||
Fill(null);
|
||||
}
|
||||
|
||||
public void Fill(WWWForm postData)
|
||||
{
|
||||
StartCoroutine(GetData(postData));
|
||||
}
|
||||
|
||||
void LoadCategoryVisualStyle(GraphChartBase graph)
|
||||
{
|
||||
var prefab = CategoryPrefab;
|
||||
if (prefab == null)
|
||||
{
|
||||
if (graph is GraphChart)
|
||||
prefab = ((GameObject)Resources.Load("Chart And Graph/DefualtGraphCategoryStyle2D")).GetComponent<GraphChartBase>();
|
||||
else
|
||||
prefab = ((GameObject)Resources.Load("Chart And Graph/DefualtGraphCategoryStyle3D")).GetComponent<GraphChartBase>(); // load default
|
||||
}
|
||||
if (prefab == null)
|
||||
Debug.LogError("missing resources for graph and chart, please reimport the package");
|
||||
else
|
||||
mCategoryVisualStyle = prefab.DataSource.StoreAllCategoriesinOrder();
|
||||
}
|
||||
|
||||
public void ApplyData(string text)
|
||||
{
|
||||
GraphChartBase graph = GraphObject.GetComponent<GraphChartBase>();
|
||||
|
||||
if (Format == DocumentFormat.JSON)
|
||||
mParser = new JsonParser(text);
|
||||
else
|
||||
mParser = new XMLParser(text);
|
||||
|
||||
LoadCategoryVisualStyle(graph);
|
||||
EnsureCreateDataTypes();
|
||||
if (mCategoryVisualStyle.Length == 0)
|
||||
{
|
||||
Debug.LogWarning("no visual styles defeind for GraphDataFiller, aborting");
|
||||
return;
|
||||
}
|
||||
|
||||
if (mCategoryVisualStyle.Length < Categories.Length)
|
||||
Debug.LogWarning("not enough visual styles in GraphDataFiller");
|
||||
|
||||
|
||||
graph.DataSource.StartBatch();
|
||||
for (int i = 0; i < Categories.Length; i++)
|
||||
{
|
||||
var cat = Categories[i];
|
||||
if (cat.Enabled == false)
|
||||
continue;
|
||||
int visualIndex = Math.Min(i, mCategoryVisualStyle.Length - 1);
|
||||
object visualStyle = mCategoryVisualStyle[visualIndex];
|
||||
|
||||
if (graph.DataSource.HasCategory(cat.Name))
|
||||
graph.DataSource.RemoveCategory(cat.Name);
|
||||
graph.DataSource.AddCategory(cat.Name, null, 0, new MaterialTiling(), null, false, null, 0);
|
||||
graph.DataSource.RestoreCategory(cat.Name, visualStyle); // set the visual style of the category to the one in the prefab
|
||||
var loader = mLoaders[cat.DataType]; // find the loader based on the data type
|
||||
loader(cat); // load the category data
|
||||
}
|
||||
graph.DataSource.EndBatch();
|
||||
}
|
||||
#if UNITY_2018_1_OR_NEWER
|
||||
UnityWebRequest CreateRequest(WWWForm postData)
|
||||
{
|
||||
if (postData == null)
|
||||
return UnityWebRequest.Get(RemoteUrl);
|
||||
return UnityWebRequest.Post(RemoteUrl, postData);
|
||||
}
|
||||
IEnumerator GetData(WWWForm postData)
|
||||
{
|
||||
using (UnityWebRequest webRequest = CreateRequest(postData))
|
||||
{
|
||||
yield return webRequest.SendWebRequest();
|
||||
#if UNITY_2020_1_OR_NEWER
|
||||
if (webRequest.result != UnityWebRequest.Result.Success)
|
||||
#else
|
||||
if (webRequest.isNetworkError)
|
||||
#endif
|
||||
Debug.LogError("Graph Data Filler : URL request failed ," + webRequest.error);
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
string text = webRequest.downloadHandler.text;
|
||||
ApplyData(text);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError("Graph Data Filler : Invalid document format, please check your settings , with exception " + e.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
IEnumerator GetData(WWWForm postData)
|
||||
{
|
||||
WWW request;
|
||||
if (postData != null)
|
||||
{
|
||||
request = new WWW(RemoteUrl, postData);
|
||||
}
|
||||
else
|
||||
request = new WWW(RemoteUrl);
|
||||
yield return request;
|
||||
if (String.IsNullOrEmpty(request.error))
|
||||
{
|
||||
try
|
||||
{
|
||||
string text = request.text;
|
||||
ApplyData(text);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError("Graph Data Filler : Invalid document format, please check your settings , with exception " + e.ToString());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("Graph Data Filler : URL request failed ," + request.error);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
void Update()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0877e747df2911349aaa842a2b45718c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
222
Assets/Chart And Graph/Script/DataFillers/PieDataFiller.cs
Normal file
222
Assets/Chart And Graph/Script/DataFillers/PieDataFiller.cs
Normal file
@@ -0,0 +1,222 @@
|
||||
#define Graph_And_Chart_PRO
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System;
|
||||
using ChartAndGraph;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
#if UNITY_2018_1_OR_NEWER
|
||||
using UnityEngine.Networking;
|
||||
#endif
|
||||
|
||||
public class PieDataFiller : MonoBehaviour
|
||||
{
|
||||
[Serializable]
|
||||
public enum DataType
|
||||
{
|
||||
/// <summary>
|
||||
/// Parent object is an array where each value matches a category that is already in the pie chart
|
||||
/// </summary>
|
||||
ValueArray,
|
||||
/// <summary>
|
||||
/// each category is an object containing a named object for each group. the pie chart is cleared and all categories are added
|
||||
/// </summary>
|
||||
ObjectForEachElement,
|
||||
}
|
||||
|
||||
public enum DocumentFormat
|
||||
{
|
||||
XML,
|
||||
JSON
|
||||
}
|
||||
|
||||
public PieChart PieObject;
|
||||
/// <summary>
|
||||
/// assign a graph chart prefab that will be used to copy category data
|
||||
/// </summary>
|
||||
public PieChart CategoryPrefab;
|
||||
|
||||
public DocumentFormat Format;
|
||||
public string RemoteUrl;
|
||||
public bool FillOnStart;
|
||||
|
||||
public string ParentObject;
|
||||
public DataType DataStructure;
|
||||
|
||||
private object[] mCategoryVisualStyle;
|
||||
|
||||
private ChartParser mParser;
|
||||
|
||||
static PieDataFiller()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
private double ParseItem(string item, string format)
|
||||
{
|
||||
if (String.IsNullOrEmpty(format) || format.Equals("none", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
double outputValueDouble;
|
||||
double.TryParse(string.Format(CultureInfo.InvariantCulture, "{0}", item), NumberStyles.Any, CultureInfo.InvariantCulture, out outputValueDouble);
|
||||
return outputValueDouble;
|
||||
}
|
||||
return ChartDateUtility.DateToValue(DateTime.ParseExact(item, format, CultureInfo.InvariantCulture));
|
||||
}
|
||||
|
||||
|
||||
void LoadObjectforEachElement()
|
||||
{
|
||||
PieChart pie = PieObject.GetComponent<PieChart>();
|
||||
var obj = mParser.GetObject(ParentObject);
|
||||
|
||||
pie.DataSource.Clear();
|
||||
int i = 0;
|
||||
foreach(var pair in mParser.GetAllChildObjects(obj))
|
||||
{
|
||||
int visualIndex = Math.Min(i, mCategoryVisualStyle.Length - 1);
|
||||
object visualStyle = mCategoryVisualStyle[visualIndex];
|
||||
pie.DataSource.AddCategory(pair.Key, null);
|
||||
pie.DataSource.RestoreCategory(pair.Key, visualStyle);
|
||||
double val = ParseItem(mParser.ObjectValue(pair.Value), null);
|
||||
pie.DataSource.SetValue(pair.Key, val);
|
||||
i++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void LoadValueArray()
|
||||
{
|
||||
PieChart pie = PieObject.GetComponent<PieChart>();
|
||||
var obj = mParser.GetObject(ParentObject);
|
||||
int size = mParser.GetArraySize(obj);
|
||||
; for (int i = 0; i < size; i++)
|
||||
{
|
||||
|
||||
double val = ParseItem(mParser.GetItem(obj, i), null);
|
||||
string category = pie.DataSource.GetCategoryName(i);
|
||||
pie.DataSource.SetValue(category, val);
|
||||
}
|
||||
}
|
||||
|
||||
void Start()
|
||||
{
|
||||
if (FillOnStart)
|
||||
Fill();
|
||||
}
|
||||
|
||||
public void Fill()
|
||||
{
|
||||
Fill(null);
|
||||
}
|
||||
|
||||
public void Fill(WWWForm postData)
|
||||
{
|
||||
StartCoroutine(GetData(postData));
|
||||
}
|
||||
|
||||
void LoadCategoryVisualStyle(PieChart bar)
|
||||
{
|
||||
var prefab = CategoryPrefab;
|
||||
if (prefab == null)
|
||||
{
|
||||
if (bar is CanvasPieChart)
|
||||
prefab = ((GameObject)Resources.Load("Chart And Graph/DefualtPieCategoryStyle2D")).GetComponent<PieChart>();
|
||||
else
|
||||
prefab = ((GameObject)Resources.Load("Chart And Graph/DefualtPieCategoryStyle3D")).GetComponent<PieChart>(); // load default
|
||||
}
|
||||
if (prefab == null)
|
||||
Debug.LogError("missing resources for graph and chart, please reimport the package");
|
||||
else
|
||||
mCategoryVisualStyle = prefab.DataSource.StoreAllCategoriesinOrder();
|
||||
}
|
||||
|
||||
public void ApplyData(string text)
|
||||
{
|
||||
|
||||
PieChart pie = PieObject.GetComponent<PieChart>();
|
||||
|
||||
if (Format == DocumentFormat.JSON)
|
||||
mParser = new JsonParser(text);
|
||||
else
|
||||
mParser = new XMLParser(text);
|
||||
|
||||
LoadCategoryVisualStyle(pie);
|
||||
if (mCategoryVisualStyle.Length == 0)
|
||||
{
|
||||
Debug.LogWarning("no visual styles defeind for BarDataFiller, aborting");
|
||||
return;
|
||||
}
|
||||
|
||||
if (DataStructure == DataType.ValueArray)
|
||||
LoadValueArray();
|
||||
else
|
||||
LoadObjectforEachElement();
|
||||
|
||||
}
|
||||
|
||||
#if UNITY_2018_1_OR_NEWER
|
||||
UnityWebRequest CreateRequest(WWWForm postData)
|
||||
{
|
||||
if (postData == null)
|
||||
return UnityWebRequest.Get(RemoteUrl);
|
||||
return UnityWebRequest.Post(RemoteUrl, postData);
|
||||
}
|
||||
IEnumerator GetData(WWWForm postData)
|
||||
{
|
||||
using (UnityWebRequest webRequest = CreateRequest(postData))
|
||||
{
|
||||
yield return webRequest.SendWebRequest();
|
||||
#if UNITY_2020_1_OR_NEWER
|
||||
if (webRequest.result != UnityWebRequest.Result.Success)
|
||||
#else
|
||||
if (webRequest.isNetworkError)
|
||||
#endif
|
||||
Debug.LogError("Bar Data Filler : URL request failed ," + webRequest.error);
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
string text = webRequest.downloadHandler.text;
|
||||
ApplyData(text);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError("Bar Data Filler : Invalid document format, please check your settings , with exception " + e.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
IEnumerator GetData(WWWForm postData)
|
||||
{
|
||||
WWW request;
|
||||
if (postData != null)
|
||||
{
|
||||
request = new WWW(RemoteUrl, postData);
|
||||
}
|
||||
else
|
||||
request = new WWW(RemoteUrl);
|
||||
yield return request;
|
||||
if (String.IsNullOrEmpty(request.error))
|
||||
{
|
||||
try
|
||||
{
|
||||
string text = request.text;
|
||||
ApplyData(text);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError("Pie Data Filler : Invalid document format, please check your settings , with exception " + e.ToString());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("Pie Data Filler : URL request failed ," + request.error);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
void Update()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4a7063dbdd24df344938eb0ef3bfe6b7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
281
Assets/Chart And Graph/Script/DataFillers/RadarDataFiller.cs
Normal file
281
Assets/Chart And Graph/Script/DataFillers/RadarDataFiller.cs
Normal file
@@ -0,0 +1,281 @@
|
||||
#define Graph_And_Chart_PRO
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System;
|
||||
using ChartAndGraph;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
#if UNITY_2018_1_OR_NEWER
|
||||
using UnityEngine.Networking;
|
||||
#endif
|
||||
|
||||
public class RadarDataFiller : MonoBehaviour
|
||||
{
|
||||
[Serializable]
|
||||
public enum DataType
|
||||
{
|
||||
/// <summary>
|
||||
/// each category is an array of values. each value matches a group in the radar chart
|
||||
/// </summary>
|
||||
ValueArray,
|
||||
/// <summary>
|
||||
/// each category is an object containing a named object for each group
|
||||
/// </summary>
|
||||
ObjectForEachElement,
|
||||
}
|
||||
|
||||
public enum DocumentFormat
|
||||
{
|
||||
XML,
|
||||
JSON
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class CategoryData
|
||||
{
|
||||
public bool Enabled = true;
|
||||
|
||||
[ChartFillerEditor(DataType.ValueArray)]
|
||||
[ChartFillerEditor(DataType.ObjectForEachElement)]
|
||||
public string Name;
|
||||
|
||||
/// <summary>
|
||||
/// The way the data is stored in the object
|
||||
/// </summary>
|
||||
public DataType DataType;
|
||||
|
||||
[ChartFillerEditorAttribute(DataType.ValueArray)]
|
||||
public string DataObjectName;
|
||||
}
|
||||
|
||||
public RadarChart RadarObject;
|
||||
/// <summary>
|
||||
/// assign a radar chart prefab that will be used to copy category data
|
||||
/// </summary>
|
||||
public RadarChart CategoryPrefab;
|
||||
|
||||
public DocumentFormat Format;
|
||||
public string RemoteUrl;
|
||||
public bool FillOnStart;
|
||||
public CategoryData[] Categories = new CategoryData[0];
|
||||
|
||||
private object[] mCategoryVisualStyle;
|
||||
delegate void CategoryLoader(CategoryData data);
|
||||
private Dictionary<DataType, CategoryLoader> mLoaders;
|
||||
private ChartParser mParser;
|
||||
|
||||
static RadarDataFiller()
|
||||
{
|
||||
}
|
||||
|
||||
void EnsureCreateDataTypes()
|
||||
{
|
||||
if (mLoaders != null)
|
||||
return;
|
||||
mLoaders = new Dictionary<DataType, CategoryLoader>();
|
||||
mLoaders[DataType.ValueArray] = LoadValueArray;
|
||||
mLoaders[DataType.ObjectForEachElement] = LoadObjectForEachElement;
|
||||
}
|
||||
|
||||
|
||||
private double ParseItem(string item, string format)
|
||||
{
|
||||
if (String.IsNullOrEmpty(format) || format.Equals("none", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
double outputValueDouble;
|
||||
double.TryParse(string.Format(CultureInfo.InvariantCulture, "{0}", item), NumberStyles.Any, CultureInfo.InvariantCulture, out outputValueDouble);
|
||||
return outputValueDouble;
|
||||
}
|
||||
return ChartDateUtility.DateToValue(DateTime.ParseExact(item, format, CultureInfo.InvariantCulture));
|
||||
}
|
||||
|
||||
void LoadValueArray(CategoryData data)
|
||||
{
|
||||
RadarChart radar = RadarObject.GetComponent<RadarChart>();
|
||||
var obj = mParser.GetObject(data.DataObjectName);
|
||||
int size = mParser.GetArraySize(obj);
|
||||
if (size < 0) // this is not an array , show warning
|
||||
{
|
||||
Debug.LogWarning("DataType " + data.DataType + " does not match category " + data.Name);
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
double val = ParseItem(mParser.GetItem(obj, i),null);
|
||||
string group = radar.DataSource.GetGroupName(i);
|
||||
radar.DataSource.SetValue(data.Name, group, val);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogWarning("Data for category " + data.Name + " does not match the specified format. Ended with exception : " + e.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
void LoadObjectForEachElement(CategoryData data)
|
||||
{
|
||||
RadarChart radar = RadarObject.GetComponent<RadarChart>();
|
||||
var obj = mParser.GetObject(data.DataObjectName);
|
||||
int size = radar.DataSource.TotalGroups;
|
||||
if (size < 0) // this is not an array , show warning
|
||||
{
|
||||
Debug.LogWarning("DataType " + data.DataType + " does not match category " + data.Name);
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
|
||||
string group = radar.DataSource.GetGroupName(i);
|
||||
var groupObj = mParser.GetChildObject(obj, group);
|
||||
|
||||
double val = ParseItem(mParser.ObjectValue(groupObj), null);
|
||||
|
||||
radar.DataSource.SetValue(data.Name, group, val);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogWarning("Data for category " + data.Name + " does not match the specified format. Ended with exception : " + e.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
void Start()
|
||||
{
|
||||
if (FillOnStart)
|
||||
Fill();
|
||||
}
|
||||
|
||||
public void Fill()
|
||||
{
|
||||
Fill(null);
|
||||
}
|
||||
|
||||
public void Fill(WWWForm postData)
|
||||
{
|
||||
StartCoroutine(GetData(postData));
|
||||
}
|
||||
|
||||
void LoadCategoryVisualStyle(RadarChart radar)
|
||||
{
|
||||
var prefab = CategoryPrefab;
|
||||
if (prefab == null)
|
||||
{
|
||||
if (radar is CanvasRadarChart)
|
||||
prefab = ((GameObject)Resources.Load("Chart And Graph/DefualtRadarCategoryStyle2D")).GetComponent<RadarChart>();
|
||||
else
|
||||
prefab = ((GameObject)Resources.Load("Chart And Graph/DefualtRadarCategoryStyle3D")).GetComponent<RadarChart>(); // load default
|
||||
}
|
||||
if (prefab == null)
|
||||
Debug.LogError("missing resources for graph and chart, please reimport the package");
|
||||
else
|
||||
mCategoryVisualStyle = prefab.DataSource.StoreAllCategoriesinOrder();
|
||||
}
|
||||
|
||||
public void ApplyData(string text)
|
||||
{
|
||||
RadarChart radar = RadarObject.GetComponent<RadarChart>();
|
||||
|
||||
if (Format == DocumentFormat.JSON)
|
||||
mParser = new JsonParser(text);
|
||||
else
|
||||
mParser = new XMLParser(text);
|
||||
|
||||
LoadCategoryVisualStyle(radar);
|
||||
EnsureCreateDataTypes();
|
||||
if (mCategoryVisualStyle.Length == 0)
|
||||
{
|
||||
Debug.LogWarning("no visual styles defeind for RadarDataFiller, aborting");
|
||||
return;
|
||||
}
|
||||
|
||||
if (mCategoryVisualStyle.Length < Categories.Length)
|
||||
Debug.LogWarning("not enough visual styles in RadarDataFiller");
|
||||
|
||||
|
||||
for (int i = 0; i < Categories.Length; i++)
|
||||
{
|
||||
var cat = Categories[i];
|
||||
if (cat.Enabled == false)
|
||||
continue;
|
||||
int visualIndex = Math.Min(i, mCategoryVisualStyle.Length - 1);
|
||||
object visualStyle = mCategoryVisualStyle[visualIndex];
|
||||
|
||||
if (radar.DataSource.HasCategory(cat.Name))
|
||||
radar.DataSource.RemoveCategory(cat.Name);
|
||||
radar.DataSource.AddCategory(cat.Name,null,null,1f,null,null,0,null);
|
||||
radar.DataSource.RestoreCategory(cat.Name, visualStyle); // set the visual style of the category to the one in the prefab
|
||||
var loader = mLoaders[cat.DataType]; // find the loader based on the data type
|
||||
loader(cat); // load the category data
|
||||
}
|
||||
}
|
||||
|
||||
#if UNITY_2018_1_OR_NEWER
|
||||
UnityWebRequest CreateRequest(WWWForm postData)
|
||||
{
|
||||
if (postData == null)
|
||||
return UnityWebRequest.Get(RemoteUrl);
|
||||
return UnityWebRequest.Post(RemoteUrl, postData);
|
||||
}
|
||||
IEnumerator GetData(WWWForm postData)
|
||||
{
|
||||
using (UnityWebRequest webRequest = CreateRequest(postData))
|
||||
{
|
||||
yield return webRequest.SendWebRequest();
|
||||
#if UNITY_2020_1_OR_NEWER
|
||||
if (webRequest.result != UnityWebRequest.Result.Success)
|
||||
#else
|
||||
if (webRequest.isNetworkError)
|
||||
#endif
|
||||
Debug.LogError("Radar Data Filler : URL request failed ," + webRequest.error);
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
string text = webRequest.downloadHandler.text;
|
||||
ApplyData(text);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError("Radar Data Filler : Invalid document format, please check your settings , with exception " + e.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
IEnumerator GetData(WWWForm postData)
|
||||
{
|
||||
WWW request;
|
||||
if (postData != null)
|
||||
{
|
||||
request = new WWW(RemoteUrl, postData);
|
||||
}
|
||||
else
|
||||
request = new WWW(RemoteUrl);
|
||||
yield return request;
|
||||
if (String.IsNullOrEmpty(request.error))
|
||||
{
|
||||
try
|
||||
{
|
||||
string text = request.text;
|
||||
ApplyData(text);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError("Radar Data Filler : Invalid document format, please check your settings , with exception " + e.ToString());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("Radar Data Filler : URL request failed ," + request.error);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
void Update()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1d63445d9b0dae5428bc3b2c57583920
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user