提交小游戏项目

This commit is contained in:
2026-07-06 16:27:14 +08:00
commit 2a717c6a2f
7575 changed files with 710847 additions and 0 deletions
+52
View File
@@ -0,0 +1,52 @@
using System.IO;
using System.Text;
using System.Security.Cryptography;
namespace TowerClimberChronicles
{
public class AESForFileKit
{
private static readonly byte[] Salt = Encoding.UTF8.GetBytes(LegendConstant.nifldg);
private const int Iterations = 1000;
public static void EncryptFile(string inputPath, string outputPath, string password)
{
var passwordBytes = Encoding.UTF8.GetBytes(password);
var inputStream = new FileStream(inputPath, FileMode.Open, FileAccess.Read);
var outputStream = new FileStream(outputPath, FileMode.Create, FileAccess.Write);
using var aes = new AesManaged();
var key = new Rfc2898DeriveBytes(passwordBytes, Salt, Iterations);
aes.Key = key.GetBytes(aes.KeySize / 8);
aes.IV = key.GetBytes(aes.BlockSize / 8);
using var cryptoStream = new CryptoStream(outputStream, aes.CreateEncryptor(), CryptoStreamMode.Write);
inputStream.CopyTo(cryptoStream);
cryptoStream.FlushFinalBlock();
cryptoStream.Close();
outputStream.Close();
inputStream.Close();
}
public static byte[] DecryptToBytes(string inputPath, string password, out int dataSize)
{
var passwordBytes = Encoding.UTF8.GetBytes(password);
var inputStream = new FileStream(inputPath, FileMode.Open, FileAccess.Read);
var outputMemoryStream = new MemoryStream();
using (var aes = new AesManaged())
{
var key = new Rfc2898DeriveBytes(passwordBytes, Salt, Iterations);
aes.Key = key.GetBytes(aes.KeySize / 8);
aes.IV = key.GetBytes(aes.BlockSize / 8);
using (var cryptoStream = new CryptoStream(inputStream, aes.CreateDecryptor(), CryptoStreamMode.Read))
{
cryptoStream.CopyTo(outputMemoryStream);
}
}
var outputBytes = outputMemoryStream.ToArray();
dataSize = outputBytes.Length;
return outputBytes;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 429efb8e8784c764387a3d6f29225252
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+118
View File
@@ -0,0 +1,118 @@
// #if UNITY_EDITOR
using System.Text;
using UnityEngine;
using UnityEngine.Events;
using Object = UnityEngine.Object;
namespace TowerClimberChronicles
{
public class AssetDataBaseKit : Singleton<AssetDataBaseKit>, ILoadAsset
{
private string assetRootPath = "LoveLegendAssets/";
public T GetAsset<T>(string dfsad, string sa) where T : Object
{
// try
// {
var asPath = new StringBuilder(AssetPathFormat(dfsad));
if (sa.EndsWith("!a.png"))
{
// assetFullPath = AssetPathFormat(dfsad, sa);
}
else
{
sa = sa.Split(".")[0];
}
var asset = Resources.Load<T>(asPath.ToString() + "/" + sa);
if (asset == null)
{
Debug.LogError($"[Jarvis] [AssetDataBaseKit] 未能加载资源: {asPath}/{sa}");
return default; // 或者返回一个备用资源,或者抛出异常
}
return asset;
// }
// catch (System.Exception e)
// {
// Debug.Log($"[Jarvis] [AssetDataBaseKit] 错误堆栈:{e.StackTrace}");
// Debug.LogError($"[Jarvis] [AssetDataBaseKit] 加载资源时发生错误: {e.Message}");
// return default; // 或者返回一个备用资源,或者抛出异常
// }
// var assetPath = new StringBuilder(AssetPathFormat(dfsad));
// var assetFullPath = "";
// if (sa.EndsWith("!a.png"))
// {
// assetFullPath = AssetPathFormat(dfsad, sa);
// }
// else
// {
// sa = sa.Split(".")[0];
// var assets = AssetDatabase.FindAssets(sa, new[] { assetPath.ToString() });
// var nameFilter = sa + ".";
// foreach (var temp in assets)
// {
// var fullPath = AssetDatabase.GUIDToAssetPath(temp);
// if (fullPath.Contains(nameFilter))
// {
// assetFullPath = fullPath;
// break;
// }
// }
// }
// var asset = AssetDatabase.LoadAssetAtPath<T>(assetFullPath);
// return asset;
}
public void GetAsset<T>(string dfsad, string sa, UnityAction<T> onCompleted) where T : Object
{
// try
// {
var asset = GetAsset<T>(dfsad, sa);
onCompleted?.Invoke(asset);
// }
// catch (System.Exception e)
// {
// Debug.Log($"[ Jarvis ] [ GetAsset ] 错误堆栈:{e.StackTrace}");
// Debug.LogError($"[ Jarvis ] [ GetAsset ] 异步加载资源 {sa} 时发生错误: {e.Message}");
// onCompleted?.Invoke(default); // 可能需要通知用户加载失败
// }
}
public void RecycleAsset(string assetUrl, UnityAction onCompleted)
{
onCompleted?.Invoke();
}
private string AssetPathFormat(string assetUrl, string assetName)
{
var replace = assetUrl.Replace(".", "/");
var sb = new StringBuilder(replace);
var folderPath = sb + "/";
var assetPath = $"{assetRootPath}{folderPath}{assetName}";
return assetPath;
}
private string AssetPathFormat(string assetUrl)
{
var assetPath = $"{assetRootPath}{assetUrl.Replace(".", "/")}";
return assetPath;
}
public static T GetAssetstatic<T>(string assetUrl, string assetName) where T : Object
{
var assetPath = $"{"LoveLegendAssets/"}{assetUrl.Replace(".", "/")}";
assetName = assetName.Split(".")[0];
var asset = Resources.Load<T>(assetPath.ToString() + "/" + assetName);
return asset;
}
}
}
// #endif
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: ab04c207993344cca1762aee3d1e840f
timeCreated: 1683361552
+477
View File
@@ -0,0 +1,477 @@
using System;
using FairyGUI;
using System.Text;
using UnityEngine;
using System.Collections.Generic;
using Application = UnityEngine.Application;
using Random = UnityEngine.Random;
using DG.Tweening;
namespace TowerClimberChronicles
{
public static class CommonHelper
{
public static Dictionary<int, int> activeTimes = new Dictionary<int, int>();
public static Dictionary<int, int> activeTimes_saveingpot = new Dictionary<int, int>();
public static int GetIndexByChanceList(int[] chanceList)
{
float total = 0;
for (int i = 0; i < chanceList.Length; i++)
{
total += chanceList[i];
}
float result = Random.Range(0, total);
float tmpTotal = 0;
for (int i = 0; i < chanceList.Length; i++)
{
float chance = chanceList[i];
tmpTotal += chance;
if (result < tmpTotal)
{
return i;
}
}
return -1;
}
public static bool GetBoolByChance(float chance)
{
var value = UnityEngine.Random.Range(0, 1f);
if (value <= chance)
return true;
return false;
}
public static void SetActive(this Component component, bool isActive)
{
component.gameObject.SetActive(isActive);
}
public static string GetAppSavePath()
{
return Application.persistentDataPath;
}
public static GTweener FadeIn(GObject obj, float duration = 0.3f, float delay = 0)
{
if (obj != null)
{
obj.alpha = 0.5f;
return obj.TweenFade(1, duration).SetDelay(delay);
}
return null;
}
public static GTweener FadeOut(GObject obj, float duration = 0.3f, float delay = 0)
{
if (obj != null)
{
obj.alpha = 1;
return obj.TweenFade(0f, duration).SetDelay(delay);
}
return null;
}
private static float clickTime;
public static bool IsClickNoQuick()
{
if (Time.time < clickTime)
{
clickTime = Time.time + 0.1f;
return false;
}
clickTime = Time.time + 0.3f;
return true;
}
public static void InitGButton(GObject button, Action action, bool isNetworkCheck = false,
bool isQuickClickCheck = true)
{
button?.onClick.Set(() =>
{
if (isQuickClickCheck && !IsClickNoQuick())
{
return;
}
action?.Invoke();
});
}
public static string TimeFormat(int second, CountDownType countDownType = CountDownType.Second,
string dayFormat = "")
{
var result = new StringBuilder();
if (second < 0)
{
second = 0;
}
if (countDownType == CountDownType.Second)
{
result.Append(second);
return result.ToString();
}
int tmpSecond;
if (second >= 60)
{
tmpSecond = second % 60;
}
else
{
tmpSecond = second;
}
result.Append(tmpSecond);
if (tmpSecond < 10)
{
result.Insert(0, 0);
}
int tmpMin = second / 60;
if (countDownType == CountDownType.Minute)
{
result.Insert(0, ":");
result.Insert(0, tmpMin);
return result.ToString();
}
int tmpHour = tmpMin / 60;
if (countDownType == CountDownType.Hour)
{
if (tmpMin >= 60)
{
tmpMin %= 60;
}
result.Insert(0, ":");
result.Insert(0, tmpMin);
if (tmpMin < 10)
{
result.Insert(0, 0);
}
result.Insert(0, ":");
result.Insert(0, tmpHour);
if (tmpHour < 10)
{
result.Insert(0, 0);
}
return result.ToString();
}
int tmpDay = tmpHour / 24;
if (countDownType == CountDownType.Day)
{
if (tmpMin >= 60)
{
tmpMin %= 60;
}
result.Insert(0, ":");
result.Insert(0, tmpMin);
if (tmpMin < 10)
{
result.Insert(0, 0);
}
if (tmpHour >= 24)
{
tmpHour %= 24;
}
result.Insert(0, ":");
result.Insert(0, tmpHour);
if (tmpHour < 10)
{
result.Insert(0, 0);
}
if (string.IsNullOrEmpty(dayFormat))
{
dayFormat = "D";
}
result.Insert(0, $" {dayFormat} ");
result.Insert(0, tmpDay);
}
return result.ToString();
}
public static string FormatTime(int second,
CountDownType countDownType = CountDownType.Second, string dayFormat = "")
{
StringBuilder result = new StringBuilder();
if (second < 0)
{
second = 0;
}
if (countDownType == CountDownType.Second)
{
result.Append(second);
return result.ToString();
}
int tmpSecond;
if (second >= 60)
{
tmpSecond = second % 60;
}
else
{
tmpSecond = second;
}
result.Append(tmpSecond);
if (tmpSecond < 10)
{
result.Insert(0, 0);
}
int tmpMin = second / 60;
if (countDownType == CountDownType.Minute)
{
result.Insert(0, ":");
result.Insert(0, tmpMin);
return result.ToString();
}
int tmpHour = tmpMin / 60;
if (countDownType == CountDownType.Hour)
{
if (tmpMin >= 60)
{
tmpMin %= 60;
}
result.Insert(0, ":");
result.Insert(0, tmpMin);
if (tmpMin < 10)
{
result.Insert(0, 0);
}
result.Insert(0, ":");
result.Insert(0, tmpHour);
if (tmpHour < 10)
{
result.Insert(0, 0);
}
return result.ToString();
}
int tmpDay = tmpHour / 24;
if (countDownType == CountDownType.Day)
{
if (tmpMin >= 60)
{
tmpMin %= 60;
}
result.Insert(0, ":");
result.Insert(0, tmpMin);
if (tmpMin < 10)
{
result.Insert(0, 0);
}
if (tmpHour >= 24)
{
tmpHour %= 24;
}
result.Insert(0, ":");
result.Insert(0, tmpHour);
if (tmpHour < 10)
{
result.Insert(0, 0);
}
if (string.IsNullOrEmpty(dayFormat))
{
dayFormat = "Days";
}
result.Insert(0, $" {dayFormat} ");
result.Insert(0, tmpDay);
}
return result.ToString();
}
public static void RandomSortList<T>(List<T> list)
{
System.Random r = new System.Random();
for (int i = 0; i < list.Count; i++)
{
int index = r.Next(list.Count);
(list[i], list[index]) = (list[index], list[i]);
}
}
public static int RandomInt(this IList<int> array)
{
return Random.Range(array[0], array[1]);
}
public static int RandomRange(int[] range)
{
if (range == null)
{
return 0;
}
if (range.Length == 2)
{
return RandomRange(range[0], range[1]);
}
else
{
return range[0];
}
}
public static int RandomRange(int begin, int end)
{
return Random.Range(begin, end);
}
public static float RandomRange(float begin, float end)
{
return Random.Range(begin, end);
}
public static T RandomWeight<T>(Dictionary<T, int> weightDic)
{
int totalWeight = 0;
foreach (var weight in weightDic)
{
totalWeight += weight.Value;
}
int randomWeight = Random.Range(0, totalWeight);
int currWeight = 0;
foreach (var weight in weightDic)
{
currWeight += weight.Value;
if (randomWeight < currWeight)
{
return weight.Key;
}
}
return default;
}
public static int RandomWeight(List<int> weightArray)
{
float totalWeight = 0;
for (var i = 0; i < weightArray.Count; i++) totalWeight += weightArray[i];
var randomWeight = Random.Range(0, totalWeight);
if (randomWeight >= totalWeight) return weightArray.Count - 1;
float currWeight = 0;
for (var i = 0; i < weightArray.Count; i++)
{
currWeight += weightArray[i];
if (randomWeight < currWeight) return i;
}
return -1;
}
public static int RandomRangeIncludeEnd(int[] range)
{
if (range == null) return 0;
if (range.Length == 2)
return RandomRange(range[0], range[1] + 1);
return range[0];
}
public static bool IsToday(long timestamp)
{
// 将时间戳转换为DateTime对象
DateTime dateTime = DateTimeOffset.FromUnixTimeSeconds(timestamp).ToLocalTime().DateTime;
// 获取今天的日期(不包含时间部分)
DateTime today = DateTime.Today;
//Debug.Log($"dateTime: {dateTime.Date} \n today: {today} \n 是否是今天: {dateTime.Date == today}");
// 比较日期部分是否相等
return dateTime.Date == today;
}
public static void CheckAdTimes()
{
DateTime today = DateTime.Today;
var localTimes = PlayerPrefs.GetString("task_ad_times");
if (string.IsNullOrEmpty(localTimes))
{
PlayerPrefs.SetString("task_ad_times", today.ToString());
return;
}
if (localTimes != today.ToString())
{
DataMgr.VideoWatchCount.Value = 0;
SaveData.GetSaveObject().ad_task_record = new List<int>();
PlayerPrefs.SetString("task_ad_times", today.ToString());
}
}
public static void ShowNumAnim(GTextField text_gold, decimal coin, int id = 102, float time = 1.0f)
{
var currency = id == 102 ? DataMgr.Ticket.Value : DataMgr.Coin.Value;
var startNum = currency - coin;
if (id == 102)
{
DOVirtual.Float((float)startNum, (float)currency, time,
value => { text_gold.text = $"{GameHelper.Get102Str((decimal)value)}"; }).OnComplete(() => {
// 动画完成时确保最终值被正确设置
text_gold.text = $"{GameHelper.Get102Str((decimal)currency)}";
});
} else {
DOVirtual.Float((float)startNum, (float)currency, time,
value => { text_gold.text = $"{GameHelper.Get101Str((decimal)value)}"; }).OnComplete(() => {
// 动画完成时确保最终值被正确设置
text_gold.text = $"{GameHelper.Get101Str((decimal)currency)}";
});
}
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 503da24caec74f59a9df8b84a7635133
timeCreated: 1681803914
+157
View File
@@ -0,0 +1,157 @@
using System.IO;
using UnityEngine;
using UnityEngine.Events;
using System.Collections;
using UnityEngine.Networking;
namespace TowerClimberChronicles
{
public class DownloadKit
{
private static void SaveTextFile(string content, string filePath, string fileName)
{
if (!Directory.Exists(filePath))
{
Directory.CreateDirectory(filePath);
}
File.WriteAllText($"{filePath}{fileName}.txt", content);
}
public static void SaveFile(string content, string filePath, string fileName)
{
SaveTextFile(content, filePath, fileName);
}
private static void SaveTextFile(byte[] content, string filePath, string fileName)
{
if (!Directory.Exists(filePath))
{
Directory.CreateDirectory(filePath);
}
File.WriteAllBytes($"{filePath}{fileName}.txt", content);
}
public static IEnumerator GetTextFromUrl(string url, string fileName, UnityAction<string> action = null,
string savePath = null, bool isSave = true)
{
var unityWebRequest = UnityWebRequest.Get(url);
yield return unityWebRequest.SendWebRequest();
if (unityWebRequest.result is UnityWebRequest.Result.ConnectionError
or UnityWebRequest.Result.ProtocolError)
{
yield return null;
action?.Invoke(default);
yield break;
}
var content = unityWebRequest.downloadHandler.text;
if (isSave)
{
savePath ??= LegendFileKit.GetFilePath();
SaveTextFile(content, savePath, fileName);
}
yield return null;
action?.Invoke(content);
}
public static IEnumerator GetTextFromUrl1(string url, string fileName, UnityAction<string> action = null,
string savePath = null, bool isSave = true)
{
var www = new WWW(url);
while (!www.isDone)
{
}
if (isSave)
{
savePath ??= LegendFileKit.GetFilePath();
SaveTextFile(www.bytes, savePath, fileName);
}
yield return null;
action?.Invoke(System.Text.Encoding.UTF8.GetString(www.bytes));
}
public static void GetTextFromUrl2(string url, string fileName, UnityAction<string> action = null,
string savePath = null, bool isSave = true)
{
var www = new WWW(url);
while (!www.isDone)
{
}
if (isSave)
{
savePath ??= LegendFileKit.GetFilePath();
SaveTextFile(www.bytes, savePath, fileName);
}
// yield return null;
action?.Invoke(System.Text.Encoding.UTF8.GetString(www.bytes));
}
public static IEnumerator GetFileFromUrl(string url, string fileName, UnityAction<bool> action)
{
var unityWebRequest = UnityWebRequest.Get(url);
yield return unityWebRequest.SendWebRequest();
if (unityWebRequest.result is
UnityWebRequest.Result.ConnectionError or UnityWebRequest.Result.ProtocolError)
{
action?.Invoke(false);
yield break;
}
var results = unityWebRequest.downloadHandler.data;
var savePath = LegendFileKit.GetFilePath();
if (!Directory.Exists(savePath))
{
Directory.CreateDirectory(savePath);
}
var filePath = $"{savePath}{fileName}";
var fileInfo = new FileInfo(filePath);
var fs = fileInfo.Create();
fs.Write(results, 0, results.Length);
fs.Flush();
fs.Close();
fs.Dispose();
yield return YieldConst.WaitForEndOfFrame;
action?.Invoke(true);
}
public static string DownloadResourceSync(string url, string savePath, string fileName, bool isSave = true)
{
using (var unityWebRequest = UnityWebRequest.Get(url))
{
unityWebRequest.SendWebRequest();
while (!unityWebRequest.isDone)
{
// 等待下载完成
}
if (unityWebRequest.result == UnityWebRequest.Result.ConnectionError ||
unityWebRequest.result == UnityWebRequest.Result.ProtocolError)
{
Debug.LogError($"Error downloading resource: {unityWebRequest.error}");
return "";
}
var content = unityWebRequest.downloadHandler.text;
if (isSave)
{
savePath ??= LegendFileKit.GetFilePath();
SaveTextFile(content, savePath, fileName);
}
return content;
}
}
}
}
+11
View File
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fe2634714606b7443a3b12c2393423fd
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
File diff suppressed because it is too large Load Diff
+3
View File
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: fd79a9adb913488d9704813bd7ebac98
timeCreated: 1681804422
+16
View File
@@ -0,0 +1,16 @@
using UnityEngine.Events;
using Object = UnityEngine.Object;
namespace TowerClimberChronicles
{
public interface ILoadAsset
{
T GetAsset<T>(string dfsad, string sa) where T : Object;
void GetAsset<T>(string dfsad, string sa, UnityAction<T> onCompleted) where T : Object;
void RecycleAsset(string assetUrl, UnityAction onCompleted);
}
}
+3
View File
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 4f5f73f6c2c342f9a9ee2cae54688486
timeCreated: 1682576608
+152
View File
@@ -0,0 +1,152 @@
using System.IO;
using System.Linq;
using UnityEngine.Events;
using System.Text.RegularExpressions;
using Application = UnityEngine.Application;
#if UNITY_EDITOR
#endif
namespace TowerClimberChronicles
{
public class LegendFileKit
{
private static bool isLog = true;
private static string AssetBundleRootUrl = Application.streamingAssetsPath + "/LoveLegendAssets/AssetBundles/";
private static string mFileUrl = Application.streamingAssetsPath + "/LoveLegendAssets/LoveLegendFile.txt";
public static string ConfigFileUrl = Application.streamingAssetsPath + "/Config/JarvisConfigFile.txt";
public static string GetSavePath()
{
return Application.persistentDataPath;
}
public static string GetLocalSavePath()
{
return Application.streamingAssetsPath;
}
public static string GetFilePath()
{
return $"{GetSavePath()}/LoveLegendAssets/";
}
public static void GetLocalAssetBundle(UnityAction<int> onPreloadCompleted, UnityAction loadCompleted)
{
GetAssetFile(s => { GetMAssetBundle(s, onPreloadCompleted, loadCompleted); });
}
public static void GetMAssetBundle(string content, UnityAction<int> onPreloadCompleted,
UnityAction onLoadCompleted)
{
if (content.IsNullOrWhiteSpace())
{
return;
}
var mFile = Regex.Split(content, "\r\n", RegexOptions.IgnoreCase).ToList();
for (var i = mFile.Count - 1; i >= 0; i--)
{
var aotMetaAssemblyFile = mFile[i];
if (string.IsNullOrEmpty(aotMetaAssemblyFile) || string.IsNullOrWhiteSpace(aotMetaAssemblyFile))
{
mFile.RemoveAt(i);
}
}
var completedCount = mFile.Count;
onPreloadCompleted?.Invoke(completedCount);
foreach (var m in mFile)
{
if (m.IsNullOrWhiteSpace())
{
onLoadCompleted?.Invoke();
completedCount--;
if (completedCount <= 0)
{
OnGetAssetBundleCompleted();
}
continue;
}
var assetBundleNameInfoArray =
m.Split(LegendConstant.fgklpk.ToCharArray());
var fileName = assetBundleNameInfoArray[0];
var mUrl = $"{AssetBundleRootUrl}{fileName}";
var mFilePath = $"{GetFilePath()}{fileName}";
if (File.Exists(mFilePath))
{
var fileMD5 = MD5Kit.GetFileMD5(mFilePath);
var fileMD5New = assetBundleNameInfoArray[1];
if (fileMD5.Equals(fileMD5New))
{
if (isLog)
{
}
onLoadCompleted?.Invoke();
completedCount--;
if (completedCount <= 0)
{
OnGetAssetBundleCompleted();
}
continue;
}
if (isLog)
{
}
}
CrazyAsyKit.StartCoroutine(DownloadKit.GetFileFromUrl(mUrl, fileName, isSuccess =>
{
if (isLog)
{
}
onLoadCompleted?.Invoke();
completedCount--;
if (completedCount <= 0)
{
OnGetAssetBundleCompleted();
}
}));
}
}
private static void OnGetAssetBundleCompleted()
{
LoveLegendKit.Instance.InitManifest(LegendConstant.lesest,
manifestInfo =>
{
AppDispatcher.Instance.Dispatch(AppMsg.UI_LoadingInitAsset);
});
}
public static void GetAssetFile(UnityAction<string> action)
{
CrazyAsyKit.StartCoroutine(DownloadKit.GetTextFromUrl(mFileUrl, "LoveLegendFile",
content => { action?.Invoke(content); }));
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 583922fa338e2bb4e840ef1b59e376a1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+287
View File
@@ -0,0 +1,287 @@
// #if UNITY_EDITOR
// #endif
using UnityEngine.Events;
namespace TowerClimberChronicles
{
using System;
using System.Linq;
using UnityEngine;
using System.Collections.Generic;
using Object = UnityEngine.Object;
public class LoadKit : Singleton<LoadKit>
{
private readonly Dictionary<string, Dictionary<int, string>> mGameObject2AbMap = new();
private readonly Dictionary<string, Dictionary<int, string>> mSprite2AbMap = new();
private readonly Dictionary<string, Dictionary<int, string>> mAudio2AbMap = new();
private ILoadAsset LoadAssetType { get; set; }
public void Init(ILoadAsset loadAssetType = null)
{
// #if UNITY_EDITOR
LoadAssetType = loadAssetType ?? new AssetDataBaseKit();
// #else
// LoadAssetType = loadAssetType ?? new LoveLegendKit();
// #endif
}
public void LoadAsset<T>(string assetUrl, string assetName, UnityAction<T> onCompleted, bool isRecord = true)
where T : Object
{
if (string.IsNullOrEmpty(assetUrl) || string.IsNullOrEmpty(assetName))
{
Debug.LogError("AssetUrl or AssetName is Empty.");
onCompleted?.Invoke(default);
return;
}
Init();
if (LoadAssetType == null)
{
Debug.LogError("Please Call LoadBox.Instance.Init() first.");
onCompleted?.Invoke(default);
return;
}
LoadAssetType.GetAsset<T>(assetUrl, assetName, (obj) =>
{
if (obj != null && isRecord)
{
RecordGameObject(assetUrl, obj);
}
onCompleted?.Invoke(obj);
});
}
public T LoadAsset<T>(string assetUrl, string assetName, bool isRecord = true) where T : Object
{
if (string.IsNullOrEmpty(assetUrl) || string.IsNullOrEmpty(assetName))
{
Debug.LogError("AssetUrl or AssetName is Empty.");
return default;
}
Init();
if (LoadAssetType == null)
{
Debug.LogError("Please Call LoadBox.Instance.Init() first.");
return default;
}
var obj = LoadAssetType.GetAsset<T>(assetUrl, assetName);
if (obj != null && isRecord)
{
RecordGameObject(assetUrl, obj);
}
return obj;
}
#region Sprite相关
public void LoadSprite(string assetUrl, string assetName, UnityAction<Sprite> onCompleted, bool isRecord = true)
{
LoadAsset(assetUrl, assetName, onCompleted, isRecord);
}
public Sprite LoadSprite(string assetUrl, string assetName, bool isRecord = true)
{
return LoadAsset<Sprite>(assetUrl, assetName, isRecord);
}
public void LoadSprite(string assetUrl, Action<Sprite> onCompleted)
{
if (string.IsNullOrEmpty(assetUrl))
{
Debug.LogError("AssetUrl is Empty.");
onCompleted?.Invoke(null);
return;
}
Init();
if (LoadAssetType == null)
{
Debug.LogError("Please Call LoadKit.Instance.Init() first.");
onCompleted?.Invoke(null);
return;
}
string assetName;
if (assetUrl.Contains("/"))
{
assetName = assetUrl.Split('/').Last();
assetUrl = assetUrl.Replace($"/{assetName}", string.Empty);
}
else
{
assetName = assetUrl.Split('.').Last();
assetUrl = assetUrl.Replace($".{assetName}", string.Empty);
}
LoadAssetType.GetAsset(assetUrl, assetName, delegate (Sprite sprite)
{
if (sprite != null)
{
RecordSprite(assetUrl, sprite);
}
onCompleted?.Invoke(sprite);
});
}
public void RecordSprite(string assetName, Sprite sprite)
{
if (sprite == null || string.IsNullOrEmpty(assetName))
{
Debug.LogError("ABName is Null or Sprite is Null");
return;
}
var instanceId = sprite.GetInstanceID();
if (mSprite2AbMap.Keys.Contains(assetName))
{
if (!mSprite2AbMap[assetName].Keys.Contains(instanceId))
{
mSprite2AbMap[assetName].Add(instanceId, sprite.name);
}
}
else
{
var spriteNameIns = new Dictionary<int, string> { { instanceId, sprite.name } };
mSprite2AbMap.Add(assetName, spriteNameIns);
}
}
#endregion
#region GameObject相关
public GameObject LoadGameObject(string assetUrl, string assetName, bool isRecord = true)
{
return LoadAsset<GameObject>(assetUrl, assetName, isRecord);
}
public void LoadGameObjectAndClone(string assetUrl, string assetName,
UnityAction<GameObject> onCompleted = null,
Transform parent = null, bool worldPositionStays = false)
{
LoadAsset<GameObject>(assetUrl, assetName,
gameObject => { InstantiateAndRecord(gameObject, parent, worldPositionStays, onCompleted); }, false);
}
public GameObject LoadGameObjectAndCloneSync(string assetUrl, string assetName, Transform parent = null,
bool worldPositionStays = false)
{
var gameObject = LoadGameObject(assetUrl, assetName, false);
return InstantiateAndRecord(gameObject, parent, worldPositionStays);
}
public void RecordGameObject(string assetName, Object gameObject)
{
if (gameObject == null || string.IsNullOrEmpty(assetName))
{
Debug.LogError("ABName is Null or Sprite is Null");
return;
}
var instanceId = gameObject.GetInstanceID();
if (mGameObject2AbMap.Keys.Contains(assetName))
{
if (!mGameObject2AbMap[assetName].Keys.Contains(instanceId))
{
mGameObject2AbMap[assetName].Add(instanceId, gameObject.name);
}
}
else
{
var gameNameIns = new Dictionary<int, string> { { instanceId, gameObject.name } };
mGameObject2AbMap.Add(assetName, gameNameIns);
}
}
public GameObject InstantiateAndRecord(GameObject gameObject, Transform parent = null,
bool worldPositionStays = false, UnityAction<GameObject> onCompleted = null)
{
if (gameObject == null)
{
Debug.LogError("GameObject is Null");
return null;
}
var newGameObject = parent
? Object.Instantiate(gameObject, parent, worldPositionStays)
: Object.Instantiate(gameObject);
if (newGameObject != null)
{
RecordCloneGameObject(gameObject, newGameObject);
}
onCompleted?.Invoke(newGameObject);
return newGameObject;
}
private void RecordCloneGameObject(GameObject gameObject, GameObject newGameObject)
{
if (gameObject == null || newGameObject == null)
{
return;
}
var oldInstanceId = gameObject.GetInstanceID();
var instanceId = newGameObject.GetInstanceID();
foreach (var keyValuePair in mGameObject2AbMap)
{
if (!keyValuePair.Value.Keys.Contains(oldInstanceId) ||
keyValuePair.Value.Keys.Contains(instanceId)) continue;
keyValuePair.Value.Add(instanceId, newGameObject.name);
break;
}
}
#endregion
#region
public void LoadAudio(string assetUrl, string assetName, UnityAction<AudioClip> onCompleted)
{
LoadAsset(assetUrl, assetName, onCompleted);
}
#endregion
public void RecycleAsset(string assetUrl, UnityAction onCompleted = null)
{
Init();
if (LoadAssetType != null)
{
LoadAssetType.RecycleAsset(assetUrl, onCompleted);
}
else
{
Debug.LogError("Please Call LoadBox.Instance.Init() first.");
}
}
}
}
+3
View File
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 283019491b0d411db1c4a6967309149e
timeCreated: 1682578772
+420
View File
@@ -0,0 +1,420 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using FairyGUI;
using SGModule.Common;
using SGModule.NetKit;
using TowerClimberChronicles;
using UnityEditor;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Networking;
using UnityEngine.Video;
using Object = UnityEngine.Object;
public class TextureHelper
{
public static void GetNTexture(string path, string name, UnityAction<NTexture> action)
{
if (!nTexturesDic.TryGetValue(path + name, out var spr))
try
{
LoadKit.Instance.LoadSprite(path, name, sprite =>
{
if (sprite != null)
{
spr = new NTexture(sprite);
action?.Invoke(spr);
nTexturesDic.TryAdd(path + name, spr);
}
});
}
catch (Exception e)
{
Debug.LogError(e);
}
else
action?.Invoke(spr);
}
public static void GetItemIcon(int itemId, UnityAction<NTexture> action = null)
{
var itemIconPath = "Atlas.Item";
var name = itemId.ToString();
if (!true)
if (itemId is 101 or 111)
name = "102";
if (itemId is 102 or 106) name += "_normal";
GetNTexture(itemIconPath, name, action);
}
#region
private static readonly Dictionary<string, NTexture> nTexturesDic = new();
private static readonly Dictionary<int, NTexture> avatarNTexturesDic = new();
#endregion
#region Texture
private static IEnumerator GetLocalTexture(string imagePath, Action<Texture> action)
{
var file = $"{Application.persistentDataPath}/{imagePath}";
var fileInfo = new FileInfo(file);
if (!fileInfo.Exists)
{
action?.Invoke(null);
yield break;
}
var avatarPath = $"file://{file}";
var uwr = UnityWebRequestTexture.GetTexture(avatarPath);
yield return uwr.SendWebRequest();
if (uwr.result is UnityWebRequest.Result.ConnectionError or UnityWebRequest.Result.ProtocolError)
{
action?.Invoke(null);
yield break;
}
var texture2D = DownloadHandlerTexture.GetContent(uwr);
action?.Invoke(texture2D);
}
public static string imgUrl = "";
#region
#endregion
#region
public static string getResPath()
{
// 删除旧资源
if (!DataMgr.curResVersion.Value.IsNullOrWhiteSpace() && DataMgr.curResVersion.Value != ConfigSystem.GetCommonConf().ResVersion)
{
var oldFolder = Path.Combine(Application.persistentDataPath, DataMgr.curResVersion.Value);
if (Directory.Exists(oldFolder))
{
Directory.Delete(oldFolder, true);
}
DataMgr.curResVersion.Value = ConfigSystem.GetCommonConf().ResVersion;
}
else if (DataMgr.curResVersion.Value.IsNullOrWhiteSpace())
{
DataMgr.curResVersion.Value = ConfigSystem.GetCommonConf().ResVersion;
}
if (ConfigSystem.GetCommonConf().ResVersion.IsNullOrWhiteSpace())
{
Debug.LogError("获取资源路径失败");
return Application.persistentDataPath;
}
string curFolder = Path.Combine(Application.persistentDataPath, ConfigSystem.GetCommonConf().ResVersion);
return curFolder;
}
public static void SetImgLoader(GLoader loader, string fileName, Action<NTexture> callback,
string folder, string localFolder, bool priority = true, bool isLoad = false, bool isGameBg = false, string image_type = "jpg")
{
var localPath = Path.Combine(getResPath(), localFolder, fileName + "." + image_type);
Debug.Log("????????????????????" + localPath);
if (File.Exists(localPath))
{
Debug.Log($"[SetImgLoader] 本地存在,直接加载 {fileName}");
CrazyAsyKit.StartCoroutine(LoadTexture(fileName, loader, callback, localFolder, isGameBg, image_type));
return;
}
}
#endregion
#region
public static IEnumerator LoadTexture(string fileName, GLoader loader, Action<NTexture> callback = null,
string folder = "", bool isGameBg = false, string img_type = "jpg")
{
string encryptedPath = Path.Combine(getResPath(), folder, fileName + "." + img_type);
Debug.Log($"[LoadEncryptedTexture] 开始加载加密图片: {fileName}");
Debug.Log($"[LoadTexture] 开始加载本地图片 {fileName}");
using (var www = UnityWebRequestTexture.GetTexture("file://"))
// using (var www = UnityWebRequestTexture.GetTexture("file://" + GetDecryptedImagePath(fileName, folder, img_type)))
{
yield return www.SendWebRequest();
if (www.result == UnityWebRequest.Result.Success)
{
var tex = DownloadHandlerTexture.GetContent(www);
var nTex = new NTexture(tex) { destroyMethod = DestroyMethod.Destroy };
tex.name = fileName;
if (loader != null && loader.texture != null)
{
loader.texture.Dispose(); // 释放 GPU 资源
loader.texture = null; // 断开引用
}
if (loader != null && !loader.isDisposed)
{
loader.texture = nTex;
// Debug.Log($"[LoadTexture] 图片已设置到 Loader {fileName}");
callback?.Invoke(nTex);
}
else
{
// Debug.Log($"[LoadTexture] Loader 不存在或已销毁 {fileName}");
}
//设置游戏背景时,传的是UGUI的,不传loader
if (isGameBg)
{
callback?.Invoke(nTex);
}
}
else
{
Debug.LogError($"[LoadTexture] 加载失败 {www.error}");
callback?.Invoke(null);
}
}
if (loader != null && !loader.isDisposed)
loader.visible = true;
}
public static void setPuzzle(string fileName, List<UnityEngine.UI.Image> image_list, List<Vector2> vec2_list)
{
Sprite _sprite = Resources.Load<Sprite>("puzzle/img/" + fileName);
for (int i = 0; i < image_list.Count; i++)
{
image_list[i].sprite = _sprite;
image_list[i].SetNativeSize();
image_list[i].rectTransform.anchoredPosition = vec2_list[i];
}
// 调用统一的 SetImgLoader,不需要再自己写下载逻辑
// SetImgLoader(null, fileName, nTex =>
// {
// Debug.Log("设置拼图的回调!!!!!!!!");
// if (nTex != null && nTex.nativeTexture != null)
// {
// var tex2D = nTex.nativeTexture as Texture2D;
// if (tex2D == null)
// {
// Debug.LogError("NTexture 转换失败!");
// return;
// }
// // 创建 Sprite
// var sprite = Sprite.Create(
// tex2D,
// new Rect(0, 0, tex2D.width, tex2D.height),
// new Vector2(0.5f, 0.5f)
// );
// for (int i = 0; i < image_list.Count; i++)
// {
// image_list[i].sprite = sprite;
// image_list[i].SetNativeSize();
// image_list[i].rectTransform.anchoredPosition = vec2_list[i];
// }
// }
// else
// {
// Debug.LogError("背景图片加载失败!");
// }
// }, FolderNames.Jigsaw + "/", FolderNames.Jigsaw, true, false, true, "png"); // ✅ 背景一般是立刻需要的,走优先下载
}
#endregion
#region
#endregion
/// <summary>
/// 彻底清理材质池(切场景/退出游戏时调用)
/// </summary>
///
private static IEnumerator GetTextureFromNet(string type, int imgId, string imgUrl, Action<bool> action = null)
{
var imagePath = $"{CommonHelper.GetAppSavePath()}/{type}/{imgId}.jpg";
var fileInfo = new FileInfo(imagePath);
if (fileInfo.Exists)
{
action?.Invoke(true);
yield break;
}
var avatarRequest = UnityWebRequest.Get(imgUrl);
yield return avatarRequest.SendWebRequest();
if (avatarRequest.result == UnityWebRequest.Result.ConnectionError ||
avatarRequest.result == UnityWebRequest.Result.ProtocolError)
{
action?.Invoke(false);
}
else
{
var avatarData = avatarRequest.downloadHandler.data;
var dirPath = Path.GetDirectoryName(imagePath);
if (!Directory.Exists(dirPath)) Directory.CreateDirectory(dirPath);
if (fileInfo.Exists)
yield break;
Stream stream = fileInfo.Create();
stream.Write(avatarData, 0, avatarData.Length);
stream.Close();
stream.Dispose();
action?.Invoke(true);
}
}
#endregion
#region
public static void SetAvatarToLoader(int avatarId, GLoader _GLoader, bool IsNeedDefAvatar = true)
{
if (!avatarNTexturesDic.TryGetValue(avatarId, out var spr))
try
{
Sprite sprite = null;
if (avatarId == 0)
{
if (!PlayerPrefsKit.ReadBool("IsLogin"))
{
avatarId = 1;
SetAvatarToLoader(avatarId, _GLoader);
return;
}
if (PlayerPrefsKit.ReadString("AvatarUrl").IsNullOrWhiteSpace())
{
_GLoader.url = "ui://pmf3wbjicxrg4";
return;
}
GetSelfFaceBookAvatar(texture =>
{
if (_GLoader != null)
{
if (texture != null)
_GLoader.texture = texture;
else
_GLoader.url = "ui://pmf3wbjicxrg4";
}
});
return;
}
if (avatarId > 100)
{
if (IsNeedDefAvatar) _GLoader.url = "ui://pmf3wbjicxrg4";
GetFaceBookAvatar(avatarId, e =>
{
if (_GLoader != null)
{
if (e == null)
_GLoader.url = "ui://pmf3wbjicxrg4";
else
_GLoader.texture = e;
}
});
return;
}
LoadKit.Instance.LoadSprite("Atlas.Avatar", avatarId.ToString(), spr =>
{
sprite = spr;
var spr1 = new NTexture(sprite);
_GLoader.texture = spr1;
avatarNTexturesDic.Add(avatarId, spr1);
});
}
catch (Exception e)
{
Debug.LogError(e);
}
else
_GLoader.texture = spr;
}
private static IEnumerator GetAvatarLocal(int avatarId, Action<Texture> action)
{
yield return GetLocalTexture($"Avatar/{avatarId}.jpg", action);
}
#endregion
#region FaceBook头像相关
public static void GetFaceBookAvatar(int avatarId, Action<NTexture> action)
{
if (!avatarNTexturesDic.TryGetValue(avatarId, out var spr))
HallManager.Instance.StartCoroutine(GetAvatarLocal(avatarId, texture =>
{
if (texture == null)
{
action?.Invoke(null);
return;
}
spr = new NTexture(texture);
if (avatarNTexturesDic.ContainsKey(avatarId)) avatarNTexturesDic.Add(avatarId, spr);
action?.Invoke(spr);
}));
else
action?.Invoke(spr);
}
public static void GetSelfFaceBookAvatar(Action<NTexture> action)
{
if (!avatarNTexturesDic.TryGetValue(0, out var spr))
{
}
else
{
action?.Invoke(spr);
}
}
#endregion
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 9fd5ef95c27f44cc8b171cbc1bfc7f7f
timeCreated: 1681806348