gameplay所有基本功能都装了,加入了全局警告。加入飘字等各种东西。

This commit is contained in:
FloatGaming
2026-02-21 00:20:03 +08:00
parent 9f7c1c57b7
commit 14fb281d6f
254 changed files with 102927 additions and 9427 deletions
+89
View File
@@ -0,0 +1,89 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
namespace Bansonic
{
/// <summary>
/// 全局通知系统入口
/// 使用方式:gNotice.message.display("内容");
/// </summary>
public static class gNotice
{
// --- 事件定义:用于通知 UI 层 ---
/// <summary>
/// 当任何通知被显示时触发
/// 参数1:类型前缀(如 [Info])
/// 参数2:消息内容
/// </summary>
public static event Action<string, string, float?, float?> OnNoticeDisplay;
/// <summary>
/// 当任何通知被中断显示时触发
/// </summary>
public static event Action OnNoticeInterrupt;
// --- 静态实例定义 (直接注入行为,无需枚举) ---
/// <summary>普通消息</summary>
public static readonly NoticeChannel message = new NoticeChannel("[Info]", Debug.Log);
/// <summary>建议</summary>
public static readonly NoticeChannel recommendation = new NoticeChannel("[Recommendation]", Debug.Log);
/// <summary>警告</summary>
public static readonly NoticeChannel warning = new NoticeChannel("[Warning]", Debug.LogWarning);
/// <summary>错误</summary>
public static readonly NoticeChannel error = new NoticeChannel("[Error]", Debug.LogError);
/// <summary>警报</summary>
public static readonly NoticeChannel alarm = new NoticeChannel("[Alarm]", Debug.LogWarning);
// --- 内部核心实现 ---
/// <summary>
/// 通知通道类:封装了通用的 display 和 interrupt 逻辑
/// </summary>
public class NoticeChannel
{
private readonly string _prefix;
private readonly Action<object> _logAction;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="prefix">日志前缀,如 [Info]</param>
/// <param name="logAction">具体的日志输出方法,如 Debug.Log</param>
internal NoticeChannel(string prefix, Action<object> logAction)
{
_prefix = prefix;
_logAction = logAction;
}
/// <summary>
/// 显示消息
/// </summary>
public void display(object message, float? waitTime = null, float? fadeTotalTime = null)
{
string content = message?.ToString() ?? "null";
_logAction($"{_prefix} {content}");
// 触发 UI 事件
OnNoticeDisplay?.Invoke(_prefix, content, waitTime, fadeTotalTime);
}
/// <summary>
/// 立即终止当前正在展示的全部警告prefab
/// </summary>
public void interrupt()
{
// 触发 UI 事件
OnNoticeInterrupt?.Invoke();
}
}
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: f18837bb8147555448daa0c0b161e81a
Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

+156
View File
@@ -0,0 +1,156 @@
fileFormatVersion: 2
guid: 1b1e113e4f51df34c981c4ebc66fb1b7
TextureImporter:
internalIDToNameTable:
- first:
213: 7676382691749075051
second: TIP_0
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 985, y: 730, z: 985, w: 753}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Android
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites:
- serializedVersion: 2
name: TIP_0
rect:
serializedVersion: 2
x: 989
y: 736
width: 576
height: 64
alignment: 0
pivot: {x: 0.5, y: 0.5}
border: {x: 0, y: 0, z: 0, w: 0}
customData:
outline: []
physicsShape: []
tessellationDetail: -1
bones: []
spriteID: b6819ad036df78a60800000000000000
internalID: 7676382691749075051
vertices: []
indices:
edges: []
weights: []
outline: []
customData:
physicsShape: []
bones: []
spriteID: 5e97eb03825dee720800000000000000
internalID: 1537655665
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable:
TIP_0: 7676382691749075051
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,6 @@
using UnityEngine;
public class _globalNoticeSystem : MonoBehaviour
{
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 0b0c42cdd2b31504ab977f0e2d0a77ae
+220
View File
@@ -0,0 +1,220 @@
using UnityEngine;
using UnityEngine.UI;
// using TMPro;
using System.Collections;
using Bansonic;
public class _gnp : MonoBehaviour
{
private const float DEFAULT_DISPLAY_DURATION = 0.5f;
private const float DEFAULT_FADE_TOTAL_TIME = 0.25f;
private const float DEFAULT_FADE_UP_DISTANCE = 20f;
private const float CANVAS_PLANE_DISTANCE = 10f;
private const string PREFAB_RESOURCE_NAME = "GlobalNoticeSystem";
private const string SCENE_INSTANCE_NAME = "GlobalNoticeSystem_SceneInstance";
[Header("UI Components")]
[SerializeField] private Text _noticeText;
[SerializeField] private Image _iconImage;
[SerializeField] private CanvasGroup _canvasGroup;
[Header("Icon Colors")]
[SerializeField] private Color _colorMessage = Color.white;
[SerializeField] private Color _colorRecommendation = Color.white;
[SerializeField] private Color _colorWarning = Color.yellow;
[SerializeField] private Color _colorError = Color.red;
[SerializeField] private Color _colorAlarm = Color.yellow;
[Header("Settings")]
[SerializeField] private float _displayDuration = DEFAULT_DISPLAY_DURATION;
[SerializeField] private float _fade_up_distance = DEFAULT_FADE_UP_DISTANCE;
[SerializeField] private float _fadeTotalTime = DEFAULT_FADE_TOTAL_TIME;
private Coroutine _fadeCoroutine;
private RectTransform _rectTransform;
private Vector3 _initialLocalPosition;
private static _gnp _currentInstance;
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)]
private static void InitGlobalListener()
{
// 确保只订阅一次,避免重复
gNotice.OnNoticeDisplay -= StaticHandleDisplay;
gNotice.OnNoticeInterrupt -= StaticHandleInterrupt;
gNotice.OnNoticeDisplay += StaticHandleDisplay;
gNotice.OnNoticeInterrupt += StaticHandleInterrupt;
}
private static void StaticHandleDisplay(string prefix, string message, float? waitTime, float? fadeTotalTime)
{
// 如果已有实例,先销毁(单例模式,覆盖旧消息)
if (_currentInstance != null)
{
Destroy(_currentInstance.gameObject);
}
GameObject prefab = Resources.Load<GameObject>(PREFAB_RESOURCE_NAME);
if (prefab == null) return;
GameObject instance = Instantiate(prefab);
instance.name = SCENE_INSTANCE_NAME;
_currentInstance = instance.GetComponent<_gnp>();
if (_currentInstance != null)
{
_currentInstance.Display(prefix, message, waitTime, fadeTotalTime);
}
}
private static void StaticHandleInterrupt()
{
if (_currentInstance != null)
{
_currentInstance.Interrupt();
}
}
private void Awake()
{
_rectTransform = transform as RectTransform;
if (_rectTransform != null)
{
_initialLocalPosition = _rectTransform.localPosition;
}
if (_canvasGroup == null)
{
_canvasGroup = GetComponent<CanvasGroup>();
if (_canvasGroup == null)
{
_canvasGroup = gameObject.AddComponent<CanvasGroup>();
}
}
// 初始化 Canvas 设置
Canvas canvas = GetComponent<Canvas>();
if (canvas != null && canvas.renderMode == RenderMode.ScreenSpaceCamera)
{
Camera mainCam = Camera.main;
if (mainCam != null)
{
canvas.worldCamera = mainCam;
canvas.planeDistance = CANVAS_PLANE_DISTANCE;
}
else
{
Camera anyCam = FindFirstObjectByType<Camera>();
if (anyCam != null)
{
canvas.worldCamera = anyCam;
}
}
}
SetComponentsActive(false);
SetCanvasAlpha(0f);
}
private void OnEnable()
{
// 实例被启用时的逻辑(如果需要)
}
private void OnDisable()
{
// 实例被禁用时的逻辑(如果需要)
}
private void OnDestroy()
{
if (_currentInstance == this)
{
_currentInstance = null;
}
}
public void Display(string prefix, string message, float? waitTime, float? fadeTotalTime)
{
Color iconColor = GetColorByPrefix(prefix);
float wait = waitTime ?? _displayDuration;
float fade = fadeTotalTime ?? _fadeTotalTime;
if (_noticeText != null) _noticeText.text = message ?? "null";
if (_iconImage != null) _iconImage.color = iconColor;
if (_rectTransform != null)
{
_rectTransform.localPosition = _initialLocalPosition;
}
SetCanvasAlpha(1f);
SetComponentsActive(true);
transform.SetAsLastSibling();
if (_fadeCoroutine != null) StopCoroutine(_fadeCoroutine);
_fadeCoroutine = StartCoroutine(FadeRoutine(wait, fade));
}
public void Interrupt()
{
// 立即销毁
if (gameObject != null)
{
Destroy(gameObject);
}
}
private IEnumerator FadeRoutine(float displayDuration, float fadeTotalTime)
{
if (displayDuration > 0f)
{
yield return new WaitForSeconds(displayDuration);
}
if (fadeTotalTime <= 0f)
{
SetCanvasAlpha(0f);
Destroy(gameObject);
yield break;
}
float elapsed = 0f;
while (elapsed < fadeTotalTime)
{
elapsed += Time.deltaTime;
float t = Mathf.Clamp01(elapsed / fadeTotalTime);
SetCanvasAlpha(1f - t);
if (_rectTransform != null)
{
_rectTransform.localPosition = _initialLocalPosition + Vector3.up * (_fade_up_distance * t);
}
yield return null;
}
SetCanvasAlpha(0f);
Destroy(gameObject);
}
private void SetComponentsActive(bool isActive)
{
if (_noticeText != null) _noticeText.gameObject.SetActive(isActive);
if (_iconImage != null) _iconImage.gameObject.SetActive(isActive);
}
private void SetCanvasAlpha(float value)
{
if (_canvasGroup != null) _canvasGroup.alpha = value;
}
private Color GetColorByPrefix(string prefix)
{
if (prefix.Contains("Info")) return _colorMessage;
if (prefix.Contains("Recommendation")) return _colorRecommendation;
if (prefix.Contains("Warning")) return _colorWarning;
if (prefix.Contains("Error")) return _colorError;
if (prefix.Contains("Alarm")) return _colorAlarm;
return _colorMessage;
}
}
+2
View File
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: fc4356408408c7a4981b59a39be930f3