(client)feat:实现子弹定义以及生成,实现初始化动画,实现血条 (#43)

Co-authored-by: zzdxxz <2079238449@qq.com>
Co-committed-by: zzdxxz <2079238449@qq.com>
This commit is contained in:
2025-08-19 20:22:10 +08:00
committed by TheRedApricot
parent 670f778eee
commit d91210a6ff
119 changed files with 4797 additions and 2929 deletions

View File

@ -0,0 +1,151 @@
using System;
using UnityEngine;
using System.Collections.Generic;
using UnityEngine.UI;
namespace Base
{
// 定义渐变方向枚举
[AddComponentMenu("UI/Effects/Gradient")]
public enum Dir
{
Horizontal, // 水平方向
Vertical, // 垂直方向
}
// 自定义梯度效果类继承自BaseMeshEffect
public class Gradient : BaseMeshEffect
{
[SerializeField] // 序列化字段可在Inspector中编辑
private Dir dir = Dir.Vertical; // 渐变方向,默认垂直
[SerializeField]
public Color32 color1 = Color.white; // 渐变起始颜色,默认白色
[SerializeField]
public Color32 color2 = Color.white; // 渐变结束颜色,默认白色
[SerializeField]
private float range = 0f; // 渐变范围,控制颜色的过渡区域,默认无范围(完全渐变)
[SerializeField]
private bool isFlip = false; // 是否翻转渐变方向,默认不翻转
public void Refresh()
{
graphic.SetVerticesDirty();
}
// 重写ModifyMesh方法用于修改UI元素的网格
public override void ModifyMesh(VertexHelper vh)
{
if (!IsActive()) // 如果组件未激活,则不执行后续操作
{
return;
}
var count = vh.currentVertCount; // 获取当前顶点数量
if (count > 0) // 如果有顶点,则进行处理
{
var vertices = new List<UIVertex>(); // 创建顶点列表
// 遍历所有顶点并添加到列表中
for (var i = 0; i < count; i++)
{
var uIVertex = new UIVertex();
vh.PopulateUIVertex(ref uIVertex, i); // 填充顶点信息
vertices.Add(uIVertex);
}
// 根据渐变方向调用相应的绘制方法
switch (dir)
{
case Dir.Horizontal:
DrawHorizontal(vh, vertices, count);
break;
case Dir.Vertical:
DrawVertical(vh, vertices, count);
break;
default:
throw new ArgumentOutOfRangeException();
}
}
}
// 绘制垂直方向的渐变
private void DrawVertical(VertexHelper vh, List<UIVertex> vertices, int count)
{
// 初始化顶部和底部Y坐标
var topY = vertices[0].position.y;
var bottomY = vertices[0].position.y;
// 遍历所有顶点找到最高和最低的Y坐标
for (var i = 0; i < count; i++)
{
var y = vertices[i].position.y;
if (y > topY) topY = y;
else if (y < bottomY) bottomY = y;
}
var height = topY - bottomY; // 计算高度差
// 遍历所有顶点,设置颜色渐变
for (var i = 0; i < count; i++)
{
var vertex = vertices[i];
Color32 color = Color.white;
// 根据是否翻转,计算当前顶点的颜色
if (isFlip)
{
color = Color32.Lerp(color2, color1, 1 - (vertex.position.y - bottomY) / height * (1f - range));
}
else
{
color = Color32.Lerp(color2, color1, (vertex.position.y - bottomY) / height * (1f - range));
}
vertex.color = color; // 设置顶点颜色
vh.SetUIVertex(vertex, i); // 更新网格中的顶点
}
}
// 绘制水平方向的渐变
private void DrawHorizontal(VertexHelper vh, List<UIVertex> vertices, int count)
{
// 注意这里应该是找到最左和最右的X坐标注释中存在笔误
var leftX = vertices[0].position.x;
var rightX = vertices[0].position.x;
// 遍历所有顶点找到最左和最右的X坐标
for (var i = 0; i < count; i++)
{
var x = vertices[i].position.x;
if (x > rightX) rightX = x;
else if (x < leftX) leftX = x;
}
var width = rightX - leftX; // 计算宽度差
// 遍历所有顶点,设置颜色渐变
for (var i = 0; i < count; i++)
{
var vertex = vertices[i];
Color32 color = Color.white;
// 根据是否翻转,计算当前顶点的颜色
if (isFlip)
{
color = Color32.Lerp(color2, color1, 1 - (vertex.position.x - leftX) / width * (1f - range));
}
else
{
color = Color32.Lerp(color2, color1, (vertex.position.x - leftX) / width * (1f - range));
}
vertex.color = color; // 设置顶点颜色
vh.SetUIVertex(vertex, i); // 更新网格中的顶点
}
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 8df3d16a358d74644b86e92ca5177fa1

View File

@ -0,0 +1,150 @@
using System.Collections;
using Logging;
using TMPro;
using UnityEngine;
namespace Base
{
public class Launcher : MonoBehaviour
{
public GameObject loadingUI;
public Gradient progressBar; // 渐变色条
public TMP_Text describeText; // 描述文本
public float duration = 0.5f; // 过渡时间
public float fadeDuration = 2f; // 不透明度渐隐的时间
private float _currentProgress = 0f; // 当前进度
private Color textColor;
private readonly string[] _loadingSteps =
{
"初始化日志", "正在载入定义", "正在加载图片资源", "正在切割瓦片", "正在加载区分派系",
"正在加载物品"
};
public float Progress
{
set
{
_currentProgress = value;
if (value < 0.5f)
{
progressBar.color2 = Color.Lerp(Color.black, Color.white, value * 2);
}
else
{
progressBar.color2 = Color.white;
progressBar.color1 = Color.Lerp(Color.black, Color.white, (value - 0.5f) * 2);
}
progressBar.Refresh();
}
}
public float Opacity
{
set
{
var alpha = (byte)(value * 255);
progressBar.color1.a = alpha;
progressBar.color2.a = alpha;
describeText.color = value > 0.5f ? Color.Lerp(new Color(1, 1, 1, 0), textColor, (value - 0.5f) * 2) : new Color(1, 1, 1, 0);
progressBar.Refresh();
}
}
private void Start()
{
Base.Setting.Instance.Init();
#if !DEBUG
duration = Base.Setting.Instance.progressStepDuration;
fadeDuration = Base.Setting.Instance.exitAnimationDuration;
#endif
loadingUI.SetActive(true);
textColor = describeText.color;
StartCoroutine(LoadAllManagers());
}
private IEnumerator LoadAllManagers()
{
for (var i = 0; i < _loadingSteps.Length; i++)
{
// 更新描述文本
describeText.text = _loadingSteps[i];
// 获取当前阶段的目标进度
var targetProgress = (float)(i + 1) / _loadingSteps.Length;
// 平滑过渡到下一个阶段
yield return SmoothTransitionTo(targetProgress);
// 初始化对应的管理器
switch (i)
{
case 0:
UnityLogger.Init();
break;
case 1:
Managers.DefineManager.Instance.Init();
break;
case 2:
Managers.PackagesImageManager.Instance.Init();
break;
case 3:
Managers.TileManager.Instance.Init();
break;
case 4:
Managers.AffiliationManager.Instance.Init();
break;
case 5:
Managers.ItemResourceManager.Instance.Init();
break;
}
}
// 加载完成后的处理
describeText.text = "加载完成!";
Progress = 1f;
// 开始渐隐效果
yield return FadeOutProgressBar();
}
private IEnumerator SmoothTransitionTo(float targetProgress)
{
var startProgress = _currentProgress;
var elapsedTime = 0f;
while (elapsedTime < duration)
{
elapsedTime += Time.deltaTime;
var t = Mathf.SmoothStep(0f, 1f, elapsedTime / duration); // 使用 SmoothStep 实现平滑过渡
Progress = Mathf.Lerp(startProgress, targetProgress, t);
yield return null;
}
// 确保最终进度达到目标值
Progress = targetProgress;
}
private IEnumerator FadeOutProgressBar()
{
var elapsedTime = 0f;
while (elapsedTime < fadeDuration)
{
elapsedTime += Time.deltaTime;
var t = Mathf.SmoothStep(0f, 1f, elapsedTime / fadeDuration); // 使用 SmoothStep 实现平滑渐隐
Opacity = 1f - t; // 不透明度从 1 到 0
yield return null;
}
// 确保最终不透明度为 0
Opacity = 0f;
loadingUI.SetActive(false);
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 1966ff90f1854aee9ca89d700abef90d
timeCreated: 1755438497

View File

@ -0,0 +1,90 @@
using Newtonsoft.Json;
using UnityEngine;
namespace Base
{
public class Setting : Utils.Singleton<Setting>
{
// 游戏设置数据类(用于序列化)
[System.Serializable]
public class GameSettings
{
public float progressStepDuration = 1f;
public float exitAnimationDuration = 2f;
public bool developerMode = false;
public bool friendlyFire = false;
public float globalVolume = 1.0f;
public WindowMode currentWindowMode = WindowMode.Fullscreen;
public Vector2Int windowResolution = new(1920, 1080);
}
// 当前游戏设置
public GameSettings CurrentSettings = new();
// 窗口模式枚举
public enum WindowMode { Fullscreen, Windowed, Borderless }
// 常用分辨率选项
public static readonly Vector2Int[] CommonResolutions = new Vector2Int[]
{
new(800, 600),
new(1024, 768),
new(1280, 720),
new(1366, 768),
new(1600, 900),
new(1920, 1080),
new(2560, 1440),
new(3840, 2160)
};
// 初始化加载设置
public void Init()
{
LoadSettings();
}
public void SaveSettings()
{
string json = JsonConvert.SerializeObject(CurrentSettings);
PlayerPrefs.SetString("GameSettings", json);
PlayerPrefs.Save();
}
public void LoadSettings()
{
if (PlayerPrefs.HasKey("GameSettings"))
{
string json = PlayerPrefs.GetString("GameSettings");
CurrentSettings = JsonConvert.DeserializeObject<GameSettings>(json);
}
// 应用加载的设置
ApplyAudioSettings();
ApplyWindowSettings();
}
// 应用音频设置
private void ApplyAudioSettings()
{
AudioListener.volume = Mathf.Clamp01(CurrentSettings.globalVolume);
}
// 应用窗口设置
private void ApplyWindowSettings()
{
switch (CurrentSettings.currentWindowMode)
{
case WindowMode.Fullscreen:
Screen.SetResolution(CurrentSettings.windowResolution.x, CurrentSettings.windowResolution.y, FullScreenMode.FullScreenWindow);
break;
case WindowMode.Windowed:
Screen.SetResolution(CurrentSettings.windowResolution.x, CurrentSettings.windowResolution.y, FullScreenMode.Windowed);
break;
case WindowMode.Borderless:
Screen.SetResolution(CurrentSettings.windowResolution.x, CurrentSettings.windowResolution.y, FullScreenMode.MaximizedWindow);
break;
}
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 9eb8b1554550478c85cc87558920ec6b
timeCreated: 1755524879