Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

[English](CHANGELOG_EN.md) | 中文

## v1.8.2

- 优化了 UI 组件的布局和初始化逻辑,使用 UIFactory 方法简化代码,提升可读性
- 改进了事件订阅清理逻辑,防止内存泄漏

## v1.8.1

- 新增音效标签 `trigger_on_hurt`,用于角色受伤时自动播放音效
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG_EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

English | [中文](CHANGELOG.md)

## v1.8.2

- Optimized UI component layout and initialization logic, simplified code using UIFactory methods, improved readability
- Improved event subscription cleanup logic to prevent memory leaks

## v1.8.1

- Added sound tag `trigger_on_hurt` for automatically playing sounds when a character is hurt
Expand Down
2 changes: 1 addition & 1 deletion DuckovCustomModel/Constant.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ public static class Constant
{
public const string ModID = "DuckovCustomModel";
public const string ModName = "Duckov Custom Model";
public const string ModVersion = "1.8.1";
public const string ModVersion = "1.8.2";
public const string HarmonyId = "com.ritsukage.DuckovCustomModel";
}
}
10 changes: 3 additions & 7 deletions DuckovCustomModel/UI/Components/FunctionButtonBar.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ public void Initialize(Transform parent)
layoutElement.flexibleHeight = 1;
layoutElement.preferredHeight = 80;

buttonBar.AddComponent<HorizontalLayoutGroup>();
UIFactory.SetupHorizontalLayoutGroup(buttonBar, 10f, new(10, 10, 10, 10));

BuildRefreshButton(buttonBar);
Expand All @@ -50,8 +49,7 @@ private void BuildRefreshButton(GameObject parent)
{
_refreshButton = UIFactory.CreateButton("RefreshButton", parent.transform, OnRefreshButtonClicked,
new(0.2f, 0.3f, 0.4f, 1)).GetComponent<Button>();
var refreshButtonRect = _refreshButton.GetComponent<RectTransform>();
refreshButtonRect.sizeDelta = new(180, 0);
UIFactory.SetupRectTransform(_refreshButton.gameObject, Vector2.zero, Vector2.zero, new(180, 0));

var refreshButtonLayoutElement = _refreshButton.gameObject.AddComponent<LayoutElement>();
refreshButtonLayoutElement.preferredWidth = 180;
Expand All @@ -70,8 +68,7 @@ private void BuildResetInvalidModelsButton(GameObject parent)
{
_resetInvalidModelsButton = UIFactory.CreateButton("ResetInvalidModelsButton", parent.transform,
OnResetInvalidModelsButtonClicked, new(0.4f, 0.2f, 0.2f, 1)).GetComponent<Button>();
var resetButtonRect = _resetInvalidModelsButton.GetComponent<RectTransform>();
resetButtonRect.sizeDelta = new(180, 0);
UIFactory.SetupRectTransform(_resetInvalidModelsButton.gameObject, Vector2.zero, Vector2.zero, new(180, 0));

var resetButtonLayoutElement = _resetInvalidModelsButton.gameObject.AddComponent<LayoutElement>();
resetButtonLayoutElement.preferredWidth = 180;
Expand All @@ -96,8 +93,7 @@ private void BuildOpenModelFolderButton(GameObject parent)
{
_openModelFolderButton = UIFactory.CreateButton("OpenModelFolderButton", parent.transform,
OnOpenModelFolderButtonClicked, new(0.3f, 0.5f, 0.3f, 1)).GetComponent<Button>();
var openFolderButtonRect = _openModelFolderButton.GetComponent<RectTransform>();
openFolderButtonRect.sizeDelta = new(180, 0);
UIFactory.SetupRectTransform(_openModelFolderButton.gameObject, Vector2.zero, Vector2.zero, new(180, 0));

var openFolderButtonLayoutElement = _openModelFolderButton.gameObject.AddComponent<LayoutElement>();
openFolderButtonLayoutElement.preferredWidth = 180;
Expand Down
98 changes: 34 additions & 64 deletions DuckovCustomModel/UI/Components/ModelListPanel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,11 @@ public void Initialize(Transform parent)
UIFactory.SetupRectTransform(scrollView.gameObject, Vector2.zero, Vector2.one, Vector2.zero);

_scrollRect = scrollView;

_content = content;
_content.AddComponent<VerticalLayoutGroup>();
_content.AddComponent<ContentSizeFitter>();

UIFactory.SetupVerticalLayoutGroup(_content, 10f, new(10, 10, 10, 10), TextAnchor.UpperLeft,
true, false, true);

var sizeFitter = _content.GetComponent<ContentSizeFitter>();
sizeFitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
sizeFitter.horizontalFit = ContentSizeFitter.FitMode.Unconstrained;
UIFactory.SetupContentSizeFitter(_content, ContentSizeFitter.FitMode.Unconstrained);
Comment thread
BAKAOLC marked this conversation as resolved.
}

public void SetTarget(TargetInfo? targetInfo)
Expand Down Expand Up @@ -246,11 +240,7 @@ private void BuildNoneModelButton()
new(0.2f, 0.15f, 0.15f, 0.8f)).gameObject;
buttonObj.transform.SetAsFirstSibling();

var buttonRect = buttonObj.GetComponent<RectTransform>();
buttonRect.anchorMin = new(0, 0);
buttonRect.anchorMax = new(1, 0);
buttonRect.pivot = new(0.5f, 0.5f);
buttonRect.sizeDelta = new(0, 150);
UIFactory.SetupRectTransform(buttonObj, new(0, 0), new(1, 0), new(0, 150), pivot: new(0.5f, 0.5f));

var layoutElement = buttonObj.AddComponent<LayoutElement>();
layoutElement.minHeight = 150;
Expand All @@ -263,9 +253,7 @@ private void BuildNoneModelButton()
outline.effectDistance = new(1, -1);

var text = UIFactory.CreateText("Text", buttonObj.transform, Localization.NoModel, 16, Color.white,
TextAnchor.MiddleCenter);
var textComponent = text.GetComponent<Text>();
textComponent.fontStyle = FontStyle.Bold;
TextAnchor.MiddleCenter, FontStyle.Bold);
UIFactory.SetupButtonText(text);

var button = buttonObj.GetComponent<Button>();
Expand All @@ -292,22 +280,15 @@ private async UniTask BuildModelButtonAsync(ModelBundleInfo bundle, ModelInfo mo
isInUse = usingModel.GetModelID(_currentTarget.TargetType) == model.ModelID;
}

var buttonObj = new GameObject($"ModelButton_{model.ModelID}", typeof(Image), typeof(Button),
typeof(LayoutElement));
buttonObj.transform.SetParent(_content.transform, false);

var buttonImage = buttonObj.GetComponent<Image>();
Color baseColor = hasError ? new(0.22f, 0.15f, 0.15f, 0.8f) : new(0.15f, 0.18f, 0.22f, 0.8f);
if (isInUse && !hasError) baseColor = new(0.15f, 0.22f, 0.18f, 0.8f);
buttonImage.color = baseColor;

var buttonRect = buttonObj.GetComponent<RectTransform>();
buttonRect.anchorMin = new(0, 0);
buttonRect.anchorMax = new(1, 0);
buttonRect.pivot = new(0.5f, 0.5f);
buttonRect.sizeDelta = new(0, 150);
var buttonObj = UIFactory.CreateButton($"ModelButton_{model.ModelID}", _content.transform, null, baseColor)
.gameObject;

var layoutElement = buttonObj.GetComponent<LayoutElement>();
UIFactory.SetupRectTransform(buttonObj, new(0, 0), new(1, 0), new(0, 150), pivot: new(0.5f, 0.5f));

var layoutElement = buttonObj.AddComponent<LayoutElement>();
layoutElement.minHeight = 150;
layoutElement.preferredHeight = 150;
layoutElement.flexibleWidth = 0;
Expand All @@ -322,15 +303,12 @@ private async UniTask BuildModelButtonAsync(ModelBundleInfo bundle, ModelInfo mo
: new(0.3f, 0.35f, 0.4f, 0.6f);
outline.effectDistance = new(1, -1);

var thumbnailImage = new GameObject("Thumbnail", typeof(Image), typeof(LayoutElement));
thumbnailImage.transform.SetParent(buttonObj.transform, false);
var thumbnailImage = UIFactory.CreateImage("Thumbnail", buttonObj.transform);
thumbnailImage.AddComponent<LayoutElement>();
var thumbnailImageComponent = thumbnailImage.GetComponent<Image>();
var thumbnailRect = thumbnailImage.GetComponent<RectTransform>();
thumbnailRect.anchorMin = new(0, 0.5f);
thumbnailRect.anchorMax = new(0, 0.5f);
thumbnailRect.pivot = new(0, 0.5f);
thumbnailRect.anchoredPosition = new(10, 0);
thumbnailRect.sizeDelta = new(130, 130);

UIFactory.SetupRectTransform(thumbnailImage, new(0, 0.5f), new(0, 0.5f), new(130, 130),
pivot: new(0, 0.5f), anchoredPosition: new(10, 0));

var thumbnailLayoutElement = thumbnailImage.GetComponent<LayoutElement>();
thumbnailLayoutElement.minWidth = 130;
Expand Down Expand Up @@ -361,12 +339,11 @@ private async UniTask BuildModelButtonAsync(ModelBundleInfo bundle, ModelInfo mo
UIFactory.SetupRectTransform(placeholderText, Vector2.zero, Vector2.one, Vector2.zero);
}

var contentArea = new GameObject("ContentArea", typeof(RectTransform), typeof(VerticalLayoutGroup));
var contentArea = new GameObject("ContentArea", typeof(RectTransform));
contentArea.transform.SetParent(buttonObj.transform, false);
UIFactory.SetupRectTransform(contentArea, new(0, 0), new(1, 1), offsetMin: new(150, 10),
offsetMax: new(-10, -10));
UIFactory.SetupVerticalLayoutGroup(contentArea, 2f, new(0, 0, 0, 0), TextAnchor.UpperLeft,
true, false, true);
UIFactory.SetupVerticalLayoutGroup(contentArea, 2f, new(0, 0, 0, 0), TextAnchor.UpperLeft, true, true);
Comment thread
BAKAOLC marked this conversation as resolved.

var nameText = UIFactory.CreateText("Name", contentArea.transform,
string.IsNullOrEmpty(model.Name) ? model.ModelID : model.Name, 20,
Expand All @@ -388,45 +365,38 @@ private async UniTask BuildModelButtonAsync(ModelBundleInfo bundle, ModelInfo mo

if (hasError)
{
var errorText = new GameObject("Error", typeof(Text), typeof(ContentSizeFitter));
errorText.transform.SetParent(contentArea.transform, false);
var errorText = UIFactory.CreateText("Error", contentArea.transform,
$"⚠ {(!string.IsNullOrEmpty(errorMessage) ? errorMessage : "Unknown error")}", 15,
new(1f, 0.4f, 0.4f, 1), TextAnchor.UpperLeft, FontStyle.Bold);
var errorTextComponent = errorText.GetComponent<Text>();
errorTextComponent.text = $"⚠ {(!string.IsNullOrEmpty(errorMessage) ? errorMessage : "Unknown error")}";
errorTextComponent.font = Resources.GetBuiltinResource<Font>("Arial.ttf");
errorTextComponent.fontSize = 15;
errorTextComponent.color = new(1f, 0.4f, 0.4f, 1);
errorTextComponent.alignment = TextAnchor.UpperLeft;
errorTextComponent.fontStyle = FontStyle.Bold;
errorTextComponent.horizontalOverflow = HorizontalWrapMode.Wrap;
errorTextComponent.verticalOverflow = VerticalWrapMode.Overflow;
var errorRect = errorText.GetComponent<RectTransform>();
errorRect.sizeDelta = new(0, 20);

UIFactory.SetupRectTransform(errorText, Vector2.zero, Vector2.one, new(0, 20));

var errorLayoutElement = errorText.AddComponent<LayoutElement>();
errorLayoutElement.minHeight = 20;
errorLayoutElement.flexibleHeight = 1;
var contentSizeFitter = errorText.GetComponent<ContentSizeFitter>();
contentSizeFitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize;

UIFactory.SetupContentSizeFitter(errorText, ContentSizeFitter.FitMode.Unconstrained);
}

if (!string.IsNullOrEmpty(model.Description))
{
var descText = new GameObject("Description", typeof(Text), typeof(ContentSizeFitter));
descText.transform.SetParent(contentArea.transform, false);
var descSpacer = new GameObject("DescriptionSpacer", typeof(RectTransform));
descSpacer.transform.SetParent(contentArea.transform, false);
var descSpacerLayout = descSpacer.AddComponent<LayoutElement>();
descSpacerLayout.minHeight = 10;
descSpacerLayout.preferredHeight = 10;
descSpacerLayout.flexibleHeight = 0;

var descText = UIFactory.CreateText("Description", contentArea.transform, model.Description, 15,
new(0.7f, 0.7f, 0.7f, 1), TextAnchor.UpperLeft);
var descTextComponent = descText.GetComponent<Text>();
descTextComponent.text = model.Description;
descTextComponent.font = Resources.GetBuiltinResource<Font>("Arial.ttf");
descTextComponent.fontSize = 15;
descTextComponent.color = new(0.7f, 0.7f, 0.7f, 1);
descTextComponent.alignment = TextAnchor.UpperLeft;
descTextComponent.horizontalOverflow = HorizontalWrapMode.Wrap;
descTextComponent.verticalOverflow = VerticalWrapMode.Overflow;
var descRect = descText.GetComponent<RectTransform>();
descRect.sizeDelta = new(0, 20);
var descLayoutElement = descText.AddComponent<LayoutElement>();
descLayoutElement.minHeight = 20;
descLayoutElement.flexibleHeight = 1;
var contentSizeFitter = descText.GetComponent<ContentSizeFitter>();
contentSizeFitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize;

Comment thread
BAKAOLC marked this conversation as resolved.
UIFactory.SetupContentSizeFitter(descText, ContentSizeFitter.FitMode.Unconstrained);
}

var button = buttonObj.GetComponent<Button>();
Expand Down
14 changes: 3 additions & 11 deletions DuckovCustomModel/UI/Components/TargetListPanel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,10 @@ public void Initialize(Transform parent)
scrollViewImage.color = new(0.05f, 0.08f, 0.12f, 0.8f);

_scrollRect = scrollView;

_content = content;
_content.AddComponent<VerticalLayoutGroup>();
_content.AddComponent<ContentSizeFitter>();

UIFactory.SetupVerticalLayoutGroup(_content, 10f, new(10, 10, 10, 10), TextAnchor.UpperLeft,
false);

var sizeFitter = _content.GetComponent<ContentSizeFitter>();
sizeFitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
sizeFitter.horizontalFit = ContentSizeFitter.FitMode.Unconstrained;
UIFactory.SetupVerticalLayoutGroup(_content, 10f, new(10, 10, 10, 10), TextAnchor.UpperLeft, false);
UIFactory.SetupContentSizeFitter(_content, ContentSizeFitter.FitMode.Unconstrained);
Comment thread
BAKAOLC marked this conversation as resolved.
}

public void Refresh()
Expand Down Expand Up @@ -119,8 +112,7 @@ private void BuildTargetButton(TargetInfo targetInfo)

var buttonObj = UIFactory.CreateButton($"TargetButton_{targetInfo.Id}", _content.transform,
() => OnTargetButtonClicked(targetInfo)).gameObject;
var buttonRect = buttonObj.GetComponent<RectTransform>();
buttonRect.sizeDelta = new(180, 50);
UIFactory.SetupRectTransform(buttonObj, Vector2.zero, Vector2.zero, new(180, 50));

var layoutElement = buttonObj.AddComponent<LayoutElement>();
layoutElement.minHeight = 50;
Expand Down
Loading
Loading