You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1604 lines
48 KiB
1604 lines
48 KiB
using System;
|
|
using UnityEngine.SceneManagement;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Reflection;
|
|
using UnityEngine;
|
|
using Newtonsoft.Json;
|
|
using UnityEngine.UI;
|
|
using UltraCombos;
|
|
using ListOfRectTrans = System.Collections.Generic.List<UnityEngine.RectTransform>;
|
|
|
|
using MapOfGroup = System.Collections.Generic.Dictionary<string, System.Collections.Generic.List<UnityEngine.RectTransform>>;
|
|
using MapOfBindInfo = System.Collections.Generic.Dictionary<string, AutoUIManager.BindInfo >;
|
|
|
|
public class AutoUIManager : Singleton<AutoUIManager>, ISerializationCallbackReceiver
|
|
{
|
|
List<Parameterizable> parameters;
|
|
|
|
bool show = false;
|
|
public bool Show { get { return show; } }
|
|
private DirectoryInfo root;
|
|
public string filename = "settings";
|
|
|
|
Transform template_trans;
|
|
RectTransform scrollView;
|
|
RectTransform layoutRoot;
|
|
List<ListOfRectTrans> layout_groups = new List<ListOfRectTrans>();
|
|
MapOfGroup map_of_layout_group = new MapOfGroup();
|
|
|
|
List<Action> layout_actions = new List<Action>();
|
|
|
|
Dropdown preset_dropdown;
|
|
InputField preset_input;
|
|
|
|
[Serializable]
|
|
public class BindInfo
|
|
{
|
|
public string key;
|
|
public string gameobject_name;
|
|
public string component_name;
|
|
public string member_name;
|
|
public bool is_property;
|
|
public bool is_serializable;
|
|
public bool has_range;
|
|
public Vector2 minmax;
|
|
}
|
|
|
|
[SerializeField]
|
|
private List<BindInfo> bindinfos;
|
|
|
|
MapOfBindInfo map_bindinfo;
|
|
|
|
public bool AddBindInfo(Component compoment, string member_name, bool is_property, bool is_serializable, RangeAttribute range)
|
|
{
|
|
if (map_bindinfo == null)
|
|
{
|
|
map_bindinfo = new MapOfBindInfo();
|
|
}
|
|
|
|
string key = GetUniqueKey(compoment, member_name);
|
|
if (map_bindinfo.ContainsKey(key))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
BindInfo info = new BindInfo();
|
|
info.key = key;
|
|
info.gameobject_name = compoment.gameObject.name;
|
|
info.component_name = compoment.GetType().FullName.Replace("UnityEngine.", "");
|
|
info.member_name = member_name;
|
|
info.is_property = is_property;
|
|
info.is_serializable = is_serializable;
|
|
if (range == null)
|
|
{
|
|
info.has_range = false;
|
|
}
|
|
else
|
|
{
|
|
info.has_range = true;
|
|
info.minmax.x = range.min;
|
|
info.minmax.y = range.max;
|
|
}
|
|
|
|
map_bindinfo.Add(key, info);
|
|
return true;
|
|
}
|
|
|
|
public void RemoveBindInfo(Component compoment, string member_name)
|
|
{
|
|
if (map_bindinfo == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
string key = GetUniqueKey(compoment, member_name);
|
|
map_bindinfo.Remove(key);
|
|
}
|
|
|
|
public IEnumerable<BindInfo> GetBindInfos()
|
|
{
|
|
if (map_bindinfo != null)
|
|
{
|
|
return map_bindinfo.Values;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public bool TryGetBindInfo(string key, out BindInfo bind_info)
|
|
{
|
|
if (map_bindinfo == null)
|
|
{
|
|
bind_info = null;
|
|
return false;
|
|
}
|
|
|
|
return map_bindinfo.TryGetValue(key, out bind_info);
|
|
}
|
|
|
|
public bool TryGetBindInfo(Component compoment, string member_name, out BindInfo bind_info)
|
|
{
|
|
if (map_bindinfo == null)
|
|
{
|
|
bind_info = null;
|
|
return false;
|
|
}
|
|
|
|
string key = GetUniqueKey(compoment, member_name);
|
|
return map_bindinfo.TryGetValue(key, out bind_info);
|
|
}
|
|
|
|
public bool IsContainedBindInfo(string key)
|
|
{
|
|
if (map_bindinfo == null)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return map_bindinfo.ContainsKey(key);
|
|
}
|
|
|
|
public bool IsContainedBindInfo(Component compoment, string member_name)
|
|
{
|
|
if (map_bindinfo == null)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
string key = GetUniqueKey(compoment, member_name);
|
|
return map_bindinfo.ContainsKey(key);
|
|
}
|
|
|
|
void ISerializationCallbackReceiver.OnBeforeSerialize()
|
|
{
|
|
if (map_bindinfo == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (bindinfos == null)
|
|
{
|
|
bindinfos = new List<BindInfo>();
|
|
}
|
|
else
|
|
{
|
|
bindinfos.Clear();
|
|
}
|
|
|
|
bindinfos.AddRange(map_bindinfo.Values);
|
|
}
|
|
|
|
void ISerializationCallbackReceiver.OnAfterDeserialize()
|
|
{
|
|
if (bindinfos == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (map_bindinfo == null)
|
|
{
|
|
map_bindinfo = new MapOfBindInfo();
|
|
}
|
|
else
|
|
{
|
|
map_bindinfo.Clear();
|
|
}
|
|
|
|
foreach (BindInfo info in bindinfos)
|
|
{
|
|
map_bindinfo.Add(info.key, info);
|
|
}
|
|
}
|
|
|
|
class CoreSetting
|
|
{
|
|
public List<string> presets = new List<string>();
|
|
public int value;
|
|
}
|
|
|
|
const string module = "<color=teal>AutoUI</color>";
|
|
|
|
string currentPresetName
|
|
{
|
|
get
|
|
{
|
|
string res = "";
|
|
if (preset_dropdown != null)
|
|
{
|
|
res = preset_dropdown.options[preset_dropdown.value].text;
|
|
res = string.Format("{0}-{1}.json", filename, res);
|
|
}
|
|
return res;
|
|
}
|
|
}
|
|
|
|
string coreSettingFilename { get { return filename + "-core.json"; } }
|
|
|
|
void mf_SetupBindInfoFromScene(Scene scene)
|
|
{
|
|
GameObject[] objs = scene.GetRootGameObjects();
|
|
foreach (BindInfo bindinfo in map_bindinfo.Values)
|
|
{
|
|
foreach (GameObject obj in objs)
|
|
{
|
|
if (obj.name != bindinfo.gameobject_name)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
Component compos = obj.GetComponent(bindinfo.component_name);
|
|
if (compos == null)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
RangeAttribute range = null;
|
|
if (bindinfo.has_range)
|
|
{
|
|
range = new RangeAttribute(bindinfo.minmax.x, bindinfo.minmax.y);
|
|
}
|
|
|
|
if (bindinfo.is_property)
|
|
{
|
|
BindProperty(compos, bindinfo.member_name, bindinfo.is_serializable, range);
|
|
}
|
|
else
|
|
{
|
|
BindField(compos, bindinfo.member_name, bindinfo.is_serializable, range);
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
#region MonoBehaviour Functions
|
|
void Start()
|
|
{
|
|
#if UNITY_EDITOR
|
|
#if UNITY_5_6_OR_NEWER
|
|
if (UnityEditor.PlayerSettings.GetApiCompatibilityLevel(UnityEditor.BuildTargetGroup.Standalone) == UnityEditor.ApiCompatibilityLevel.NET_2_0_Subset)
|
|
#else
|
|
if (UnityEditor.PlayerSettings.apiCompatibilityLevel == UnityEditor.ApiCompatibilityLevel.NET_2_0_Subset)
|
|
#endif
|
|
Misc.Verbose(module, "require Api Compatibility Level to be .NET 2.0", 2);
|
|
#endif
|
|
|
|
root = Directory.GetParent(Application.dataPath);
|
|
template_trans = transform.Find("Template");
|
|
|
|
scrollView = transform.Find("Scroll View") as RectTransform;
|
|
layoutRoot = scrollView.Find("Viewport").Find("Content") as RectTransform;
|
|
|
|
FindAttributes();
|
|
|
|
preset_input = layout_groups[0][0].GetComponentInChildren<InputField>();
|
|
preset_dropdown = layout_groups[0][0].GetComponentInChildren<Dropdown>();
|
|
preset_dropdown.ClearOptions();
|
|
|
|
if (map_bindinfo != null && map_bindinfo.Count > 0)
|
|
{
|
|
mf_SetupBindInfoFromScene(SceneManager.GetActiveScene());
|
|
|
|
//Scene scene = SceneManager.GetSceneByName("DontDestroyOnLoad");
|
|
//if (scene != null)
|
|
//{
|
|
// mf_SetupBindInfoFromScene(scene);
|
|
//}
|
|
}
|
|
|
|
var data_list = new List<Dropdown.OptionData>();
|
|
|
|
string path = Path.Combine(root.FullName, coreSettingFilename);
|
|
if (File.Exists(path))
|
|
{
|
|
var sr = File.OpenText(path);
|
|
var json = sr.ReadToEnd();
|
|
sr.Close();
|
|
|
|
var cs = JsonUtility.FromJson<CoreSetting>(json);
|
|
foreach (var preset in cs.presets)
|
|
{
|
|
var option_data = new Dropdown.OptionData();
|
|
option_data.text = preset;
|
|
data_list.Add(option_data);
|
|
}
|
|
preset_dropdown.options = data_list;
|
|
preset_dropdown.value = cs.value;
|
|
}
|
|
else
|
|
{
|
|
Misc.Verbose(module, "File " + coreSettingFilename + " is not found, save default settings instead.", 1);
|
|
|
|
var option_data = new Dropdown.OptionData();
|
|
option_data.text = "default";
|
|
data_list.Add(option_data);
|
|
preset_dropdown.options = data_list;
|
|
preset_dropdown.value = 0;
|
|
|
|
SaveSettings();
|
|
}
|
|
|
|
LoadSettings();
|
|
}
|
|
|
|
bool cursorVisiable = false;
|
|
void Update()
|
|
{
|
|
if (Input.GetKeyDown(KeyCode.F1))
|
|
{
|
|
if (show == false)
|
|
{
|
|
cursorVisiable = Cursor.visible;
|
|
}
|
|
else
|
|
{
|
|
Cursor.visible = cursorVisiable;
|
|
}
|
|
show = !show;
|
|
scrollView.gameObject.SetActive(show);
|
|
}
|
|
|
|
if (scrollView.gameObject.activeSelf)
|
|
{
|
|
int x = 15;
|
|
int y = 25;
|
|
int field_offset = 36;
|
|
int section_offset = 10;
|
|
for (int i = 0; i < layout_groups.Count; i++)
|
|
{
|
|
var group = layout_groups[i];
|
|
bool is_expand = group[0].GetComponentInChildren<Toggle>(true).isOn;
|
|
for (int j = 0; j < group.Count; j++)
|
|
{
|
|
group[j].anchoredPosition = new Vector2(x, -y);
|
|
// offset more for main buttons
|
|
float offset = (i == 0) ? 2.5f : 1.0f;
|
|
if (j > 0)
|
|
{
|
|
group[j].gameObject.SetActive(is_expand);
|
|
offset *= is_expand ? field_offset : 0.0f;
|
|
}
|
|
else
|
|
{
|
|
offset *= field_offset;
|
|
}
|
|
y += (int)offset;
|
|
}
|
|
y += section_offset;
|
|
}
|
|
|
|
int approx_height = y;
|
|
layoutRoot.sizeDelta = new Vector2(layoutRoot.sizeDelta.x, approx_height);
|
|
approx_height = Mathf.Min(approx_height, Screen.height);
|
|
scrollView.sizeDelta = new Vector2(scrollView.sizeDelta.x, approx_height);
|
|
|
|
foreach (var act in layout_actions)
|
|
act.Invoke();
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
public string PresetName
|
|
{
|
|
set
|
|
{
|
|
var index = preset_dropdown.options.FindIndex(
|
|
delegate (Dropdown.OptionData data)
|
|
{
|
|
return (data.text == value);
|
|
});
|
|
if (index > -1)
|
|
{
|
|
Misc.Verbose(module, "Set preset: " + value);
|
|
preset_dropdown.value = index;
|
|
LoadSettings();
|
|
}
|
|
else
|
|
{
|
|
Misc.Verbose(module, "Preset " + value + " is not exist.", 1);
|
|
}
|
|
}
|
|
get
|
|
{
|
|
return preset_dropdown.options[preset_dropdown.value].text;
|
|
}
|
|
}
|
|
|
|
public void AddPreset()
|
|
{
|
|
var option_data = new Dropdown.OptionData();
|
|
option_data.text = preset_input.text;
|
|
preset_dropdown.options.Add(option_data);
|
|
preset_input.text = "";
|
|
preset_dropdown.value = preset_dropdown.options.Count - 1;
|
|
}
|
|
|
|
public void RemovePreset()
|
|
{
|
|
if (preset_dropdown.options.Count > 1)
|
|
{
|
|
int v = preset_dropdown.value - 1;
|
|
preset_dropdown.options.RemoveAt(preset_dropdown.value);
|
|
preset_dropdown.value = v;
|
|
}
|
|
}
|
|
|
|
public void SaveSettings()
|
|
{
|
|
Misc.Verbose(module, "Save settings.");
|
|
var values = new Dictionary<string, object>();
|
|
foreach (var obj in parameters)
|
|
{
|
|
if (obj.isSerialized == false)
|
|
continue;
|
|
values[obj.path] = obj.val;
|
|
}
|
|
|
|
// save preset setting
|
|
string res = JsonConvert.SerializeObject(values, Formatting.Indented);
|
|
string path = Path.Combine(root.FullName, currentPresetName);
|
|
File.WriteAllText(path, res);
|
|
|
|
// save core setting
|
|
CoreSetting cs = new CoreSetting();
|
|
foreach (var opt in preset_dropdown.options)
|
|
cs.presets.Add(opt.text);
|
|
cs.value = preset_dropdown.value;
|
|
res = JsonUtility.ToJson(cs, true);
|
|
path = Path.Combine(root.FullName, coreSettingFilename);
|
|
File.WriteAllText(path, res);
|
|
}
|
|
|
|
public void LoadSettings()
|
|
{
|
|
string path = Path.Combine(root.FullName, currentPresetName);
|
|
if (File.Exists(path))
|
|
{
|
|
Misc.Verbose(module, "Load settings.");
|
|
var sr = File.OpenText(path);
|
|
var json = sr.ReadToEnd();
|
|
sr.Close();
|
|
JsonSerializerSettings setting = new JsonSerializerSettings();
|
|
setting.MissingMemberHandling = MissingMemberHandling.Ignore;
|
|
setting.DefaultValueHandling = DefaultValueHandling.Include;
|
|
setting.NullValueHandling = NullValueHandling.Ignore;
|
|
var res = JsonConvert.DeserializeObject<Dictionary<string, object>>(json, setting);
|
|
|
|
foreach (var obj in parameters)
|
|
{
|
|
string obj_path = obj.path;
|
|
if (res.ContainsKey(obj.path))
|
|
{
|
|
obj.val = res[obj_path];
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Misc.Verbose(module, "Could not Open the file: " + path + " for reading.", 1);
|
|
}
|
|
}
|
|
|
|
public void Close()
|
|
{
|
|
show = false;
|
|
}
|
|
|
|
public bool BindProperty(object obj, string propertyName, bool isSerialized, RangeAttribute range)
|
|
{
|
|
Component compoment = obj as Component;
|
|
if (compoment == null)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (propertyName == null || propertyName.Equals(""))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
var labelLayout = template_trans.Find("Label") as RectTransform;
|
|
ListOfRectTrans layouts;
|
|
|
|
string key = sf_GetMapKey(compoment);
|
|
bool need_to_add = false;
|
|
if (!map_of_layout_group.TryGetValue(key, out layouts))
|
|
{
|
|
layouts = new ListOfRectTrans();
|
|
need_to_add = true;
|
|
}
|
|
|
|
BindingFlags bindingFlag = BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public;
|
|
bool yes = mf_FindPropertyAndCreateParameter(labelLayout, bindingFlag, obj, propertyName, isSerialized, range, layouts);
|
|
if (!yes)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (need_to_add)
|
|
{
|
|
mf_AddLayoutsToGroups(labelLayout, layouts, key);
|
|
}
|
|
else
|
|
{
|
|
mf_UpdateLayout(layouts, key);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public bool BindField(object obj, string fieldName, bool isSerialized, RangeAttribute range)
|
|
{
|
|
Component compoment = obj as Component;
|
|
if (compoment == null)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (fieldName == null || fieldName.Equals(""))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
var labelLayout = template_trans.Find("Label") as RectTransform;
|
|
ListOfRectTrans layouts;
|
|
|
|
string key = sf_GetMapKey(compoment);
|
|
bool need_to_add = false;
|
|
if (!map_of_layout_group.TryGetValue(key, out layouts))
|
|
{
|
|
layouts = new ListOfRectTrans();
|
|
need_to_add = true;
|
|
}
|
|
|
|
BindingFlags bindingFlag = BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public;
|
|
bool yes = mf_FindFieldAndCreateParameter(labelLayout, bindingFlag, obj, fieldName, isSerialized, range, layouts);
|
|
if (!yes)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (need_to_add)
|
|
{
|
|
mf_AddLayoutsToGroups(labelLayout, layouts, key);
|
|
}
|
|
else
|
|
{
|
|
mf_UpdateLayout(layouts, key);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void FindAttributes()
|
|
{
|
|
var labelLayout = template_trans.Find("Label") as RectTransform;
|
|
var mainButtons = template_trans.Find("Main") as RectTransform;
|
|
|
|
parameters = new List<Parameterizable>();
|
|
|
|
layout_groups.Add(new List<RectTransform>() { Instantiate(mainButtons, layoutRoot) });
|
|
|
|
//var bs = Resources.FindObjectsOfTypeAll(typeof(MonoBehaviour)) as MonoBehaviour[];
|
|
var scene = UnityEngine.SceneManagement.SceneManager.GetActiveScene();
|
|
|
|
var root_objects = new List<GameObject>();
|
|
scene.GetRootGameObjects(root_objects);
|
|
root_objects.Sort(delegate (GameObject a, GameObject b)
|
|
{
|
|
return a.transform.GetSiblingIndex().CompareTo(b.transform.GetSiblingIndex());
|
|
});
|
|
|
|
foreach (var obj in root_objects)
|
|
{
|
|
var monos = obj.GetComponentsInChildren<MonoBehaviour>(true);
|
|
|
|
foreach (MonoBehaviour mono in monos)
|
|
{
|
|
// if script reference is missing, mono will be null
|
|
if (mono == null)
|
|
continue;
|
|
BindingFlags bindingFlag = BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public;
|
|
|
|
ListOfRectTrans layouts = new ListOfRectTrans();
|
|
|
|
mf_FindAttributeFromFields(labelLayout, bindingFlag, mono, layouts);
|
|
|
|
if (layouts.Count > 0)
|
|
{
|
|
mf_AddLayoutsToGroups(labelLayout, layouts, sf_GetMapKey(mono));
|
|
}
|
|
}
|
|
}
|
|
#if false // no longer need to sort parameters
|
|
// may use better sort method
|
|
parameters.Sort(delegate (ParameterInfo a, ParameterInfo b)
|
|
{
|
|
return a.index.CompareTo(b.index);
|
|
});
|
|
#endif
|
|
}
|
|
|
|
void TrySetInputField(InputField input_field, string value)
|
|
{
|
|
if (input_field.isFocused == false)
|
|
input_field.text = value;
|
|
}
|
|
|
|
public static string GetUniqueKey(Component component, string memberName)
|
|
{
|
|
return sf_GetMapKey(component) + ":" + memberName;
|
|
}
|
|
|
|
#region Private Method
|
|
|
|
private static string sf_GetMapKey(Component component)
|
|
{
|
|
var parent_names = new Stack<string>();
|
|
parent_names.Push(component.ToString());
|
|
var parent_trans = component.transform.parent;
|
|
while (parent_trans != null)
|
|
{
|
|
parent_names.Push(parent_trans.name);
|
|
parent_trans = parent_trans.parent;
|
|
}
|
|
string label_name = "";
|
|
label_name = parent_names.Peek();
|
|
parent_names.Pop();
|
|
while (parent_names.Count > 0)
|
|
{
|
|
string format = (parent_names.Count == 1) ? "{0}.[{1}]" : "{0}.{1}";
|
|
label_name = string.Format(format, label_name, parent_names.Peek());
|
|
parent_names.Pop();
|
|
}
|
|
return label_name;
|
|
}
|
|
|
|
private static AutoUIAttribute sf_CheckAutoUIAttribute(MemberInfo memberInfo)
|
|
{
|
|
foreach (object attribute in memberInfo.GetCustomAttributes(true))
|
|
{
|
|
var attr = attribute as AutoUIAttribute;
|
|
if (attr == null)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
return attr;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private void mf_AddLayoutsToGroups(RectTransform labelLayout, ListOfRectTrans layouts, string key)
|
|
{
|
|
string label_name = key;
|
|
label_name += string.Format(": {0}", layouts.Count);
|
|
|
|
var rt = Instantiate(labelLayout, layoutRoot);
|
|
var text = rt.GetComponentInChildren<Text>();
|
|
text.text = label_name;
|
|
layouts.Insert(0, rt);
|
|
|
|
layout_groups.Add(layouts);
|
|
map_of_layout_group.Add(key, layouts);
|
|
}
|
|
|
|
private void mf_UpdateLayout(ListOfRectTrans layouts, string key)
|
|
{
|
|
string label_name = key;
|
|
label_name += string.Format(": {0}", (layouts.Count - 1));
|
|
|
|
var text = layouts[0].GetComponentInChildren<Text>();
|
|
text.text = label_name;
|
|
}
|
|
|
|
private bool mf_CreateParameter<T>(T obj_info, Type obj_type, object obj, bool is_serialized, RangeAttribute range, out Parameterizable parameter, out RectTransform rt)
|
|
{
|
|
parameter = null;
|
|
rt = null;
|
|
|
|
try
|
|
{
|
|
if (obj_type.Equals(typeof(float)))
|
|
{
|
|
ParameterFloat<T> param = new ParameterFloat<T>(obj_info, obj, is_serialized, range);
|
|
rt = createFloatLayout(param);
|
|
parameter = param;
|
|
}
|
|
else if (obj_type.Equals(typeof(int)))
|
|
{
|
|
ParameterInt<T> param = new ParameterInt<T>(obj_info, obj, is_serialized, range);
|
|
rt = createIntLayout(param);
|
|
parameter = param;
|
|
}
|
|
else if (obj_type.Equals(typeof(string)))
|
|
{
|
|
ParameterString<T> param = new ParameterString<T>(obj_info, obj, is_serialized, range);
|
|
rt = createStringLayout(param);
|
|
parameter = param;
|
|
}
|
|
else if (obj_type.Equals(typeof(bool)))
|
|
{
|
|
ParameterBool<T> param = new ParameterBool<T>(obj_info, obj, is_serialized, range);
|
|
rt = createBoolLayout(param);
|
|
parameter = param;
|
|
}
|
|
else if (obj_type.Equals(typeof(Vector2)))
|
|
{
|
|
ParameterVector2<T> param = new ParameterVector2<T>(obj_info, obj, is_serialized, range);
|
|
rt = createVec2Layout(param);
|
|
parameter = param;
|
|
}
|
|
else if (obj_type.Equals(typeof(Vector3)))
|
|
{
|
|
ParameterVector3<T> param = new ParameterVector3<T>(obj_info, obj, is_serialized, range);
|
|
rt = createVec3Layout(param);
|
|
parameter = param;
|
|
}
|
|
else if (obj_type.Equals(typeof(Vector4)))
|
|
{
|
|
ParameterVector4<T> param = new ParameterVector4<T>(obj_info, obj, is_serialized, range);
|
|
rt = createVec4Layout(param);
|
|
parameter = param;
|
|
}
|
|
else if (obj_type.BaseType.Equals(typeof(Enum)))
|
|
{
|
|
ParameterEnum<T> param = new ParameterEnum<T>(obj_info, obj, is_serialized, range);
|
|
rt = createEnumLayout(param);
|
|
parameter = param;
|
|
}
|
|
else
|
|
{
|
|
Misc.Verbose(module, "Field Type of " + obj_type + " is not supported yet... (used in " + obj.ToString() + ")", 1);
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Misc.Verbose(module, e.Message, 1);
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
private void mf_SetupParameter(Parameterizable parameter, RectTransform rt, ListOfRectTrans layouts)
|
|
{
|
|
parameters.Add(parameter);
|
|
|
|
rt.gameObject.name = parameter.name;
|
|
var title = rt.Find("Title");
|
|
if (title != null)
|
|
{
|
|
var text = title.GetComponent<Text>();
|
|
if (text != null)
|
|
text.text = parameter.name;
|
|
}
|
|
layouts.Add(rt);
|
|
}
|
|
|
|
private bool mf_FindFieldAndCreateParameter(RectTransform labelLayout, BindingFlags bindingFlag, object obj, string targetName, bool is_serialized, RangeAttribute range, ListOfRectTrans layouts)
|
|
{
|
|
foreach (FieldInfo field in (obj.GetType().GetFields(bindingFlag)))
|
|
{
|
|
if (field.Name != targetName)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
Parameterizable parameter;
|
|
RectTransform rt;
|
|
|
|
mf_CreateParameter(field, field.FieldType, obj, is_serialized, range, out parameter, out rt);
|
|
|
|
if (parameter == null)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
mf_SetupParameter(parameter, rt, layouts);
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
private bool mf_FindPropertyAndCreateParameter(RectTransform labelLayout, BindingFlags bindingFlag, object obj, string targetName, bool isSerialized, RangeAttribute range, ListOfRectTrans layouts)
|
|
{
|
|
foreach (PropertyInfo property in (obj.GetType().GetProperties(bindingFlag)))
|
|
{
|
|
if (property.Name != targetName)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (property.GetGetMethod() == null)
|
|
{
|
|
Debug.LogWarning("[Property]:" + property.Name + " has no GetMethod");
|
|
return false;
|
|
}
|
|
|
|
if (property.GetSetMethod() == null)
|
|
{
|
|
Debug.LogWarning("[Property]:" + property.Name + " has no SetMethod");
|
|
return false;
|
|
}
|
|
|
|
Parameterizable parameter;
|
|
RectTransform rt;
|
|
|
|
mf_CreateParameter(property, property.PropertyType, obj, isSerialized, range, out parameter, out rt);
|
|
|
|
if (parameter == null)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
mf_SetupParameter(parameter, rt, layouts);
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
private void mf_FindAttributeFromProperties(RectTransform labelLayout, BindingFlags bindingFlag, object obj, ListOfRectTrans layouts)
|
|
{
|
|
foreach (PropertyInfo property in (obj.GetType().GetProperties(bindingFlag)))
|
|
{
|
|
AutoUIAttribute attr = sf_CheckAutoUIAttribute(property);
|
|
if (attr == null)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (property.GetGetMethod() == null)
|
|
{
|
|
Debug.LogWarning("[Property]:" + property.Name + " has no GetMethod");
|
|
continue;
|
|
}
|
|
|
|
if (property.GetSetMethod() == null)
|
|
{
|
|
Debug.LogWarning("[Property]:" + property.Name + " has no SetMethod");
|
|
continue;
|
|
}
|
|
|
|
bool is_serialized = (attr.flag != AutoUIAttribute.BindingFlag.NonSerialized);
|
|
Parameterizable parameter;
|
|
RectTransform rt;
|
|
|
|
mf_CreateParameter(property, property.PropertyType, obj, is_serialized, null, out parameter, out rt);
|
|
|
|
if (parameter == null)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
mf_SetupParameter(parameter, rt, layouts);
|
|
}
|
|
}
|
|
|
|
private void mf_FindAttributeFromFields(RectTransform labelLayout, BindingFlags bindingFlag, object obj, ListOfRectTrans layouts)
|
|
{
|
|
foreach (FieldInfo field in (obj.GetType().GetFields(bindingFlag)))
|
|
{
|
|
AutoUIAttribute attr = sf_CheckAutoUIAttribute(field);
|
|
if (attr == null)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
bool is_serialized = (attr.flag != AutoUIAttribute.BindingFlag.NonSerialized);
|
|
Parameterizable parameter;
|
|
RectTransform rt;
|
|
|
|
mf_CreateParameter(field, field.FieldType, obj, is_serialized, null, out parameter, out rt);
|
|
|
|
if (parameter == null)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
mf_SetupParameter(parameter, rt, layouts);
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region Parameter Base
|
|
interface Parameterizable
|
|
{
|
|
string name { get; }
|
|
object val { get; set; }
|
|
Type valType { get; }
|
|
|
|
string path { get; set; }
|
|
bool isSerialized { get; set; }
|
|
bool hasRange { get; set; }
|
|
Vector2 minmax { get; set; }
|
|
}
|
|
|
|
|
|
class ParameterInfo < T > : Parameterizable
|
|
{
|
|
protected object m_object_info;
|
|
protected MemberInfo m_member_info;
|
|
protected MethodInfo m_get_method;
|
|
protected MethodInfo m_set_method;
|
|
protected object m_object;
|
|
protected string m_path;
|
|
|
|
protected bool m_isSerialized;
|
|
protected bool m_hasRange;
|
|
protected Vector2 m_minmax;
|
|
protected Type m_val_type;
|
|
|
|
protected float m_index;
|
|
|
|
private object[] m_get_method_params;
|
|
private object[] m_set_method_params;
|
|
|
|
protected ParameterInfo(T info, object obj, bool isSerialized, RangeAttribute range)
|
|
{
|
|
Type info_type = typeof(T);
|
|
if (info_type == typeof(FieldInfo))
|
|
{
|
|
FieldInfo field = info as FieldInfo;
|
|
m_get_method = info_type.GetMethod("GetValue", new Type[] { typeof(object) });
|
|
m_get_method_params = new object[1];
|
|
|
|
m_set_method = info_type.GetMethod("SetValue", new Type[] { typeof(object), typeof(object) });
|
|
m_set_method_params = new object[2];
|
|
|
|
m_val_type = field.FieldType;
|
|
}
|
|
else if (info_type == typeof(PropertyInfo))
|
|
{
|
|
PropertyInfo property = info as PropertyInfo;
|
|
m_get_method = info_type.GetMethod("GetValue", new Type[] { typeof(object), typeof(object[]) });
|
|
m_get_method_params = new object[2];
|
|
|
|
m_set_method = info_type.GetMethod("SetValue", new Type[] { typeof(object), typeof(object), typeof(object[]) });
|
|
m_set_method_params = new object[3];
|
|
|
|
m_val_type = property.PropertyType;
|
|
}
|
|
else
|
|
{
|
|
throw new Exception("ParameterInfo() failed: The info_type = " + info_type.ToString() + ", is not support.");
|
|
}
|
|
|
|
if (m_set_method == null)
|
|
{
|
|
throw new Exception("ParameterInfo() failed: Can not get SetMethod");
|
|
}
|
|
|
|
if (m_get_method == null)
|
|
{
|
|
throw new Exception("ParameterInfo() failed: Can not get GetMethod");
|
|
}
|
|
|
|
m_object_info = info;
|
|
|
|
mf_Setup(info as MemberInfo, obj, isSerialized, range);
|
|
|
|
m_get_method_params[0] = m_object;
|
|
m_set_method_params[0] = m_object;
|
|
}
|
|
|
|
private void mf_Setup(MemberInfo info, object obj, bool isSerialized, RangeAttribute range)
|
|
{
|
|
m_member_info = info;
|
|
m_object = obj;
|
|
m_isSerialized = isSerialized;
|
|
|
|
if (range == null)
|
|
{
|
|
var attrs = (RangeAttribute[])m_member_info.GetCustomAttributes(typeof(RangeAttribute), false);
|
|
if(m_hasRange = attrs.Length > 0)
|
|
{
|
|
range = attrs[0];
|
|
}
|
|
}
|
|
else
|
|
{
|
|
m_hasRange = true;
|
|
}
|
|
|
|
if (m_hasRange)
|
|
{
|
|
m_minmax = new Vector2(range.min, range.max);
|
|
}
|
|
|
|
string res = "";
|
|
Component comp = obj as Component;
|
|
if (comp != null)
|
|
{
|
|
Stack<string> tree = new Stack<string>();
|
|
tree.Push(comp.name);
|
|
m_index = comp.transform.GetSiblingIndex() + 1.0f;
|
|
var parent = comp.transform.parent;
|
|
while (parent != null)
|
|
{
|
|
m_index = m_index * 0.1f + parent.GetSiblingIndex() + 1.0f;
|
|
tree.Push(parent.name);
|
|
parent = parent.parent;
|
|
}
|
|
|
|
while (tree.Count > 0)
|
|
{
|
|
res += string.Format("{0}/", tree.Peek());
|
|
tree.Pop();
|
|
}
|
|
}
|
|
|
|
res += m_member_info.Name;
|
|
m_path = res;
|
|
}
|
|
|
|
public string name
|
|
{
|
|
get { return m_member_info.Name; }
|
|
}
|
|
|
|
public virtual object val
|
|
{
|
|
get { return GetValue(); }
|
|
set { SetValue(value); }
|
|
}
|
|
|
|
public Type valType
|
|
{
|
|
get { return m_val_type; }
|
|
}
|
|
|
|
public string path
|
|
{
|
|
get { return m_path; }
|
|
set { path = value; }
|
|
}
|
|
|
|
public bool isSerialized
|
|
{
|
|
get { return m_isSerialized; }
|
|
set { m_isSerialized = value; }
|
|
}
|
|
|
|
public bool hasRange
|
|
{
|
|
get { return m_hasRange; }
|
|
set { m_hasRange = value; }
|
|
}
|
|
|
|
public Vector2 minmax
|
|
{
|
|
get { return m_minmax; }
|
|
set { m_minmax = value; }
|
|
}
|
|
|
|
protected object GetValue()
|
|
{
|
|
return m_get_method.Invoke(m_object_info, m_get_method_params);
|
|
}
|
|
|
|
protected void SetValue(object object_value)
|
|
{
|
|
m_set_method_params[1] = object_value;
|
|
m_set_method.Invoke(m_object_info, m_set_method_params);
|
|
}
|
|
}
|
|
|
|
// just for copy past template
|
|
class ParameterTemplate < T > : ParameterInfo < T >
|
|
{
|
|
public ParameterTemplate(T field, object obj, bool isSerialized, RangeAttribute range) : base(field, obj, isSerialized, range) { }
|
|
|
|
public override object val
|
|
{
|
|
get { return null; }
|
|
set { }
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region Parameter Float
|
|
class ParameterFloat<T> : ParameterInfo<T>
|
|
{
|
|
public ParameterFloat(T field, object obj, bool isSerialized, RangeAttribute range) : base(field, obj, isSerialized, range) { }
|
|
|
|
public override object val
|
|
{
|
|
set
|
|
{
|
|
float v;
|
|
if (float.TryParse(value.ToString(), out v))
|
|
{
|
|
SetValue(v);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void onValueChanged(string value)
|
|
{
|
|
val = value;
|
|
}
|
|
|
|
public void onValueChanged(float value)
|
|
{
|
|
val = value;
|
|
}
|
|
}
|
|
|
|
RectTransform createFloatLayout<T> (ParameterFloat <T> param)
|
|
{
|
|
var floatLayout = template_trans.Find("ParameterFloat") as RectTransform;
|
|
var floatRangeLayout = template_trans.Find("ParameterFloatRange") as RectTransform;
|
|
|
|
var rt = Instantiate(param.hasRange ? floatRangeLayout : floatLayout, layoutRoot);
|
|
if (param.hasRange)
|
|
{
|
|
var slider = rt.GetComponentInChildren<Slider>();
|
|
if (slider != null)
|
|
{
|
|
slider.minValue = param.minmax.x;
|
|
slider.maxValue = param.minmax.y;
|
|
slider.onValueChanged.AddListener((v) => param.onValueChanged(v));
|
|
layout_actions.Add(() => { slider.value = (float)param.val; });
|
|
}
|
|
}
|
|
{
|
|
var input_field = rt.GetComponentInChildren<InputField>();
|
|
if (input_field != null)
|
|
{
|
|
input_field.onEndEdit.AddListener((v) => param.onValueChanged(v));
|
|
layout_actions.Add(() => TrySetInputField(input_field, param.val.ToString()));
|
|
}
|
|
}
|
|
return rt;
|
|
}
|
|
#endregion
|
|
|
|
#region Parameter Int
|
|
class ParameterInt<T> : ParameterInfo<T>
|
|
{
|
|
public ParameterInt(T field, object obj, bool isSerialized, RangeAttribute range) : base(field, obj, isSerialized, range) { }
|
|
|
|
public override object val
|
|
{
|
|
set
|
|
{
|
|
int v;
|
|
if (int.TryParse(value.ToString(), out v))
|
|
{
|
|
SetValue(v);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void onValueChanged(string value)
|
|
{
|
|
val = value;
|
|
}
|
|
|
|
public void onValueChanged(float value)
|
|
{
|
|
val = value;
|
|
}
|
|
}
|
|
|
|
RectTransform createIntLayout<T>(ParameterInt<T> param)
|
|
{
|
|
var intLayout = template_trans.Find("ParameterInt") as RectTransform;
|
|
var intRangeLayout = template_trans.Find("ParameterIntRange") as RectTransform;
|
|
|
|
var rt = Instantiate(param.hasRange ? intRangeLayout : intLayout, layoutRoot);
|
|
if (param.hasRange)
|
|
{
|
|
var slider = rt.GetComponentInChildren<Slider>();
|
|
if (slider != null)
|
|
{
|
|
slider.minValue = param.minmax.x;
|
|
slider.maxValue = param.minmax.y;
|
|
slider.onValueChanged.AddListener((v) => param.onValueChanged(v));
|
|
slider.wholeNumbers = true;
|
|
layout_actions.Add(() => { slider.value = (int)param.val; });
|
|
}
|
|
}
|
|
{
|
|
var input_field = rt.GetComponentInChildren<InputField>();
|
|
if (input_field != null)
|
|
{
|
|
input_field.onEndEdit.AddListener((v) => param.onValueChanged(v));
|
|
layout_actions.Add(() => TrySetInputField(input_field, param.val.ToString()));
|
|
}
|
|
}
|
|
return rt;
|
|
}
|
|
#endregion
|
|
|
|
#region Parameter String
|
|
class ParameterString<T> : ParameterInfo<T>
|
|
{
|
|
public ParameterString(T field, object obj, bool isSerialized, RangeAttribute range) : base(field, obj, isSerialized, range) { }
|
|
|
|
public override object val
|
|
{
|
|
set
|
|
{
|
|
SetValue(value.ToString());
|
|
}
|
|
}
|
|
|
|
public void onValueChanged(string value)
|
|
{
|
|
val = value;
|
|
}
|
|
}
|
|
|
|
RectTransform createStringLayout<T>(ParameterString<T> param)
|
|
{
|
|
var stringLayout = template_trans.Find("ParameterString") as RectTransform;
|
|
|
|
var rt = Instantiate(stringLayout, layoutRoot);
|
|
var input_field = rt.GetComponentInChildren<InputField>();
|
|
if (input_field != null)
|
|
{
|
|
input_field.onEndEdit.AddListener((v) => param.onValueChanged(v));
|
|
layout_actions.Add(() => TrySetInputField(input_field, param.val.ToString()));
|
|
}
|
|
return rt;
|
|
}
|
|
#endregion
|
|
|
|
#region Parameter Bool
|
|
class ParameterBool<T> : ParameterInfo<T>
|
|
{
|
|
public ParameterBool(T field, object obj, bool isSerialized, RangeAttribute range) : base(field, obj, isSerialized, range) { }
|
|
|
|
public override object val
|
|
{
|
|
set
|
|
{
|
|
bool v;
|
|
if (bool.TryParse(value.ToString(), out v))
|
|
{
|
|
SetValue(v);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void onValueChanged(bool value)
|
|
{
|
|
val = value;
|
|
}
|
|
}
|
|
|
|
RectTransform createBoolLayout<T>(ParameterBool<T> param)
|
|
{
|
|
var boolLayout = template_trans.Find("ParameterBool") as RectTransform;
|
|
|
|
var rt = Instantiate(boolLayout, layoutRoot);
|
|
var toggle = rt.GetComponentInChildren<Toggle>();
|
|
if (toggle != null)
|
|
{
|
|
toggle.onValueChanged.AddListener((v) => param.onValueChanged(v));
|
|
layout_actions.Add(() => { toggle.isOn = (bool)param.val; });
|
|
}
|
|
return rt;
|
|
}
|
|
#endregion
|
|
|
|
#region Parameter Vector2
|
|
class ParameterVector2<T> : ParameterInfo<T>
|
|
{
|
|
public ParameterVector2(T field, object obj, bool isSerialized, RangeAttribute range) : base(field, obj, isSerialized, range) { }
|
|
|
|
public override object val
|
|
{
|
|
get
|
|
{
|
|
var value = (Vector2)GetValue();
|
|
List<float> array = new List<float>();
|
|
array.Add(value.x);
|
|
array.Add(value.y);
|
|
return array;
|
|
}
|
|
set
|
|
{
|
|
if (value is Newtonsoft.Json.Linq.JArray)
|
|
{
|
|
var array = value as Newtonsoft.Json.Linq.JArray;
|
|
if (array.Count != 2)
|
|
return;
|
|
|
|
SetValue( new Vector2(array[0].ToObject<float>(), array[1].ToObject<float>()));
|
|
}
|
|
}
|
|
}
|
|
|
|
public void onValueXChanged(string value)
|
|
{
|
|
var v = (Vector2)GetValue();
|
|
float res;
|
|
if (float.TryParse(value, out res))
|
|
{
|
|
SetValue(new Vector2(res, v.y));
|
|
}
|
|
}
|
|
|
|
public void onValueYChanged(string value)
|
|
{
|
|
var v = (Vector2)GetValue();
|
|
float res;
|
|
if (float.TryParse(value, out res))
|
|
{
|
|
SetValue(new Vector2(v.x, res));
|
|
}
|
|
}
|
|
}
|
|
|
|
RectTransform createVec2Layout<T>(ParameterVector2<T> param)
|
|
{
|
|
var vec2Layout = template_trans.Find("ParameterVector2") as RectTransform;
|
|
|
|
var rt = Instantiate(vec2Layout, layoutRoot);
|
|
var inputs = rt.GetComponentsInChildren<InputField>();
|
|
|
|
inputs[0].onEndEdit.AddListener((v) => param.onValueXChanged(v));
|
|
layout_actions.Add(() => TrySetInputField(inputs[0], ((List<float>)param.val)[0].ToString()));
|
|
|
|
inputs[1].onEndEdit.AddListener((v) => param.onValueYChanged(v));
|
|
layout_actions.Add(() => TrySetInputField(inputs[1], ((List<float>)param.val)[1].ToString()));
|
|
|
|
return rt;
|
|
}
|
|
#endregion
|
|
|
|
#region Parameter Vector3
|
|
class ParameterVector3<T> : ParameterInfo<T>
|
|
{
|
|
public ParameterVector3(T field, object obj, bool isSerialized, RangeAttribute range) : base(field, obj, isSerialized, range) { }
|
|
|
|
public override object val
|
|
{
|
|
get
|
|
{
|
|
var value = (Vector3)GetValue();
|
|
List<float> array = new List<float>();
|
|
array.Add(value.x);
|
|
array.Add(value.y);
|
|
array.Add(value.z);
|
|
return array;
|
|
}
|
|
set
|
|
{
|
|
if (value is Newtonsoft.Json.Linq.JArray)
|
|
{
|
|
var array = value as Newtonsoft.Json.Linq.JArray;
|
|
if (array.Count != 3)
|
|
return;
|
|
|
|
SetValue(new Vector3(array[0].ToObject<float>(), array[1].ToObject<float>(), array[2].ToObject<float>()));
|
|
}
|
|
}
|
|
}
|
|
|
|
public void onValueXChanged(string value)
|
|
{
|
|
var v = (Vector3)GetValue();
|
|
float res;
|
|
if (float.TryParse(value, out res))
|
|
{
|
|
SetValue(new Vector3(res, v.y, v.z));
|
|
}
|
|
}
|
|
|
|
public void onValueYChanged(string value)
|
|
{
|
|
var v = (Vector3)GetValue();
|
|
float res;
|
|
if (float.TryParse(value, out res))
|
|
{
|
|
SetValue(new Vector3(v.x, res, v.z));
|
|
}
|
|
}
|
|
|
|
public void onValueZChanged(string value)
|
|
{
|
|
var v = (Vector3)GetValue();
|
|
float res;
|
|
if (float.TryParse(value, out res))
|
|
{
|
|
SetValue(new Vector3(v.x, v.y, res));
|
|
}
|
|
}
|
|
}
|
|
|
|
RectTransform createVec3Layout<T>(ParameterVector3<T> param)
|
|
{
|
|
var vec3Layout = template_trans.Find("ParameterVector3") as RectTransform;
|
|
|
|
var rt = Instantiate(vec3Layout, layoutRoot);
|
|
var inputs = rt.GetComponentsInChildren<InputField>();
|
|
|
|
inputs[0].onEndEdit.AddListener((v) => param.onValueXChanged(v));
|
|
layout_actions.Add(() => TrySetInputField(inputs[0], ((List<float>)param.val)[0].ToString()));
|
|
|
|
inputs[1].onEndEdit.AddListener((v) => param.onValueYChanged(v));
|
|
layout_actions.Add(() => TrySetInputField(inputs[1], ((List<float>)param.val)[1].ToString()));
|
|
|
|
inputs[2].onEndEdit.AddListener((v) => param.onValueZChanged(v));
|
|
layout_actions.Add(() => TrySetInputField(inputs[2], ((List<float>)param.val)[2].ToString()));
|
|
|
|
return rt;
|
|
}
|
|
#endregion
|
|
|
|
#region Parameter Vector4
|
|
class ParameterVector4<T> : ParameterInfo<T>
|
|
{
|
|
public ParameterVector4(T field, object obj, bool isSerialized, RangeAttribute range) : base(field, obj, isSerialized, range) { }
|
|
|
|
public override object val
|
|
{
|
|
get
|
|
{
|
|
var value = (Vector4)GetValue();
|
|
List<float> array = new List<float>();
|
|
array.Add(value.x);
|
|
array.Add(value.y);
|
|
array.Add(value.z);
|
|
array.Add(value.w);
|
|
return array;
|
|
}
|
|
set
|
|
{
|
|
if (value is Newtonsoft.Json.Linq.JArray)
|
|
{
|
|
var array = value as Newtonsoft.Json.Linq.JArray;
|
|
if (array.Count != 4)
|
|
return;
|
|
|
|
SetValue(new Vector4(array[0].ToObject<float>(), array[1].ToObject<float>(), array[2].ToObject<float>(), array[3].ToObject<float>()));
|
|
}
|
|
}
|
|
}
|
|
|
|
public void onValueXChanged(string value)
|
|
{
|
|
var v = (Vector4)GetValue();
|
|
float res;
|
|
if (float.TryParse(value, out res))
|
|
{
|
|
SetValue(new Vector4(res, v.y, v.z, v.w));
|
|
}
|
|
}
|
|
|
|
public void onValueYChanged(string value)
|
|
{
|
|
var v = (Vector4)GetValue();
|
|
float res;
|
|
if (float.TryParse(value, out res))
|
|
{
|
|
SetValue(new Vector4(v.x, res, v.z, v.w));
|
|
}
|
|
}
|
|
|
|
public void onValueZChanged(string value)
|
|
{
|
|
var v = (Vector4)GetValue();
|
|
float res;
|
|
if (float.TryParse(value, out res))
|
|
{
|
|
SetValue(new Vector4(v.x, v.y, res, v.w));
|
|
}
|
|
}
|
|
|
|
public void onValueWChanged(string value)
|
|
{
|
|
var v = (Vector4)GetValue();
|
|
float res;
|
|
if (float.TryParse(value, out res))
|
|
{
|
|
SetValue(new Vector4(v.x, v.y, v.z, res));
|
|
}
|
|
}
|
|
}
|
|
|
|
RectTransform createVec4Layout<T>(ParameterVector4<T> param)
|
|
{
|
|
var vec4Layout = template_trans.Find("ParameterVector4") as RectTransform;
|
|
|
|
var rt = Instantiate(vec4Layout, layoutRoot);
|
|
var inputs = rt.GetComponentsInChildren<InputField>();
|
|
|
|
inputs[0].onEndEdit.AddListener((v) => param.onValueXChanged(v));
|
|
layout_actions.Add(() => TrySetInputField(inputs[0], ((List<float>)param.val)[0].ToString()));
|
|
|
|
inputs[1].onEndEdit.AddListener((v) => param.onValueYChanged(v));
|
|
layout_actions.Add(() => TrySetInputField(inputs[1], ((List<float>)param.val)[1].ToString()));
|
|
|
|
inputs[2].onEndEdit.AddListener((v) => param.onValueZChanged(v));
|
|
layout_actions.Add(() => TrySetInputField(inputs[2], ((List<float>)param.val)[2].ToString()));
|
|
|
|
inputs[3].onEndEdit.AddListener((v) => param.onValueWChanged(v));
|
|
layout_actions.Add(() => TrySetInputField(inputs[3], ((List<float>)param.val)[3].ToString()));
|
|
|
|
return rt;
|
|
}
|
|
#endregion
|
|
|
|
#region Parameter Enum
|
|
class ParameterEnum<T> : ParameterInfo<T>
|
|
{
|
|
public ParameterEnum(T field, object obj, bool isSerialized, RangeAttribute range) : base(field, obj, isSerialized, range)
|
|
{
|
|
foreach (Enum e in Enum.GetValues(valType))
|
|
{
|
|
_enumerator_list.Add(new GUIContent(e.ToString()));
|
|
}
|
|
}
|
|
|
|
public override object val
|
|
{
|
|
set { trySetValue(value.ToString()); }
|
|
}
|
|
|
|
List<GUIContent> _enumerator_list = new List<GUIContent>();
|
|
|
|
void trySetValue(string s)
|
|
{
|
|
try
|
|
{
|
|
Enum v = (Enum)Enum.Parse(valType, s);
|
|
if (Enum.IsDefined(valType, v))
|
|
{
|
|
SetValue(v);
|
|
}
|
|
else
|
|
Debug.LogWarning(s + " is not an underlying value of the " + valType + " enumeration.");
|
|
}
|
|
catch (ArgumentException)
|
|
{
|
|
Debug.LogWarning(s + " is not a member of the " + valType + " enumeration.");
|
|
}
|
|
}
|
|
|
|
public Dictionary<int, int> data_table = new Dictionary<int, int>();
|
|
public void onValueChanged(int value)
|
|
{
|
|
val = _enumerator_list[value].text;
|
|
}
|
|
}
|
|
|
|
RectTransform createEnumLayout<T>(ParameterEnum<T> param)
|
|
{
|
|
var enumLayout = template_trans.Find("ParameterEnum") as RectTransform;
|
|
|
|
var rt = Instantiate(enumLayout, layoutRoot);
|
|
|
|
var data_list = new List<Dropdown.OptionData>();
|
|
foreach (Enum e in Enum.GetValues(param.valType))
|
|
{
|
|
param.data_table.Add(Convert.ToInt32(e), data_list.Count);
|
|
|
|
var data = new Dropdown.OptionData();
|
|
data.text = e.ToString();
|
|
data_list.Add(data);
|
|
}
|
|
|
|
var drop_down = rt.GetComponentInChildren<Dropdown>();
|
|
if (drop_down != null)
|
|
{
|
|
drop_down.ClearOptions();
|
|
drop_down.options = data_list;
|
|
|
|
drop_down.onValueChanged.AddListener((v) => param.onValueChanged(v));
|
|
layout_actions.Add(() => { drop_down.value = param.data_table[(int)param.val]; });
|
|
}
|
|
|
|
return rt;
|
|
}
|
|
#endregion
|
|
} |