chore: initialize standalone UPM package
Publish UPM package / publish (push) Failing after 1s

This commit is contained in:
2026-08-26 02:50:43 +08:00
commit 1180be88a6
72 changed files with 3331 additions and 0 deletions
@@ -0,0 +1,277 @@
using System.Collections;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
namespace ShrinkTutorial
{
public class ShrinkTutorialSampleSceneController : MonoBehaviour
{
public const string TutorialId = "sample.shrink_tutorial.basic";
public const string RewardAnchorId = "sample.reward.item";
public const string RewardClaimEventName = "sample.reward.claimed";
[SerializeField] private Button openInventoryButton;
[SerializeField] private Button spawnRewardButton;
[SerializeField] private GameObject inventoryPanel;
[SerializeField] private RectTransform rewardContainer;
[SerializeField] private TextMeshProUGUI statusText;
private Button _spawnedRewardButton;
private void Awake()
{
AutoWire();
BindButtons();
LogDebug($"Awake, openButton={DescribeObject(openInventoryButton)}, spawnButton={DescribeObject(spawnRewardButton)}, inventoryPanel={DescribeObject(inventoryPanel)}");
if (inventoryPanel)
inventoryPanel.SetActive(false);
ClearRewardItems();
SetStatus("Waiting for tutorial start.");
}
private IEnumerator Start()
{
yield return null;
var tutorialManager = ShrinkTutorialManager.EnsureInstance();
tutorialManager.ClearProgress(TutorialId);
tutorialManager.StartTutorial(TutorialId);
}
private void OnDestroy()
{
if (openInventoryButton)
openInventoryButton.onClick.RemoveListener(HandleOpenInventory);
if (spawnRewardButton)
spawnRewardButton.onClick.RemoveListener(HandleSpawnReward);
if (_spawnedRewardButton)
_spawnedRewardButton.onClick.RemoveListener(HandleClaimReward);
}
private void Reset()
{
AutoWire();
}
private void OnValidate()
{
AutoWire();
}
public void HandleOpenInventory()
{
LogDebug($"HandleOpenInventory before, inventoryActive={inventoryPanel && inventoryPanel.activeSelf}");
if (inventoryPanel)
inventoryPanel.SetActive(true);
SetStatus("Inventory panel opened.");
LogDebug($"HandleOpenInventory after, inventoryActive={inventoryPanel && inventoryPanel.activeSelf}");
}
public void HandleSpawnReward()
{
LogDebug($"HandleSpawnReward start, hasReward={_spawnedRewardButton}");
if (!rewardContainer)
return;
if (_spawnedRewardButton)
{
SetStatus("Reward item has already been created.");
return;
}
var buttonObject = new GameObject("RuntimeRewardButton",
typeof(RectTransform),
typeof(Image),
typeof(Button),
typeof(LayoutElement),
typeof(ShrinkTutorialAnchor));
var rectTransform = buttonObject.GetComponent<RectTransform>();
rectTransform.SetParent(rewardContainer, false);
rectTransform.anchorMin = new Vector2(0f, 0.5f);
rectTransform.anchorMax = new Vector2(1f, 0.5f);
rectTransform.pivot = new Vector2(0.5f, 0.5f);
rectTransform.offsetMin = new Vector2(0f, 0f);
rectTransform.offsetMax = new Vector2(0f, 0f);
rectTransform.sizeDelta = new Vector2(0f, 58f);
var image = buttonObject.GetComponent<Image>();
image.color = new Color(0.18f, 0.48f, 0.28f, 1f);
var button = buttonObject.GetComponent<Button>();
button.targetGraphic = image;
button.onClick.AddListener(HandleClaimReward);
_spawnedRewardButton = button;
var layoutElement = buttonObject.GetComponent<LayoutElement>();
layoutElement.minHeight = 58f;
layoutElement.preferredHeight = 58f;
layoutElement.preferredWidth = 420f;
layoutElement.flexibleWidth = 1f;
var anchor = buttonObject.GetComponent<ShrinkTutorialAnchor>();
anchor.SetAnchorId(RewardAnchorId);
var labelObject = new GameObject("Label", typeof(RectTransform), typeof(TextMeshProUGUI));
var labelRect = labelObject.GetComponent<RectTransform>();
labelRect.SetParent(rectTransform, false);
labelRect.anchorMin = Vector2.zero;
labelRect.anchorMax = Vector2.one;
labelRect.offsetMin = Vector2.zero;
labelRect.offsetMax = Vector2.zero;
var label = labelObject.GetComponent<TextMeshProUGUI>();
label.text = "Claim Runtime Reward";
label.fontSize = 24f;
label.alignment = TextAlignmentOptions.Center;
label.color = Color.white;
label.enableWordWrapping = false;
label.overflowMode = TextOverflowModes.Ellipsis;
if (spawnRewardButton)
spawnRewardButton.interactable = false;
LayoutRebuilder.ForceRebuildLayoutImmediate(rewardContainer);
Canvas.ForceUpdateCanvases();
SetStatus("Reward button created. Waiting for dynamic anchor step.");
LogDebug($"HandleSpawnReward created reward button, path={GetTransformPath(buttonObject.transform)}");
}
public void HandleClaimReward()
{
LogDebug($"HandleClaimReward start, hasReward={_spawnedRewardButton}");
if (_spawnedRewardButton)
{
_spawnedRewardButton.interactable = false;
var image = _spawnedRewardButton.GetComponent<Image>();
if (image)
image.color = new Color(0.25f, 0.25f, 0.25f, 1f);
var label = _spawnedRewardButton.GetComponentInChildren<TextMeshProUGUI>();
if (label)
label.text = "Reward Claimed";
}
SetStatus("Custom completion event sent.");
ShrinkTutorialManager.Instance?.CompleteStep(RewardClaimEventName);
LogDebug($"HandleClaimReward complete, event={RewardClaimEventName}");
}
private void BindButtons()
{
if (openInventoryButton)
{
openInventoryButton.onClick.RemoveListener(HandleOpenInventory);
openInventoryButton.onClick.AddListener(HandleOpenInventory);
LogDebug($"Bound openInventoryButton -> {GetTransformPath(openInventoryButton.transform)}");
}
if (spawnRewardButton)
{
spawnRewardButton.onClick.RemoveListener(HandleSpawnReward);
spawnRewardButton.onClick.AddListener(HandleSpawnReward);
LogDebug($"Bound spawnRewardButton -> {GetTransformPath(spawnRewardButton.transform)}");
}
}
private void AutoWire()
{
if (!openInventoryButton)
openInventoryButton = FindButton("Tutorial Sample Canvas/OpenInventoryButton");
if (!spawnRewardButton)
spawnRewardButton = FindButton("Tutorial Sample Canvas/InventoryPanel/SpawnRewardButton");
if (!inventoryPanel)
{
var inventoryTransform = transform.Find("Tutorial Sample Canvas/InventoryPanel");
inventoryPanel = inventoryTransform ? inventoryTransform.gameObject : null;
}
if (!rewardContainer)
rewardContainer = FindRectTransform("Tutorial Sample Canvas/InventoryPanel/RewardContainer");
if (!statusText)
statusText = FindText("Tutorial Sample Canvas/StatusText");
}
private void ClearRewardItems()
{
if (!rewardContainer)
return;
for (var i = rewardContainer.childCount - 1; i >= 0; i--)
{
Destroy(rewardContainer.GetChild(i).gameObject);
}
_spawnedRewardButton = null;
if (spawnRewardButton)
spawnRewardButton.interactable = true;
}
private void SetStatus(string text)
{
if (statusText)
statusText.text = text;
}
private Button FindButton(string path)
{
var target = transform.Find(path);
return target ? target.GetComponent<Button>() : null;
}
private RectTransform FindRectTransform(string path)
{
var target = transform.Find(path);
return target ? target as RectTransform : null;
}
private TextMeshProUGUI FindText(string path)
{
var target = transform.Find(path);
return target ? target.GetComponent<TextMeshProUGUI>() : null;
}
[System.Diagnostics.Conditional("UNITY_EDITOR")]
private static void LogDebug(string message)
{
if (!IsDebugLoggingEnabled())
return;
Debug.Log($"[ShrinkTutorialSample][Debug] {message}");
}
private static bool IsDebugLoggingEnabled()
{
return false;
}
private static string DescribeObject(Object value)
{
return value ? value.name : "<null>";
}
private static string GetTransformPath(Transform transform)
{
if (!transform)
return "<null>";
var path = transform.name;
while (transform.parent)
{
transform = transform.parent;
path = $"{transform.name}/{path}";
}
return path;
}
}
}