add skin color modifier

This commit is contained in:
2025-01-07 21:43:47 +02:00
parent bf4bdfdfd1
commit 090ffeb17d
34 changed files with 532 additions and 15 deletions
+106
View File
@@ -0,0 +1,106 @@
using Assets.Scripts.Interfaces;
using System;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class DialogOptionsUI : MonoBehaviour
{
[SerializeField]
private TextMeshProUGUI _title;
[SerializeField]
private TextMeshProUGUI _subTitle;
[SerializeField]
private Button _btnCancel;
[SerializeField]
private Button _btnOk;
[SerializeField]
private Transform _itemsContainer;
[SerializeField]
private Transform _tabsContainer;
[SerializeField]
private JobItemUITemplate _jobItemUItemplate;
[SerializeField]
private DialogTabUITemplate _dialogTabUI;
private DialogTabUITemplate _selectedTab;
private IDialogItemUI _selectedItem;
private DialogSO _dialogSO;
public void ShowCategoriesDialog(DialogSO dialogSO, Action onCancel, Action<IDialogOption> onConfirm)
{
GameManager.Instance.UI.Freeze();
_dialogSO = dialogSO;
gameObject.SetActive(true);
_title.text = _dialogSO.Title;
//Create Tabs
for (int count = 0; count < _dialogSO.CategoriesSO.Count; count++)
{
var dialogOption = _dialogSO.CategoriesSO[count];
var itemUI = Instantiate(_dialogTabUI, _tabsContainer);
itemUI.gameObject.SetActive(true);
var template = itemUI.GetComponent<DialogTabUITemplate>();
template.SetItem(this, dialogOption);
if (count== 0) {
OnTabSelected(template);
}
}
_btnCancel.onClick.AddListener(() =>
{
onCancel?.Invoke();
Hide();
});
_btnOk.onClick.AddListener(() =>
{
onConfirm?.Invoke(_selectedItem.Item);
Hide();
});
}
public void OnTabEnter(DialogTabUITemplate button)
{
print($"enter to {button.DialogOption.name}");
}
public void OnTabSelected(DialogTabUITemplate button)
{
_selectedTab = button;
_subTitle.text = _selectedTab.DialogOption.Title;
while (_itemsContainer.childCount > 0)
{
DestroyImmediate(_itemsContainer.GetChild(0).gameObject);
}
foreach (var job in _selectedTab.DialogOption.OptionsList)
{
var itemUI = Instantiate(_dialogSO.UITemplate, _itemsContainer);
itemUI.gameObject.SetActive(true);
itemUI.GetComponent<IDialogItemUI>().SetItem(this, job);
}
}
public void OnTabExit(DialogTabUITemplate button)
{
}
public void OnItemSelected(IDialogItemUI button)
{
_selectedItem = button;
}
private void CloseDialog()
{
GameManager.Instance.UI.Unfreeze();
Destroy(this);
}
private void Hide()
{
gameObject.SetActive(false);
CloseDialog();
}
}
+11
View File
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 26f26f444ba4dae48853b4658b997156
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+39
View File
@@ -0,0 +1,39 @@
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class DialogTabUITemplate : MonoBehaviour, IPointerEnterHandler,IPointerClickHandler, IPointerExitHandler
{
[SerializeField]
private TextMeshProUGUI _description;
[SerializeField]
private Image _icon;
public DialogCategorySO DialogOption=> _dialogOption;
private DialogCategorySO _dialogOption;
private DialogOptionsUI _parent;
public void SetItem(DialogOptionsUI parent, DialogCategorySO dialogOption)
{
_dialogOption = dialogOption;
_parent = parent;
_icon.sprite = _dialogOption.Icon;
}
public void OnPointerClick(PointerEventData eventData)
{
_parent.OnTabSelected(this);
}
public void OnPointerEnter(PointerEventData eventData)
{
_parent.OnTabEnter(this);
}
public void OnPointerExit(PointerEventData eventData)
{
_parent.OnTabExit(this);
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6ef82e356ce0b8542a02cd451578f20b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+49
View File
@@ -0,0 +1,49 @@
using Assets.Scripts.Interfaces;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class EducationItemUI : MonoBehaviour, IDialogItemUI ,IPointerEnterHandler
{
[SerializeField]
private TextMeshProUGUI _description;
[SerializeField]
private TextMeshProUGUI _duration;
[SerializeField]
private TextMeshProUGUI _price;
[SerializeField]
private Image _icon;
[SerializeField]
private Button _button;
private DialogOptionsUI _parent;
private EducationInfoSO _item;
public IDialogOption Item => _item;
public void SetItem(DialogOptionsUI parent,IDialogOption item)
{
_item= item as EducationInfoSO;
_parent = parent;
_duration.text = _item.Duration.ToString();
_description.text = _item.Description;
_price.text = $"{_item.EnrollPrice}$";
_icon.sprite = item.Icon;
_button.enabled = true;
_button.onClick.AddListener(() => {
if (_button.enabled)
{
_parent.OnItemSelected(this);
}
});
}
public void OnPointerEnter(PointerEventData eventData)
{
if (!_button.enabled) { print("Not enough education"); }
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: ae4f157b0a61c52409c1c86ea3826ab1
+40
View File
@@ -0,0 +1,40 @@
using System;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class ImageColorPicker : MonoBehaviour, IPointerClickHandler
{
public Color selectedColor;
[Serializable]
public class ColorEvent : UnityEvent<Color> { }
public ColorEvent OnColorPicked = new ColorEvent();
public void OnPointerClick(PointerEventData eventData)
{
selectedColor = GetColor(GetPointUVPosition());
OnColorPicked.Invoke(selectedColor);
}
private Color GetColor(Vector2 pos)
{
Texture2D texture = GetComponent<Image>().sprite.texture;
Color selected = texture.GetPixelBilinear(pos.x, pos.y);
selected.a = 1;
return selected;
}
private Vector2 GetPointUVPosition()
{
Vector3[] imageCorners = new Vector3[4];
gameObject.GetComponent<RectTransform>().GetWorldCorners(imageCorners);
float texWidth = imageCorners[2].x - imageCorners[0].x;
float texHeight = imageCorners[2].y - imageCorners[0].y;
float uvX = (Input.mousePosition.x - imageCorners[0].x) / texWidth;
float uvY = (Input.mousePosition.y - imageCorners[0].y) / texHeight;
return new Vector2(uvX, uvY);
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 2f3eb60cba57441478f606990bede4d9
+42
View File
@@ -0,0 +1,42 @@
using Assets.Scripts.Interfaces;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class JobItemUITemplate : MonoBehaviour, IDialogItemUI ,IPointerEnterHandler
{
[SerializeField]
private TextMeshProUGUI _descreiption;
[SerializeField]
private TextMeshProUGUI _sallary;
[SerializeField]
private Image _icon;
[SerializeField]
private Button _button;
private DialogOptionsUI _parent;
private JobInfoSO _item;
public IDialogOption Item=> _item;
public void SetItem(DialogOptionsUI parent,IDialogOption item)
{
_item= item as JobInfoSO;
_parent = parent;
_descreiption.text = _item.Description;
_sallary.text = $"{_item.Salary}$";
_icon.sprite = item.Icon;
_button.enabled = Player.Instance.Education>= _item.MinimumEducationSkill;
_button.onClick.AddListener(() => {
if (_button.enabled)
{
_parent.OnItemSelected(this);
}
});
}
public void OnPointerEnter(PointerEventData eventData)
{
if (!_button.enabled) { print("Not enough education"); }
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d3e8f5b6c634f0348a6d19591cef88e2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+62
View File
@@ -0,0 +1,62 @@
using Cysharp.Threading.Tasks;
using System.Collections.Generic;
using System.Linq;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class RadialMenuItem : MonoBehaviour
{
[SerializeField]
private Button _radialMenuItemPrefab;
private Dictionary<RadialMenuActions, RadialMenuActionDescription> _actions;
private UniTaskCompletionSource<RadialMenuActions> tcs = new UniTaskCompletionSource<RadialMenuActions>();
public UniTask<RadialMenuActions> ShowButtons(Dictionary<RadialMenuActions, RadialMenuActionDescription> actions)
{
_actions = actions;
for (int buttonsCount = 0; buttonsCount < actions.Count; buttonsCount++)
{
var button = Instantiate(_radialMenuItemPrefab);
button.transform.SetParent(transform, false);
//button.transform.localScale *= 2;
float theta = (2 * Mathf.PI / actions.Count) * buttonsCount;
float posX = Mathf.Sin(theta);
float posY = Mathf.Cos(theta);
button.transform.localPosition = new Vector3(posX, posY, 0) * 100f;
var textMeshPro = button.GetComponentInChildren<TextMeshProUGUI>();
if (textMeshPro != null)
{
textMeshPro.text = actions.ElementAt(buttonsCount).Value.Description;
}
AddEvent(button, buttonsCount);
}
return tcs.Task;
}
void AddEvent(Button b, int buttonNumber)
{
b.onClick.AddListener(() =>
{
tcs.TrySetResult(_actions.ElementAt(buttonNumber).Key);
Close();
});
}
public void CancelAndClose()
{
tcs.TrySetResult(RadialMenuActions.Cancel);
Close();
}
private void Close()
{
GameManager.Instance.UI.Unfreeze();
Destroy(this);
gameObject.SetActive(false);
Destroy(gameObject);
}
}
+11
View File
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0652e5472d3afcf4f8d99f61ca2dc62e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+71
View File
@@ -0,0 +1,71 @@
using System;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class TimeSliderUI : MonoBehaviour
{
[SerializeField]
private TextMeshProUGUI _title;
[SerializeField]
private TextMeshProUGUI _description;
[SerializeField]
private TextMeshProUGUI _timeText;
[SerializeField]
private Button _btnCancel;
[SerializeField]
private Button _btnOk;
[SerializeField]
private Slider _slider;
private TimeSpan _time;
public void ShowTimeSliderDialog(string title, string description, Action onCancel, Action<TimeSpan> onConfirm)
{
GameManager.Instance.Time.OnFastForwardEnd += CloseDialog;
GameManager.Instance.Pause();
GameManager.Instance.UI.Freeze();
gameObject.SetActive(true);
_title.text = title;
_description.text = description;
_btnCancel.onClick.AddListener(() =>
{
onCancel?.Invoke();
Hide();
CloseDialog();
});
_btnOk.onClick.AddListener(() =>
{
onConfirm?.Invoke(_time);
Hide();
});
SliderValueChanger(_slider.value);
_slider.onValueChanged.AddListener(x=>SliderValueChanger(x));
}
private void CloseDialog()
{
GameManager.Instance.UI.Unfreeze();
Destroy(this);
}
private void SliderValueChanger(float time)
{
if (gameObject.activeSelf)
{
_time = TimeSpan.FromHours(time);
_timeText.text = $"{_time.Hours} hours";
}
}
private void Hide()
{
_slider.onValueChanged.RemoveListener(x=>SliderValueChanger(x));
gameObject.SetActive(false);
GameManager.Instance.Resume();
}
}
+11
View File
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 108151baa6db03042b0bcf80b1a30a66
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+56
View File
@@ -0,0 +1,56 @@
using TMPro;
using UnityEngine;
using UnityEngine.UI;
[ExecuteInEditMode()]
public class ToolTip : MonoBehaviour
{
public TextMeshProUGUI headerField;
public TextMeshProUGUI contentField;
public LayoutElement layoutElement;
public int characterWrapLimit;
public RectTransform rectTransform;
private void Awake()
{
rectTransform = GetComponent<RectTransform>();
}
// Start is called before the first frame update
public void SetText(string content, string header = "")
{
if (string.IsNullOrEmpty(header))
{
headerField.gameObject.SetActive(false);
}
else
{
headerField.gameObject.SetActive(true);
headerField.text = header;
}
contentField.text = content;
int headerLength = headerField.text.Length;
int contentLength = contentField.text.Length;
layoutElement.enabled = (headerLength > characterWrapLimit || contentLength > characterWrapLimit);
}
// Update is called once per frame
void Update()
{
if (Application.isEditor)
{
int headerLength = headerField.text.Length;
int contentLength = contentField.text.Length;
layoutElement.enabled = (headerLength > characterWrapLimit || contentLength > characterWrapLimit);
}
Vector2 position = Input.mousePosition;
float pivotX = position.x / Screen.width;
float pivotY = position.y / Screen.height;
rectTransform.pivot = new Vector2(pivotX, pivotY);
transform.position = position;
}
}
+11
View File
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: feff04ad815f5974cb387c4ae348a844
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+22
View File
@@ -0,0 +1,22 @@
using UnityEngine;
public class ToolTipSystem : MonoBehaviour
{
private static ToolTipSystem _current;
[SerializeField] private ToolTip _toolTip;
public void Awake()
{
_current = this;
_current._toolTip.gameObject.SetActive(false);
}
public static void Show(string content, string header = "")
{
_current._toolTip.SetText(content, header);
_current._toolTip.gameObject.SetActive(true);
}
public static void Hide()
{
_current._toolTip.gameObject.SetActive(false);
}
}
+11
View File
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 49f5114aac344be42a48ac8ceb3b93fb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+22
View File
@@ -0,0 +1,22 @@
using UnityEngine;
public class ToolTipTrigger : MonoBehaviour
{
//private static LTDescr delay;
//[SerializeField] private string _content;
//[SerializeField] private string _header;
//public void OnPointerEnter(PointerEventData eventData)
//{
// delay = LeanTween.delayedCall(0.5f, () =>
// {
// ToolTipSystem.Show(_content, _header);
// });
//}
//public void OnPointerExit(PointerEventData eventData)
//{
// LeanTween.cancel(delay.uniqueId);
// ToolTipSystem.Hide();
//}
}
+11
View File
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b31294925f6cbdb40969c856428d8894
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+52
View File
@@ -0,0 +1,52 @@
using Assets.Scripts.Interfaces;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class TopBarUI : MonoBehaviour
{
[SerializeField]
private TextMeshProUGUI _timeText;
[SerializeField]
private TextMeshProUGUI _moneyText;
[SerializeField]
private TextMeshProUGUI _locationText;
[SerializeField]
public Slider _energy;
[SerializeField]
public Slider _food;
// Start is called before the first frame update
private void Awake()
{
GameManager.Instance.Time.OnMinuteChanged -= UpdateTime;
GameManager.Instance.Time.OnMinuteChanged += UpdateTime;
}
private void OnDisable()
{
GameManager.Instance.Time.OnMinuteChanged -= UpdateTime;
}
// Update is called once per frame
void Update()
{
_moneyText.text = $"${(Player.Instance.Stats[StatsId.Money] as INumericStat).Value}";
_locationText.text= $"{(Player.Instance.Stats[StatsId.LocationName] as IStringStat).Value}";
}
private void UpdateTime()
{
if (_timeText != null)
{
_timeText.text = $"{GameManager.Instance.Time.CurrentTime.GetDayName()} {GameManager.Instance.Time.CurrentTime.ToString(@"hh\:mm")} day ({GameManager.Instance.Time.CurrentTime.Days})";
}
_energy.value = (Player.Instance.Stats[StatsId.Energy] as INumericStat).Value;
_food.value = (Player.Instance.Stats[StatsId.Food] as INumericStat).Value;
}
}
+11
View File
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2649ed9748ff3864880311f1c2aecdef
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+72
View File
@@ -0,0 +1,72 @@
using UnityEngine;
public class UIContainer : MonoBehaviour
{
[SerializeField]
private Transform _container;
[SerializeField]
private Transform _itemsList;
[SerializeField]
private Transform _itemUITemplate;
private ContainerItem _playerContainer;
private void Awake()
{
_container.gameObject.SetActive(false);
}
private void Start()
{
Player.Instance.OnContainerChanged += OnContainerChanged;
}
private void OnContainerChanged(object sender, bool e)
{
if (e)
{
_container.gameObject.SetActive(true);
_playerContainer = Player.Instance.GetContainerItem();
_playerContainer.OnItemsChange += OnItemsChange;
}
else
{
_container.gameObject.SetActive(false);
_playerContainer.OnItemsChange -= OnItemsChange;
}
}
private void OnItemsChange(object sender, System.EventArgs e)
{
ClearObject();
var playerItemsList = _playerContainer.GetItems();
for (int count = 0; count < playerItemsList.Count; count++)
{
var itemUI = Instantiate(_itemUITemplate, _itemsList);
itemUI.gameObject.SetActive(true);
var item = itemUI.GetComponent<UIContainerItem>();
item.SetItem((SellableItemSO)playerItemsList[count]);
RemoveButton(playerItemsList[count], item);
}
}
private void RemoveButton(BaseItemSO item, UIContainerItem UIItem)
{
UIItem._removeButton.onClick.AddListener(() =>
{
_playerContainer.Remove(item);
});
}
private void ClearObject()
{
foreach (Transform child in _itemsList)
{
if (child == _itemUITemplate) continue;
Destroy(child.gameObject);
}
}
}
+11
View File
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7c4e9fa0f730f1b4698d6adaca1b8ffd
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+22
View File
@@ -0,0 +1,22 @@
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class UIContainerItem : MonoBehaviour
{
[SerializeField]
private TextMeshProUGUI _name;
[SerializeField]
private TextMeshProUGUI _price;
[SerializeField]
private Image _icon;
[SerializeField]
public Button _removeButton;
public void SetItem(SellableItemSO item)
{
_name.text = item.ItemName;
_price.text = $"{item.Price}$";
_icon.sprite = item.Icon;
}
}
+11
View File
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5de15a198a3ca5240a6c21ae0a8c6c8f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+62
View File
@@ -0,0 +1,62 @@
using Assets.Scripts.Interfaces;
using Cysharp.Threading.Tasks;
using System;
using System.Collections.Generic;
using UnityEngine;
public class UISystem : MonoBehaviour
{
[SerializeField]
private TimeSliderUI _timeSliderPrefab;
[SerializeField]
private DialogOptionsUI _DialogUIPrefab;
[SerializeField]
private GameObject _blurOverlay;
[SerializeField]
private RadialMenuItem _radialMenuItemPrefab;
RadialMenuItem _popupMenu;
private void Start()
{
_blurOverlay.SetActive(false);
}
public void ShowTimeSliderDialog(string title, string description, Action onCancel, Action<TimeSpan> onConfirm)
{
var timeSlider = Instantiate(_timeSliderPrefab, transform);
timeSlider.ShowTimeSliderDialog(title, description, onCancel, onConfirm);
}
public void ShowTabOptionsDialog(DialogSO dialogSO, Action onCancel, Action<IDialogOption> onConfirm)
{
var dialog = Instantiate(_DialogUIPrefab, transform);
dialog.ShowCategoriesDialog(dialogSO, onCancel, onConfirm);
}
public async UniTask<RadialMenuActions> ShowItemPopupMenu(Dictionary<RadialMenuActions, RadialMenuActionDescription> actions)
{
_popupMenu = Instantiate(_radialMenuItemPrefab);
_popupMenu.transform.transform.SetParent(transform, false);
_popupMenu.transform.position = Input.mousePosition;
return await _popupMenu.ShowButtons(actions);
}
public void ClosePopupMenu()
{
if (_popupMenu != null)
{
_popupMenu.CancelAndClose();
}
}
public void Freeze()
{
_blurOverlay.SetActive(true);
}
public void Unfreeze()
{
_blurOverlay.SetActive(false);
}
}
+11
View File
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 152bb7481f494844aa5ddb27a421f8b4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: