using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; namespace Rukha93.ModularAnimeCharacter.Customization.UI { public class UICustomizationDemo : MonoBehaviour { [Header("category")] [SerializeField] private LayoutGroup m_CategoryPanel; [SerializeField] private UICategoryItem m_CategoryItemPrefab; [Header("customization")] [SerializeField] private Text m_CustomizationTitle; [SerializeField] private LayoutGroup m_CustomizationPanel; [SerializeField] private UISwapperItem m_SwapperItem; [SerializeField] private UIMaterialItem m_MaterialItemPrefab; [Space] [SerializeField] private UIColorPicker m_ColorPicker; public string CurrentCategory { get; private set; } private List m_CategoryItems = new List(); private List m_MaterialItems = new List(); private List m_ItemOptions; private int m_CurrentItemIndex; public System.Action OnClickCategory; public System.Action OnChangeItem; public System.Action OnChangeColor; public bool IsCustomizationOpen => m_CustomizationPanel.gameObject.activeSelf; private void Awake() { m_CategoryItemPrefab.gameObject.SetActive(false); m_MaterialItemPrefab.gameObject.SetActive(false); m_SwapperItem.OnClickLeft = _OnSwapPrevious; m_SwapperItem.OnClickRight = _OnSwapNext; } private void Start() { ShowCustomization(false); m_ColorPicker.Close(); } #region CATEGORY PANEL public void SetCategories(string[] categories) { for(int i = 0; i < categories.Length; i++) { UICategoryItem item; if (i < m_CategoryItems.Count) { item = m_CategoryItems[i]; } else { item = Instantiate(m_CategoryItemPrefab, m_CategoryPanel.transform); m_CategoryItems.Add(item); } item.gameObject.SetActive(true); item.Title = categories[i]; string aux = categories[i]; item.OnClick = () => OnClickCategory?.Invoke(aux); } for (int i = categories.Length; i < m_CategoryItems.Count; i++) m_CategoryItems[i].gameObject.SetActive(false); } public void SetCategoryValue(int index, string value) { UICategoryItem item = m_CategoryItems[index]; item.Value = value; } #endregion #region CUSTOMIZATION PANEL public void ShowCustomization(bool value) { //todo: add basic animation if (value == false) { CurrentCategory = ""; m_CustomizationPanel.gameObject.SetActive(false); m_ColorPicker.Close(); return; } m_CustomizationPanel.gameObject.SetActive(true); } public void SetCustomizationOptions(string category, string[] items, string currentItem) { CurrentCategory = category; m_ItemOptions = new List(items); m_CurrentItemIndex = Mathf.Max(m_ItemOptions.IndexOf(currentItem), 0); m_CustomizationTitle.text = category; //item swapping if( m_CurrentItemIndex >= m_ItemOptions.Count) { m_SwapperItem.gameObject.SetActive(false); return; } m_SwapperItem.Text = m_ItemOptions[m_CurrentItemIndex]; m_SwapperItem.gameObject.SetActive(true); } public void SetCustomizationMaterials(Renderer[] renderers) { if (renderers == null) renderers = new Renderer[0]; //get all available materials List materials = new List(); List renderersPerMaterial = new List(); List rendererMaterialIndex = new List(); List propertyBlock = new List(); for(int i = 0; i < renderers.Length; i++) { var renderer = renderers[i]; var sharedMaterials = renderer.sharedMaterials; for (int j = 0; j < sharedMaterials.Length; j++) { if (materials.Contains(sharedMaterials[j])) continue; materials.Add(sharedMaterials[j]); renderersPerMaterial.Add(renderer); rendererMaterialIndex.Add(j); var block = new MaterialPropertyBlock(); renderer.GetPropertyBlock(block, j); propertyBlock.Add(block); } } for (int i = 0; i < materials.Count; i++) { //item from pool or instantiate UIMaterialItem item; if (i < m_MaterialItems.Count) { item = m_MaterialItems[i]; } else { item = Instantiate(m_MaterialItemPrefab, m_CustomizationPanel.transform); item.ColorPicker = m_ColorPicker; m_MaterialItems.Add(item); } item.gameObject.SetActive(true); //setup item item.Title = materials[i].name; var auxRenderer = renderersPerMaterial[i]; var auxMatIndex = rendererMaterialIndex[i]; var auxPropertyBlock = propertyBlock[i]; if (materials[i].HasProperty("_MaskRemap")) { item.ResetColors(); //customization channel 1 item.AddDoubleColor( auxPropertyBlock.HasColor("_Color_A_2") ? auxPropertyBlock.GetColor("_Color_A_2") : materials[i].GetColor("_Color_A_2"), auxPropertyBlock.HasColor("_Color_A_1") ? auxPropertyBlock.GetColor("_Color_A_1") : materials[i].GetColor("_Color_A_1"), (c) => OnChangeColor?.Invoke(auxRenderer, auxMatIndex, "_Color_A_2", c), (c) => OnChangeColor?.Invoke(auxRenderer, auxMatIndex, "_Color_A_1", c) ); //customization channel 2 item.AddDoubleColor( auxPropertyBlock.HasColor("_Color_B_2") ? auxPropertyBlock.GetColor("_Color_B_2") : materials[i].GetColor("_Color_B_2"), auxPropertyBlock.HasColor("_Color_B_1") ? auxPropertyBlock.GetColor("_Color_B_1") : materials[i].GetColor("_Color_B_1"), (c) => OnChangeColor?.Invoke(auxRenderer, auxMatIndex, "_Color_B_2", c), (c) => OnChangeColor?.Invoke(auxRenderer, auxMatIndex, "_Color_B_1", c) ); //customization channel 3 item.AddDoubleColor( auxPropertyBlock.HasColor("_Color_C_2") ? auxPropertyBlock.GetColor("_Color_C_2") : materials[i].GetColor("_Color_C_2"), auxPropertyBlock.HasColor("_Color_C_1") ? auxPropertyBlock.GetColor("_Color_C_1") : materials[i].GetColor("_Color_C_1"), (c) => OnChangeColor?.Invoke(auxRenderer, auxMatIndex, "_Color_C_2", c), (c) => OnChangeColor?.Invoke(auxRenderer, auxMatIndex, "_Color_C_1", c) ); } else if (materials[i].HasProperty("_Color")) { item.SetupSingleColor( auxPropertyBlock.HasColor("_Color") ? auxPropertyBlock.GetColor("_Color") : materials[i].GetColor("_Color"), (c) => OnChangeColor?.Invoke(auxRenderer, auxMatIndex, "_Color", c)); } } for (int i = materials.Count; i < m_MaterialItems.Count; i++) m_MaterialItems[i].gameObject.SetActive(false); m_ColorPicker.Close(); } private void _OnSwapPrevious() { m_CurrentItemIndex = m_CurrentItemIndex - 1; if (m_CurrentItemIndex < 0) m_CurrentItemIndex = m_ItemOptions.Count - 1; m_SwapperItem.Text = m_ItemOptions[m_CurrentItemIndex]; OnChangeItem?.Invoke(CurrentCategory, m_ItemOptions[m_CurrentItemIndex]); } private void _OnSwapNext() { m_CurrentItemIndex = (m_CurrentItemIndex + 1) % m_ItemOptions.Count; m_SwapperItem.Text = m_ItemOptions[m_CurrentItemIndex]; OnChangeItem?.Invoke(CurrentCategory, m_ItemOptions[m_CurrentItemIndex]); } #endregion } }