UniversalViewer/Assets/Eversoul/Scripts/UI/EversoulCharacterDropdown.cs

132 lines
4.1 KiB
C#
Raw Normal View History

using TMPro;
using System.Linq;
using UnityEngine;
using UnityEngine.Events;
using System.Collections.Generic;
using System;
public class EversoulCharacterDropdown : MonoBehaviour
{
[SerializeField] private TMP_Dropdown MainDropdown;
[SerializeField] private TMP_InputField MainLabel;
public List<string> DropdownLabels = new List<string>() { "Character", "Costume" };
public List<TMP_Dropdown> Dropdowns = new List<TMP_Dropdown>();
public List<TMP_InputField> Labels = new List<TMP_InputField>();
private bool _awake;
private void Awake()
{
if (_awake) return;
_awake = true;
Rebuild();
}
private void Rebuild()
{
var labelParent = MainLabel.transform.parent;
var dropdownParent = MainDropdown.transform.parent;
MainDropdown.ClearOptions();
Dropdowns.Clear();
Dropdowns.Add(MainDropdown);
foreach (var child in dropdownParent.GetComponentsInChildren<TMP_Dropdown>())
{
if (child != MainDropdown) Destroy(child);
}
foreach (var child in labelParent.GetComponentsInChildren<TMP_Dropdown>())
{
if (child != MainLabel) Destroy(child);
}
MainDropdown.name = DropdownLabels[0];
MainLabel.text = DropdownLabels[0];
foreach (var label in DropdownLabels.Skip(1))
{
var dd = Instantiate(MainDropdown, dropdownParent);
dd.name = "dropdown_" + label;
var ll = Instantiate(MainLabel, labelParent);
ll.name = label + " (TMP)";
ll.text = label;
Dropdowns.Add(dd);
}
}
public void SetData(List<CharacterAsset> characters)
{
Awake();
SetDropdownData(0, characters.Select(c => c.Name).Distinct().ToList(), true, true);
UnityAction<int> groupCallback = (index) =>
{
if (index == 0) return;
var name = GetOption(0);
SetDropdownData(1, characters.Where(c => c.Name == name).Select(c => c.Prefab).Distinct().ToList(), true, true);
//SetDropdownData(2, new List<string>(), true, true);
};
UnityAction<int> charaCallback = (index) =>
{
if (index == 0) return;
var name = GetOption(0);
var prefab = GetOption(1);
var costume = characters.First(c => c.Name == name && c.Prefab == prefab);
EversoulModelBuilder.Instance.SpawnCharacter(costume);
};
SetCallbacks(new List<UnityAction<int>>()
{
groupCallback,
charaCallback
});
}
public void SetCallbacks(List<UnityAction<int>> callbacks)
{
if (callbacks.Count < Dropdowns.Count)
{
Error.Log(Color.red, $"Incorrect number of callbacks for dropdowns. Got {callbacks.Count}, required {Dropdowns.Count}");
}
for (int i = 0; i < Dropdowns.Count; i++)
{
Dropdowns[i].onValueChanged.RemoveAllListeners();
Dropdowns[i].onValueChanged.AddListener(callbacks[i]);
}
}
public void OnDropdownSelected(int selection)
{
if (selection == 0)
{
Debug.LogError("Delete Current");
}
StartCoroutine(ModelBuilder.GetInstance().SpawnAssetCoroutine(AssetTypes.Character, MainDropdown.options[selection].text));
}
public void SetDropdownData(string label, List<string> options, bool nullValue = false, bool sortValues = false)
{
var depth = DropdownLabels.IndexOf(label);
SetDropdownData(depth, options, nullValue, sortValues);
}
public string GetOption(int depth)
{
if (Dropdowns[depth].value == 0) return null;
return Dropdowns[depth].options[Dropdowns[depth].value].text;
}
public void SetDropdownData(int depth, List<string> options, bool nullValue = false, bool sortValues = false)
{
if (depth >= Dropdowns.Count || depth < 0)
{
Error.Log(Color.red, $"Dropdown {depth} out of range");
return;
}
ModelViewerInterface.SetDropdownData(Dropdowns[depth], options, nullValue, sortValues);
}
}