646 lines
24 KiB
C#
646 lines
24 KiB
C#
using System.Collections;
|
||
using UnityEngine;
|
||
using UnityEngine.UI;
|
||
using UnityEngine.SceneManagement;
|
||
|
||
namespace GameFramework
|
||
{
|
||
/// <summary>
|
||
/// 游戏失败叠加层 —— 直接挂在 Gameplay 场景的 Canvas 上。
|
||
///
|
||
/// 使用方式:
|
||
/// 1. 在 Gameplay 场景里创建一个空物体,挂上本脚本
|
||
/// 2. 运行一次游戏(或点 Editor 按钮),脚本会自动构建子 UI
|
||
/// 3. 停止运行后,子 UI 留在场景中,可自由编辑样式/位置/精灵
|
||
/// 4. 运行时由 GameManager 调用 GameLostOverlay.Show() 激活
|
||
///
|
||
/// 所有 UI 元素均为 [SerializeField],可在 Inspector 中替换。
|
||
/// </summary>
|
||
public class GameLostOverlay : MonoBehaviour
|
||
{
|
||
private static GameLostOverlay _instance;
|
||
|
||
// ====== Canvas ======
|
||
[Header("Canvas(留空则自动创建)")]
|
||
[SerializeField] private Canvas lostCanvas;
|
||
|
||
// ====== UI 元素引用(全部可编辑) ======
|
||
[Header("背景蒙版")]
|
||
[SerializeField] private Image dimBackground;
|
||
|
||
[Header("标题 —— 你已迷失……")]
|
||
[SerializeField] private Text lostTitleText;
|
||
[SerializeField] private Image lostTitleImage; // 可用图片替代文字
|
||
|
||
[Header("装饰")]
|
||
[SerializeField] private Image leftDecoration;
|
||
[SerializeField] private Image rightDecoration;
|
||
|
||
[Header("主界面按钮")]
|
||
[SerializeField] private Button mainMenuButton;
|
||
[SerializeField] private Image mainMenuButtonImage;
|
||
|
||
[Header("音效")]
|
||
[SerializeField] private AudioData lostSFX;
|
||
|
||
[Header("标题渐现动效")]
|
||
[Tooltip("标题渐现总时长(秒)")]
|
||
[SerializeField] private float titleFadeDuration = 1.5f;
|
||
[Tooltip("水面波纹位置抖动幅度(像素)")]
|
||
[SerializeField] private float ripplePositionAmplitude = 8f;
|
||
[Tooltip("水面波纹缩放抖动幅度")]
|
||
[SerializeField] private float rippleScaleAmplitude = 0.08f;
|
||
[Tooltip("水面波纹频率(越大抖动越快)")]
|
||
[SerializeField] private float rippleFrequency = 15f;
|
||
[Tooltip("水波纹材质(留空则自动从 Shader 创建)")]
|
||
[SerializeField] private Material rippleMaterial;
|
||
[Tooltip("主界面按钮延迟出现时间(秒)")]
|
||
[SerializeField] private float buttonFadeDelay = 2f;
|
||
[Tooltip("按钮渐现时长(秒)")]
|
||
[SerializeField] private float buttonFadeDuration = 0.5f;
|
||
|
||
private bool _isVisible;
|
||
private Coroutine _titleAnimCoroutine;
|
||
private Coroutine _buttonFadeCoroutine;
|
||
private Material _rippleMaterial;
|
||
|
||
// ====================================================================
|
||
// 静态入口
|
||
// ====================================================================
|
||
|
||
/// <summary>
|
||
/// 显示失败叠加层。优先使用场景中已有的实例,
|
||
/// 没有则动态创建一个。
|
||
/// </summary>
|
||
public static void Show()
|
||
{
|
||
// 场景中已有(隐藏的)实例?
|
||
if (_instance != null)
|
||
{
|
||
_instance.Activate();
|
||
return;
|
||
}
|
||
|
||
// 尝试在场景中找到
|
||
var found = FindObjectOfType<GameLostOverlay>();
|
||
if (found != null)
|
||
{
|
||
_instance = found;
|
||
found.Activate();
|
||
return;
|
||
}
|
||
|
||
// 都没有 → 动态创建
|
||
var obj = new GameObject("GameLostOverlay");
|
||
var overlay = obj.AddComponent<GameLostOverlay>();
|
||
overlay.BuildAll();
|
||
overlay.Activate();
|
||
}
|
||
|
||
// ====================================================================
|
||
// 生命周期
|
||
// ====================================================================
|
||
|
||
void Awake()
|
||
{
|
||
_instance = this;
|
||
|
||
// 如果 Canvas 还没赋值,尝试从自身获取
|
||
if (lostCanvas == null)
|
||
lostCanvas = GetComponent<Canvas>();
|
||
|
||
// 初始隐藏
|
||
if (lostCanvas != null)
|
||
lostCanvas.enabled = false;
|
||
}
|
||
|
||
void Update()
|
||
{
|
||
if (!_isVisible) return;
|
||
|
||
if (Input.GetKeyDown(KeyCode.Return) || Input.GetKeyDown(KeyCode.Space) || Input.GetKeyDown(KeyCode.Escape))
|
||
{
|
||
ReturnToMainMenu();
|
||
}
|
||
}
|
||
|
||
// ====================================================================
|
||
// 激活 / 隐藏
|
||
// ====================================================================
|
||
|
||
private void Activate()
|
||
{
|
||
_isVisible = true;
|
||
|
||
if (lostCanvas != null)
|
||
lostCanvas.enabled = true;
|
||
|
||
// 自动查找标题元素(兜底:Inspector 未赋值时从 Canvas 子节点中找)
|
||
AutoFindTitleElement();
|
||
|
||
Debug.Log($"[GameLostOverlay] Activate - lostTitleImage={lostTitleImage != null}, lostTitleText={lostTitleText != null}, canvas={lostCanvas != null}");
|
||
|
||
// 启动标题渐现动效(水面波纹 + 渐现)
|
||
if (_titleAnimCoroutine != null)
|
||
StopCoroutine(_titleAnimCoroutine);
|
||
_titleAnimCoroutine = StartCoroutine(TitleRippleFadeIn());
|
||
|
||
// 绑定按钮 + 延迟渐现
|
||
if (mainMenuButton != null)
|
||
{
|
||
mainMenuButton.onClick.RemoveAllListeners();
|
||
mainMenuButton.onClick.AddListener(ReturnToMainMenu);
|
||
|
||
// 初始隐藏按钮
|
||
SetButtonAlpha(0f);
|
||
|
||
// 延迟后渐现
|
||
if (_buttonFadeCoroutine != null)
|
||
StopCoroutine(_buttonFadeCoroutine);
|
||
_buttonFadeCoroutine = StartCoroutine(ButtonFadeIn());
|
||
}
|
||
|
||
// 音效
|
||
if (AudioManager.Instance != null && lostSFX != null)
|
||
AudioManager.Instance.PlaySFX(lostSFX);
|
||
|
||
// 显示鼠标
|
||
Cursor.visible = true;
|
||
Cursor.lockState = CursorLockMode.None;
|
||
|
||
// 确保 EventSystem 有输入模块(UI 点击必需)
|
||
EnsureEventSystemInputModule();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 确保 EventSystem 有 StandaloneInputModule,否则 UI 按钮无法响应点击。
|
||
/// </summary>
|
||
private void EnsureEventSystemInputModule()
|
||
{
|
||
var es = UnityEngine.EventSystems.EventSystem.current;
|
||
if (es == null) return;
|
||
if (es.GetComponent<UnityEngine.EventSystems.StandaloneInputModule>() == null)
|
||
{
|
||
es.gameObject.AddComponent<UnityEngine.EventSystems.StandaloneInputModule>();
|
||
Debug.Log("[GameLostOverlay] 已自动添加 StandaloneInputModule");
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 按钮延迟渐现协程:等待 buttonFadeDelay 秒后,用 buttonFadeDuration 秒渐现。
|
||
/// </summary>
|
||
private IEnumerator ButtonFadeIn()
|
||
{
|
||
yield return new WaitForSecondsRealtime(buttonFadeDelay);
|
||
|
||
float elapsed = 0f;
|
||
while (elapsed < buttonFadeDuration)
|
||
{
|
||
elapsed += Time.unscaledDeltaTime;
|
||
float t = Mathf.Clamp01(elapsed / buttonFadeDuration);
|
||
SetButtonAlpha(t);
|
||
yield return null;
|
||
}
|
||
SetButtonAlpha(1f);
|
||
|
||
if (mainMenuButton != null)
|
||
mainMenuButton.Select();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设置按钮整体透明度(通过 Image.color.a)。
|
||
/// </summary>
|
||
private void SetButtonAlpha(float alpha)
|
||
{
|
||
if (mainMenuButtonImage != null)
|
||
{
|
||
var c = mainMenuButtonImage.color;
|
||
c.a = alpha;
|
||
mainMenuButtonImage.color = c;
|
||
}
|
||
// 同时处理按钮子物体的 Text
|
||
if (mainMenuButton != null)
|
||
{
|
||
var texts = mainMenuButton.GetComponentsInChildren<Text>(true);
|
||
foreach (var t in texts)
|
||
{
|
||
var c = t.color;
|
||
c.a = alpha;
|
||
t.color = c;
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 返回主界面。
|
||
/// </summary>
|
||
private void ReturnToMainMenu()
|
||
{
|
||
_isVisible = false;
|
||
|
||
Time.timeScale = 1f;
|
||
Cursor.visible = true;
|
||
Cursor.lockState = CursorLockMode.None;
|
||
|
||
if (SceneLoader.Instance != null)
|
||
SceneLoader.Instance.LoadMainMenuScene();
|
||
else
|
||
SceneManager.LoadScene("MainMenu");
|
||
}
|
||
|
||
/// <summary>
|
||
/// 自动查找标题元素。搜索范围:
|
||
/// 1. 自身 transform 子节点
|
||
/// 2. 场景中所有 Canvas 的子节点
|
||
/// 3. 都找不到则动态创建
|
||
/// </summary>
|
||
private void AutoFindTitleElement()
|
||
{
|
||
if (lostTitleImage != null || lostTitleText != null) return;
|
||
|
||
// 1. 从自身子节点查找
|
||
TryFindTitleInHierarchy(transform);
|
||
if (lostTitleText != null || lostTitleImage != null) return;
|
||
|
||
// 2. 从 lostCanvas 子节点查找
|
||
if (lostCanvas != null)
|
||
{
|
||
TryFindTitleInHierarchy(lostCanvas.transform);
|
||
if (lostTitleText != null || lostTitleImage != null) return;
|
||
}
|
||
|
||
// 3. 从场景中所有 Canvas 查找
|
||
var allCanvases = FindObjectsOfType<Canvas>();
|
||
foreach (var c in allCanvases)
|
||
{
|
||
if (c == lostCanvas) continue;
|
||
TryFindTitleInHierarchy(c.transform);
|
||
if (lostTitleText != null || lostTitleImage != null) return;
|
||
}
|
||
|
||
// 4. 都找不到
|
||
Debug.LogWarning("[GameLostOverlay] 未找到标题元素,请在 Inspector 中拖入 lostTitleImage 或 lostTitleText。");
|
||
}
|
||
|
||
private void TryFindTitleInHierarchy(Transform root)
|
||
{
|
||
// 按路径查找
|
||
var titleObj = root.Find("CenterPanel/LostTitle");
|
||
if (titleObj != null)
|
||
{
|
||
lostTitleImage = titleObj.GetComponent<Image>();
|
||
if (lostTitleImage != null) return;
|
||
lostTitleText = titleObj.GetComponent<Text>();
|
||
if (lostTitleText != null) return;
|
||
}
|
||
|
||
// 按名称查找 Image(lostTitleImage 节点)
|
||
var allImages = root.GetComponentsInChildren<Image>(true);
|
||
foreach (var img in allImages)
|
||
{
|
||
var name = img.gameObject.name.ToLower();
|
||
if (name.Contains("lost") || name.Contains("title") || name.Contains("迷失"))
|
||
{
|
||
lostTitleImage = img;
|
||
return;
|
||
}
|
||
}
|
||
|
||
// 按文字内容查找 Text
|
||
var allTexts = root.GetComponentsInChildren<Text>(true);
|
||
foreach (var t in allTexts)
|
||
{
|
||
if (t.text.Contains("迷失") || t.text.Contains("Lost"))
|
||
{
|
||
lostTitleText = t;
|
||
return;
|
||
}
|
||
}
|
||
|
||
// 兜底:第一个非按钮 Text
|
||
foreach (var t in allTexts)
|
||
{
|
||
if (t.GetComponentInParent<Button>() == null)
|
||
{
|
||
lostTitleText = t;
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 标题渐现动效:Shader 水波纹扭曲 + 透明度渐现。
|
||
/// 前 60% 时间波纹强烈,后 40% 时间波纹减弱至消失。
|
||
/// 使用 unscaledDeltaTime 不受 timeScale 暂停影响。
|
||
/// </summary>
|
||
private IEnumerator TitleRippleFadeIn()
|
||
{
|
||
float elapsed = 0f;
|
||
|
||
// 优先用图片(Shader 动效),其次用文字(抖动动效)
|
||
Image titleImg = lostTitleImage;
|
||
Text titleTxt = lostTitleText;
|
||
|
||
// ---- Image: Shader 水波纹 ----
|
||
if (titleImg != null)
|
||
{
|
||
// 创建/获取水波纹材质
|
||
if (_rippleMaterial == null)
|
||
{
|
||
// 优先用 Inspector 拖入的材质
|
||
if (rippleMaterial != null)
|
||
{
|
||
_rippleMaterial = rippleMaterial;
|
||
Debug.Log("[GameLostOverlay] 使用 Inspector 指定的水波纹材质。");
|
||
}
|
||
else
|
||
{
|
||
var shader = Shader.Find("GameFramework/UI/WaterRippleFade");
|
||
if (shader == null)
|
||
{
|
||
Debug.LogWarning("[GameLostOverlay] 找不到 WaterRippleFade Shader!请确认 Assets/UI/shaders/WaterRippleFade.shader 存在且无编译错误。回退到抖动动效。");
|
||
}
|
||
else
|
||
{
|
||
_rippleMaterial = new Material(shader);
|
||
_rippleMaterial.SetFloat("_RippleAmplitude", ripplePositionAmplitude / 100f);
|
||
_rippleMaterial.SetFloat("_RippleFrequency", rippleFrequency);
|
||
_rippleMaterial.SetFloat("_RippleSpeed", 3f);
|
||
Debug.Log($"[GameLostOverlay] 已创建水波纹材质 - Amp={ripplePositionAmplitude / 100f}, Freq={rippleFrequency}");
|
||
}
|
||
}
|
||
}
|
||
|
||
if (_rippleMaterial != null)
|
||
{
|
||
titleImg.material = _rippleMaterial;
|
||
_rippleMaterial.SetFloat("_RippleIntensity", 1f);
|
||
_rippleMaterial.SetFloat("_FadeAlpha", 0f);
|
||
}
|
||
|
||
while (elapsed < titleFadeDuration)
|
||
{
|
||
elapsed += Time.unscaledDeltaTime;
|
||
float t = Mathf.Clamp01(elapsed / titleFadeDuration);
|
||
|
||
// 波纹强度:前 60% 强,后 40% 衰减至 0
|
||
float rippleIntensity;
|
||
if (t < 0.6f)
|
||
rippleIntensity = 1f;
|
||
else
|
||
rippleIntensity = Mathf.InverseLerp(1f, 0.6f, t);
|
||
|
||
// 渐现曲线(EaseOut)
|
||
float fadeT = 1f - Mathf.Pow(1f - t, 2.5f);
|
||
|
||
if (_rippleMaterial != null)
|
||
{
|
||
_rippleMaterial.SetFloat("_RippleIntensity", rippleIntensity);
|
||
_rippleMaterial.SetFloat("_FadeAlpha", fadeT);
|
||
}
|
||
|
||
yield return null;
|
||
}
|
||
|
||
// 确保最终状态
|
||
if (_rippleMaterial != null)
|
||
{
|
||
_rippleMaterial.SetFloat("_RippleIntensity", 0f);
|
||
_rippleMaterial.SetFloat("_FadeAlpha", 1f);
|
||
}
|
||
yield break;
|
||
}
|
||
|
||
// ---- Text: 抖动动效(回退方案) ----
|
||
if (titleTxt != null)
|
||
{
|
||
var titleTransform = titleTxt.rectTransform;
|
||
var c = titleTxt.color;
|
||
c.a = 0f;
|
||
titleTxt.color = c;
|
||
Vector2 targetPosition = titleTransform.anchoredPosition;
|
||
Vector3 targetScale = titleTransform.localScale;
|
||
|
||
while (elapsed < titleFadeDuration)
|
||
{
|
||
elapsed += Time.unscaledDeltaTime;
|
||
float t = Mathf.Clamp01(elapsed / titleFadeDuration);
|
||
|
||
float rippleIntensity = t < 0.6f ? 1f : Mathf.InverseLerp(1f, 0.6f, t);
|
||
float fadeT = 1f - Mathf.Pow(1f - t, 2.5f);
|
||
|
||
float jitterX = Random.Range(-1f, 1f) * ripplePositionAmplitude * rippleIntensity;
|
||
float jitterY = Random.Range(-1f, 1f) * ripplePositionAmplitude * rippleIntensity * 0.5f;
|
||
float jitterScale = Random.Range(-1f, 1f) * rippleScaleAmplitude * rippleIntensity;
|
||
|
||
titleTransform.anchoredPosition = targetPosition + new Vector2(jitterX, jitterY);
|
||
titleTransform.localScale = targetScale * (1f + jitterScale);
|
||
|
||
var col = titleTxt.color;
|
||
col.a = fadeT;
|
||
titleTxt.color = col;
|
||
|
||
yield return null;
|
||
}
|
||
|
||
titleTransform.anchoredPosition = targetPosition;
|
||
titleTransform.localScale = targetScale;
|
||
var finalCol = titleTxt.color;
|
||
finalCol.a = 1f;
|
||
titleTxt.color = finalCol;
|
||
}
|
||
}
|
||
|
||
// ====================================================================
|
||
// Editor 辅助:一键构建 UI 子节点(在场景编辑时调用)
|
||
// ====================================================================
|
||
|
||
#if UNITY_EDITOR
|
||
/// <summary>
|
||
/// 在 Unity 编辑器中调用此方法,自动构建所有 UI 子节点。
|
||
/// 构建完成后停止运行,即可在 Inspector 中编辑所有引用。
|
||
/// </summary>
|
||
[ContextMenu("构建 UI(Build UI)")]
|
||
public void EditorBuildUI()
|
||
{
|
||
BuildAll();
|
||
// 构建完显示 Canvas 方便预览
|
||
if (lostCanvas != null)
|
||
lostCanvas.enabled = true;
|
||
Debug.Log("[GameLostOverlay] UI 构建完成,可在场景中编辑。");
|
||
}
|
||
#endif
|
||
|
||
// ====================================================================
|
||
// 动态构建 UI(首次使用 / 无预制体时)
|
||
// ====================================================================
|
||
|
||
/// <summary>
|
||
/// 构建整个 UI 结构。构建后所有引用自动填入 SerializeField。
|
||
/// </summary>
|
||
private void BuildAll()
|
||
{
|
||
// ---- Canvas ----
|
||
if (lostCanvas == null)
|
||
{
|
||
var canvasObj = new GameObject("LostCanvas");
|
||
canvasObj.transform.SetParent(transform, false);
|
||
|
||
lostCanvas = canvasObj.AddComponent<Canvas>();
|
||
lostCanvas.renderMode = RenderMode.ScreenSpaceOverlay;
|
||
lostCanvas.sortingOrder = 100000;
|
||
|
||
var scaler = canvasObj.AddComponent<CanvasScaler>();
|
||
scaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize;
|
||
scaler.referenceResolution = new Vector2(1920, 1080);
|
||
scaler.matchWidthOrHeight = 0.5f;
|
||
|
||
canvasObj.AddComponent<GraphicRaycaster>();
|
||
}
|
||
|
||
var root = lostCanvas.gameObject;
|
||
|
||
// ---- 全屏暗色蒙版 ----
|
||
if (dimBackground == null)
|
||
dimBackground = CreateFullScreenImage(root, "DimBackground", new Color(0f, 0f, 0f, 0.6f));
|
||
|
||
// ---- 中央面板 ----
|
||
var centerPanel = FindOrCreateChild(root, "CenterPanel");
|
||
var cpRect = centerPanel.GetComponent<RectTransform>();
|
||
if (cpRect.anchorMin == Vector2.zero && cpRect.anchorMax == Vector2.zero)
|
||
{
|
||
cpRect.anchorMin = new Vector2(0.15f, 0.3f);
|
||
cpRect.anchorMax = new Vector2(0.85f, 0.75f);
|
||
cpRect.sizeDelta = Vector2.zero;
|
||
}
|
||
|
||
// ---- 左装饰 ----
|
||
if (leftDecoration == null)
|
||
leftDecoration = CreateDecoration(centerPanel, "LeftDecoration", true);
|
||
|
||
// ---- 右装饰 ----
|
||
if (rightDecoration == null)
|
||
rightDecoration = CreateDecoration(centerPanel, "RightDecoration", false);
|
||
|
||
// ---- 标题文字 ----
|
||
if (lostTitleText == null && lostTitleImage == null)
|
||
{
|
||
lostTitleText = CreateTitleText(centerPanel);
|
||
}
|
||
|
||
// ---- 主界面按钮 ----
|
||
if (mainMenuButton == null)
|
||
CreateMainMenuButton(centerPanel);
|
||
}
|
||
|
||
// ------ 构建子元素 ------
|
||
|
||
private Image CreateFullScreenImage(GameObject parent, string name, Color color)
|
||
{
|
||
var obj = new GameObject(name);
|
||
obj.transform.SetParent(parent.transform, false);
|
||
var rect = obj.AddComponent<RectTransform>();
|
||
rect.anchorMin = Vector2.zero;
|
||
rect.anchorMax = Vector2.one;
|
||
rect.sizeDelta = Vector2.zero;
|
||
var img = obj.AddComponent<Image>();
|
||
img.color = color;
|
||
return img;
|
||
}
|
||
|
||
private GameObject FindOrCreateChild(GameObject parent, string name)
|
||
{
|
||
var t = parent.transform.Find(name);
|
||
if (t != null) return t.gameObject;
|
||
|
||
var obj = new GameObject(name);
|
||
obj.transform.SetParent(parent.transform, false);
|
||
obj.AddComponent<RectTransform>();
|
||
return obj;
|
||
}
|
||
|
||
private Image CreateDecoration(GameObject parent, string name, bool isLeft)
|
||
{
|
||
var obj = new GameObject(name);
|
||
obj.transform.SetParent(parent.transform, false);
|
||
var rect = obj.AddComponent<RectTransform>();
|
||
rect.anchorMin = new Vector2(0.5f, 0.5f);
|
||
rect.anchorMax = new Vector2(0.5f, 0.5f);
|
||
rect.pivot = new Vector2(0.5f, 0.5f);
|
||
rect.sizeDelta = new Vector2(120, 200);
|
||
rect.anchoredPosition = new Vector2(isLeft ? -300 : 300, 0);
|
||
var img = obj.AddComponent<Image>();
|
||
img.color = new Color(0.9f, 0.4f, 0.5f, 0.5f);
|
||
return img;
|
||
}
|
||
|
||
private Text CreateTitleText(GameObject parent)
|
||
{
|
||
var obj = new GameObject("LostTitle");
|
||
obj.transform.SetParent(parent.transform, false);
|
||
var rect = obj.AddComponent<RectTransform>();
|
||
rect.anchorMin = new Vector2(0.5f, 0.5f);
|
||
rect.anchorMax = new Vector2(0.5f, 0.5f);
|
||
rect.pivot = new Vector2(0.5f, 0.5f);
|
||
rect.anchoredPosition = new Vector2(0, 30);
|
||
rect.sizeDelta = new Vector2(800, 120);
|
||
|
||
var text = obj.AddComponent<Text>();
|
||
text.text = "你已迷失……";
|
||
text.fontSize = 72;
|
||
text.alignment = TextAnchor.MiddleCenter;
|
||
text.color = Color.white;
|
||
text.font = Resources.GetBuiltinResource<Font>("LegacyRuntime.ttf");
|
||
text.fontStyle = FontStyle.Bold;
|
||
|
||
var shadow = obj.AddComponent<Shadow>();
|
||
shadow.effectColor = new Color(0f, 0f, 0f, 0.5f);
|
||
shadow.effectDistance = new Vector2(3, -3);
|
||
|
||
var outline = obj.AddComponent<Outline>();
|
||
outline.effectColor = new Color(0.3f, 0.1f, 0.1f, 0.6f);
|
||
outline.effectDistance = new Vector2(2, -2);
|
||
|
||
return text;
|
||
}
|
||
|
||
private void CreateMainMenuButton(GameObject parent)
|
||
{
|
||
var btnObj = new GameObject("MainMenuButton");
|
||
btnObj.transform.SetParent(parent.transform, false);
|
||
|
||
var btnRect = btnObj.AddComponent<RectTransform>();
|
||
btnRect.anchorMin = new Vector2(0.5f, 0.5f);
|
||
btnRect.anchorMax = new Vector2(0.5f, 0.5f);
|
||
btnRect.pivot = new Vector2(0.5f, 0.5f);
|
||
btnRect.anchoredPosition = new Vector2(0, -80);
|
||
btnRect.sizeDelta = new Vector2(200, 60);
|
||
|
||
var btnImage = btnObj.AddComponent<Image>();
|
||
btnImage.color = new Color(1f, 1f, 1f, 0.2f);
|
||
|
||
mainMenuButtonImage = btnImage;
|
||
|
||
var textObj = new GameObject("Text");
|
||
textObj.transform.SetParent(btnObj.transform, false);
|
||
var textRect = textObj.AddComponent<RectTransform>();
|
||
textRect.anchorMin = Vector2.zero;
|
||
textRect.anchorMax = Vector2.one;
|
||
textRect.sizeDelta = Vector2.zero;
|
||
|
||
var text = textObj.AddComponent<Text>();
|
||
text.text = "主界面";
|
||
text.fontSize = 28;
|
||
text.alignment = TextAnchor.MiddleCenter;
|
||
text.color = Color.white;
|
||
text.font = Resources.GetBuiltinResource<Font>("LegacyRuntime.ttf");
|
||
|
||
mainMenuButton = btnObj.AddComponent<Button>();
|
||
var colors = mainMenuButton.colors;
|
||
colors.highlightedColor = new Color(1.2f, 1.2f, 1.2f);
|
||
colors.pressedColor = new Color(0.8f, 0.8f, 0.8f);
|
||
mainMenuButton.colors = colors;
|
||
}
|
||
}
|
||
}
|