备份CatanBuilding瘦身独立工程

This commit is contained in:
JSD\13999
2026-05-26 16:15:54 +08:00
commit 2d0e6a61b7
12001 changed files with 2431925 additions and 0 deletions

View File

@@ -0,0 +1,44 @@
using UnityEngine;
using UnityEngine.EventSystems;
using System;
namespace Game
{
public class CameraScroller : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{
public bool isDragging { get; private set; }
float _yMax = 4.5f;
float _yMin = -1f;
public void OnBeginDrag(PointerEventData eventData)
{
isDragging = true;
}
public void OnDrag(PointerEventData eventData)
{
var main_cam = Camera.main;
if (main_cam != null)
{
var pos = main_cam.transform.position;
var new_y = pos.y;
new_y -= eventData.delta.y * 0.01f;
pos.y = Mathf.Clamp(new_y, _yMin, _yMax);
main_cam.transform.position = pos;
}
}
public void OnEndDrag(PointerEventData eventData)
{
isDragging = false;
}
public void OnPointerClick(PointerEventData eventData)
{
throw new NotImplementedException();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 579052b1391d8f6479d60cf35900d4ca
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,162 @@
using asap.core;
using LitJson;
using System;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
public interface ICustomServerMgr
{
Task<string> GetStringAsync(string url);
Task<string> CustomServerPost(string url, string bodyString, string contentType = "application/json");
Task<string> AccountRequest(string url, object data);
Task<string> EventRequest(string url, object data);
Task<string> ClubRequest(string url, object data);
Task<string> BombRequest(string url, object data);
Task<string> DuelRequest(string url, object data);
Task<string> CommonDataRequest(string url, object data);
Task<string> FriendRequest(string url, object data);
Task<T> EventPartnerRequest<T>(string url, object data = null);
CookieContainer Cookie { get; }
}
public class CustomServerMgr : ICustomServerMgr
{
IConfig config { get; set; }
//网络客户端
HttpClient client;
private CookieContainer _cookie;
public CookieContainer Cookie => _cookie ?? throw new System.NullReferenceException();
public CustomServerMgr(IConfig config)
{
this.config = config;
var httpClientHandler = new HttpClientHandler();
_cookie = new CookieContainer();
httpClientHandler.CookieContainer = _cookie;
client = new HttpClient(httpClientHandler);
client.BaseAddress =
new System.Uri(config.Get<string>(GConstant.K_Event_API_URL,
"http://192.168.9.101:5292/"));
client.Timeout = TimeSpan.FromSeconds(15);
}
public async Task<string> CustomServerPost(string url, string bodyString,
string contentType = "application/json")
{
try
{
//#if UNITY_EDITOR
// Debug.Log("CustomServerPost url:" + url);
// Debug.Log("CustomServerPost bodyString:" + bodyString);
//#endif
var content = new StringContent(bodyString, Encoding.UTF8, "application/json");
var response = await client.PostAsync(url, content);
string result = await response.Content.ReadAsStringAsync();
if (response.StatusCode == System.Net.HttpStatusCode.OK)
{
//GameDebug.Log("CustomServerPost result:" + result.ToString());
return result;
}
else if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized || response.StatusCode == System.Net.HttpStatusCode.Forbidden)
{
GContext.Publish(new game.EvtAPISvrUnauthorized());
return null;
}
else
{
Debug.LogError(response.StatusCode.ToString() + "+++CustomServerPost error:" +
result.ToString() + "+++CustomServerPost url:" + url + ":" +
bodyString);
return null;
}
}
catch (Exception e)
{
Debug.LogError("CustomServerPost error:" + e.Message + "---CustomServerPost url:" +
url + ":" + bodyString + "\n" + e.StackTrace);
return null;
}
}
public async Task<string> GetStringAsync(string url)
{
var response = await client.GetAsync(url);
if (response.StatusCode == HttpStatusCode.OK)
{
return await response.Content.ReadAsStringAsync();
}
if (response.StatusCode == HttpStatusCode.Unauthorized)
{
GContext.Publish(new game.EvtAPISvrUnauthorized());
}
return null;
}
public async Task<string> AccountRequest(string url, object data)
{
return await CustomServerPost($"account/{url}",
Newtonsoft.Json.JsonConvert.SerializeObject(data));
}
public async Task<string> EventRequest(string url, object data)
{
return await CustomServerPost($"event/{url}",
Newtonsoft.Json.JsonConvert.SerializeObject(data));
}
public async Task<string> ClubRequest(string url, object data)
{
return await CustomServerPost($"club/{url}",
Newtonsoft.Json.JsonConvert.SerializeObject(data));
}
public async Task<string> BombRequest(string url, object data)
{
return await CustomServerPost($"bomb/{url}",
Newtonsoft.Json.JsonConvert.SerializeObject(data));
}
public async Task<string> CommonDataRequest(string url, object data)
{
return await CustomServerPost($"commondata/{url}",
Newtonsoft.Json.JsonConvert.SerializeObject(data));
}
public async Task<string> DuelRequest(string url, object data)
{
return await CustomServerPost($"duel/{url}",
Newtonsoft.Json.JsonConvert.SerializeObject(data));
}
public async Task<string> FriendRequest(string url, object data)
{
return await CustomServerPost($"friend/{url}",
Newtonsoft.Json.JsonConvert.SerializeObject(data));
}
public async Task<T> EventPartnerRequest<T>(string url, object data = null)
{
var body = Newtonsoft.Json.JsonConvert.SerializeObject(data);
var responseString = await CustomServerPost($"eventpartner/{url}", body);
try
{
return Newtonsoft.Json.JsonConvert.DeserializeObject<T>(responseString);
}
catch(Exception e)
{
Debug.LogError(
$"<color=red>[EventPartner] Response {responseString} failed to be deserialized: {e.Message}</color>");
return default(T);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d9344f5533a12764aa95085ab91f05a2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,381 @@
using System;
using UnityEngine;
using UnityEngine.UI;
using DG.Tweening;
using GameCore;
using asap.core;
public static class DoTweenExtension
{
public static void Popup(this Transform rec_trans, TweenCallback complete_action = null,bool isUnScale = false)
{
/*rec_trans.localScale = Vector3.one;
rec_trans.DOKill();
var t = rec_trans.DOPunchScale(new Vector3(0.1f, 0.1f, 1), 0.3f);*/
rec_trans.localScale = new Vector3(0.5f, 0.5f, 1);// Vector3.zero;
rec_trans.DOKill();
var t = rec_trans.DOScale(1, 0.3f);
t.SetEase(Ease.OutBack);
if (isUnScale)
{
t.SetUpdate(true);
}
if (complete_action != null)
{
t.OnComplete(complete_action);
}
}
public static void ShrinkDown(this Transform rec_trans, TweenCallback complete_action = null,bool isUnScale = false)
{
rec_trans.DOKill();
var t = rec_trans.DOScale(0.5f, 0.3f).SetEase(Ease.InBack);
if (isUnScale)
{
t.SetUpdate(true);
}
if (complete_action != null)
{
t.OnComplete(complete_action);
}
}
public static void Popup(this Transform t, Image mask, TweenCallback fun = null)
{
t.localScale = new Vector3(0.5f, 0.5f, 1);
t.DOKill();
var x = t.DOScale(1, 0.3f).SetEase(Ease.OutBack).SetUpdate(true);
if(mask != null)
{
mask.DOFade(0f,0f).SetUpdate(true);
mask.DOFade(0.9f,0.1f).SetUpdate(true);
}
if (fun != null)
{
x.OnComplete(fun);
}
}
public static void ShrinkDown(this Transform t, Image mask, TweenCallback fun = null)
{
t.DOKill();
var x = t.DOScale(0.5f, 0.3f).SetEase(Ease.InBack).SetUpdate(true);
if(mask != null)
{
mask.DOFade(0f,0.3f).SetUpdate(true);
}
if (fun != null)
{
x.OnComplete(fun);
}
}
public static void PopupByCanvasGroup(this Transform rec_trans, TweenCallback complete_action = null)
{
CanvasGroup cg = rec_trans.GetComponent<CanvasGroup>();
if(cg == null)
cg = rec_trans.gameObject.AddComponent<CanvasGroup>();
rec_trans.DOKill();
cg.alpha = 0.2f;
rec_trans.localScale = new Vector3(0.33f, 0.33f, 1);
// var t = rec_trans.DOScale(1, 0.3f);
// t.SetEase(Ease.OutBack);
// t.SetUpdate(true);
// var tw = cg.DOFade(1f,0.3f);
// tw.SetUpdate(true);
// if (complete_action != null)
// {
// t.OnComplete(complete_action);
// }
}
public static void ShrinkDownByCanvasGroup(this Transform rec_trans, TweenCallback complete_action = null)
{
CanvasGroup cg = rec_trans.GetComponent<CanvasGroup>();
if(cg == null)
cg = rec_trans.gameObject.AddComponent<CanvasGroup>();
rec_trans.DOKill();
cg.alpha = 1;
rec_trans.localScale = new Vector3(1f, 1f, 1);
float f = 1f/60;
// UnityEngine.Debug.Log("fff "+f + " " + Application.targetFrameRate);
var tw = rec_trans.DOScale(1.1f,f * 11).OnComplete(()=>
{
var tw1 = rec_trans.DOScale(0.33f,f * 16);
var tw2 = cg.DOFade(0f,f*16);
tw1.SetUpdate(true);
tw2.SetUpdate(true);
if (complete_action != null)
{
tw2.OnComplete(complete_action);
}
});
tw.SetUpdate(true);
}
public static void Shake(this RectTransform rec_trans)
{
rec_trans.localScale = Vector3.one;
rec_trans.DOKill();
rec_trans.DOPunchScale(Vector3.one, 0.3f, 5);
}
public static void Shake(this Transform rec_trans)
{
rec_trans.localScale = Vector3.one;
rec_trans.DOKill();
rec_trans.DOPunchScale(Vector3.one, 0.3f, 5);
}
public static void FlyingOut(this Text fade_text, Vector3 default_local_pos, Action on_complete = null)
{
var rec_trans = fade_text.rectTransform;
FlyingOutPosition(rec_trans, default_local_pos, on_complete);
fade_text.DOFade(0, 1).From(1).SetEase(Ease.InOutSine);
}
public static void FlyingOut(this CanvasGroup canvas_group, Vector3 default_local_pos, Action on_complete = null)
{
var rec_trans = canvas_group.GetComponent<RectTransform>();
if (rec_trans == null) return;
FlyingOutPosition(rec_trans, default_local_pos, on_complete);
canvas_group.DOFade(0, 1).From(1).SetEase(Ease.InOutSine);
}
public static void FlyingOutPosition(RectTransform rec_trans, Vector3 default_local_pos, Action on_complete = null)
{
rec_trans.gameObject.SetActiveAsNeed(true);
rec_trans.DOKill();
var move_from = default_local_pos;
var move_to = move_from;
move_to.y += 200;
var t = rec_trans.DOLocalMove(move_to, 1f).SetEase(Ease.InOutSine).From(move_from);
t.OnComplete(() =>
{
rec_trans.gameObject.SetActiveAsNeed(false);
rec_trans.localPosition = move_from;
if (on_complete != null)
{
try
{
on_complete.Invoke();
}
catch (Exception ex)
{
GameDebug.LogError($"[DoTweenExtension]FlyingOutPosition: {ex.Message}");
}
}
});
}
public static Tween WorldMoveTo(this Transform flyobj, Transform target, float duration)
{
var end_pos = target.position;
var tw = flyobj.DOMove(end_pos, duration);
if (tw != null)
{
tw.SetEase(Ease.InOutExpo);
}
return tw;
}
public static Tween MoveTo(this Transform move_obj, Transform target, float duration, Ease ease = Ease.InOutExpo)
{
var target_pos = target.position;
return move_obj.MoveTo(target_pos, duration, ease);
}
public static Tween MoveTo(this Transform move_obj, Vector3 target_local_pos, float duration, Ease ease = Ease.InOutExpo)
{
var tw = move_obj.DOMove(target_local_pos, duration);
if (tw != null)
{
tw.SetEase(ease);
}
return tw;
}
public static Tween LocalMoveTo(this Transform move_obj, Transform target, float duration, Ease ease = Ease.InOutExpo)
{
var target_pos = target.position;
return move_obj.LocalMoveTo(target_pos, duration, ease);
}
public static Tween LocalMoveTo(this Transform move_obj, Vector3 target_local_pos, float duration, Ease ease = Ease.InOutExpo)
{
var tw = move_obj.DOLocalMove(target_local_pos, duration); // Note: DOMove seems not hit the target position after finished
if (tw != null)
{
tw.SetEase(ease);
}
return tw;
}
public static Tween FlyTo(this Transform flyobj, Transform target, float duration, PathMode mode = PathMode.Full3D,bool isUnScale = false)
{
var start_pos = flyobj.position;
start_pos.z = 0;
var end_pos = target.position;
end_pos.z = 0;
var dir = end_pos - start_pos;
var center = (end_pos + start_pos) * 0.5f;
var off_v = Vector3.up;
if (Mathf.Abs(start_pos.x) < 10f)
{
off_v = Vector3.right;
}
var ratio = Mathf.Abs(dir.y) / 650f;
var middle_pos = center + off_v * 400f * ratio;
middle_pos.z = 0;
var path = new Vector3[] { start_pos, middle_pos, end_pos };
var tw = flyobj.DOPath(path, duration, PathType.CatmullRom, mode);
if(isUnScale)
tw.SetUpdate(true);
if (tw != null)
{
tw.SetEase(Ease.Linear);
}
return tw;
}
public static Tween FlyTo(this Transform flyobj, Transform target, Transform middle, float duration, PathMode mode = PathMode.Full3D,bool isUnScale = false)
{
var start_pos = flyobj.position;
start_pos.z = 0;
var end_pos = target.position;
end_pos.z = 0;
var middle_pos = middle.position;
middle_pos.z = 0;
var path = new Vector3[] { start_pos, middle_pos, end_pos };
var tw = flyobj.DOPath(path, duration, PathType.CatmullRom, mode);
if(isUnScale)
tw.SetUpdate(true);
if (tw != null)
{
tw.SetEase(Ease.Linear);
}
return tw;
}
public static Tween FlyTo(this Transform flyobj, Vector3 target, Vector3 middle, float duration, PathMode mode = PathMode.Full3D,bool isUnScale = false)
{
var start_pos = flyobj.position;
start_pos.z = 0;
var end_pos = target;
end_pos.z = 0;
var middle_pos = middle;
middle_pos.z = 0;
var path = new Vector3[] { start_pos, middle_pos, end_pos };
var tw = flyobj.DOPath(path, duration, PathType.CatmullRom, mode);
if(isUnScale)
tw.SetUpdate(true);
if (tw != null)
{
tw.SetEase(Ease.Linear);
}
return tw;
}
public static Tween FlyTo(this Transform flyobj, Vector3 target_pos, Vector3 middle_pos, float duration,bool isUnScale = false)
{
var start_pos = flyobj.position;
start_pos.z = 0;
var path = new Vector3[] { start_pos, middle_pos, target_pos };
var tw = flyobj.DOPath(path, duration, PathType.CatmullRom, PathMode.Full3D);
if(isUnScale)
tw.SetUpdate(true);
if (tw != null)
{
tw.SetEase(Ease.Linear);
}
return tw;
}
public static Tween Flash(this Graphic target, float duration)
{
var t = DOTween.ToAlpha(() => target.color, x => target.color = x, 0, duration);
t.SetTarget(target);
t.SetLoops(-1, LoopType.Yoyo);
return t;
}
public static Tween DOFadeAlpha(this Graphic target, float endValue, float duration)
{
var t = DOTween.ToAlpha(() => target.color, x => target.color = x, endValue, duration);
t.SetTarget(target);
return t;
}
public static Tween DOFadeAlpha(this SpriteRenderer target, float endValue, float duration)
{
var t = DOTween.ToAlpha(() => target.color, x => target.color = x, endValue, duration);
t.SetTarget(target);
return t;
}
public static Tween DOFadeAlpha(this TextMesh target, float endValue, float duration)
{
var t = DOTween.ToAlpha(() => target.color, x => target.color = x, endValue, duration);
t.SetTarget(target);
return t;
}
public static Tween DOFadeAlpha(this CanvasGroup target, float endValue, float duration)
{
var t = DOTween.To(() => target.alpha, x => target.alpha = x, endValue, duration);
t.SetTarget(target);
return t;
}
public static Tween DoCircularTop(this RectTransform target, float ridus, float duration, bool isIgnoreTimeScale = false)
{
float time = 0;
Vector2 vector2 = new Vector2();
var t = DOTween.To(() => time, x => time = x, 1, duration).OnUpdate(() =>
{
float b = time;
b = (-b * 360 + 90) * Mathf.Deg2Rad;
vector2.x = Mathf.Cos(b) * ridus;
vector2.y = Mathf.Sin(b) * ridus;
target.anchoredPosition = vector2;
});
if (isIgnoreTimeScale)
t.SetUpdate(true);
return t;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 01ec160c2da27a9408bf02c3635f4394
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,902 @@
using System;
using System.Collections.Generic;
using UnityEngine;
namespace GameCore
{
public static class GameCoreEvents
{
public static readonly int GameStateEnd = 0;
public static readonly int GameStateStart = 1;
}
public class GameEventMgr
{
private static GameEventMgr _instance;
public static GameEventMgr Instance
{
get
{
if (_instance == null)
{
_instance = new GameEventMgr();
}
return _instance;
}
}
public static void Init(bool is_debug_mode = false)
{
if (_instance == null)
{
_instance = new GameEventMgr();
}
_isDebugMode = is_debug_mode;
if(_isDebugMode)
{
Debug.Log($"[GameEventMgr]Init: Running in debug mode");
}
}
public static bool _isDebugMode = false;
struct DelegateGameObjectBonding
{
public GameObject gameObject;
public Delegate listener;
public DelegateGameObjectBonding(GameObject game_object, Delegate del)
{
gameObject = game_object;
listener = del;
}
}
private readonly Queue<List<Delegate>> _listenerListQueue = new Queue<List<Delegate>>();
private readonly Queue<List<DelegateGameObjectBonding>> _listenerBondingListQueue = new Queue<List<DelegateGameObjectBonding>>();
private readonly Dictionary<int, List<Delegate>> _eventTable = new Dictionary<int, List<Delegate>>();
private readonly Dictionary<int, List<DelegateGameObjectBonding>> _eventObjTable = new Dictionary<int, List<DelegateGameObjectBonding>>();
private readonly Dictionary<string, List<Delegate>> _strEventTable = new Dictionary<string, List<Delegate>>();
private readonly Dictionary<string, List<DelegateGameObjectBonding>> _strEventObjTable = new Dictionary<string, List<DelegateGameObjectBonding>>();
private readonly Dictionary<int, List<Delegate>> _pendingAddTable = new Dictionary<int, List<Delegate>>();
private readonly Dictionary<int, List<DelegateGameObjectBonding>> _pendingObjAddTable = new Dictionary<int, List<DelegateGameObjectBonding>>();
private readonly Dictionary<int, List<Delegate>> _pendingRemoveTable = new Dictionary<int, List<Delegate>>();
private readonly Dictionary<int, List<DelegateGameObjectBonding>> _pendingObjRemoveTable = new Dictionary<int, List<DelegateGameObjectBonding>>();
private readonly Dictionary<string, List<Delegate>> _pendingAddNameTable = new Dictionary<string, List<Delegate>>();
private readonly Dictionary<string, List<DelegateGameObjectBonding>> _pendingObjAddNameTable = new Dictionary<string, List<DelegateGameObjectBonding>>();
private readonly Dictionary<string, List<Delegate>> _pendingRemoveNameTable = new Dictionary<string, List<Delegate>>();
private readonly Dictionary<string, List<DelegateGameObjectBonding>> _pendingObjRemoveNameTable = new Dictionary<string, List<DelegateGameObjectBonding>>();
// Using raising event list to prevent infinite loop call or changing delegate list
private readonly List<int> _raisingEventIds = new List<int>();
private readonly List<string> _raisingEventNames = new List<string>();
private GameEventMgr() { }
public void AddListener(int event_id, Action new_listener, GameObject life_cycle_obj = null)
{
DoAddListener(event_id, new_listener, life_cycle_obj);
}
public void AddListener<T>(int event_id, Action<T> new_listener, GameObject life_cycle_obj = null)
{
DoAddListener(event_id, new_listener, life_cycle_obj);
}
public void AddListener<T1, T2>(int event_id, Action<T1, T2> new_listener, GameObject life_cycle_obj = null)
{
DoAddListener(event_id, new_listener, life_cycle_obj);
}
public void AddListener<T1, T2, T3>(int event_id, Action<T1, T2, T3> new_listener, GameObject life_cycle_obj = null)
{
DoAddListener(event_id, new_listener, life_cycle_obj);
}
public void AddListener(string event_name, Action new_listener, GameObject life_cycle_obj = null)
{
DoAddListener(event_name, new_listener, life_cycle_obj);
}
public void AddListener<T>(string event_name, Action<T> new_listener, GameObject life_cycle_obj = null)
{
DoAddListener(event_name, new_listener, life_cycle_obj);
}
public void AddListener<T1, T2>(string event_name, Action<T1, T2> new_listener, GameObject life_cycle_obj = null)
{
DoAddListener(event_name, new_listener, life_cycle_obj);
}
public void AddListener<T1, T2, T3>(string event_name, Action<T1, T2, T3> new_listener, GameObject life_cycle_obj = null)
{
DoAddListener(event_name, new_listener, life_cycle_obj);
}
public void RemoveListener(int event_id, Action listener, GameObject life_cycle_obj = null)
{
DoRemoveListener(event_id, listener, life_cycle_obj);
}
public void RemoveListener<T>(int event_id, Action<T> listener, GameObject life_cycle_obj = null)
{
DoRemoveListener(event_id, listener, life_cycle_obj);
}
public void RemoveListener<T1, T2>(int event_id, Action<T1, T2> listener, GameObject life_cycle_obj = null)
{
DoRemoveListener(event_id, listener, life_cycle_obj);
}
public void RemoveListener<T1, T2, T3>(int event_id, Action<T1, T2, T3> listener, GameObject life_cycle_obj = null)
{
DoRemoveListener(event_id, listener, life_cycle_obj);
}
public void RemoveListener(string event_name, Action listener, GameObject life_cycle_obj = null)
{
DoRemoveListener(event_name, listener, life_cycle_obj);
}
public void RemoveListener<T>(string event_name, Action<T> listener, GameObject life_cycle_obj = null)
{
DoRemoveListener(event_name, listener, life_cycle_obj);
}
public void RemoveListener<T1, T2>(string event_name, Action<T1, T2> listener, GameObject life_cycle_obj = null)
{
DoRemoveListener(event_name, listener, life_cycle_obj);
}
public void RemoveListener<T1, T2, T3>(string event_name, Action<T1, T2, T3> listener, GameObject life_cycle_obj = null)
{
DoRemoveListener(event_name, listener, life_cycle_obj);
}
public void Raise(int event_id)
{
DoRaise(event_id);
}
public void Raise<T>(int event_id, T arg1)
{
DoRaise(event_id, arg1);
}
public void Raise<T1, T2>(int event_id, T1 arg1, T2 arg2)
{
DoRaise(event_id, arg1, arg2);
}
public void Raise<T1, T2, T3>(int event_id, T1 arg1, T2 arg2, T3 arg3)
{
DoRaise(event_id, arg1, arg2, arg3);
}
public void Raise(string event_name)
{
DoRaise(event_name);
}
public void Raise<T>(string event_name, T arg1)
{
DoRaise(event_name, arg1);
}
public void Raise<T1, T2>(string event_name, T1 arg1, T2 arg2)
{
DoRaise(event_name, arg1, arg2);
}
public void Raise<T1, T2, T3>(string event_name, T1 arg1, T2 arg2, T3 arg3)
{
DoRaise(event_name, arg1, arg2, arg3);
}
public void ClearNullGameObjectListeners()
{
var etor = _eventObjTable.GetEnumerator();
while (etor.MoveNext())
{
var listeners = etor.Current.Value;
for (int i = 0; i < listeners.Count; i++)
{
if(listeners[i].gameObject == null)
{
listeners.RemoveAt(i--);
}
}
}
var str_etor = _strEventObjTable.GetEnumerator();
while (str_etor.MoveNext())
{
var listeners = str_etor.Current.Value;
for (int i = 0; i < listeners.Count; i++)
{
if (listeners[i].gameObject == null)
{
listeners.RemoveAt(i--);
}
}
}
}
private List<Delegate> SpawnDelegateList()
{
if(_listenerListQueue.Count > 0)
{
return _listenerListQueue.Dequeue();
}
else
{
return new List<Delegate>();
}
}
private void DespawnDelegateList(List<Delegate> list)
{
if (list == null) return;
list.Clear();
_listenerListQueue.Enqueue(list);
}
private List<DelegateGameObjectBonding> SpawnDelegateBondingList()
{
if (_listenerBondingListQueue.Count > 0)
{
return _listenerBondingListQueue.Dequeue();
}
else
{
return new List<DelegateGameObjectBonding>();
}
}
private void DespawnDelegateBondingList(List<DelegateGameObjectBonding> list)
{
if (list == null) return;
list.Clear();
_listenerBondingListQueue.Enqueue(list);
}
private bool DoAddListener(int event_id, Delegate new_listener, GameObject life_cycle_obj = null)
{
if (new_listener == null)
{
Debug.LogError($"[GameEventMgr]DoAddListener: Can't add empty listener for event {event_id}!");
return false;
}
bool result = true;
// If event is raising, add it into pending list
if (_raisingEventIds.Contains(event_id))
{
if (life_cycle_obj != null)
{
if (!_pendingObjAddTable.TryGetValue(event_id, out var pending_listeners))
{
pending_listeners = SpawnDelegateBondingList();
_pendingObjAddTable[event_id] = pending_listeners;
}
pending_listeners.Add(new DelegateGameObjectBonding(life_cycle_obj, new_listener));
}
else
{
if (!_pendingAddTable.TryGetValue(event_id, out var pending_listeners))
{
pending_listeners = SpawnDelegateList();
_pendingAddTable[event_id] = pending_listeners;
}
pending_listeners.Add(new_listener);
}
}
else
{
if (life_cycle_obj != null)
{
if (!_eventObjTable.TryGetValue(event_id, out var listener_bondings))
{
listener_bondings = SpawnDelegateBondingList();
_eventObjTable[event_id] = listener_bondings;
}
if (listener_bondings.Count == 0 || listener_bondings[0].listener.GetType() == new_listener.GetType())
{
var bonding = new DelegateGameObjectBonding(life_cycle_obj, new_listener);
if (_isDebugMode && listener_bondings.Contains(bonding))
{
Debug.LogError($"[GameEventMgr]DoAddListener: Already in the list, will not add it again [{new_listener.Target}.{new_listener.Method?.Name}]");
}
else
{
listener_bondings.Add(bonding);
}
}
else if (listener_bondings[0].listener.GetType() != new_listener.GetType())
{
Debug.LogError($"[GameEventMgr]DoAddListener: Attempting to add listener with inconsistent signature for event {event_id}. Current listeners type({listener_bondings[0].listener.GetType().Name}) != added type({new_listener.GetType().Name})");
result = false;
}
}
else
{
if (!_eventTable.TryGetValue(event_id, out var listeners))
{
listeners = SpawnDelegateList();
_eventTable[event_id] = listeners;
}
if (listeners.Count == 0 || listeners[0].GetType() == new_listener.GetType())
{
if (_isDebugMode && listeners.Contains(new_listener))
{
Debug.LogError($"[GameEventMgr]DoAddListener: Already in the list, will not add it again [{new_listener.Target}.{new_listener.Method?.Name}]");
}
else
{
listeners.Add(new_listener);
}
}
else if (listeners[0].GetType() != new_listener.GetType())
{
Debug.LogError($"[GameEventMgr]DoAddListener: Attempting to add listener with inconsistent signature for event {event_id}. Current listeners type({listeners[0].GetType().Name}) != added type({new_listener.GetType().Name})");
result = false;
}
}
}
return result;
}
private bool DoAddListener(string event_name, Delegate new_listener, GameObject life_cycle_obj = null)
{
if (new_listener == null)
{
Debug.LogError($"[GameEventMgr]DoAddListener: Can't add empty listener for event {event_name}!");
return false;
}
bool result = true;
// If event is raising, add it into pending list
if (_raisingEventNames.Contains(event_name))
{
if (life_cycle_obj != null)
{
if (!_pendingObjAddNameTable.TryGetValue(event_name, out var pending_listeners))
{
pending_listeners = SpawnDelegateBondingList();
_pendingObjAddNameTable[event_name] = pending_listeners;
}
pending_listeners.Add(new DelegateGameObjectBonding(life_cycle_obj, new_listener));
}
else
{
if (!_pendingAddNameTable.TryGetValue(event_name, out var pending_listeners))
{
pending_listeners = SpawnDelegateList();
_pendingAddNameTable[event_name] = pending_listeners;
}
pending_listeners.Add(new_listener);
}
}
else
{
if (life_cycle_obj != null)
{
if (!_strEventObjTable.TryGetValue(event_name, out var listeners))
{
listeners = SpawnDelegateBondingList();
_strEventObjTable[event_name] = listeners;
}
if (listeners.Count == 0 || listeners[0].listener.GetType() == new_listener.GetType())
{
var bonding = new DelegateGameObjectBonding(life_cycle_obj, new_listener);
if (_isDebugMode && listeners.Contains(bonding))
{
Debug.LogError($"[GameEventMgr]DoAddListener: Already in the list, will not add it again [{new_listener.Target}.{new_listener.Method?.Name}]");
}
else
{
listeners.Add(bonding);
}
}
else if (listeners[0].listener.GetType() != new_listener.GetType())
{
Debug.LogError($"[GameEventMgr]DoAddListener: Attempting to add listener with inconsistent signature for event {event_name}. Current listeners type({listeners[0].listener.GetType().Name}) != added type({new_listener.GetType().Name})");
result = false;
}
}
else
{
if (!_strEventTable.TryGetValue(event_name, out var listeners))
{
listeners = SpawnDelegateList();
_strEventTable[event_name] = listeners;
}
if (listeners.Count == 0 || listeners[0].GetType() == new_listener.GetType())
{
if (_isDebugMode && listeners.Contains(new_listener))
{
Debug.LogError($"[GameEventMgr]DoAddListener: Already in the list, will not add it again [{new_listener.Target}.{new_listener.Method?.Name}]");
}
else
{
listeners.Add(new_listener);
}
}
else if (listeners[0].GetType() != new_listener.GetType())
{
Debug.LogError($"[GameEventMgr]DoAddListener: Attempting to add listener with inconsistent signature for event {event_name}. Current listeners type({listeners[0].GetType().Name}) != added type({new_listener.GetType().Name})");
result = false;
}
}
}
return result;
}
private bool DoRemoveListener(int event_id, Delegate listener, GameObject life_cycle_obj = null)
{
if (listener == null)
{
Debug.LogError($"[GameEventMgr]DoRemoveListener: Can't remove empty listener for event {event_id}!");
return false;
}
bool result = false;
// If event is raising, add it into pending list
if (_raisingEventIds.Contains(event_id))
{
if (life_cycle_obj != null)
{
if (!_pendingObjRemoveTable.TryGetValue(event_id, out var pending_listeners))
{
pending_listeners = SpawnDelegateBondingList();
_pendingObjRemoveTable[event_id] = pending_listeners;
}
pending_listeners.Add(new DelegateGameObjectBonding(life_cycle_obj, listener));
}
else
{
if (!_pendingRemoveTable.TryGetValue(event_id, out var pending_listeners))
{
pending_listeners = SpawnDelegateList();
_pendingRemoveTable[event_id] = pending_listeners;
}
pending_listeners.Add(listener);
}
result = true;
}
else
{
if (life_cycle_obj != null)
{
if (_eventObjTable.TryGetValue(event_id, out var listeners))
{
if (listeners.Count > 0)
{
listeners.Remove(new DelegateGameObjectBonding(life_cycle_obj, listener));
result = true;
}
if (listeners.Count == 0)
{
DespawnDelegateBondingList(listeners);
_eventObjTable.Remove(event_id);
}
}
}
else
{
if (_eventTable.TryGetValue(event_id, out var listeners))
{
if (listeners.Count > 0)
{
listeners.Remove(listener);
result = true;
}
if (listeners.Count == 0)
{
DespawnDelegateList(listeners);
_eventTable.Remove(event_id);
}
}
}
}
return result;
}
private bool DoRemoveListener(string event_name, Delegate listener, GameObject life_cycle_obj = null)
{
if (listener == null)
{
Debug.LogError($"[GameEventMgr]DoRemoveListener: Can't remove empty listener for event {event_name}!");
return false;
}
bool result = false;
// If event is raising, add it into pending list
if (_raisingEventNames.Contains(event_name))
{
if (life_cycle_obj != null)
{
if (!_pendingObjRemoveNameTable.TryGetValue(event_name, out var pending_listeners))
{
pending_listeners = SpawnDelegateBondingList();
_pendingObjRemoveNameTable[event_name] = pending_listeners;
}
pending_listeners.Add(new DelegateGameObjectBonding(life_cycle_obj, listener));
}
else
{
if (!_pendingRemoveNameTable.TryGetValue(event_name, out var pending_listeners))
{
pending_listeners = SpawnDelegateList();
_pendingRemoveNameTable[event_name] = pending_listeners;
}
pending_listeners.Add(listener);
}
result = true;
}
else
{
if (life_cycle_obj != null)
{
if (_strEventObjTable.TryGetValue(event_name, out var listeners))
{
if (listeners.Count > 0)
{
listeners.Remove(new DelegateGameObjectBonding(life_cycle_obj, listener));
result = true;
}
if (listeners.Count == 0)
{
DespawnDelegateBondingList(listeners);
_strEventObjTable.Remove(event_name);
}
}
}
else
{
if (_strEventTable.TryGetValue(event_name, out var listeners))
{
if (listeners.Count > 0)
{
listeners.Remove(listener);
result = true;
}
if (listeners.Count == 0)
{
DespawnDelegateList(listeners);
_strEventTable.Remove(event_name);
}
}
}
}
return result;
}
private void LogException(Exception ex, string event_tag, string method_name)
{
string msg = ex.Message;
string stack_trace = ex.StackTrace;
if (ex.InnerException != null)
{
msg = ex.InnerException.Message;
stack_trace = ex.InnerException.StackTrace;
}
Debug.LogError($"[GameEventMgr]{method_name}: Event({event_tag}) {msg}\nStack Trace: {stack_trace}");
}
private bool DoRaise(int event_id, params object[] args)
{
if (_raisingEventIds.Contains(event_id))
{
Debug.LogError($"[GameEventMgr]DoRaise: Can't raise event({event_id}) again inside the same event raising process!");
return false;
}
bool result = false;
_raisingEventIds.Add(event_id);
if (_eventObjTable.TryGetValue(event_id, out var bond_listeners))
{
for (int i = 0; i < bond_listeners.Count; i++)
{
var bond_listener = bond_listeners[i];
if (bond_listener.gameObject != null)
{
try
{
bond_listener.listener.Method.Invoke(bond_listener.listener.Target, args);
result = true;
}
catch (Exception ex)
{
bond_listeners.RemoveAt(i--);
LogException(ex, $"{event_id}_Obj[{bond_listener.gameObject.name}]", "DoRaise");
}
}
else
{
bond_listeners.RemoveAt(i--);
Debug.Log($"[GameEventMgr]DoRaise: Remove null GameObject listener ({event_id})!");
continue;
}
}
}
if (_eventTable.TryGetValue(event_id, out var listeners))
{
for (int i = 0; i < listeners.Count; i++)
{
var listener = listeners[i];
if(listener != null)
{
try
{
listener.Method.Invoke(listener.Target, args);
result = true;
}
catch (Exception ex)
{
listeners.RemoveAt(i--);
LogException(ex, event_id.ToString(), "DoRaise");
}
}
}
}
_raisingEventIds.Remove(event_id);
if (_pendingObjAddTable.TryGetValue(event_id, out var add_bond_listeners))
{
if (add_bond_listeners != null && add_bond_listeners.Count > 0)
{
bond_listeners.AddRange(add_bond_listeners);
DespawnDelegateBondingList(add_bond_listeners);
}
_pendingObjAddTable.Remove(event_id);
}
if (_pendingObjRemoveTable.TryGetValue(event_id, out var remove_bond_listeners))
{
if (remove_bond_listeners != null && remove_bond_listeners.Count > 0)
{
for (int i = 0; i < remove_bond_listeners.Count; i++)
{
bond_listeners.Remove(remove_bond_listeners[i]);
}
DespawnDelegateBondingList(remove_bond_listeners);
}
_pendingObjRemoveTable.Remove(event_id);
}
if (bond_listeners?.Count == 0)
{
DespawnDelegateBondingList(bond_listeners);
_eventObjTable.Remove(event_id);
}
if (_pendingAddTable.TryGetValue(event_id, out var add_listeners))
{
if (add_listeners != null && add_listeners.Count > 0)
{
listeners.AddRange(add_listeners);
DespawnDelegateList(add_listeners);
}
_pendingAddTable.Remove(event_id);
}
if (_pendingRemoveTable.TryGetValue(event_id, out var remove_listeners))
{
if (remove_listeners != null && remove_listeners.Count > 0)
{
for (int i = 0; i < remove_listeners.Count; i++)
{
listeners.Remove(remove_listeners[i]);
}
DespawnDelegateList(remove_listeners);
}
_pendingRemoveTable.Remove(event_id);
}
if (listeners?.Count == 0)
{
DespawnDelegateList(listeners);
_eventTable.Remove(event_id);
}
return result;
}
private bool DoRaise(string event_name, params object[] args)
{
if (_raisingEventNames.Contains(event_name))
{
Debug.LogError($"[GameEventMgr]DoRaise: Can't raise event({event_name}) again inside the same event raising process!");
return false;
}
bool result = false;
_raisingEventNames.Add(event_name);
if (_strEventObjTable.TryGetValue(event_name, out var bond_listeners))
{
for (int i = 0; i < bond_listeners.Count; i++)
{
var bond_listener = bond_listeners[i];
if (bond_listener.gameObject != null)
{
try
{
bond_listener.listener.Method.Invoke(bond_listener.listener.Target, args);
result = true;
}
catch (Exception ex)
{
bond_listeners.RemoveAt(i--);
LogException(ex, $"{event_name}_Obj[{bond_listener.gameObject.name}]", "DoRaise");
}
}
else
{
bond_listeners.RemoveAt(i--);
Debug.Log($"[GameEventMgr]DoRaise: Remove null GameObject listener ({event_name})!");
}
}
}
if (_strEventTable.TryGetValue(event_name, out var listeners))
{
for (int i = 0; i < listeners.Count; i++)
{
var listener = listeners[i];
if (listener != null)
{
try
{
listener.Method.Invoke(listener.Target, args);
result = true;
}
catch (Exception ex)
{
listeners.RemoveAt(i--);
LogException(ex, event_name, "DoRaise");
}
}
}
}
_raisingEventNames.Remove(event_name);
if (_pendingObjAddNameTable.TryGetValue(event_name, out var add_bond_listeners))
{
if (add_bond_listeners != null && add_bond_listeners.Count > 0)
{
bond_listeners.AddRange(add_bond_listeners);
DespawnDelegateBondingList(add_bond_listeners);
}
_pendingObjAddNameTable.Remove(event_name);
}
if (_pendingObjRemoveNameTable.TryGetValue(event_name, out var remove_bond_listeners))
{
if (remove_bond_listeners != null && remove_bond_listeners.Count > 0)
{
for (int i = 0; i < remove_bond_listeners.Count; i++)
{
bond_listeners.Remove(remove_bond_listeners[i]);
}
DespawnDelegateBondingList(remove_bond_listeners);
}
_pendingObjRemoveNameTable.Remove(event_name);
}
if (bond_listeners?.Count == 0)
{
DespawnDelegateBondingList(bond_listeners);
_strEventObjTable.Remove(event_name);
}
if (_pendingAddNameTable.TryGetValue(event_name, out var add_listeners))
{
if (add_listeners != null && add_listeners.Count > 0)
{
listeners.AddRange(add_listeners);
DespawnDelegateList(add_listeners);
}
_pendingAddNameTable.Remove(event_name);
}
if (_pendingRemoveNameTable.TryGetValue(event_name, out var remove_listeners))
{
if (remove_listeners != null && remove_listeners.Count > 0)
{
for (int i = 0; i < remove_listeners.Count; i++)
{
listeners.Remove(remove_listeners[i]);
}
DespawnDelegateList(remove_listeners);
}
_pendingRemoveNameTable.Remove(event_name);
}
if (listeners?.Count == 0)
{
DespawnDelegateList(listeners);
_strEventTable.Remove(event_name);
}
return result;
}
public void Clear()
{
_eventTable.Clear();
_eventObjTable.Clear();
_strEventTable.Clear();
_strEventObjTable.Clear();
_pendingAddTable.Clear();
_pendingObjAddTable.Clear();
_pendingRemoveTable.Clear();
_pendingObjRemoveTable.Clear();
_pendingAddNameTable.Clear();
_pendingObjAddNameTable.Clear();
_pendingRemoveNameTable.Clear();
_pendingObjRemoveNameTable.Clear();
_raisingEventIds.Clear();
_raisingEventNames.Clear();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: af0b2f5d34d2eef43999b48f9d3e0a54
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,31 @@
using System.Resources;
public static class GameEvents
{
public static readonly int EVENTS_START_ID = 100;
public static readonly int DownloadStart = EVENTS_START_ID++;
public static readonly int DownloadTotalSize = EVENTS_START_ID++;
public static readonly int DownloadingSingleFile = EVENTS_START_ID++;
public static readonly int DownloadAssetProgress = EVENTS_START_ID++;
public static readonly int DownloadAssetComplete = EVENTS_START_ID++;
public static readonly int FinishDownloadSingleFile = EVENTS_START_ID++;
public static readonly int ApplicationFocus = EVENTS_START_ID++;
public static readonly int ApplicationQuit = EVENTS_START_ID++;
public static readonly int SetGameState = EVENTS_START_ID++;
public static readonly int GameRestart = EVENTS_START_ID++;
public static readonly int ShowErrorDialog = EVENTS_START_ID++;
public static readonly int DeviceProfileChange = EVENTS_START_ID++;
public static readonly int FinishUpdateEvent = EVENTS_START_ID++;
public static readonly int LoggedIn = EVENTS_START_ID++;
public static readonly int StageDraggerClick = EVENTS_START_ID++;
public static readonly int FishCountChange = EVENTS_START_ID++;
public static readonly int ShowHomeMap = EVENTS_START_ID++;
public static readonly int HideHomeMap = EVENTS_START_ID++;
public static readonly int FishingEvent = EVENTS_START_ID++;
public static readonly int EventFishingPlay = EVENTS_START_ID++;
public static readonly int Social_InfoClub = EVENTS_START_ID++;
public static readonly int EVENTS_END_ID = EVENTS_START_ID++;
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b033b66c2c06ed240b0f43d2520b1bd1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,436 @@
//#define EDITOR_GAMEVIEW_CHANGE_ENABLE
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text;
using UnityEngine;
using GameCore;
using asap.core;
#if UNITY_EDITOR
using UnityEditor;
#endif
public class GlobalUtils
{
public static string gameVersion
{
get
{
#if UNITY_EDITOR
return Application.version;
#else
return string.Format("{0}.{1}", Application.version, Application.buildGUID.GetHashCode().ToString("x"));
#endif
}
}
public static T StringToEnum<T>(string modestr, T defaultValue) where T : Enum
{
foreach (T mode in Enum.GetValues(typeof(T)))
{
if (mode.ToString() == modestr)
return mode;
}
return defaultValue;
}
public static bool SaveFile(string content, string destPath)
{
byte[] bytes = Encoding.UTF8.GetBytes(content);
return SaveFile(bytes, destPath);
}
public static bool SaveFile(Byte[] bytes, string destPath)
{
if (bytes == null || string.IsNullOrEmpty(destPath))
{
return false;
}
bool result = true;
int index = destPath.LastIndexOf("/");
string directory = destPath.Substring(0, index);
if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory))
{
try
{
Directory.CreateDirectory(directory);
}
catch (Exception ex)
{
GameDebug.LogError("[GlobalUtils]SaveFile: {0}", ex.Message);
result = false;
}
}
if (Directory.Exists(directory) && !File.Exists(destPath))
{
try
{
using (var file = File.Create(destPath)) { }
}
catch (Exception ex)
{
GameDebug.LogError("[GlobalUtils]SaveFile: {0}", ex.Message);
result = false;
}
}
if (File.Exists(destPath))
{
try
{
File.WriteAllBytes(destPath, bytes);
}
catch (IOException ex)
{
GameDebug.LogError("[GlobalUtils]SaveFile: {0}", ex.Message);
result = false;
}
catch (Exception ex)
{
GameDebug.LogError("[GlobalUtils]SaveFile: {0}", ex.Message);
result = false;
}
}
if (!result)
{
MessageDialog.ShowSomethingWrong();
}
return result;
}
public static byte[] AesEncrypt(byte[] array, string key)
{
if (array == null || array.Length <= 0)
{
return null;
}
var toEncryptArray = array;
var rm = new System.Security.Cryptography.RijndaelManaged
{
Key = Encoding.UTF8.GetBytes(key),
Mode = System.Security.Cryptography.CipherMode.ECB,
Padding = System.Security.Cryptography.PaddingMode.PKCS7
};
var cTransform = rm.CreateEncryptor();
var resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
return resultArray;
}
public static byte[] AesDecrypt(byte[] array, string key)
{
if (array == null || array.Length <= 0)
{
return null;
}
var toEncryptArray = array;
var rm = new System.Security.Cryptography.RijndaelManaged
{
Key = Encoding.UTF8.GetBytes(key),
Mode = System.Security.Cryptography.CipherMode.ECB,
Padding = System.Security.Cryptography.PaddingMode.PKCS7
};
var cTransform = rm.CreateDecryptor();
var resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
return resultArray;
}
static decimal unitT = new decimal(1000000000000L);
static decimal unitQ = new decimal(1000000000000000L);
public static string GetNumStringFloorInt(ulong coin_num)
{
decimal v = 0m;
var suffix = string.Empty;
if (coin_num < 1000)
{
v = coin_num;
}
else if (coin_num >= 1000 && coin_num < 1000000)
{
v = coin_num / 1000m;
suffix = "K";
}
else if (coin_num >= 1000000 && coin_num < 1000000000)
{
v = coin_num / 1000000m;
suffix = "M";
}
else if (coin_num >= 1000000000 && coin_num < 1000000000000)
{
v = coin_num / 1000000000m;
suffix = "B";
}
else if (coin_num >= 1000000000000 && coin_num < 1000000000000000)
{
v = coin_num / unitT;
suffix = "T";
}
else if (coin_num >= 1000000000000000)
{
v = coin_num / unitQ;
suffix = "Q";
}
var floor_v = decimal.Truncate(v);
var num_str = $"{floor_v:0}{suffix}";
return num_str;
}
public static string GetNumString(ulong coin_num)
{
decimal v = 0m;
var suffix = string.Empty;
if (coin_num < 1000)
{
v = coin_num;
}
else if (coin_num >= 1000 && coin_num < 1000000)
{
v = coin_num / 1000m;
suffix = "K";
}
else if (coin_num >= 1000000 && coin_num < 1000000000)
{
v = coin_num / 1000000m;
suffix = "M";
}
else if (coin_num >= 1000000000 && coin_num < 1000000000000)
{
v = coin_num / 1000000000m;
suffix = "B";
}
else if (coin_num >= 1000000000000 && coin_num < 1000000000000000)
{
v = coin_num / unitT;
suffix = "T";
}
else if (coin_num >= 1000000000000000)
{
v = coin_num / unitQ;
suffix = "Q";
}
var truncate_v = decimal.Truncate(v * 10) / 10;
var num_str = $"{truncate_v:0.#}{suffix}";
return num_str;
}
// public static string GetPayCountStr(uint price)
// {
// double pricereal = (double)((double)price / 100f);
// return pricereal.ToString("N");
// }
static readonly string[] suffixes = { "B", "KB", "MB", "GB", "TB", "PB" };
public static string GetSizeString(Int64 bytes)
{
int counter = 0;
decimal number = (decimal)bytes;
while (Math.Round(number / 1024) >= 1)
{
number /= 1024;
counter++;
}
return string.Format("{0:n1}{1}", number, suffixes[counter]);
}
public static RectTransform SetParent(Transform child, Transform parent)
{
RectTransform childrect = child.transform.GetComponent<RectTransform>();
RectTransform _parent = parent.transform.GetComponent<RectTransform>();
childrect.SetParent(_parent);
childrect.localScale = Vector3.one;
childrect.anchoredPosition = Vector2.zero;
return childrect;
}
//public static void SetRendererGray(SpriteRenderer rend)
//{
//Material mat = AssetManager.LoadAsset<Material>("ImageGrayMat");
//if (mat != null)
//{
//rend.material = mat;
//}
//}
public static int TryParseInt(string data_string, int default_value = 0)
{
int set_data = default_value;
if (int.TryParse(data_string, out int parsed_value))
{
set_data = parsed_value;
}
return set_data;
}
public static ulong TryParseUlong(string data_string, ulong default_value = 0)
{
ulong set_data = default_value;
if (ulong.TryParse(data_string, out ulong parsed_value))
{
set_data = parsed_value;
}
return set_data;
}
public static DateTime TryParseDateTime(string data_string, DateTime default_value)
{
DateTime set_data = default_value;
if (DateTime.TryParse(data_string, out DateTime parsed_value))
{
set_data = parsed_value;
}
return set_data;
}
#if UNITY_EDITOR && EDITOR_GAMEVIEW_CHANGE_ENABLE
static ScreenType currentGameViewType = ScreenType.INVALID;
#endif
public static void ChangeEditorGameView(ScreenType game_view_type)
{
#if UNITY_EDITOR && EDITOR_GAMEVIEW_CHANGE_ENABLE
if (currentGameViewType == game_view_type) return;
var is_auto_change_gameview = EditorPrefs.GetBool("AutoChangeGameView", false);
if (is_auto_change_gameview)
{
var windows = (EditorWindow[])Resources.FindObjectsOfTypeAll(typeof(EditorWindow));
EditorWindow gameview_landscape = null;
EditorWindow gameview_portrait = null;
EditorWindow ab_buildview = null;
EditorWindow inspector_window = null;
EditorWindow jconsole_window = null;
int num_gameview = 0;
foreach (var window in windows)
{
if (window == null) continue;
if (window.GetType().FullName == "UnityEditor.GameView")
{
var gameview_type = GameViewUtils.GetGameViewType(window);
if (gameview_type == ScreenType.LANDSCAPE)
{
gameview_landscape = window;
}
else
{
gameview_portrait = window;
}
num_gameview++;
}
else if (window.titleContent.text == "Inspector")
{
inspector_window = window;
}
else if (window.titleContent.text == "AB打包窗口")
{
ab_buildview = window;
}
else if (window.titleContent.text == "JConsole")
{
jconsole_window = window;
}
}
if (game_view_type == ScreenType.PORTRAIT)
{
if (num_gameview == 1)
{
GameViewUtils.SetSize(5);
}
else if (num_gameview == 2)
{
if (ab_buildview != null)
{
ab_buildview.Focus();
}
if (gameview_portrait != null)
{
gameview_portrait.Focus();
}
UnityEditorInternal.InternalEditorUtility.RepaintAllViews();
}
}
else
{
if (num_gameview == 1)
{
GameViewUtils.SetSize(6);
}
else if (num_gameview == 2)
{
if (jconsole_window != null)
{
jconsole_window.Focus();
}
else if (inspector_window != null)
{
inspector_window.Focus();
}
if (gameview_landscape != null)
{
gameview_landscape.Focus();
}
UnityEditorInternal.InternalEditorUtility.RepaintAllViews();
}
}
}
else
{
var windows = (EditorWindow[])Resources.FindObjectsOfTypeAll(typeof(EditorWindow));
foreach (var window in windows)
{
if (window != null && window.GetType().FullName == "UnityEditor.GameView")
{
if (!window.hasFocus)
{
window.Focus();
break;
}
}
}
UnityEditorInternal.InternalEditorUtility.RepaintAllViews();
}
currentGameViewType = game_view_type;
#endif
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3472c8c4e5f231c4084dbb54174de30e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,11 @@
using asap.core;
using UnityEngine;
public class OutPlayVibration : MonoBehaviour
{
public HapticTypes hapticTypes;
private void OnEnable()
{
GContext.Publish(new VibrationData(hapticTypes));
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 30d578e4d3eaa404895ab4710bfb96fe
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,271 @@
using asap.core;
using PlayFab;
using PlayFab.ClientModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using UnityEngine;
public class PlayFabMgr : MonoBehaviour
{
const int USER_DATA_UPDATE_INTERVAL = 40;
const int Buffer_Count = 5;
const string Last_Update_Time_Key_Prefix = "LastUpdateTime";
const string Local_Data_Key_prefix = "LocalData";
private string Last_Update_Time_Key;
private string Local_Data_Key;
private LinkedList<Dictionary<string, string>> dataBuffer;
private Dictionary<string, string> swapData;
private Dictionary<string, long> lastUpdateTime;
private Dictionary<string, string> localData;
private CancellationTokenSource tokenSource;
static PlayFabMgr _instance = null;
public static PlayFabMgr Instance
{
get
{
if (_instance == null)
{
GameDebug.LogError("PlayFabMgr Instance doesn't exist yet!");
}
return _instance;
}
}
public Dictionary<string, string> CompareDatas(Dictionary<string, UserDataRecord> remoteDatas, string userId)
{
Last_Update_Time_Key = $"{Last_Update_Time_Key_Prefix}_{userId}";
Local_Data_Key = $"{Local_Data_Key_prefix}_{userId}";
var lastUpdateTimeStr = PlayerPrefs.GetString(Last_Update_Time_Key, string.Empty);
var now = ZZTimeHelper.UtcNow().Ticks;
localData = new Dictionary<string, string>();
lastUpdateTime = new Dictionary<string, long>();
if (string.IsNullOrEmpty(lastUpdateTimeStr))
{
if (remoteDatas != null && remoteDatas.Count > 0)
{
lastUpdateTime = remoteDatas.ToDictionary(x => x.Key, x => x.Value.LastUpdated.Ticks);
localData = remoteDatas.ToDictionary(x => x.Key, x => x.Value.Value);
}
}
else
{
var tempLastUpdateTime = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, long>>(lastUpdateTimeStr);
var localDataStr = PlayerPrefs.GetString(Local_Data_Key);
var tempLocalData = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, string>>(localDataStr);
var allKeys = tempLocalData.Keys.Concat(remoteDatas.Keys).Distinct();
foreach (var key in allKeys)
{
var localValue = tempLocalData.ContainsKey(key) ? tempLocalData[key] : null;
var remoteValue = remoteDatas.ContainsKey(key) ? remoteDatas[key].Value : null;
var localTime = tempLastUpdateTime.ContainsKey(key) ? tempLastUpdateTime[key] : 0;
var remoteTime = remoteDatas.ContainsKey(key) ? remoteDatas[key].LastUpdated.Ticks : 0;
if (localValue == null)
{
localData[key] = remoteValue;
lastUpdateTime[key] = remoteTime;
continue;
}
if (remoteValue == null)
{
UpdateUserDataValue(key, localValue);
lastUpdateTime[key] = now;
localData[key] = localValue;
continue;
}
var timeDelta = localTime - remoteTime;
if (Math.Abs(timeDelta) > TimeSpan.TicksPerSecond * 60)
{
if (localTime > remoteTime)
{
UpdateUserDataValue(key, localValue);
lastUpdateTime[key] = now;
localData[key] = localValue;
}
else
{
lastUpdateTime[key] = remoteTime;
localData[key] = remoteValue;
}
}
else
{
lastUpdateTime[key] = localTime;
localData[key] = localValue;
}
}
}
PlayerPrefs.SetString(Last_Update_Time_Key, LitJson.JsonMapper.ToJson(lastUpdateTime));
PlayerPrefs.SetString(Local_Data_Key, LitJson.JsonMapper.ToJson(localData));
return localData;
}
void Awake()
{
_instance = this;
InitBuffer();
tokenSource = new CancellationTokenSource();
UpdateUserDataValue(tokenSource.Token);
}
void InitBuffer()
{
dataBuffer = new LinkedList<Dictionary<string, string>>();
for (int i = 0; i < Buffer_Count; i++)
{
dataBuffer.AddLast(new Dictionary<string, string>());
}
swapData = new Dictionary<string, string>();
}
void OnApplicationPause(bool is_pause)
{
if (is_pause)
{
tokenSource.Cancel();
tokenSource = null;
SyncData();
}
else
{
tokenSource = new CancellationTokenSource();
UpdateUserDataValue(tokenSource.Token);
}
}
void OnApplicationQuit()
{
tokenSource.Cancel();
tokenSource = null;
SyncData();
}
void OnDestroy()
{
tokenSource?.Cancel();
tokenSource = null;
SyncData();
}
private async void UpdateUserDataValue(CancellationToken token)
{
try
{
while (!token.IsCancellationRequested)
{
SyncData();
await Task.Delay(USER_DATA_UPDATE_INTERVAL * 1000);
}
}
catch (System.Exception) { }
}
public void UpdateUserDataValue(string key, string data, bool remoteStore = true)
{
if(remoteStore)
{
var cbuff = dataBuffer.First;
while (cbuff != null)
{
var datas = cbuff.Value;
if (!datas.ContainsKey(key) && datas.Count >= 10)
{
cbuff = cbuff.Next;
continue;
}
cbuff.Value[key] = data;
break;
}
}
localData[key] = data;
lastUpdateTime[key] = ZZTimeHelper.UtcNow().Ticks;
PlayerPrefs.SetString(Last_Update_Time_Key, LitJson.JsonMapper.ToJson(lastUpdateTime));
PlayerPrefs.SetString(Local_Data_Key, LitJson.JsonMapper.ToJson(localData));
}
/// <summary>
/// 没有数据返回 null 一定一定一定判空!!!
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public string GetLocalData(string key)
{
if (localData.ContainsKey(key))
{
return localData[key];
}
else
{
return null;
}
}
private void SyncData()
{
var buf = dataBuffer.First;
if (buf.Value.Count == 0)
return;
var datas = buf.Value;
swapData.Clear();
buf.Value = swapData;
swapData = datas;
dataBuffer.RemoveFirst();
dataBuffer.AddLast(buf);
var request = new UpdateUserDataRequest()
{
Data = swapData,
Permission = UserDataPermission.Public
};
PlayFabClientAPI.UpdateUserData(request, null, UpdateFaild);
}
private void UpdateFaild(PlayFabError error)
{
GameDebug.LogError("[PlayFabMgr]UpdateUserData Error: {0}", error.ToString());
}
public async Task<bool> SyncDataImmidiate(string key, string data)
{
foreach(var buff in dataBuffer)
{
if(buff.ContainsKey(key))
{
buff.Remove(key);
}
}
var taskSource = new TaskCompletionSource<bool>();
var request = new UpdateUserDataRequest()
{
Data = new Dictionary<string, string>() { { key, data } },
Permission = UserDataPermission.Public
};
PlayFabClientAPI.UpdateUserData(request,
(r) => { taskSource.SetResult(true); },
(e) => {
taskSource.SetResult(false);
UnityEngine.Debug.LogError($"[PlayFabMgr]UpdateUserData Error: {e.ToString()}");
}
);
return await taskSource.Task;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ee122ad5cb7a1f142a4c150b403102bd
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,610 @@
using UnityEngine;
using asap.core;
using UnityEngine.AddressableAssets;
using System.Collections.Generic;
using UniRx;
using GameCore;
using cfg;
using Task = System.Threading.Tasks.Task;
using game;
using UnityEngine.ResourceManagement.AsyncOperations;
using System.Linq;
namespace Game
{
public struct ChangeRodDataEvent
{
public ChangeRodDataEvent(int rodId)
{
RodId = rodId;
}
public int RodId;
}
public interface IEventData
{
public SoundType audioType { set; get; }
public string audioNameStr { set; get; }
public float time { set; get; }
}
public class EventFishingSound : IEventData
{
public EventFishingSound(SoundType audioName, float time = 0, bool loop = false)
{
this.audioType = audioName;
this.audioNameStr = audioName.ToString();
this.time = time;
this.loop = loop;
}
public EventFishingSound(string audioName, float time = 0)
{
this.audioType = SoundType.Fishing;
this.audioNameStr = audioName;
this.time = time;
}
public Sound Sound { set; get; }
public SoundType audioType { set; get; }
public string audioNameStr { set; get; }
public float time { set; get; }
public bool loop { set; get; }
}
public class EventUISound : IEventData
{
public EventUISound(SoundType audioName, float time = 0)
{
this.audioType = audioName;
this.audioNameStr = audioName.ToString();
this.time = time;
}
public EventUISound(string audioName, float time = 0)
{
this.audioType = SoundType.UI;
this.audioNameStr = audioName;
this.time = time;
}
public Sound Sound { set; get; }
public SoundType audioType { set; get; }
public string audioNameStr { set; get; }
public float time { set; get; }
}
public class EventBGMSound : IEventData
{
public EventBGMSound(string audioName, float time = 0)
{
this.audioType = SoundType.BGM;
this.audioNameStr = audioName;
this.time = time;
}
public SoundType audioType { set; get; }
public string audioNameStr { set; get; }
public float time { set; get; }
}
public class FadeOutEvent
{
public FadeOutEvent(Sound sound, float timer = 0.5f)
{
this.sound = sound;
this.timer = timer;
}
public Sound sound { set; get; }
public float timer { set; get; }
}
public struct SoundMuteEvent
{
public SoundMuteEvent(int muteType)
{
this.muteType = muteType;
}
public int muteType;
}
public class AssetReferenceAudioClip
{
public AssetReferenceAudioClip(AssetReferenceT<AudioClip> assetReference, bool isOutDisable = false, SoundMainType mainType = SoundMainType.UI, float time = 0)
{
this.assetReference = assetReference;
this.time = time;
this.mainType = mainType;
this.isOutDisable = isOutDisable;
}
public AssetReferenceT<AudioClip> assetReference;
public Sound Sound { set; get; }
public float time { set; get; }
public SoundMainType mainType { set; get; }
public bool isOutDisable = false;
}
public class AssetReferenceAudioVoiceClip
{
public AssetReferenceAudioVoiceClip(AssetReferenceT<AudioClip> assetReference)
{
this.assetReference = assetReference;
}
public AssetReferenceT<AudioClip> assetReference;
public Sound Sound { set; get; }
}
public class OnSoundStateEvent
{
public OnSoundStateEvent(int type)
{
this.type = type;
}
public int type;
}
public class SoundMgr
{
[Inject]
public ISoundService soundService { set; get; }
public Tables _tables { set; get; }
string[] residentFish =
{ SoundType.audio_fishing_waiting.ToString(),
SoundType.audio_fishing_waiting_fishgathering.ToString(),
"audio_fishing_drawing_hpevent_01", "audio_fishing_drawing_hpevent_02","audio_fishing_drawing_hpevent_03","audio_fishing_drawing_hpevent_04","audio_fishing_drawing_hpevent_05",
SoundType.audio_fishing_welldone.ToString(),
SoundType.audio_fishing_switchrod.ToString(),
SoundType.audio_ui_targetcollect_collecting.ToString(),
SoundType.audio_ui_targetcollect_fly.ToString(),
"audio_fishing_pulling_fishflapping_01","audio_fishing_pulling_fishflapping_02","audio_fishing_pulling_fishflapping_03",
SoundType.audio_ui_fishingmap_btn_levelup.ToString(),
SoundType.audio_ui_fishingmap_fishpointfly.ToString(),
SoundType.audio_fishing_dash.ToString(),
SoundType.audio_fishing_fail_forcetoobig.ToString(),
SoundType.audio_fishing_fail_forcetoosmall.ToString(),
"audio_fishing_piercing01","audio_fishing_piercing02","audio_fishing_piercing03",
};
Dictionary<string, AudioClip> residentClip;
Sound BGM_Sound;
AudioClip BGM_Clip;
RodSkinData rodData;
OnSoundStateEvent onSoundState = new OnSoundStateEvent(0);
string BGMName;
protected CompositeDisposable disposables;
public async Task Init(System.Action<float> progress)
{
//playerData = GContext.container.Resolve<PlayerData>();
_tables = GContext.container.Resolve<cfg.Tables>();
//var service = (SoundService)soundService;
await soundService.InitAsync();
var opMap = new Dictionary<string, AsyncOperationHandle<AudioClip>>();
foreach (var addr in residentFish)
{
opMap[addr] = Addressables.LoadAssetAsync<AudioClip>(addr);
}
var tasks = opMap.Values.Select(_ => _.Task);
var total = (float)tasks.Count();
while (true)
{
var completed = tasks.Count(_ => _.IsCompleted);
if (completed == total)
{
progress.Invoke(1f);
break;
}
else
{
progress.Invoke(completed / total);
}
await Awaiters.NextFrame;
}
residentClip = opMap.ToDictionary(_ => _.Key, _ => _.Value.Result);
disposables = new CompositeDisposable();
GContext.OnEvent<EventUISound>().Subscribe(PlaySound).AddTo(disposables);
GContext.OnEvent<EventFishingSound>().Subscribe(PlayFishingSound).AddTo(disposables);
GContext.OnEvent<EventBGMSound>().Subscribe(PlayMusic).AddTo(disposables);
GContext.OnEvent<FadeOutEvent>().Subscribe(FadeOutEvent).AddTo(disposables);
GContext.OnEvent<AssetReferenceAudioClip>().Subscribe(PlaySoundByReference).AddTo(disposables);
GContext.OnEvent<AssetReferenceAudioVoiceClip>().Subscribe(PlayVoiceSoundByReference).AddTo(disposables);
GContext.OnEvent<ChangeRodDataEvent>().Subscribe(OnChangeRodData).AddTo(disposables);
GContext.OnEvent<SoundMuteEvent>().Subscribe(OnSoundMute).AddTo(disposables);
GContext.OnEvent<OnSoundStateEvent>().Subscribe(OnSoundStateEvent).AddTo(disposables);
soundService.BGMVol = GContext.container.Resolve<ISettingService>().Music ? 80 : 0;
soundService.SFXVol = GContext.container.Resolve<ISettingService>().Sound ? 80 : 0;
soundService.VoiceVol = GContext.container.Resolve<ISettingService>().Sound ? 80 : 0;
}
void OnSoundStateEvent(OnSoundStateEvent onSoundStateEvent)
{
onSoundState = onSoundStateEvent;
SetSoundVolume(onSoundStateEvent.type);
}
void OnSoundMute(SoundMuteEvent soundMuteEvent)
{
if (soundMuteEvent.muteType == 0)
{
soundService.BGMVol = GContext.container.Resolve<ISettingService>().Music ? 80 : 0;
}
else
{
soundService.VoiceVol = GContext.container.Resolve<ISettingService>().Sound ? 80 : 0;
soundService.SFXVol = GContext.container.Resolve<ISettingService>().Sound ? 80 : 0;
}
}
public async void OnChangeRodData(ChangeRodDataEvent changeRodDataEvent)
{
AudioClip audioClip;
if (rodData != null)
{
if (residentClip.TryGetValue(rodData.ThrowingAudio, out audioClip))
{
Addressables.Release(audioClip);
residentClip.Remove(rodData.ThrowingAudio);
}
if (residentClip.TryGetValue(rodData.ReelingAudio, out audioClip))
{
Addressables.Release(audioClip);
residentClip.Remove(rodData.ReelingAudio);
}
if (residentClip.TryGetValue(rodData.LineAudio, out audioClip))
{
Addressables.Release(audioClip);
residentClip.Remove(rodData.LineAudio);
}
if (residentClip.TryGetValue(rodData.ComboOutAudio, out audioClip))
{
Addressables.Release(audioClip);
residentClip.Remove(rodData.ComboOutAudio);
}
if (residentClip.TryGetValue(rodData.ComboLoopAudio, out audioClip))
{
Addressables.Release(audioClip);
residentClip.Remove(rodData.ComboLoopAudio);
}
if (residentClip.TryGetValue(rodData.ComboIntoAudio, out audioClip))
{
Addressables.Release(audioClip);
residentClip.Remove(rodData.ComboIntoAudio);
}
}
int skindID = GContext.container.Resolve<PlayerFishData>().GetRodSkin(changeRodDataEvent.RodId);
rodData = _tables.TbRodSkinData.GetOrDefault(skindID);
audioClip = await Addressables.LoadAssetAsync<AudioClip>(rodData.ThrowingAudio).Task;
residentClip.Add(rodData.ThrowingAudio, audioClip);
audioClip = await Addressables.LoadAssetAsync<AudioClip>(rodData.ReelingAudio).Task;
residentClip.Add(rodData.ReelingAudio, audioClip);
audioClip = await Addressables.LoadAssetAsync<AudioClip>(rodData.LineAudio).Task;
residentClip.Add(rodData.LineAudio, audioClip);
audioClip = await Addressables.LoadAssetAsync<AudioClip>(rodData.ComboOutAudio).Task;
residentClip.Add(rodData.ComboOutAudio, audioClip);
audioClip = await Addressables.LoadAssetAsync<AudioClip>(rodData.ComboLoopAudio).Task;
residentClip.Add(rodData.ComboLoopAudio, audioClip);
audioClip = await Addressables.LoadAssetAsync<AudioClip>(rodData.ComboIntoAudio).Task;
residentClip.Add(rodData.ComboIntoAudio, audioClip);
}
public async void PlaySoundByReference(AssetReferenceAudioClip eventSound)
{
string audioName = eventSound.assetReference.AssetGUID;
if (!residentClip.TryGetValue(audioName, out var audioClip) || audioClip == null)
{
if (audioClip == null)
{
residentClip.Remove(audioName);
}
var audioClipL = await Addressables.LoadAssetAsync<AudioClip>(eventSound.assetReference).Task;//.LoadAssetAsync<AudioClip>().Task;
if (disposables == null)
{
return;
}
if (residentClip.TryGetValue(audioName, out audioClip))
{
Addressables.Release(audioClipL);
}
else
{
residentClip.Add(audioName, audioClipL);
audioClip = audioClipL;
}
}
if (audioClip == null)
{
soundService.ReturnSound(eventSound.Sound);
eventSound.Sound = null;
return;
}
SoundMainType soundMainType = eventSound.mainType;
Sound sound;
switch (soundMainType)
{
case SoundMainType.BGM:
await PlayBGM(audioClip, eventSound.time);
residentClip.Remove(audioName);
if (disposables == null)
{
return;
}
return;
case SoundMainType.Fishing:
sound = soundService.GetNewFishingSound(audioClip, time: eventSound.time);
sound.soundMainType = SoundMainType.Fishing;
break;
case SoundMainType.Voice:
SetSoundVolume(2);
sound = soundService.GetNewVoiceSound(audioClip);
sound.soundMainType = SoundMainType.Voice;
break;
case SoundMainType.UILoop:
sound = soundService.GetNewUISound(audioClip, loop: true, time: eventSound.time);
sound.soundMainType = SoundMainType.UI;
break;
case SoundMainType.UI:
default:
sound = soundService.GetNewUISound(audioClip, time: eventSound.time);
sound.soundMainType = SoundMainType.UI;
break;
}
if (sound != null)
{
sound.audioSource.Play();
eventSound.Sound = sound;
await Awaiters.Seconds(audioClip.length);
if (eventSound.Sound.soundMainType == SoundMainType.Voice)
{
SetSoundVolume(onSoundState.type);
}
if (soundMainType == eventSound.Sound.soundMainType && !eventSound.isOutDisable)
{
soundService.ReturnSound(sound);
eventSound.Sound = null;
}
}
}
async void PlayVoiceSoundByReference(AssetReferenceAudioVoiceClip eventSound)
{
var audioClip = await Addressables.LoadAssetAsync<AudioClip>(eventSound.assetReference).Task; // eventSound.assetReference.LoadAssetAsync<AudioClip>().Task;
if (audioClip == null)
{
eventSound.Sound = null;
return;
}
SetSoundVolume(2);
var sound = soundService.GetNewVoiceSound(audioClip);
sound.soundMainType = SoundMainType.Voice;
sound.audioSource.Play();
eventSound.Sound = sound;
await Awaiters.Seconds(audioClip.length);
if (eventSound.Sound.soundMainType == SoundMainType.Voice)
{
SetSoundVolume(onSoundState.type);
soundService.ReturnSound(sound);
}
Addressables.Release(audioClip);
eventSound.Sound = null;
}
/// <summary>
/// 0默认 type==1 钓鱼 type==2 人声
/// </summary>
/// <param name="type"></param>
void SetSoundVolume(int type)
{
if (GContext.container.Resolve<ISettingService>().Music)
{
soundService.BGMVol = type == 0 ? 80 : 72;
}
if (GContext.container.Resolve<ISettingService>().Sound)
{
soundService.SFXVol = type == 2 ? 70 : 80;
}
}
public async void PlaySound(EventUISound eventSound)
{
string audioName = GetAudioName(eventSound);
if (!residentClip.TryGetValue(audioName, out var audioClip))
{
var audioClipL = await Addressables.LoadAssetAsync<AudioClip>(audioName).Task;
if (residentClip.TryGetValue(audioName, out audioClip))
{
Addressables.Release(audioClipL);
}
else
{
residentClip.Add(audioName, audioClipL);
audioClip = audioClipL;
}
}
if (audioClip == null)
{
eventSound.Sound = null;
return;
}
var sound = soundService.GetNewUISound(audioClip, time: eventSound.time);
sound.soundMainType = SoundMainType.UI;
sound.audioSource.Play();
eventSound.Sound = sound;
await Awaiters.Seconds(audioClip.length);
if (SoundMainType.UI == eventSound.Sound.soundMainType)
{
soundService.ReturnSound(sound);
}
eventSound.Sound = null;
}
public async void PlayFishingSound(EventFishingSound eventSound)
{
string audioName = GetAudioName(eventSound);
if (!residentClip.TryGetValue(audioName, out var audioClip))
{
var audioClipL = await Addressables.LoadAssetAsync<AudioClip>(audioName).Task;
if (residentClip.TryGetValue(audioName, out audioClip))
{
Addressables.Release(audioClipL);
}
else
{
residentClip.Add(audioName, audioClipL);
audioClip = audioClipL;
}
}
if (audioClip == null)
{
eventSound.Sound = null;
return;
}
bool isLoop = eventSound.loop;
//if (eventSound.audioType == SoundType.LineAudioReeling || eventSound.audioType == SoundType.ReelingAudioReeling)
//{
// isLoop = true;
//}
var sound = soundService.GetNewFishingSound(audioClip, loop: isLoop, time: eventSound.time);
sound.soundMainType = SoundMainType.Fishing;
sound.audioSource.Play();
eventSound.Sound = sound;
if (!isLoop)
{
await Awaiters.Seconds(audioClip.length);
if (eventSound.Sound != null && SoundMainType.Fishing == eventSound.Sound.soundMainType)
{
soundService.ReturnSound(sound);
}
eventSound.Sound = null;
}
}
public async void PlayMusic(EventBGMSound eventSound)
{
string audioName = GetAudioName(eventSound);
if (BGMName == audioName)
{
return;
}
var audioClip = await Addressables.LoadAssetAsync<AudioClip>(audioName).Task;
if (BGMName == audioName)
{
Addressables.Release(audioClip);
return;
}
await PlayBGM(audioClip, eventSound.time);
}
async Task PlayBGM(AudioClip audioClip, float time = 0)
{
if (audioClip == null)
{
return;
}
BGMName = audioClip.name;
if (BGM_Clip != null)
{
AudioClip audioClip1 = BGM_Clip;
BGM_Clip = null;
Sound bgm_Sound = BGM_Sound;
BGM_Sound = null;
soundService.FadeOut(bgm_Sound, 0.5f);
await Task.Delay(500);
Addressables.Release(audioClip1);
soundService.ReturnSound(bgm_Sound);
}
if (BGMName != audioClip.name)
{
return;
}
BGM_Sound = soundService.GetNewBgmSound(audioClip, time: time);
BGM_Sound.soundMainType = SoundMainType.BGM;
BGM_Clip = audioClip;
BGM_Sound.audioSource.Play();
soundService.FadeIn(BGM_Sound, 0.5f);
}
public void SetBGM(AudioClip audioClip)
{
if (audioClip == BGM_Clip)
return;
if (BGM_Sound == null)
{
BGM_Sound = soundService.GetNewBgmSound(audioClip);
}
BGM_Sound.audioSource.clip = audioClip;
BGM_Sound.soundMainType = SoundMainType.BGM;
BGM_Clip = audioClip;
BGM_Sound.audioSource.Play();
}
void FadeOutEvent(FadeOutEvent fadeOutEvent)
{
_ = FadeOutAsync(fadeOutEvent.sound, fadeOutEvent.timer);
fadeOutEvent.sound = null;
}
async Task FadeOutAsync(Sound sound, float timer = 0.5f)
{
if (sound == null)
{
return;
}
if (sound.soundMainType == SoundMainType.Voice)
{
SetSoundVolume(onSoundState.type);
}
if (sound.soundMainType == SoundMainType.BGM)
{
return;
}
soundService.FadeOut(sound, timer);
await Task.Delay((int)(timer * 1000));
if (sound.soundMainType != SoundMainType.None)
{
soundService.ReturnSound(sound);
}
}
string GetAudioName(IEventData eventData)
{
PlayerData playerData = GContext.container.Resolve<PlayerData>();
PlayerFishData playerFishData = GContext.container.Resolve<PlayerFishData>();
int skindID = playerFishData.GetRodSkin(playerData.equipRodID);
RodSkinData rodSkinData = _tables.TbRodSkinData.GetOrDefault(skindID);
switch (eventData.audioType)
{
case SoundType.ThrowingAudio:
return rodSkinData.ThrowingAudio;
case SoundType.ReelingAudio:
case SoundType.ReelingAudioReeling:
return rodSkinData.ReelingAudio;
case SoundType.LineAudioReeling:
return rodSkinData.LineAudio;
case SoundType.ComboOutAudio:
return rodSkinData.ComboOutAudio;
case SoundType.ComboLoopAudio:
return rodSkinData.ComboLoopAudio;
case SoundType.ComboIntoAudio:
return rodSkinData.ComboIntoAudio;
case SoundType.HPEvent:
return "audio_fishing_drawing_hpevent_0" + Random.Range(1, 6);
case SoundType.audio_fishing_piercing:
return "audio_fishing_piercing0" + Random.Range(1, 4);
case SoundType.audio_fishing_jumpout:
return "audio_fishing_jumpout_0" + Random.Range(1, 4);
case SoundType.audio_fishing_jumpinto:
return "audio_fishing_jumpinto_0" + Random.Range(1, 4);
case SoundType.BGM:
case SoundType.Fishing:
case SoundType.UI:
default:
return eventData.audioNameStr;
}
}
public void Release()
{
disposables?.Dispose();
disposables = null;
residentClip.Clear();
soundService.Release();
foreach (var item in residentClip)
{
Addressables.Release(item.Value);
}
Addressables.Release(BGM_Clip);
GameObject.Destroy(BGM_Sound.gameObject);
BGM_Sound = null;
BGM_Clip = null;
BGMName = null;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 909412df6a7eddf4c8882ebbe72fdcd6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,537 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using Object = UnityEngine.Object;
/// <summary>
/// Allows you to run events on a delay without the use of <see cref="Coroutine"/>s
/// or <see cref="MonoBehaviour"/>s.
///
/// To create and start a Timer, use the <see cref="Register"/> method.
/// </summary>
namespace GameCore
{
public class Timer
{
#region Public Properties/Fields
/// <summary>
/// How long the timer takes to complete from start to finish.
/// </summary>
public float duration { get; private set; }
/// <summary>
/// Whether the timer will run again after completion.
/// </summary>
public bool isLooped { get; set; }
/// <summary>
/// Whether or not the timer completed running. This is false if the timer was canceled.
/// </summary>
public bool isCompleted { get; private set; }
/// <summary>
/// Whether the timer uses real-time or game-time. Real time is unaffected by changes to the timescale
/// of the game(e.g. pausing, slow-mo), while game time is affected.
/// </summary>
public bool usesRealTime { get; private set; }
/// <summary>
/// Whether the timer is currently paused.
/// </summary>
public bool isPaused
{
get { return _timeElapsedBeforePause.HasValue; }
}
/// <summary>
/// Whether or not the timer was canceled.
/// </summary>
public bool isCancelled
{
get { return _timeElapsedBeforeCancel.HasValue; }
}
/// <summary>
/// Get whether or not the timer has finished running for any reason.
/// </summary>
public bool isDone
{
get { return isCompleted || isCancelled || isOwnerDestroyed; }
}
#endregion
#region Public Static Methods
public static void Create()
{
// create a manager object to update all the timers if one does not already exist.
if (_manager != null)
{
Debug.LogError("[UnityTimer]Create: TimerManager already exist, ignore this call!");
return;
}
Debug.Log($"[UnityTimer]Create");
var managerObject = new GameObject { name = nameof(TimerMgr) };
Object.DontDestroyOnLoad(managerObject);
_manager = managerObject.AddComponent<TimerMgr>();
}
public static void Destroy()
{
Debug.Log($"[UnityTimer]Destroy");
if (_manager != null)
{
GameObject.Destroy(_manager.gameObject);
_manager = null;
}
}
/// <summary>
/// Register a new timer that should fire an event after a certain amount of time
/// has elapsed.
///
/// Registered timers are destroyed when the scene changes.
/// </summary>
/// <param name="duration">The time to wait before the timer should fire, in seconds.</param>
/// <param name="onComplete">An action to fire when the timer completes.</param>
/// <param name="onUpdate">An action that should fire each time the timer is updated. Takes the amount
/// of time passed in seconds since the start of the timer's current loop.</param>
/// <param name="isLooped">Whether the timer should repeat after executing.</param>
/// <param name="useRealTime">Whether the timer uses real-time(i.e. not affected by pauses,
/// slow/fast motion) or game-time(will be affected by pauses and slow/fast-motion).</param>
/// <param name="autoDestroyOwner">An object to attach this timer to. After the object is destroyed,
/// the timer will expire and not execute. This allows you to avoid annoying <see cref="NullReferenceException"/>s
/// by preventing the timer from running and accessing its parents' components
/// after the parent has been destroyed.</param>
/// <returns>A timer object that allows you to examine stats and stop/resume progress.</returns>
public static Timer Register(float duration, Action onComplete, Action<float> onUpdate = null,
bool isLooped = false, bool useRealTime = false, MonoBehaviour autoDestroyOwner = null)
{
if (_manager == null)
{
Debug.LogError("[UnityTimer]Register: TimerManager doesn't exist yet!");
return null;
}
Timer timer = new Timer(duration, onComplete, onUpdate, isLooped, useRealTime, autoDestroyOwner);
_manager.RegisterTimer(timer);
return timer;
}
/// <summary>
/// Cancels a timer. The main benefit of this over the method on the instance is that you will not get
/// a <see cref="NullReferenceException"/> if the timer is null.
/// </summary>
/// <param name="timer">The timer to cancel.</param>
public static void Cancel(Timer timer)
{
timer?.Cancel();
}
/// <summary>
/// Pause a timer. The main benefit of this over the method on the instance is that you will not get
/// a <see cref="NullReferenceException"/> if the timer is null.
/// </summary>
/// <param name="timer">The timer to pause.</param>
public static void Pause(Timer timer)
{
timer?.Pause();
}
/// <summary>
/// Resume a timer. The main benefit of this over the method on the instance is that you will not get
/// a <see cref="NullReferenceException"/> if the timer is null.
/// </summary>
/// <param name="timer">The timer to resume.</param>
public static void Resume(Timer timer)
{
timer?.Resume();
}
public static void CancelAllRegisteredTimers()
{
if (_manager != null)
{
_manager.CancelAllTimers();
}
// if the manager doesn't exist, we don't have any registered timers yet, so don't
// need to do anything in this case
}
public static void PauseAllRegisteredTimers()
{
if (_manager != null)
{
_manager.PauseAllTimers();
}
// if the manager doesn't exist, we don't have any registered timers yet, so don't
// need to do anything in this case
}
public static void ResumeAllRegisteredTimers()
{
if (_manager != null)
{
_manager.ResumeAllTimers();
}
// if the manager doesn't exist, we don't have any registered timers yet, so don't
// need to do anything in this case
}
#endregion
#region Public Methods
/// <summary>
/// Stop a timer that is in-progress or paused. The timer's on completion callback will not be called.
/// </summary>
public void Cancel()
{
if (isDone)
{
return;
}
_timeElapsedBeforeCancel = GetTimeElapsed();
_timeElapsedBeforePause = null;
}
/// <summary>
/// Pause a running timer. A paused timer can be resumed from the same point it was paused.
/// </summary>
public void Pause()
{
if (isPaused || isDone)
{
return;
}
_timeElapsedBeforePause = GetTimeElapsed();
}
/// <summary>
/// Continue a paused timer. Does nothing if the timer has not been paused.
/// </summary>
public void Resume()
{
if (!isPaused || isDone)
{
return;
}
_timeElapsedBeforePause = null;
}
/// <summary>
/// Get how many seconds have elapsed since the start of this timer's current cycle.
/// </summary>
/// <returns>The number of seconds that have elapsed since the start of this timer's current cycle, i.e.
/// the current loop if the timer is looped, or the start if it isn't.
///
/// If the timer has finished running, this is equal to the duration.
///
/// If the timer was cancelled/paused, this is equal to the number of seconds that passed between the timer
/// starting and when it was cancelled/paused.</returns>
public float GetTimeElapsed()
{
if (isCompleted || GetWorldTime() >= GetFireTime())
{
return duration;
}
return _timeElapsedBeforeCancel ??
_timeElapsedBeforePause ??
GetWorldTime() - _startTime;
}
/// <summary>
/// Get how many seconds remain before the timer completes.
/// </summary>
/// <returns>The number of seconds that remain to be elapsed until the timer is completed. A timer
/// is only elapsing time if it is not paused, cancelled, or completed. This will be equal to zero
/// if the timer completed.</returns>
public float GetTimeRemaining()
{
return duration - GetTimeElapsed();
}
/// <summary>
/// Get how much progress the timer has made from start to finish as a ratio.
/// </summary>
/// <returns>A value from 0 to 1 indicating how much of the timer's duration has been elapsed.</returns>
public float GetRatioComplete()
{
return GetTimeElapsed() / duration;
}
/// <summary>
/// Get how much progress the timer has left to make as a ratio.
/// </summary>
/// <returns>A value from 0 to 1 indicating how much of the timer's duration remains to be elapsed.</returns>
public float GetRatioRemaining()
{
return GetTimeRemaining() / duration;
}
#endregion
#region Private Static Properties/Fields
// responsible for updating all registered timers
private static TimerMgr _manager;
#endregion
#region Private Properties/Fields
private bool isOwnerDestroyed
{
get { return _hasAutoDestroyOwner && _autoDestroyOwner == null; }
}
private readonly Action _onComplete;
private readonly Action<float> _onUpdate;
private float _startTime;
private float _lastUpdateTime;
// for pausing, we push the start time forward by the amount of time that has passed.
// this will mess with the amount of time that elapsed when we're cancelled or paused if we just
// check the start time versus the current world time, so we need to cache the time that was elapsed
// before we paused/cancelled
private float? _timeElapsedBeforeCancel;
private float? _timeElapsedBeforePause;
// after the auto destroy owner is destroyed, the timer will expire
// this way you don't run into any annoying bugs with timers running and accessing objects
// after they have been destroyed
private readonly MonoBehaviour _autoDestroyOwner;
private readonly bool _hasAutoDestroyOwner;
#endregion
#region Private Constructor (use static Register method to create new timer)
private Timer(float duration, Action onComplete, Action<float> onUpdate,
bool isLooped, bool usesRealTime, MonoBehaviour autoDestroyOwner)
{
this.duration = duration;
_onComplete = onComplete;
_onUpdate = onUpdate;
this.isLooped = isLooped;
this.usesRealTime = usesRealTime;
_autoDestroyOwner = autoDestroyOwner;
_hasAutoDestroyOwner = autoDestroyOwner != null;
_startTime = GetWorldTime();
_lastUpdateTime = _startTime;
}
#endregion
#region Private Methods
private float GetWorldTime()
{
return usesRealTime ? Time.realtimeSinceStartup : Time.time;
}
private float GetFireTime()
{
return _startTime + duration;
}
private float GetTimeDelta()
{
return GetWorldTime() - _lastUpdateTime;
}
private void Update()
{
if (isDone)
{
return;
}
if (isPaused)
{
_startTime += GetTimeDelta();
_lastUpdateTime = GetWorldTime();
return;
}
_lastUpdateTime = GetWorldTime();
try
{
_onUpdate?.Invoke(GetTimeElapsed());
}
catch (Exception ex)
{
Debug.LogError($"[Timer]Update: onUpdate error! {ex.Message}");
}
if (GetWorldTime() >= GetFireTime())
{
try
{
_onComplete?.Invoke();
}
catch (Exception ex)
{
Debug.LogError($"[Timer]Update: onComplete error! {ex.Message}");
}
if (isLooped)
{
_startTime = GetWorldTime();
}
else
{
isCompleted = true;
}
}
}
#endregion
#region Manager Class (implementation detail, spawned automatically and updates all registered timers)
/// <summary>
/// Manages updating all the <see cref="Timer"/>s that are running in the application.
/// This will be instantiated the first time you create a timer -- you do not need to add it into the
/// scene manually.
/// </summary>
private class TimerMgr : MonoBehaviour
{
public int TimerCount { get; private set; }
private ulong _timerID;
private Dictionary<ulong, Timer> _timers = new Dictionary<ulong, Timer>();
// buffer adding timers so we don't edit a collection during iteration
private List<Timer> _timersToAdd = new List<Timer>();
// buffer removing timers
private List<ulong> _timersToRemove = new List<ulong>();
public void RegisterTimer(Timer timer)
{
_timersToAdd.Add(timer);
Debug.Log($"[TimerMgr]RegisterTimer: {TimerCount + _timersToAdd.Count} timers in total");
}
public void CancelAllTimers()
{
Debug.Log($"[TimerMgr]CancelAllTimers");
var etor = _timers.GetEnumerator();
while (etor.MoveNext())
{
var timer = etor.Current.Value;
timer.Cancel();
}
_timers.Clear();
_timersToAdd.Clear();
TimerCount = 0;
}
public void PauseAllTimers()
{
Debug.Log($"[TimerMgr]PauseAllTimers");
var etor = _timers.GetEnumerator();
while (etor.MoveNext())
{
var timer = etor.Current.Value;
timer.Pause();
}
}
public void ResumeAllTimers()
{
Debug.Log($"[TimerMgr]ResumeAllTimers");
var etor = _timers.GetEnumerator();
while (etor.MoveNext())
{
var timer = etor.Current.Value;
timer.Resume();
}
}
// update all the registered timers on every frame
private void Update()
{
if (_timersToAdd.Count > 0)
{
for (int i = 0; i < _timersToAdd.Count; i++)
{
_timers.Add(_timerID++, _timersToAdd[i]);
}
_timersToAdd.Clear();
}
_timersToRemove.Clear();
var etor = _timers.GetEnumerator();
while (etor.MoveNext())
{
var timer = etor.Current.Value;
timer.Update();
if (timer.isDone)
{
_timersToRemove.Add(etor.Current.Key);
}
}
if (_timersToRemove.Count > 0)
{
for (int i = 0; i < _timersToRemove.Count; i++)
{
_timers.Remove(_timersToRemove[i]);
}
}
TimerCount = _timers.Count;
}
}
#endregion
}
public static class TimerExtensions
{
/// <summary>
/// Attach a timer on to the behaviour. If the behaviour is destroyed before the timer is completed,
/// e.g. through a scene change, the timer callback will not execute.
/// </summary>
/// <param name="behaviour">The behaviour to attach this timer to.</param>
/// <param name="duration">The duration to wait before the timer fires.</param>
/// <param name="onComplete">The action to run when the timer elapses.</param>
/// <param name="onUpdate">A function to call each tick of the timer. Takes the number of seconds elapsed since
/// the start of the current cycle.</param>
/// <param name="isLooped">Whether the timer should restart after executing.</param>
/// <param name="useRealTime">Whether the timer uses real-time(not affected by slow-mo or pausing) or
/// game-time(affected by time scale changes).</param>
public static Timer AttachTimer(this MonoBehaviour behaviour, float duration, Action onComplete,
Action<float> onUpdate = null, bool isLooped = false, bool useRealTime = false)
{
return Timer.Register(duration, onComplete, onUpdate, isLooped, useRealTime, behaviour);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 96b0c5856df7d62488eef989a3453c60
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,251 @@
using UnityEngine;
using asap.core;
using game;
using UniRx;
using System;
using MoreMountains.NiceVibrations;
using System.Collections.Generic;
public class VibrationData
{
public VibrationData(HapticTypes hapticTypes)
{
this.hapticTypes = hapticTypes;
}
public HapticTypes hapticTypes { get; set; }
public VibrationData(int id)
{
this.id = id;
}
public int id { get; set; }
}
public class VibrationController
{
IDisposable disposable;
public void Init()
{
disposable = GContext.OnEvent<VibrationData>().Subscribe(OnVibrationData);
Debug.Log("[VibrationController] Init iOSInitializeHaptics");
MMVibrationManager.iOSInitializeHaptics();
}
void OnVibrationData(VibrationData data)
{
bool isVibrate = GContext.container.Resolve<ISettingService>().Vibration;
if (isVibrate)
{
if (data.id > 0)
{
PlayVibrationList(data.id);
return;
}
switch (data.hapticTypes)
{
case HapticTypes.Selection:
case HapticTypes.Success:
case HapticTypes.Warning:
case HapticTypes.Failure:
case HapticTypes.LightImpact:
case HapticTypes.MediumImpact:
case HapticTypes.HeavyImpact:
case HapticTypes.SoftImpact:
case HapticTypes.RigidImpact:
MMVibrationManager.Haptic(data.hapticTypes);
break;
case HapticTypes.Vibrate:
MMVibrationManager.Vibrate();
break;
default:
#if UNITY_IOS || UNITY_ANDROID
Handheld.Vibrate();
#endif
break;
}
}
}
~VibrationController()
{
disposable.Dispose();
disposable = null;
MMVibrationManager.iOSReleaseHaptics();
}
/// <summary>
/// Triggers the default Unity vibration, without any control over duration, pattern or amplitude
/// </summary>
public void TriggerDefault()
{
if (IsVibrate)
{
#if UNITY_IOS || UNITY_ANDROID
Handheld.Vibrate();
#endif
}
}
/// <summary>
/// Triggers the default Vibrate method, which will result in a medium vibration on Android and a medium impact on iOS
/// </summary>
public void TriggerVibrate()
{
if (IsVibrate)
{
MMVibrationManager.Vibrate();
}
}
/// <summary>
/// Triggers the selection haptic feedback, a light vibration on Android, and a light impact on iOS
/// </summary>
public void TriggerSelection()
{
if (IsVibrate)
{
MMVibrationManager.Haptic(HapticTypes.Selection);
}
}
/// <summary>
/// Triggers the success haptic feedback, a light then heavy vibration on Android, and a success impact on iOS
/// </summary>
public void TriggerSuccess()
{
if (IsVibrate)
{
MMVibrationManager.Haptic(HapticTypes.Success);
}
}
/// <summary>
/// Triggers the warning haptic feedback, a heavy then medium vibration on Android, and a warning impact on iOS
/// </summary>
public void TriggerWarning()
{
if (IsVibrate)
{
MMVibrationManager.Haptic(HapticTypes.Warning);
}
}
/// <summary>
/// Triggers the failure haptic feedback, a medium / heavy / heavy / light vibration pattern on Android, and a failure impact on iOS
/// </summary>
public void TriggerFailure()
{
if (IsVibrate)
{
MMVibrationManager.Haptic(HapticTypes.Failure);
}
}
/// <summary>
/// Triggers a light impact on iOS and a short and light vibration on Android.
/// </summary>
public void TriggerLightImpact()
{
if (IsVibrate)
{
MMVibrationManager.Haptic(HapticTypes.LightImpact);
}
}
/// <summary>
/// Triggers a medium impact on iOS and a medium and regular vibration on Android.
/// </summary>
public void TriggerMediumImpact()
{
if (IsVibrate)
{
MMVibrationManager.Haptic(HapticTypes.MediumImpact);
}
}
/// <summary>
/// Triggers a heavy impact on iOS and a long and heavy vibration on Android.
/// </summary>
public void TriggerHeavyImpact()
{
if (IsVibrate)
{
MMVibrationManager.Haptic(HapticTypes.HeavyImpact);
}
}
public void TriggerSoftImpact()
{
if (IsVibrate)
{
MMVibrationManager.Haptic(HapticTypes.SoftImpact);
}
}
public void TriggerRigidImpact()
{
if (IsVibrate)
{
MMVibrationManager.Haptic(HapticTypes.RigidImpact);
}
}
bool IsVibrate
{
get
{
ISettingService settingService = GContext.container.Resolve<ISettingService>();
return settingService.Vibration;
}
}
async void PlayVibrationList(int id)
{
if (IsVibrate)
{
cfg.Tables tables = GContext.container.Resolve<cfg.Tables>();
if (tables != null)
{
cfg.VibrationDef vibrationDef = tables.TbVibrationDef.GetOrDefault(id);
if (vibrationDef != null)
{
List<string> VibrationList = vibrationDef.VibrationList;
List<float> DelayList = vibrationDef.DelayList;
for (int i = 0; i < VibrationList.Count; i++)
{
await Awaiters.Seconds(DelayList[i]);
OnVibrationData(VibrationList[i]);
}
}
}
}
}
void OnVibrationData(string hapticTypes)
{
bool success = Enum.TryParse(hapticTypes, out HapticTypes value);
if (success)
{
switch (value)
{
case HapticTypes.Selection:
case HapticTypes.Success:
case HapticTypes.Warning:
case HapticTypes.Failure:
case HapticTypes.LightImpact:
case HapticTypes.MediumImpact:
case HapticTypes.HeavyImpact:
case HapticTypes.SoftImpact:
case HapticTypes.RigidImpact:
MMVibrationManager.Haptic(value);
break;
case HapticTypes.Vibrate:
MMVibrationManager.Vibrate();
break;
default:
#if UNITY_IOS || UNITY_ANDROID
Handheld.Vibrate();
#endif
break;
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 73f660bbef6338449b1155c9e17131fd
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: -250
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: