首次提交

This commit is contained in:
2026-07-13 18:14:23 +08:00
commit 20d09e4ebb
5293 changed files with 621708 additions and 0 deletions
+41
View File
@@ -0,0 +1,41 @@
using System.Collections;
using System.Collections.Generic;
using Roy;
using UnityEngine;
public class AndroidVibration : SingletonMonoBehaviour<AndroidVibration>
{
AndroidJavaClass VibratorTool = null;
AndroidJavaClass ToastTool = null;
void Awake()
{
VibratorTool = new AndroidJavaClass("com.tools.common.VibratorTool");
ToastTool = new AndroidJavaClass("com.tools.common.ToastTool");
ToastTool.CallStatic("SetShowToast", false);//关闭测试toast
//smsDialog.CallStatic<AndroidJavaObject>("getInstance").Call("init", getContext());
}
public void CVibrate(int milliseconds)
{
// Debug.LogError("---- 调用震动");
VibratorTool.CallStatic("CVibrate", milliseconds);
}
public void CVibrateShort()
{
// Debug.LogError("---- 调用震动 -- 短");
VibratorTool.CallStatic("CVibrateShort");
}
public void CVibrateLong()
{
// Debug.LogError("---- 调用震动 -- 长");
VibratorTool.CallStatic("CVibrateLong");
}
public void CCannelVibrate()
{
// Debug.LogError("---- 调用震动 -- 取消");
VibratorTool.CallStatic("CCancelVibrate");
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: bf48492c834d5a145b3a992bcffb4bef
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+3
View File
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 1425010c752246ffa6889c5e6b6b05ec
timeCreated: 1727339286
+20
View File
@@ -0,0 +1,20 @@
namespace Roy
{
/// <summary>
/// 管理类基类
/// </summary>
/// <typeparam name="T"></typeparam>
public class BaseManager<T> where T : new()
{
private static T _instance;
public static T GetInstance
{
get
{
_instance ??= new T();
return _instance;
}
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 91c3234e0b0b4940992129af43d62f99
timeCreated: 1727164456
@@ -0,0 +1,55 @@
using UnityEngine;
namespace Roy
{
public class SingletonMonoBehaviour<T> : MonoBehaviour where T : MonoBehaviour
{
private static T _instance;
public static T Instance
{
get
{
if (_instance == null)
{
// 尝试找到已存在的实例
_instance = FindObjectOfType<T>();
// 如果没有找到,则创建一个新的实例
if (_instance == null)
{
GameObject singletonObject = new GameObject(typeof(T).Name);
_instance = singletonObject.AddComponent<T>();
DontDestroyOnLoad(singletonObject); // 不在场景切换时销毁
}
}
return _instance;
}
}
// 确保在场景中只存在一个实例
protected virtual void Awake()
{
if (_instance == null)
{
_instance = this as T;
}
else if (_instance != this)
{
Debug.LogWarning($"An instance of {typeof(T)} already exists! Destroying this instance.");
Destroy(gameObject); // 如果有其他实例,销毁当前对象
}
}
protected virtual void OnDestroy()
{
if (_instance == this)
{
_instance = null; // 清除引用
}
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 54bf3c952fe4494dbae47a7a63806362
timeCreated: 1728986962
+3
View File
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: aa366da86c25451b99f84f4fa7fd8d4f
timeCreated: 1727318395
+8
View File
@@ -0,0 +1,8 @@
namespace Roy.Datas
{
public class PropViewData
{
public int type;
public int index;
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: ad8b86d6227e44b4bc9bdf88413402fb
timeCreated: 1727318419
@@ -0,0 +1,11 @@
namespace Roy.Datas
{
public class SettlementData
{
public bool is_success;
public float cash_number;
public float rate;
public bool is_level_success;
public bool is_h5_reward;
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 6e4551287fa849ba86b54304a2d9e71e
timeCreated: 1727318650
+25
View File
@@ -0,0 +1,25 @@
#if UNITY_IOS
using System.Runtime.InteropServices;
using UnityEngine;
public class HapticManager
{
[DllImport("__Internal")]
private static extern void TriggerCustomHaptic(float intensity, float sharpness, float duration);
public static void TriggerHapticFeedback(float intensity, float sharpness, float duration)
{
if (Application.platform == RuntimePlatform.IPhonePlayer)
{
TriggerCustomHaptic(intensity, sharpness, duration);
}
else
{
Debug.Log("Haptic feedback is only available on iOS.");
}
}
}
#endif
+3
View File
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 108ec92fa01a4e42b4594ca3561d77bd
timeCreated: 1729504904
+3
View File
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 60448bf52bae4ca4bb0edaf413418b1c
timeCreated: 1727339306
@@ -0,0 +1,51 @@
using System.Collections.Generic;
using DG.Tweening;
namespace Roy
{
public class AnimationPipeline : BaseManager<AnimationPipeline>
{
private Queue<Tween> _tweenQueue = new Queue<Tween>(); // 动画队列
private Sequence _currentSequence; // 当前的动画Sequence
private bool _isPlaying = false; // 管线是否正在播放
// 向管线添加一个新的动画
public void AddToPipeline(Tween newTween)
{
_tweenQueue.Enqueue(newTween); // 将新的动画放入队列
if (!_isPlaying)
{
StartNextSequence(); // 如果没有播放中的动画,启动队列中的下一个动画
}
}
// 启动下一个动画序列
private void StartNextSequence()
{
if (_tweenQueue.Count == 0)
{
_isPlaying = false; // 队列为空,停止播放
return;
}
_isPlaying = true;
_currentSequence = DOTween.Sequence(); // 创建一个新的Sequence
while (_tweenQueue.Count > 0)
{
Tween nextTween = _tweenQueue.Dequeue();
_currentSequence.Append(nextTween); // 将每个Tween按顺序加入到Sequence
}
// 当Sequence完成时,检查队列中是否还有新的动画
_currentSequence.OnComplete(() =>
{
_isPlaying = false;
StartNextSequence(); // 如果还有新动画,继续播放
});
_currentSequence.Play(); // 播放当前Sequence
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: a5e50fdce1d843d891c5bb1f55668145
timeCreated: 1728459955
@@ -0,0 +1,261 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using ScrewsMaster;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Networking;
using UnityEngine.ResourceManagement.AsyncOperations;
namespace Roy
{
public class FileNetworkManager : BaseManager<FileNetworkManager>
{
private readonly string _copyFolderPath;
private readonly string _configFolderPath;
public const string FolderName = "Configs";
public const string FolderLabel = "config";
public FileNetworkManager()
{
_copyFolderPath = Path.Combine(Application.streamingAssetsPath, FolderName);
_configFolderPath = Path.Combine(Application.persistentDataPath, FolderName);
}
public string GetConfigFOlderPath()
{
return _configFolderPath;
}
// 示例解析文件列表方法(你可以根据实际需求实现)
List<string> ParseFileList(string data)
{
// 假设 data 是文件列表的文本,解析文件名
// 根据实际情况解析,例如通过换行符分割
return data.Split(new[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries).ToList();
}
public void CopyStreamingAssetsToPersistentDataPath(Action<bool> onComplete = null)
{
// 如果目标文件夹不存在,创建它
if (!Directory.Exists(_configFolderPath))
{
Directory.CreateDirectory(_configFolderPath);
}
CrazyAsyKit.StartCoroutine(CopyFile(onComplete));
// // 获取StreamingAssets中的文件,排除后缀为.meta的文件
// var files = Directory.GetFiles(_copyFolderPath)
// .Where(file => !file.EndsWith(".meta")) // 过滤 .meta 文件
// .ToList(); // 转换为列表以方便使用
//
// if (files.Count == 0)
// {
// onComplete?.Invoke(true); // 如果没有文件,直接回调成功
// return;
// }
//
// // 使用计数器来跟踪完成的文件复制
// int completedCount = 0;
//
// foreach (var file in files)
// {
// string fileName = Path.GetFileName(file);
// string sourceFilePath = file; // 原始文件路径
// string destFilePath = Path.Combine(_configFolderPath, fileName);
//
// // 读取并写入文件
// CrazyAsyKit.StartCoroutine(CopyFile(sourceFilePath, destFilePath,
// (result) =>
// {
// completedCount++;
// // 如果所有文件都已复制完成,调用回调
// if (completedCount == files.Count)
// {
// onComplete?.Invoke(true);
// }
// }));
// }
}
private IEnumerator CopyFile(Action<bool> onComplete = null)
{
var handle = Addressables.LoadResourceLocationsAsync(FolderLabel);
yield return handle;
if (handle.Status == AsyncOperationStatus.Succeeded)
{
// 查找以 ".json" 结尾的文件
var jsonLocation = handle.Result.FirstOrDefault(loc => loc.PrimaryKey.EndsWith(".json"));
if (jsonLocation != null)
{
var jsonFileName = Path.GetFileName(jsonLocation.PrimaryKey);
// 加载 JSON 文件
var textAssetAsync = Addressables.LoadAssetAsync<TextAsset>(jsonLocation);
yield return textAssetAsync;
if (textAssetAsync.Status == AsyncOperationStatus.Succeeded)
{
TextAsset jsonFile = textAssetAsync.Result;
Debug.Log("Loaded JSON content: " + jsonFile.text);
string destFilePath = Path.Combine(_configFolderPath, jsonFileName);
File.WriteAllBytes(destFilePath, jsonFile.bytes);
onComplete?.Invoke(true);
}
else
{
Debug.LogError("Failed to load JSON file");
onComplete?.Invoke(false);
}
}
else
{
Debug.LogError("No JSON file found in folder");
onComplete?.Invoke(false);
}
}
else
{
Debug.LogError("Failed to load folder resources");
onComplete?.Invoke(false);
}
}
private IEnumerator CopyFile(string sourceFile, string destFile, Action<bool> onComplete = null)
{
string filePath = "file://" + sourceFile;
using (UnityWebRequest www = UnityWebRequest.Get(filePath))
{
yield return www.SendWebRequest();
if (www.result == UnityWebRequest.Result.Success)
{
File.WriteAllBytes(destFile, www.downloadHandler.data);
Debug.Log($"File copied to {destFile}");
onComplete?.Invoke(true);
}
else
{
Debug.LogError("Failed to copy file: " + www.error);
onComplete?.Invoke(false);
}
}
}
/// <summary>
/// 读取或下载
/// </summary>
/// <param name="path"></param>
/// <param name="callback"></param>
public void ReadData(string path, Action<string> callback)
{
CrazyAsyKit.StartCoroutine(ReadDataEnumerator(path, callback));
}
/// <summary>
/// 读取或下载
/// </summary>
/// <param name="path"></param>
/// <param name="callback"></param>
/// <returns></returns>
private IEnumerator ReadDataEnumerator(string path, Action<string> callback)
{
string fullPath;
// 判断是网络URL还是本地文件路径
if (path.StartsWith("http://") || path.StartsWith("https://"))
{
fullPath = path; // 网络URL
}
else
{
// 本地文件路径
fullPath = "file://" + path;
}
// 使用UnityWebRequest读取数据
using (UnityWebRequest webRequest = UnityWebRequest.Get(fullPath))
{
yield return webRequest.SendWebRequest();
if (webRequest.result == UnityWebRequest.Result.ConnectionError || webRequest.result == UnityWebRequest.Result.ProtocolError)
{
Debug.LogError($"Error while reading file: {webRequest.error} path: {fullPath}");
callback?.Invoke(null); // 返回null表示出错
}
else
{
string data = webRequest.downloadHandler.text;
Debug.Log($"Data read successfully: {data}");
callback?.Invoke(data); // 通过回调传出数据
}
}
}
/// <summary>
/// 将内容写入指定文件,并删除原有文件。
/// </summary>
/// <param name="folderName">文件夹名称</param>
/// <param name="fileName">文件名称</param>
/// <param name="content">要写入的内容</param>
public void WriteToPersistentData(string folderName, string fileName, string content)
{
// 获取持久化数据路径
string folderPath = Path.Combine(Application.persistentDataPath, folderName);
// 如果文件夹不存在,则创建它
if (!Directory.Exists(folderPath))
{
Directory.CreateDirectory(folderPath);
}
// 删除原有文件
var existingFiles = Directory.GetFiles(folderPath);
foreach (var file in existingFiles)
{
File.Delete(file);
}
// 完整文件路径
string filePath = Path.Combine(folderPath, fileName);
// 写入新文件
File.WriteAllText(filePath, content);
Debug.Log($"File written to: {filePath}");
}
/// <summary>
/// 提取指定目录下所有文件文件名
/// </summary>
/// <param name="subdirectory"></param>
/// <returns></returns>
public string[] GetFileNamesFromPersistentDataPath(string subdirectory)
{
string directoryPath = Path.Combine(Application.persistentDataPath, subdirectory);
if (Directory.Exists(directoryPath))
{
// 获取目录中的所有文件名
return Directory.GetFiles(directoryPath)
.Select(Path.GetFileName) // 只提取文件名
.ToArray();
}
else
{
Debug.LogWarning($"Directory does not exist: {directoryPath}");
return new string[0]; // 返回空数组
}
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 2d7ee718e2a1471fa1d948628a66d1aa
timeCreated: 1727164004
+3
View File
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 8495bd5c9c964c9893df4d30e80f2649
timeCreated: 1727581465
@@ -0,0 +1,86 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using Object = UnityEngine.Object;
namespace Roy.ObjectPool
{
public class ObjectPool<T> where T : ObjectPoolItem
{
private readonly Queue<T> _pool; // 存储可重用对象的队列
private readonly T _prefab; // 预制体
private readonly string _poolName; // 预制体
private readonly Transform _parent; // 对象的父级
// 构造函数
public ObjectPool(string objectName, T prefab, int initialSize, Transform parent = null)
{
_poolName = objectName;
_prefab = prefab;
_parent = parent;
_pool = new Queue<T>();
// 初始化对象池
for (int i = 0; i < initialSize; i++)
{
T obj = CreateInstance();
_pool.Enqueue(obj);
}
}
// 创建对象的实例
private T CreateInstance()
{
var gameObject = Object.Instantiate(_prefab.gameObject, _parent);
gameObject.SetActive(false); // 初始化时设置为不激活
var instance = gameObject.GetComponent<T>();
instance.objectName = _poolName;
return instance;
}
// 获取一个对象
public T Get()
{
if (_pool.Count > 0)
{
T obj = _pool.Dequeue();
obj.gameObject.SetActive(true); // 获取时激活对象
return obj;
}
else
{
// 如果没有可用对象,创建一个新的
var obj = CreateInstance();
obj.gameObject.SetActive(true);// 激活对象
return obj;
}
}
// 归还对象
public void ReturnToPool(T obj)
{
obj.OnRecycle();
obj.gameObject.SetActive(false); // 归还时设置为不激活
obj.transform.SetParent(_parent);
obj.transform.localPosition = Vector3.zero;
_pool.Enqueue(obj); // 将对象返回池中
}
// 清空对象池
public void ClearPool()
{
while (_pool.Count > 0)
{
T obj = _pool.Dequeue();
Object.Destroy(obj.gameObject); // 清除所有对象
}
Object.Destroy(_parent);
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 43b0aa3ccb0740cdacd10e06164ecb74
timeCreated: 1728964545
@@ -0,0 +1,17 @@
using UnityEngine;
namespace Roy.ObjectPool
{
public class ObjectPoolItem : MonoBehaviour
{
public string objectName;
/// <summary>
/// 返回对象池,回收时执行
/// </summary>
public virtual void OnRecycle()
{
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 97032cf20b09454ca983b038b9ff147b
timeCreated: 1729045887
@@ -0,0 +1,117 @@
using System.Collections.Generic;
using ScrewsMaster;
using UnityEngine;
using UnityEngine.UI;
namespace Roy.ObjectPool
{
public class PoolManager : SingletonMonoBehaviour<PoolManager>
{
private GameObject _gameObjectParentNode;
private GameObject _uiPoolParentNode;
private readonly Dictionary<string, object> _pools = new Dictionary<string, object>();
protected override void Awake()
{
_gameObjectParentNode = new GameObject("GameObjectPool");
_gameObjectParentNode.transform.SetParent(transform); // 设置为对象池管理类的子节点
// 创建一个用于存放UI元素的节点
_uiPoolParentNode = new GameObject("UIPool");
_uiPoolParentNode.transform.SetParent(transform); // 设置为对象池管理类的子节点
// 添加必需的组件
var canvas = _uiPoolParentNode.AddComponent<Canvas>();
canvas.renderMode = RenderMode.ScreenSpaceCamera;
foreach (var c in Camera.allCameras)
{
if (!c.name.Equals("Camera")) continue;//TODO 当前是去找固定名称的摄像机 后续看看怎么优化调整
canvas.worldCamera = c;
break;
}
var canvasScaler = _uiPoolParentNode.AddComponent<CanvasScaler>(); // 添加适配组件
canvasScaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize;
canvasScaler.referenceResolution = new Vector2(Screen.width, Screen.height);
_uiPoolParentNode.AddComponent<GraphicRaycaster>(); // 添加事件处理组件
base.Awake();
}
// 创建对象池
public void CreatePool<T>(string poolName, T prefab, int initialSize, bool isUI = false) where T : ObjectPoolItem
{
if (!_pools.ContainsKey(poolName))
{
var poolGameObject = new GameObject(poolName);
if (isUI)
{
poolGameObject.AddComponent<RectTransform>();
poolGameObject.SetParent(_uiPoolParentNode);
}
else
{
poolGameObject.SetParent(_gameObjectParentNode);
}
ObjectPool<T> pool = new ObjectPool<T>(poolName, prefab, initialSize, poolGameObject.transform);
_pools.Add(poolName, pool);
}
else
{
Debug.LogError($"尝试创建已经存在的的对象池,请检查 !!!");
}
}
// 获取对象
public T GetObject<T>(string poolName) where T : ObjectPoolItem
{
if (_pools.TryGetValue(poolName, out var pool))
{
return ((ObjectPool<T>)pool).Get();
}
else
{
Debug.LogError($"尝试获取没有初始化的对象池,请检查!!!!");
return null;
}
}
// 判断是否存在名称为 poolName 的对象池
public bool HasPool(string poolName)
{
return _pools.ContainsKey(poolName);
}
// 归还对象
public void ReturnObject<T>(string poolName, T obj) where T : ObjectPoolItem
{
if (_pools.TryGetValue(poolName, out var pool))
{
((ObjectPool<T>)pool).ReturnToPool(obj);
}
else
{
Destroy(obj.gameObject);
Debug.LogError($"归还了不存在对象池 {poolName} 的对象");
}
}
// 清空指定池
public void ClearPool(string poolName)
{
if (_pools.TryGetValue(poolName, out var pool))
{
((ObjectPool<ObjectPoolItem>)pool).ClearPool();
_pools.Remove(poolName); // 清空后移除池
}
else
{
Debug.LogError($"尝试清空不存在的对象池,请检查!!!");
}
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: bfc0527198b24e8983adfd0c2f9e2ef1
timeCreated: 1728964617