Compare commits

...

11 Commits

Author SHA1 Message Date
김판돌 1f24f3ad99 필오없는 스크립트 삭제 및 클로즈 베타전 마지막 업데이트 2025-03-09 22:20:43 +09:00
김판돌 1269673cf7 이미지 업로드 1차 작업 2025-03-05 11:29:13 +09:00
김판돌 e016254acb 검색 페이지 ui작업 완료 2025-02-27 21:19:25 +09:00
김판돌 fedc3551e3 검색창 ui작업 2025-02-23 20:42:25 +09:00
김판돌 97183a184a 등록 페이지 1차 완료 2025-02-19 00:08:24 +09:00
김판돌 2e215f080e 임시 커밋 2025-02-18 21:33:49 +09:00
김판돌 6771b0aa81 api 주소 변경 2025-02-17 16:24:50 +09:00
김판돌 740bb595ab 버그 수정 및 로딩 추가 2025-02-12 08:10:53 +09:00
김판돌 8107321f04 UI 버그 전부 수정완료 2025-02-08 17:38:03 +09:00
김판돌 31b5804fd8 잘못된 스크롤 받아오는 문제 해결
이미지 문제 해결해야함
2025-02-08 16:24:24 +09:00
김판돌 a8cdc427f1 Unitask 적용
데이터를 받아오지 못하는 버그와 종종 itemPrefabs_OnCreate에서 null버그 발생
2025-02-08 16:16:18 +09:00
492 changed files with 390558 additions and 7487 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,20 +1,23 @@
using BestHTTP;
using System.Collections.Generic; using System.Collections.Generic;
using TMPro; using TMPro;
using UnityEngine; using UnityEngine;
using UnityEngine.UI;
public class Common : MonoBehaviour public class Common : MonoBehaviour
{ {
[SerializeField] TMP_Dropdown dAnimal; [SerializeField] TMP_Dropdown sAnimal;
[SerializeField] TMP_Dropdown dSuitStyle; [SerializeField] TMP_Dropdown sSuitStyle;
[SerializeField] TMP_Dropdown dSuitType; [SerializeField] TMP_Dropdown sSuitType;
[SerializeField] TMP_Dropdown dRegion; [SerializeField] TMP_Dropdown sRegion;
// TODO 내부 저장 기능 만들기
// TODO 버전 기능 까지 만들어서 버전 체크후 새로 다운받아오게 만들기. [SerializeField] TMP_Dropdown fAnimal;
[SerializeField] TMP_Dropdown fSuitStyle;
[SerializeField] TMP_Dropdown fSuitType;
[SerializeField] TMP_Dropdown fRegion;
void Start() void Start()
{ {
NetworkManager.Instance.CreateRequest<List<CommonData>>("common/animalTypes", new object(), (data) => HTTPRequest httpAnimal = NetworkManager.Instance.CreateRequest<List<CommonData>>("common/animalTypes", new object(), (data) =>
{ {
GameManager.Instance.animalTypes = data; GameManager.Instance.animalTypes = data;
List<string> strings = new List<string>(); List<string> strings = new List<string>();
@ -22,9 +25,11 @@ public class Common : MonoBehaviour
{ {
strings.Add(data[n].code_nm); strings.Add(data[n].code_nm);
} }
dAnimal.AddOptions(strings); sAnimal.AddOptions(strings);
}, null, BestHTTP.HTTPMethods.Get); fAnimal.AddOptions(strings);
NetworkManager.Instance.CreateRequest<List<CommonData>>("common/suitStyle", new object(), (data) =>
}, null, HTTPMethods.Get);
HTTPRequest httpSuitStyle = NetworkManager.Instance.CreateRequest<List<CommonData>>("common/suitStyle", new object(), (data) =>
{ {
GameManager.Instance.suitStyle = data; GameManager.Instance.suitStyle = data;
List<string> strings = new List<string>(); List<string> strings = new List<string>();
@ -32,9 +37,10 @@ public class Common : MonoBehaviour
{ {
strings.Add(data[n].code_nm); strings.Add(data[n].code_nm);
} }
dSuitStyle.AddOptions(strings); sSuitStyle.AddOptions(strings);
}, null, BestHTTP.HTTPMethods.Get); fSuitStyle.AddOptions(strings);
NetworkManager.Instance.CreateRequest<List<CommonData>>("common/suitType", new object(), (data) => }, null, HTTPMethods.Get);
HTTPRequest httpSuitType = NetworkManager.Instance.CreateRequest<List<CommonData>>("common/suitType", new object(), (data) =>
{ {
GameManager.Instance.suitType = data; GameManager.Instance.suitType = data;
List<string> strings = new List<string>(); List<string> strings = new List<string>();
@ -42,9 +48,10 @@ public class Common : MonoBehaviour
{ {
strings.Add(data[n].code_nm); strings.Add(data[n].code_nm);
} }
dSuitType.AddOptions(strings); sSuitType.AddOptions(strings);
}, null, BestHTTP.HTTPMethods.Get); fSuitType.AddOptions(strings);
NetworkManager.Instance.CreateRequest<List<CommonData>>("common/region", new object(), (data) => }, null, HTTPMethods.Get);
HTTPRequest httpRegion = NetworkManager.Instance.CreateRequest<List<CommonData>>("common/region", new object(), (data) =>
{ {
GameManager.Instance.region = data; GameManager.Instance.region = data;
List<string> strings = new List<string>(); List<string> strings = new List<string>();
@ -52,8 +59,13 @@ public class Common : MonoBehaviour
{ {
strings.Add(data[n].code_nm); strings.Add(data[n].code_nm);
} }
dRegion.AddOptions(strings); sRegion.AddOptions(strings);
}, null, BestHTTP.HTTPMethods.Get); fRegion.AddOptions(strings);
}, null, HTTPMethods.Get);
httpAnimal.Send();
httpSuitStyle.Send();
httpSuitType.Send();
httpRegion.Send();
} }
public class CommonData public class CommonData

View File

@ -1,8 +1,4 @@
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine; using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI; using UnityEngine.UI;
public class DropdownCtrl : MonoBehaviour public class DropdownCtrl : MonoBehaviour
@ -10,12 +6,22 @@ public class DropdownCtrl : MonoBehaviour
[SerializeField] Sprite on; [SerializeField] Sprite on;
[SerializeField] Sprite off; [SerializeField] Sprite off;
[SerializeField] Image image; [SerializeField] Image image;
[SerializeField] bool isPixels;
[SerializeField] float[] pixels;
private void OnEnable() private void OnEnable()
{ {
image.sprite = on; image.sprite = on;
if (isPixels)
{
image.pixelsPerUnitMultiplier = pixels[1];
}
} }
private void OnDestroy() private void OnDestroy()
{ {
image.sprite = off; image.sprite = off;
if (isPixels)
{
image.pixelsPerUnitMultiplier = pixels[0];
}
} }
} }

View File

@ -0,0 +1,216 @@
using BestHTTP;
using System;
using System.Collections.Generic;
using System.Globalization;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class FursuitAddCtrl : SingletonMonoBehaviour<FursuitAddCtrl>
{
[SerializeField] Image setImage;
[SerializeField] GameObject[] stepMenus;
[SerializeField] TMP_Text xid;
[SerializeField] TMP_InputField owner;
[SerializeField] TMP_InputField introeuce;
[SerializeField] TMP_InputField characterName;
[SerializeField] TMP_InputField makerName;
[SerializeField] TMP_Dropdown animalType;
[SerializeField] TMP_Dropdown suitType;
[SerializeField] TMP_Dropdown suitStyle;
[SerializeField] TMP_Dropdown region;
[SerializeField] TMP_InputField productionDate;
[SerializeField] Toggle[] colors;
[SerializeField] Sprite[] isOnSprite;
[SerializeField] TMP_Text sXid;
[SerializeField] TMP_Text sOwner;
[SerializeField] TMP_Text sCharacterName;
[SerializeField] TMP_Text sMmakerName;
[SerializeField] TMP_Text sAnimalType;
[SerializeField] TMP_Text sSuitType;
[SerializeField] TMP_Text sSuitStyle;
[SerializeField] TMP_Text sRegion;
[SerializeField] TMP_Text sProductionDate;
[SerializeField] GameObject[] sColors;
[SerializeField] GameObject infoUI;
[SerializeField] GameObject successUI;
[SerializeField] ScreenMove screenMove;
private byte[] image;
private void OnEnable()
{
WebGl.Instance.isOn = true;
image = null;
setImage.gameObject.SetActive(false);
UIReset();
xid.text = GameManager.Instance.xid;
sXid.text = GameManager.Instance.xid;
owner.text = GameManager.Instance.xname;
sOwner.text = GameManager.Instance.xname;
}
private void OnDisable()
{
WebGl.Instance.isOn = false;
}
public void SetImage(byte[] image)
{
this.image = image;
Texture2D texture = new Texture2D(2, 2);
if (texture.LoadImage(image))
{
setImage.sprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), new Vector2(0.5f, 0.5f));
setImage.gameObject.SetActive(true);
}
else
{
Debug.LogError("이미지 로드 실패!");
}
}
private void UIReset()
{
stepMenus[0].SetActive(false);
stepMenus[1].SetActive(false);
infoUI.SetActive(true);
successUI.SetActive(false);
xid.text = string.Empty;
owner.text = string.Empty;
introeuce.text = string.Empty;
characterName.text = string.Empty;
makerName.text = string.Empty;
animalType.value = 0;
suitType.value = 0;
suitStyle.value = 0;
region.value = 0;
productionDate.text = DateTime.Now.ToString("yyyy-MM-dd");
for (int n = 0; n < colors.Length; n++)
{
colors[n].isOn = false;
colors[n].image.sprite = isOnSprite[0];
}
}
private bool DateTimeCheck(string dateString, out DateTime date)
{
return DateTime.TryParseExact(dateString, "yyyy-MM-dd", CultureInfo.InvariantCulture, DateTimeStyles.None, out date);
}
public void SuccessButton()
{
if (xid.text == string.Empty)
{
GameManager.Instance.infoPageUI.SetError(InfoMessage.NotLogin);
return;
}
if (owner.text == string.Empty)
{
GameManager.Instance.infoPageUI.SetError(InfoMessage.NotOwner);
return;
}
if (characterName.text == string.Empty)
{
GameManager.Instance.infoPageUI.SetError(InfoMessage.NotName);
return;
}
if (animalType.value == 0)
{
GameManager.Instance.infoPageUI.SetError(InfoMessage.NotAnimalType);
return;
}
if (suitType.value == 0)
{
GameManager.Instance.infoPageUI.SetError(InfoMessage.NotSuitType);
return;
}
if (suitStyle.value == 0)
{
GameManager.Instance.infoPageUI.SetError(InfoMessage.NotSuitStyle);
return;
}
if (region.value == 0)
{
GameManager.Instance.infoPageUI.SetError(InfoMessage.NotRegion);
return;
}
DateTime date;
if (!DateTimeCheck(productionDate.text, out date))
{
GameManager.Instance.infoPageUI.SetError(InfoMessage.NotProductionDate);
return;
}
sXid.text = xid.text;
sOwner.text = owner.text;
sCharacterName.text = characterName.text;
sMmakerName.text = makerName.text;
sAnimalType.text = GameManager.Instance.animalTypes[animalType.value - 1].code_nm;
sSuitType.text = GameManager.Instance.suitType[suitType.value - 1].code_nm;
sSuitStyle.text = GameManager.Instance.suitStyle[suitStyle.value - 1].code_nm;
sRegion.text = GameManager.Instance.region[region.value - 1].code_nm;
sProductionDate.text = productionDate.text;
for(int n = 0; n < colors.Length; n++)
{
sColors[n].SetActive(colors[n].isOn);
}
if (image == null)
{
GameManager.Instance.infoPageUI.SetError(InfoMessage.NotImageSet);
return;
}
infoUI.SetActive(false);
successUI.SetActive(true);
}
public void OnToggle(int velue)
{
colors[velue].image.sprite = isOnSprite[(colors[velue].isOn ? 1 : 0)];
}
public void FursuitAdd()
{
RegSuitInfo regSuitInfo = new RegSuitInfo();
regSuitInfo.ownerName = owner.text;
regSuitInfo.charName = characterName.text;
regSuitInfo.suitAnimalType = GameManager.Instance.animalTypes[animalType.value - 1].code_id;
regSuitInfo.suitStyle = GameManager.Instance.suitStyle[suitStyle.value - 1].code_id;
regSuitInfo.suitType = GameManager.Instance.suitType[suitType.value - 1].code_id;
regSuitInfo.suitRegion = GameManager.Instance.region[region.value - 1].code_id;
regSuitInfo.suitMaker = makerName.text;
regSuitInfo.colorList = new List<string>();
regSuitInfo.suitImg = image;
regSuitInfo.userInfo = introeuce.text;
regSuitInfo.productionDate = productionDate.text;
for (int n = 0; n < colors.Length; n++)
{
if (colors[n].isOn)
{
GameManager.eColor color = GameManager.eColor. + n;
regSuitInfo.colorList.Add(((int)color).ToString());
}
}
HTTPRequest httpFursuitAdd = NetworkManager.Instance.CreateRequest<object>("register/regFursuiterInfo", regSuitInfo, (data) =>
{
GameManager.Instance.infoPageUI.Set(InfoMessage.FursuitAdd, () => { screenMove.SearchView(); });
}, null, HTTPMethods.Post);
httpFursuitAdd.Send();
}
public class RegSuitInfo
{
public string ownerName;
public string charName;
public string suitAnimalType;
public string suitStyle;
public string suitType;
public string suitRegion;
public string suitMaker;
public List<string> colorList;
public byte[] suitImg;
public string userInfo;
public string productionDate;
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: fef2c46c5ce9b124bbaf48ad0f128730

View File

@ -0,0 +1,39 @@
using System;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class InfoPageCtrl : MonoBehaviour
{
[SerializeField] TMP_Text message;
[SerializeField] Image outLine;
[SerializeField] Image button;
[SerializeField] Color success;
[SerializeField] Color fail;
private Action action;
public void Set(string message, Action action = null)
{
outLine.color = success;
button.color = success;
this.message.text = message;
this.action = action;
gameObject.SetActive(true);
}
public void SetError(string message, Action action = null)
{
outLine.color = fail;
button.color = fail;
this.message.text = message;
this.action = action;
gameObject.SetActive(true);
}
public void okButton()
{
action?.Invoke();
gameObject.SetActive(false);
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 5fbc49285d6699848b5befdb66a6ba82

View File

@ -2,30 +2,41 @@ using TMPro;
using UnityEngine; using UnityEngine;
using UnityEngine.UI; using UnityEngine.UI;
public class ItemPrefab : MonoBehaviour public class ItemPrefab : MonoBehaviour, System.IEquatable<ItemPrefab>
{ {
Library library; [SerializeField]
Library _library;
public Library library { get { return _library; } }
[SerializeField] TMP_Text suitName; [SerializeField] TMP_Text suitName;
[SerializeField] TMP_Text ownerName; [SerializeField] TMP_Text ownerName;
[SerializeField] Image suitImage; [SerializeField] RawImage suitImage;
[SerializeField] GameObject loading;
public void Set(Library library) public void Set(Library library)
{ {
this.library = library; this._library = library;
suitName.text = library.suit_name; suitName.text = library.suit_name;
ownerName.text = library.owner_name; ownerName.text = library.owner_name;
if(library._suit_image == null) if(library._suit_image == null)
{ {
SearchCtrl.Instance.GetImage(this, library); loading.SetActive(true);
suitImage.texture = null;
} }
else }
private void Update()
{ {
ImageSet(); if (loading.activeSelf)
{
loading.transform.rotation *= Quaternion.Euler(0, 0, 5);
} }
} }
public void ImageSet() public void ImageSet()
{ {
suitImage.sprite = library._suit_image; loading.SetActive(false);
suitImage.texture = library._suit_image;
suitImage.SetNativeSize(); suitImage.SetNativeSize();
RectTransform rect = suitImage.gameObject.GetComponent<RectTransform>(); RectTransform rect = suitImage.gameObject.GetComponent<RectTransform>();
rect.anchorMin = new Vector2(0.5f, 0.5f); rect.anchorMin = new Vector2(0.5f, 0.5f);
@ -37,6 +48,11 @@ public class ItemPrefab : MonoBehaviour
public void Button() public void Button()
{ {
SearchCtrl.Instance.ModelSet(library); SearchCtrl.Instance.ModelSet(_library);
}
public bool Equals(ItemPrefab other)
{
return (_library?.Equals(other?._library) == true) && ReferenceEquals(this, other);
} }
} }

View File

@ -5,19 +5,32 @@ using UnityEngine.UI;
public class ModalCtrl : MonoBehaviour public class ModalCtrl : MonoBehaviour
{ {
[SerializeField] RectTransform imageMask; [SerializeField] RectTransform imageMask;
[SerializeField] Image suitImage; [SerializeField] RawImage suitImage;
[SerializeField] TMP_Text suitName; [SerializeField] TMP_Text suitName;
[SerializeField] TMP_Text userInfo;
[SerializeField] TMP_Text ownerName; [SerializeField] TMP_Text ownerName;
[SerializeField] TMP_Text suitMaker; [SerializeField] TMP_Text suitMaker;
[SerializeField] TMP_Text debutDate; [SerializeField] TMP_Text debutDate;
[SerializeField] TMP_Text suitType; [SerializeField] TMP_Text animalType;
[SerializeField] TMP_Text suitStyle; [SerializeField] TMP_Text suitStyle;
[SerializeField] GameObject[] colors; [SerializeField] GameObject[] colors;
[SerializeField] GameObject _modelCanvas;
public GameObject modelCanvas { get { return _modelCanvas; } }
private void Update()
{
if (Input.GetKey(KeyCode.Escape))
{
_modelCanvas.SetActive(false);
}
}
public void Set(Library library) public void Set(Library library)
{ {
gameObject.SetActive(true); _modelCanvas.SetActive(true);
suitImage.sprite = library._suit_image; suitImage.texture = library._suit_image;
suitImage.SetNativeSize(); suitImage.SetNativeSize();
RectTransform rect = suitImage.gameObject.GetComponent<RectTransform>(); RectTransform rect = suitImage.gameObject.GetComponent<RectTransform>();
rect.anchorMin = new Vector2(0.5f, 0.5f); rect.anchorMin = new Vector2(0.5f, 0.5f);
@ -26,10 +39,19 @@ public class ModalCtrl : MonoBehaviour
Vector2 newSize = new Vector2(rect.sizeDelta.x / size, rect.sizeDelta.y / size); Vector2 newSize = new Vector2(rect.sizeDelta.x / size, rect.sizeDelta.y / size);
rect.sizeDelta = newSize; rect.sizeDelta = newSize;
suitName.text = library.suit_name; suitName.text = library.suit_name;
userInfo.text = library.user_info;
ownerName.text = library.owner_name; ownerName.text = library.owner_name;
suitMaker.text = library.maker; suitMaker.text = library.maker;
debutDate.text = library.production_date; debutDate.text = library.production_date;
suitType.text = library.suit_type; animalType.text = library.animal_type;
suitStyle.text = library.suit_style; suitStyle.text = library.suit_style;
for(int n = 0; n < colors.Length; n++)
{
colors[n].SetActive(false);
}
for (int n = 0; n < library.suit_color.Count; n++)
{
colors[int.Parse(library.suit_color[n]) - (int)GameManager.eColor.ÇÎÅ©º¢²É].SetActive(true);
}
} }
} }

View File

@ -1,5 +1,4 @@
using System.Collections; using BestHTTP;
using System.Collections.Generic;
using UnityEngine; using UnityEngine;
public class ScreenMove : MonoBehaviour public class ScreenMove : MonoBehaviour
@ -7,6 +6,13 @@ public class ScreenMove : MonoBehaviour
[SerializeField] RectTransform rectTransform; [SerializeField] RectTransform rectTransform;
[SerializeField] RectTransform test_rectTransform; [SerializeField] RectTransform test_rectTransform;
[SerializeField] GameObject searchView;
[SerializeField] GameObject fursuitAdd;
[SerializeField] GameObject[] closeUI;
readonly Vector2 stretch = new Vector2(0f, 0.5f); readonly Vector2 stretch = new Vector2(0f, 0.5f);
readonly Vector2 middle = new Vector2(1f, 0.5f); readonly Vector2 middle = new Vector2(1f, 0.5f);
readonly Vector2 center = new Vector2(0.5f, 0.5f); readonly Vector2 center = new Vector2(0.5f, 0.5f);
@ -17,6 +23,7 @@ public class ScreenMove : MonoBehaviour
void Awake() void Awake()
{ {
isMobile = Application.isMobilePlatform; isMobile = Application.isMobilePlatform;
SearchView();
} }
private void Start() private void Start()
@ -66,4 +73,59 @@ public class ScreenMove : MonoBehaviour
} }
public void SearchView()
{
searchView.SetActive(true);
fursuitAdd.SetActive(false);
for(int n = 0; n < closeUI.Length; n++)
{
closeUI[n].SetActive(false);
}
}
public void FursuitAdd()
{
#if UNITY_EDITOR
GameManager.Instance.xid = "Fursuit_Library";
GameManager.Instance.xname = "ÆÛ½´Æ®µµ¼­°ü";
#endif
if (GameManager.Instance.xid == string.Empty)
{
HTTPRequest http = NetworkManager.Instance.CreateRequest<Session>("common/session/user", new object(), (data) =>
{
if(data.status == "L0002")
{
Application.OpenURL($"{NetworkManager.Instance.baseUrl}/oauth2/authorization/twitter");
}
else
{
GameManager.Instance.xid = data.userId;
GameManager.Instance.xname = data.userName;
searchView.SetActive(false);
fursuitAdd.SetActive(true);
for (int n = 0; n < closeUI.Length; n++)
{
closeUI[n].SetActive(false);
}
}
}, null, HTTPMethods.Get);
http.Send();
return;
}
searchView.SetActive(false);
fursuitAdd.SetActive(true);
for (int n = 0; n < closeUI.Length; n++)
{
closeUI[n].SetActive(false);
}
}
class Session
{
public string status;
public string userId;
public string userName;
}
} }

View File

@ -2,14 +2,21 @@ using System.Collections.Generic;
using TMPro; using TMPro;
using UnityEngine; using UnityEngine;
using UnityEngine.UI; using UnityEngine.UI;
using UnityEngine.Pool;
using Cysharp.Threading.Tasks;
using System.Threading.Tasks;
using System.Linq;
using System;
using BestHTTP;
using System.Runtime.CompilerServices;
public class SearchCtrl : SingletonMonoBehaviour<SearchCtrl> public class SearchCtrl : SingletonMonoBehaviour<SearchCtrl>
{ {
//옵션 페이지 UI
[SerializeField] GameObject opsion; [SerializeField] GameObject opsion;
[SerializeField] Image searchMenuButtonImage; [SerializeField] Image searchMenuButtonImage;
[SerializeField] Sprite[] searchMenuButton; [SerializeField] Sprite[] searchMenuButton;
[SerializeField] TMP_Text searchMenuButtonText; [SerializeField] TMP_Text searchMenuButtonText;
[SerializeField] TMP_InputField name; [SerializeField] TMP_InputField name;
[SerializeField] TMP_Dropdown suitStyle; [SerializeField] TMP_Dropdown suitStyle;
[SerializeField] TMP_Dropdown suitType; [SerializeField] TMP_Dropdown suitType;
@ -18,50 +25,88 @@ public class SearchCtrl : SingletonMonoBehaviour<SearchCtrl>
[SerializeField] Toggle[] colors; [SerializeField] Toggle[] colors;
[SerializeField] Sprite[] isOnSprite; [SerializeField] Sprite[] isOnSprite;
[SerializeField] GameObject item; // 검색 결과 UI
[SerializeField] ItemPrefab item;
[SerializeField] Transform results; [SerializeField] Transform results;
[SerializeField] GameObject listTop; [SerializeField] GameObject listTop;
[SerializeField] GameObject bar;
[SerializeField] RectTransform content; [SerializeField] RectTransform content;
[SerializeField] Animator searchUI; [SerializeField] Animator searchUI;
[SerializeField] GameObject loading;
[SerializeField] Transform loadingImage;
// 모달 UI
[SerializeField] ModalCtrl model; [SerializeField] ModalCtrl model;
private SearchRequest request; // 검색 결과 데이터
private List<Library> librarys; private SearchRequest request = new SearchRequest();
[SerializeField] private List<Library> librarys;
private bool hasMore; private bool hasMore;
private List<GameObject> itemPrefabs; // 검색결과 UI 프리팹
private List<ItemPrefab> itemPrefabs;
private ObjectPool<ItemPrefab> itemPrefabPool;
// ???
private bool isSearching = false;
private bool isRefreshing = false;
private Queue<Library> searchResults = new Queue<Library>();
bool isLoading = false;
protected override void OnAwake() protected override void OnAwake()
{ {
itemPrefabs = new List<GameObject>(); name.onEndEdit.AddListener(INPUTFIELD);
librarys = new List<Library>();
itemPrefabPool = new ObjectPool<ItemPrefab>(itemPrefabs_OnCreate, itemPrefabs_OnGet, itemPrefabs_OnRelease, null, true, 100);
itemPrefabs = new List<ItemPrefab>();
} }
void INPUTFIELD(string input)
{
if (Input.GetKeyDown(KeyCode.Return) || Input.GetKeyDown(KeyCode.KeypadEnter))
{
SearchButton();
}
}
#region ObjectPool
private ItemPrefab itemPrefabs_OnCreate()
{
return Instantiate<ItemPrefab>(item, results);
}
private void itemPrefabs_OnGet(ItemPrefab itemPrefab)
{
itemPrefabs.Add(itemPrefab);
itemPrefab.gameObject.SetActive(true);
}
private void itemPrefabs_OnRelease(ItemPrefab itemPrefab)
{
itemPrefab.gameObject.SetActive(false);
itemPrefabs.Remove(itemPrefab);
}
#endregion
private void OnEnable() private void OnEnable()
{ {
hasMore = false; hasMore = false;
model.gameObject.SetActive(false); model.modelCanvas.SetActive(false);
searchUI.SetTrigger("reset"); searchUI.SetTrigger("reset");
loading.SetActive(false);
ResetButton(); ResetButton();
ObjectClear(); ObjectClear();
} }
private void ObjectClear() private void ObjectClear()
{ {
//TODO 재활용 할 수 있게 만들기
results.gameObject.SetActive(false); results.gameObject.SetActive(false);
listTop.SetActive(false); listTop.SetActive(false);
bar.SetActive(false); librarys.Clear();
if (itemPrefabs.Count != 0) while (itemPrefabPool.CountActive > 0)
{ {
for (int n = 0; n < itemPrefabs.Count; n++) var item = itemPrefabs[itemPrefabs.Count - 1];
{ itemPrefabPool.Release(item);
Destroy(itemPrefabs[n]);
}
itemPrefabs.Clear();
} }
} }
@ -80,70 +125,232 @@ public class SearchCtrl : SingletonMonoBehaviour<SearchCtrl>
public void SearchButton() public void SearchButton()
{ {
ObjectClear(); bool isBefore = true;
request = new SearchRequest(); if(request.fursuitName != name.text)
request.fursuitName = name.text;
if (suitStyle.value != 0)
request.suitStyle = GameManager.Instance.suitStyle[suitStyle.value - 1].code_id;
if (suitType.value != 0)
request.suitType = GameManager.Instance.suitType[suitType.value - 1].code_id;
if (region.value != 0)
request.suitRegion = GameManager.Instance.region[region.value - 1].code_id;
if (animalTypes.value != 0)
request.suitAnimalType = GameManager.Instance.animalTypes[animalTypes.value - 1].code_id;
NetworkManager.Instance.CreateRequest<SearchResponse>("library/select/suiters", request, (data) =>
{ {
librarys = data.data; request.fursuitName = name.text;
isBefore = false;
}
if (suitStyle.value != 0)
{
if (request.suitStyle != GameManager.Instance.suitStyle[suitStyle.value - 1].code_id)
{
request.suitStyle = GameManager.Instance.suitStyle[suitStyle.value - 1].code_id;
isBefore = false;
}
}
else if(request.suitStyle != "")
{
request.suitStyle = "";
isBefore = false;
}
if (suitType.value != 0)
{
if (request.suitType != GameManager.Instance.suitType[suitType.value - 1].code_id)
{
request.suitType = GameManager.Instance.suitType[suitType.value - 1].code_id;
isBefore = false;
}
}
else if (request.suitType != "")
{
request.suitType = "";
isBefore = false;
}
if (region.value != 0)
{
if (request.suitRegion != GameManager.Instance.region[region.value - 1].code_id)
{
request.suitRegion = GameManager.Instance.region[region.value - 1].code_id;
isBefore = false;
}
}
else if (request.suitRegion != "")
{
request.suitRegion = "";
isBefore = false;
}
if (animalTypes.value != 0)
{
if (request.suitAnimalType != GameManager.Instance.animalTypes[animalTypes.value - 1].code_id)
{
request.suitAnimalType = GameManager.Instance.animalTypes[animalTypes.value - 1].code_id;
isBefore = false;
}
}
else if (request.suitAnimalType != "")
{
request.suitAnimalType = "";
isBefore = false;
}
List<string> selectColor = new List<string>();
for (int n = 0; n < colors.Length; n++) {
if (colors[n].isOn)
{
selectColor.Add((n + (int)GameManager.eColor.).ToString());
}
}
if(selectColor.Count != request.colorList.Count)
{
request.colorList = selectColor;
isBefore = false;
}
else
{
for(int n = 0; n < selectColor.Count; n++)
{
if (selectColor[n] != request.colorList[n])
{
request.colorList = selectColor;
isBefore = false;
break;
}
}
}
//첫 검색이거나 이전과 검색결과가 같지 않으면 검색진행
if (!isBefore || !listTop.activeSelf)
{
request.offset = 0;
request.page = 1;
request.size = 10;
ObjectClear();
results.gameObject.SetActive(true); results.gameObject.SetActive(true);
listTop.SetActive(true); listTop.SetActive(true);
bar.SetActive(true); SearchSuiters().Forget();
ItemPrefab[] items = new ItemPrefab[data.data.Count];
for (int n = 0; n < data.data.Count; n++)
{
GameObject prefab = Instantiate(item, results);
itemPrefabs.Add(prefab);
items[n] = prefab.GetComponent<ItemPrefab>();
} }
}
private void Update()
{
if (isLoading)
{
loadingImage.rotation *= Quaternion.Euler(0, 0, 5);
}
}
public async UniTask SearchSuiters()
{
if (isSearching) return;
isSearching = true;
var tcs = new TaskCompletionSource<bool>();
HTTPRequest searchRequest = NetworkManager.Instance.CreateRequest<SearchResponse>("library/select/suiters", request, (data) =>
{
for (int n = 0; n < data.data.Count; n++) for (int n = 0; n < data.data.Count; n++)
{ {
items[n].Set(data.data[n]); searchResults.Enqueue(data.data[n]);
} }
hasMore = data.hasMore; hasMore = data.hasMore;
//LayoutRebuilder.ForceRebuildLayoutImmediate(content); tcs.SetResult(true); // 응답 완료 신호
}); loading.SetActive(hasMore);
}
);
await searchRequest.Send();
await tcs.Task; // 응답이 완료될 때까지 대기
await RefreshScroll();
isSearching = false;
}
public async UniTask RefreshScroll()
{
if (isRefreshing) return;
isRefreshing = true;
if (searchResults.Count > 0)
{
while (searchResults.TryDequeue(out var result))
{
librarys.Add(result);
}
}
int n = 0;
for (; n < itemPrefabs.Count; n++)
{
var item = itemPrefabs[n];
item.Set(librarys[n]);
await UniTask.Yield();
}
for (; n < librarys.Count; n++)
{
var item = itemPrefabPool.Get();
LayoutRebuilder.ForceRebuildLayoutImmediate(content);
item.Set(librarys[n]);
await UniTask.Yield();
}
isLoading = false;
loadingImage.rotation = Quaternion.identity;
for (; n > librarys.Count; n--)
{
var item = itemPrefabs.Last();
itemPrefabPool.Release(item);
await UniTask.Yield();
}
await ApplayImages();
isRefreshing = false;
}
private async UniTask ApplayImages()
{
for (int i = 0; itemPrefabs.Count > i; i++)
{
await GetImage(itemPrefabs[i].library);
itemPrefabs[i].ImageSet();
}
}
public async UniTask<Texture2D> GetImage(Library library)
{
if (library._suit_image != null)
{
return library._suit_image;
}
var tcs = new TaskCompletionSource<Texture2D>();
var request = NetworkManager.Instance.CreateImageRequest(
library.imageBase64.Substring(1),
new object(),
(data) =>
{
library._suit_image = data;
tcs.SetResult(data);
},
(fail) =>
{
//Debug.LogError("GetImage Fail");
tcs.SetResult(null);
},
BestHTTP.HTTPMethods.Get
);
await request.Send();
await tcs.Task;
return library._suit_image;
} }
public void NextSearch() public void NextSearch()
{
if (isSearching == false)
{ {
hasMore = false; hasMore = false;
request.page++; request.page++;
NetworkManager.Instance.CreateRequest<SearchResponse>("library/select/suiters", request, (data) => SearchSuiters().Forget();
{
librarys.AddRange(data.data);
Debug.Log(data.data.Count);
ItemPrefab[] items = new ItemPrefab[data.data.Count];
for (int n = 0; n < items.Length; n++)
{
GameObject prefab = Instantiate(item, results);
itemPrefabs.Add(prefab);
items[n] = prefab.GetComponent<ItemPrefab>();
} }
for (int n = 0; n < data.data.Count; n++)
{
items[n].Set(data.data[n]);
}
hasMore = data.hasMore;
LayoutRebuilder.ForceRebuildLayoutImmediate(content);
});
}
public void GetImage(ItemPrefab itemPrefab, Library library)
{
NetworkManager.Instance.CreateImageRequest(library.imageBase64.Substring(1), new object(), (data) =>
{
library._suit_image = Sprite.Create(data, new Rect(0, 0, data.width, data.height), new Vector2(0.5f, 0.5f));
itemPrefab.ImageSet();
}, null, BestHTTP.HTTPMethods.Get);
} }
public void ResetButton() public void ResetButton()
@ -169,13 +376,15 @@ public class SearchCtrl : SingletonMonoBehaviour<SearchCtrl>
model.Set(library); model.Set(library);
} }
public void ScrollValue(RectTransform Content) { public void ScrollValue(RectTransform Content)
{
if (Content.anchoredPosition.y < 0.0f) if (Content.anchoredPosition.y < 0.0f)
{ {
Content.anchoredPosition = Vector2.zero; Content.anchoredPosition = Vector2.zero;
} }
else if(hasMore && Content.sizeDelta.y != Screen.height && Content.sizeDelta.y - Screen.height < Content.anchoredPosition.y) else if (hasMore && Content.sizeDelta.y != Screen.height && Content.sizeDelta.y - Screen.height < (Content.anchoredPosition.y + 25))
{ {
isLoading = true;
NextSearch(); NextSearch();
} }
} }
@ -192,7 +401,7 @@ public class SearchRequest
public string suitType = ""; /*½´Æ® ÇüÅÂ*/ public string suitType = ""; /*½´Æ® ÇüÅÂ*/
public List<string> colorList = new List<string>(); /*½´Æ® »ö»ó*/ public List<string> colorList = new List<string>(); /*½´Æ® »ö»ó*/
public int page = 1; public int page = 1;
public int size = 5; public int size = 10;
public int offset = 0; public int offset = 0;
} }
public class SearchResponse public class SearchResponse
@ -205,15 +414,16 @@ public class ImageResponse
public byte[] imageBytes; public byte[] imageBytes;
} }
[Serializable]
public class Library public class Library
{ {
public string imageBase64; public string imageBase64;
public string suit_name; public string suit_name;
public string user_info;
public string owner_id; public string owner_id;
public string owner_name; public string owner_name;
public string production_date; public string production_date;
public string suit_image;//사용안함 public Texture2D _suit_image = null;
public Sprite _suit_image = null;
public string maker; public string maker;
public string region; public string region;
public string animal_type; public string animal_type;

View File

@ -10,8 +10,35 @@ public class GameManager : DontDestroy<GameManager>
public List<CommonData> suitType; public List<CommonData> suitType;
public List<CommonData> region; public List<CommonData> region;
public InfoPageCtrl infoPageUI;
public string xid;
public string xname;
protected override void OnAwake() protected override void OnAwake()
{ {
Application.targetFrameRate = 100; Application.targetFrameRate = 100;
infoPageUI.gameObject.SetActive(false);
xid = string.Empty;
}
public enum eColor
{
= 500001,
= 500002,
= 500003,
= 500004,
= 500005,
= 500006,
= 500007,
= 500008,
= 500009,
= 500010,
= 500011,
= 500012,
= 500013,
= 500014,
= 500015,
= 500016,
} }
} }

View File

@ -1,6 +1,4 @@
using System.Collections; using System.Collections.Generic;
using System.Collections.Generic;
using UnityEngine;
public class GameObjectPool<T> where T : class public class GameObjectPool<T> where T : class
{ {

View File

@ -0,0 +1,30 @@
public static class InfoMessage
{
public static readonly string FursuitAdd = "등록신청이 완료되었습니다!\n<size=66%>주말 / 공휴일 제외 3일 이내로 등록 예정으로 추가 문의는 @fursuit_library로 문의바랍니다.</size>";
//Error
public static readonly string NotLogin = "문제 발생!\n<size=66%>트위터 로그인이 되어있지 않습니다.\n@fursuit_library로 문의바랍니다.</size>";
public static readonly string NotOwner = "확인해 주세요\n<size=66%>오너 정보가 없습니다.</size>";
public static readonly string NotName = "확인해 주세요\n<size=66%>케릭터 이름을 등록하지 않으셨습니다</size>";
public static readonly string NotAnimalType = "확인해 주세요\n<size=66%>동물 종을 선택하지 않으셨습니다. \n만약 리스트에 없을경우 @fursuit_library로 문의바랍니다.</size>";
public static readonly string NotSuitType = "확인해 주세요\n<size=66%>슈트 타입정보가 없습니다.</size>";
public static readonly string NotSuitStyle = "확인해 주세요\n<size=66%>슈트 스타일정보가 없습니다.</size>";
public static readonly string NotRegion = "확인해 주세요\n<size=66%>활동 국가 정보가 없습니다.</size>";
public static readonly string NotProductionDate = "확인해 주세요\n<size=66%>활동 시작일 정보가 잘못되었습니다.\n예)2025-04-01</size>";
public static readonly string NotImage = "확인해 주세요\n<size=66%>이미지 파일이 아닙니다.</size>";
public static readonly string NotImageType = "확인해 주세요\n<size=66%>잘못된 이미지 타입입니다.\n현재 jpg, jpeg, png만 지원하고 있습니다.\n추가 지원문의는 @fursuit_library로 문의바랍니다.</size>";
public static readonly string NotImageSet = "확인해 주세요\n<size=66%>이미지를 등록해 주세요.</size>";
public static readonly string NotImageSize = "확인해 주세요\n<size=66%>등록 가능한 이미지 최대 크기는 10MB입니다.</size>";
//ErrorCode
//잘못된 압축 형식 Base64가 아닌경우 발생
public static readonly string SystemError00001 = "문제 발생!\n<size=66%>아래 코드를 @fursuit_library로 문의해주세요\nE00001</size>";
//json 처리 오류
public static readonly string SystemError00002 = "문제 발생!\n<size=66%>아래 코드를 @fursuit_library로 문의해주세요\nE00002</size>";
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: bd699c354f1fbc24ab3d3d6821f6bdaa

View File

@ -2,13 +2,15 @@ using UnityEngine;
using BestHTTP; using BestHTTP;
using System; using System;
using Newtonsoft.Json; using Newtonsoft.Json;
using MEC; using BestHTTP.JSON;
using System.Collections.Generic;
public class NetworkManager : SingletonMonoBehaviour<NetworkManager> public class NetworkManager : SingletonMonoBehaviour<NetworkManager>
{ {
[SerializeField] private string baseUrl; [SerializeField] private string _baseUrl;
[SerializeField] private string _baseEndpoint;
public string baseUrl { get { return _baseUrl; } }
/// <summary> /// <summary>
/// 데이터를 송수신해야할 때 사용합니다. send()는 생성을 마치고 자동으로 보냅니다. /// 데이터를 송수신해야할 때 사용합니다. send()는 생성을 마치고 자동으로 보냅니다.
@ -21,7 +23,7 @@ public class NetworkManager : SingletonMonoBehaviour<NetworkManager>
/// <returns>역직렬화된 데이터 or 기본값(반환 받지 못함)</returns> /// <returns>역직렬화된 데이터 or 기본값(반환 받지 못함)</returns>
public HTTPRequest CreateRequest<T>(string api, object serializeData, Action<T> onSuccess, Action<T> onFail = null, HTTPMethods methods = HTTPMethods.Post) public HTTPRequest CreateRequest<T>(string api, object serializeData, Action<T> onSuccess, Action<T> onFail = null, HTTPMethods methods = HTTPMethods.Post)
{ {
string url = $"{baseUrl}{api}".Replace("\\p{Z}", String.Empty); string url = $"{_baseUrl}/{_baseEndpoint}/{api}".Replace("\\p{Z}", String.Empty);
var httpRquest = new HTTPRequest(new Uri(url) //url 넣기 var httpRquest = new HTTPRequest(new Uri(url) //url 넣기
, methods //동작 방식 넣기 , methods //동작 방식 넣기
@ -44,13 +46,21 @@ public class NetworkManager : SingletonMonoBehaviour<NetworkManager>
httpRquest.RawData = System.Text.Encoding.UTF8.GetBytes(json); httpRquest.RawData = System.Text.Encoding.UTF8.GetBytes(json);
} }
httpRquest.Send();
return httpRquest; return httpRquest;
} }
/// <summary>
/// Texture2D Åë½Å¿ë ÇÔ¼ö
/// </summary>
/// <param name="api"></param>
/// <param name="serializeData"></param>
/// <param name="onSuccess"></param>
/// <param name="onFail"></param>
/// <param name="methods"></param>
/// <returns></returns>
public HTTPRequest CreateImageRequest(string api, object serializeData, Action<Texture2D> onSuccess, Action<Texture2D> onFail = null, HTTPMethods methods = HTTPMethods.Post) public HTTPRequest CreateImageRequest(string api, object serializeData, Action<Texture2D> onSuccess, Action<Texture2D> onFail = null, HTTPMethods methods = HTTPMethods.Post)
{ {
string url = $"{baseUrl}{api}".Replace("\\p{Z}", String.Empty); string url = $"{_baseUrl}/{_baseEndpoint}/{api}".Replace("\\p{Z}", String.Empty);
var httpRquest = new HTTPRequest(new Uri(url) //url 넣기 var httpRquest = new HTTPRequest(new Uri(url) //url 넣기
, methods //동작 방식 넣기 , methods //동작 방식 넣기
, (request, response) => { , (request, response) => {
@ -71,14 +81,6 @@ public class NetworkManager : SingletonMonoBehaviour<NetworkManager>
string json = JsonConvert.SerializeObject(serializeData); string json = JsonConvert.SerializeObject(serializeData);
httpRquest.RawData = System.Text.Encoding.UTF8.GetBytes(json); httpRquest.RawData = System.Text.Encoding.UTF8.GetBytes(json);
} }
httpRquest.Send();
return httpRquest; return httpRquest;
} }
private IEnumerator<float> Sendearch()
{
//Timing.RunCoroutine(BuildingSet());
yield return Timing.WaitForSeconds(0.1f);
}
} }

View File

@ -1,6 +1,4 @@
using System.Collections; using UnityEngine;
using System.Collections.Generic;
using UnityEngine;
public class SingletonMonoBehaviour<T> : MonoBehaviour where T : SingletonMonoBehaviour<T> public class SingletonMonoBehaviour<T> : MonoBehaviour where T : SingletonMonoBehaviour<T>
{ {
@ -15,8 +13,8 @@ public class SingletonMonoBehaviour<T> : MonoBehaviour where T : SingletonMonoBe
} }
else else
{ {
Debug.Log("1개이상의 싱글턴이 존재합니다" + gameObject.name); //Debug.Log("1개이상의 싱글턴이 존재합니다" + gameObject.name);
Debug.Log("같은 함수가 들어간 싱글턴을 제거해 주세요"); //Debug.Log("같은 함수가 들어간 싱글턴을 제거해 주세요");
Destroy(gameObject); Destroy(gameObject);
} }
} }

View File

@ -0,0 +1,72 @@
using System;
using UnityEngine;
public class WebGl : SingletonMonoBehaviour<WebGl>
{
public bool isOn = false;
public byte[] image { get { return _images; } }
byte[] _images;
public void GetDragAndDrop(string base64Json)
{
if (!isOn)
return;
try
{
base64Json = base64Json.Replace("[\"", "").Replace("\"]", "");
string[] data = base64Json.Split(',');
data[0] = data[0].Replace("data:", "");
data[0] = data[0].Replace("/", ";");
string[] info = data[0].Split(";");
if (info[0] != "image")
{
GameManager.Instance.infoPageUI.SetError(InfoMessage.NotImage);
return;
}
if (!(info[1] == "png" || info[1] == "jpg" || info[1] == "jpeg"))
{
GameManager.Instance.infoPageUI.SetError(InfoMessage.NotImageType);
return;
}
if (info[2] != "base64")
{
GameManager.Instance.infoPageUI.SetError(InfoMessage.SystemError00001);
return;
}
_images = DecodeBase64(data[1]);
double fileSizeInMB = _images.Length / (1024.0 * 1024.0);
if (fileSizeInMB > 10.0d)
{
GameManager.Instance.infoPageUI.SetError(InfoMessage.NotImageSize);
Debug.Log($"파일 크기: {fileSizeInMB:F2} MB");
return;
}
FursuitAddCtrl.Instance.SetImage(image);
}
catch (Exception e)
{
GameManager.Instance.infoPageUI.SetError(InfoMessage.SystemError00002);
}
}
public byte[] DecodeBase64(string base64String)
{
try
{
// Base64 문자열을 byte[]로 디코딩
byte[] byteArray = Convert.FromBase64String(base64String);
return byteArray;
}
catch (FormatException ex)
{
// 잘못된 Base64 문자열 처리
Console.WriteLine("Base64 디코딩 실패: " + ex.Message);
return null;
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 061efe05400e6e34c8d1e9dc2bc05eb8

View File

@ -16,9 +16,6 @@ public class TopMenuCtrl : MonoBehaviour
float time; float time;
float speed = 10; float speed = 10;
//50
//-100
private void Awake() private void Awake()
{ {
rectTransform = GetComponent<RectTransform>(); rectTransform = GetComponent<RectTransform>();
@ -28,11 +25,8 @@ public class TopMenuCtrl : MonoBehaviour
if(isUp) if(isUp)
{ {
time += Time.deltaTime * speed; time += Time.deltaTime * speed;
Debug.Log(time);
if(time < 1.0f) if(time < 1.0f)
{
content.anchoredPosition = new Vector2(0, pointY - (pointY * time)); content.anchoredPosition = new Vector2(0, pointY - (pointY * time));
}
else else
{ {
content.anchoredPosition = new Vector2(0, 0); content.anchoredPosition = new Vector2(0, 0);
@ -46,7 +40,7 @@ public class TopMenuCtrl : MonoBehaviour
fursuit.text = sizeY < 0.5f ? "ÆÛ\n½´\nÆ®\n\nµî\n·Ï" : "ÆÛ\n½´\nÆ®"; fursuit.text = sizeY < 0.5f ? "ÆÛ\n½´\nÆ®\n\nµî\n·Ï" : "ÆÛ\n½´\nÆ®";
sizeY = (sizeY < 1.0f ? sizeY : 1.0f); sizeY = (sizeY < 1.0f ? sizeY : 1.0f);
rectTransform.sizeDelta = new Vector2(282.5f, 242 - (sizeY * 87)); rectTransform.sizeDelta = new Vector2(282.5f, 242 - (sizeY * 87));
topButton.anchoredPosition = new Vector2(-50, -100f + (sizeY * 150f)); topButton.anchoredPosition = new Vector2(-28, -100f + (sizeY * 129f));
} }
} }
public void TopButton() public void TopButton()

Binary file not shown.

After

Width:  |  Height:  |  Size: 380 B

View File

@ -0,0 +1,156 @@
fileFormatVersion: 2
guid: c2e67ac5578599b44bd53919f12594f8
TextureImporter:
internalIDToNameTable:
- first:
213: -2301733007492010490
second: Dropdown_Input_0
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 2
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: WebGL
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites:
- serializedVersion: 2
name: Dropdown_Input_0
rect:
serializedVersion: 2
x: 0
y: 0
width: 50
height: 50
alignment: 0
pivot: {x: 0, y: 0}
border: {x: 0, y: 0, z: 0, w: 0}
customData:
outline: []
physicsShape: []
tessellationDetail: -1
bones: []
spriteID: 60ea5a8560a9e00e0800000000000000
internalID: -2301733007492010490
vertices: []
indices:
edges: []
weights: []
outline: []
customData:
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable:
Dropdown_Input_0: -2301733007492010490
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

View File

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -3,7 +3,7 @@ guid: 861fc7ede2a1c3d4f815235336202eba
TextureImporter: TextureImporter:
internalIDToNameTable: [] internalIDToNameTable: []
externalObjects: {} externalObjects: {}
serializedVersion: 12 serializedVersion: 13
mipmaps: mipmaps:
mipMapMode: 0 mipMapMode: 0
enableMipMap: 0 enableMipMap: 0
@ -67,7 +67,7 @@ TextureImporter:
swizzle: 50462976 swizzle: 50462976
cookieLightType: 0 cookieLightType: 0
platformSettings: platformSettings:
- serializedVersion: 3 - serializedVersion: 4
buildTarget: DefaultTexturePlatform buildTarget: DefaultTexturePlatform
maxTextureSize: 2048 maxTextureSize: 2048
resizeAlgorithm: 0 resizeAlgorithm: 0
@ -80,7 +80,7 @@ TextureImporter:
ignorePlatformSupport: 0 ignorePlatformSupport: 0
androidETC2FallbackOverride: 0 androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0 forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3 - serializedVersion: 4
buildTarget: WebGL buildTarget: WebGL
maxTextureSize: 2048 maxTextureSize: 2048
resizeAlgorithm: 0 resizeAlgorithm: 0
@ -93,7 +93,7 @@ TextureImporter:
ignorePlatformSupport: 0 ignorePlatformSupport: 0
androidETC2FallbackOverride: 0 androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0 forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3 - serializedVersion: 4
buildTarget: Standalone buildTarget: Standalone
maxTextureSize: 2048 maxTextureSize: 2048
resizeAlgorithm: 0 resizeAlgorithm: 0
@ -106,7 +106,7 @@ TextureImporter:
ignorePlatformSupport: 0 ignorePlatformSupport: 0
androidETC2FallbackOverride: 0 androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0 forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3 - serializedVersion: 4
buildTarget: Android buildTarget: Android
maxTextureSize: 2048 maxTextureSize: 2048
resizeAlgorithm: 0 resizeAlgorithm: 0
@ -119,7 +119,7 @@ TextureImporter:
ignorePlatformSupport: 0 ignorePlatformSupport: 0
androidETC2FallbackOverride: 0 androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0 forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3 - serializedVersion: 4
buildTarget: Server buildTarget: Server
maxTextureSize: 2048 maxTextureSize: 2048
resizeAlgorithm: 0 resizeAlgorithm: 0
@ -136,6 +136,7 @@ TextureImporter:
serializedVersion: 2 serializedVersion: 2
sprites: [] sprites: []
outline: [] outline: []
customData:
physicsShape: [] physicsShape: []
bones: [] bones: []
spriteID: 5e97eb03825dee720800000000000000 spriteID: 5e97eb03825dee720800000000000000
@ -145,6 +146,8 @@ TextureImporter:
edges: [] edges: []
weights: [] weights: []
secondaryTextures: [] secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable: {} nameFileIdTable: {}
mipmapLimitGroupName: mipmapLimitGroupName:
pSDRemoveMatte: 0 pSDRemoveMatte: 0

Binary file not shown.

After

Width:  |  Height:  |  Size: 729 B

View File

@ -0,0 +1,156 @@
fileFormatVersion: 2
guid: b837c489f1e01ab429ca7eb0049b01f9
TextureImporter:
internalIDToNameTable:
- first:
213: -2278566297644842510
second: Icon_0
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 2
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: WebGL
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites:
- serializedVersion: 2
name: Icon_0
rect:
serializedVersion: 2
x: 0
y: 0
width: 24
height: 42
alignment: 0
pivot: {x: 0, y: 0}
border: {x: 0, y: 0, z: 0, w: 0}
customData:
outline: []
physicsShape: []
tessellationDetail: -1
bones: []
spriteID: 2f1c3bf4608e060e0800000000000000
internalID: -2278566297644842510
vertices: []
indices:
edges: []
weights: []
outline: []
customData:
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable:
Icon_0: -2278566297644842510
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1,156 @@
fileFormatVersion: 2
guid: be55064a11650084a98e70d3710ab911
TextureImporter:
internalIDToNameTable:
- first:
213: -8320539100486018772
second: Rectangle_27_1_0
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 2
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: WebGL
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites:
- serializedVersion: 2
name: Rectangle_27_1_0
rect:
serializedVersion: 2
x: 0
y: 0
width: 60
height: 60
alignment: 0
pivot: {x: 0.5, y: 0.5}
border: {x: 30, y: 30, z: 30, w: 30}
customData:
outline: []
physicsShape: []
tessellationDetail: -1
bones: []
spriteID: c2958cfa5c1878c80800000000000000
internalID: -8320539100486018772
vertices: []
indices:
edges: []
weights: []
outline: []
customData:
physicsShape: []
bones: []
spriteID: 0baa582e3dcf32c46ac65e46bda1b95b
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable:
Rectangle_27_1_0: -8320539100486018772
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1,156 @@
fileFormatVersion: 2
guid: e35ef1df33597934b888a3455d587531
TextureImporter:
internalIDToNameTable:
- first:
213: 807920327669769301
second: Style_Background2_0
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 2
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: WebGL
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites:
- serializedVersion: 2
name: Style_Background2_0
rect:
serializedVersion: 2
x: 0
y: 0
width: 60
height: 60
alignment: 0
pivot: {x: 0.5, y: 0.5}
border: {x: 30, y: 30, z: 30, w: 30}
customData:
outline: []
physicsShape: []
tessellationDetail: -1
bones: []
spriteID: 554e299e14f463b00800000000000000
internalID: 807920327669769301
vertices: []
indices:
edges: []
weights: []
outline: []
customData:
physicsShape: []
bones: []
spriteID: 3a5f5d7e08f89ec43a3210429e89b90e
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable:
Style_Background2_0: 807920327669769301
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 8e7e8f5a82a3a134e91c54efd2274ea9 guid: a77e3012f37e98f4fb0c9f538d96d114
folderAsset: yes folderAsset: yes
DefaultImporter: DefaultImporter:
externalObjects: {} externalObjects: {}

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -0,0 +1,156 @@
fileFormatVersion: 2
guid: c76b64f4a1f71e64784ddec0898842ef
TextureImporter:
internalIDToNameTable:
- first:
213: -5579834082741855272
second: stamp_0
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 2
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: WebGL
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites:
- serializedVersion: 2
name: stamp_0
rect:
serializedVersion: 2
x: 0
y: 0
width: 604
height: 153
alignment: 0
pivot: {x: 0, y: 0}
border: {x: 0, y: 0, z: 0, w: 0}
customData:
outline: []
physicsShape: []
tessellationDetail: -1
bones: []
spriteID: 8dbdd8807727092b0800000000000000
internalID: -5579834082741855272
vertices: []
indices:
edges: []
weights: []
outline: []
customData:
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable:
stamp_0: -5579834082741855272
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

View File

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@ -3,7 +3,7 @@ guid: 50a793ca026e5f94db805e7d6ef95009
TextureImporter: TextureImporter:
internalIDToNameTable: [] internalIDToNameTable: []
externalObjects: {} externalObjects: {}
serializedVersion: 12 serializedVersion: 13
mipmaps: mipmaps:
mipMapMode: 0 mipMapMode: 0
enableMipMap: 0 enableMipMap: 0
@ -67,7 +67,7 @@ TextureImporter:
swizzle: 50462976 swizzle: 50462976
cookieLightType: 0 cookieLightType: 0
platformSettings: platformSettings:
- serializedVersion: 3 - serializedVersion: 4
buildTarget: DefaultTexturePlatform buildTarget: DefaultTexturePlatform
maxTextureSize: 2048 maxTextureSize: 2048
resizeAlgorithm: 0 resizeAlgorithm: 0
@ -80,7 +80,7 @@ TextureImporter:
ignorePlatformSupport: 0 ignorePlatformSupport: 0
androidETC2FallbackOverride: 0 androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0 forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3 - serializedVersion: 4
buildTarget: WebGL buildTarget: WebGL
maxTextureSize: 2048 maxTextureSize: 2048
resizeAlgorithm: 0 resizeAlgorithm: 0
@ -93,7 +93,7 @@ TextureImporter:
ignorePlatformSupport: 0 ignorePlatformSupport: 0
androidETC2FallbackOverride: 0 androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0 forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3 - serializedVersion: 4
buildTarget: Standalone buildTarget: Standalone
maxTextureSize: 2048 maxTextureSize: 2048
resizeAlgorithm: 0 resizeAlgorithm: 0
@ -106,7 +106,7 @@ TextureImporter:
ignorePlatformSupport: 0 ignorePlatformSupport: 0
androidETC2FallbackOverride: 0 androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0 forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3 - serializedVersion: 4
buildTarget: Android buildTarget: Android
maxTextureSize: 2048 maxTextureSize: 2048
resizeAlgorithm: 0 resizeAlgorithm: 0
@ -119,7 +119,7 @@ TextureImporter:
ignorePlatformSupport: 0 ignorePlatformSupport: 0
androidETC2FallbackOverride: 0 androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0 forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3 - serializedVersion: 4
buildTarget: Server buildTarget: Server
maxTextureSize: 2048 maxTextureSize: 2048
resizeAlgorithm: 0 resizeAlgorithm: 0
@ -136,6 +136,7 @@ TextureImporter:
serializedVersion: 2 serializedVersion: 2
sprites: [] sprites: []
outline: [] outline: []
customData:
physicsShape: [] physicsShape: []
bones: [] bones: []
spriteID: 5e97eb03825dee720800000000000000 spriteID: 5e97eb03825dee720800000000000000
@ -145,6 +146,8 @@ TextureImporter:
edges: [] edges: []
weights: [] weights: []
secondaryTextures: [] secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable: {} nameFileIdTable: {}
mipmapLimitGroupName: mipmapLimitGroupName:
pSDRemoveMatte: 0 pSDRemoveMatte: 0

Binary file not shown.

After

Width:  |  Height:  |  Size: 225 B

View File

@ -0,0 +1,156 @@
fileFormatVersion: 2
guid: 0762348e1598d934f8cc44835fe5d687
TextureImporter:
internalIDToNameTable:
- first:
213: -6889361472651060198
second: Frame_5080_0
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 2
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: WebGL
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites:
- serializedVersion: 2
name: Frame_5080_0
rect:
serializedVersion: 2
x: 0
y: 0
width: 5
height: 40
alignment: 0
pivot: {x: 0.5, y: 0.5}
border: {x: 0, y: 0, z: 0, w: 0}
customData:
outline: []
physicsShape: []
tessellationDetail: -1
bones: []
spriteID: a1c1f55fd321460a0800000000000000
internalID: -6889361472651060198
vertices: []
indices:
edges: []
weights: []
outline: []
customData:
physicsShape: []
bones: []
spriteID: 5bd39ce4a78806048a51e60d8ff06d85
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable:
Frame_5080_0: -6889361472651060198
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 907 B

View File

@ -0,0 +1,155 @@
fileFormatVersion: 2
guid: 1dc401a7352bb85449909791095ea911
TextureImporter:
internalIDToNameTable:
- first:
213: -2278566297644842510
second: Icon_0
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 2
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: WebGL
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites:
- serializedVersion: 2
name: Icon_0
rect:
serializedVersion: 2
x: 0
y: 0
width: 46
height: 53
alignment: 0
pivot: {x: 0, y: 0}
border: {x: 0, y: 0, z: 0, w: 0}
customData:
outline: []
physicsShape: []
tessellationDetail: -1
bones: []
spriteID: 2f1c3bf4608e060e0800000000000000
internalID: -2278566297644842510
vertices: []
indices:
edges: []
weights: []
outline: []
customData:
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

View File

@ -0,0 +1,156 @@
fileFormatVersion: 2
guid: edb55753fb01eb24d89a734b4b947399
TextureImporter:
internalIDToNameTable:
- first:
213: 7227660148774810713
second: Frame_5074_0
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 2
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: WebGL
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites:
- serializedVersion: 2
name: Frame_5074_0
rect:
serializedVersion: 2
x: 0
y: 0
width: 1920
height: 1080
alignment: 0
pivot: {x: 0, y: 0}
border: {x: 0, y: 0, z: 0, w: 0}
customData:
outline: []
physicsShape: []
tessellationDetail: -1
bones: []
spriteID: 95438fc8c9ecd4460800000000000000
internalID: 7227660148774810713
vertices: []
indices:
edges: []
weights: []
outline: []
customData:
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable:
Frame_5074_0: 7227660148774810713
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

View File

@ -0,0 +1,156 @@
fileFormatVersion: 2
guid: 4db3f7ebab1f61e44ba206af4a54e5ea
TextureImporter:
internalIDToNameTable:
- first:
213: 4827032453998402069
second: Frame_5077_0
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 2
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: WebGL
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites:
- serializedVersion: 2
name: Frame_5077_0
rect:
serializedVersion: 2
x: 0
y: 0
width: 1920
height: 1080
alignment: 0
pivot: {x: 0, y: 0}
border: {x: 0, y: 0, z: 0, w: 0}
customData:
outline: []
physicsShape: []
tessellationDetail: -1
bones: []
spriteID: 51a5bd331701df240800000000000000
internalID: 4827032453998402069
vertices: []
indices:
edges: []
weights: []
outline: []
customData:
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable:
Frame_5077_0: 4827032453998402069
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

Before

Width:  |  Height:  |  Size: 223 KiB

After

Width:  |  Height:  |  Size: 165 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1023 KiB

View File

@ -0,0 +1,155 @@
fileFormatVersion: 2
guid: 4385301616fa72b46a8eab5ea05c13c0
TextureImporter:
internalIDToNameTable:
- first:
213: 2478865279642758037
second: Main_Container_0
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 2
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: WebGL
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites:
- serializedVersion: 2
name: Main_Container_0
rect:
serializedVersion: 2
x: 0
y: 0
width: 1920
height: 1080
alignment: 0
pivot: {x: 0, y: 0}
border: {x: 0, y: 0, z: 0, w: 0}
customData:
outline: []
physicsShape: []
tessellationDetail: -1
bones: []
spriteID: 59be72796d2b66220800000000000000
internalID: 2478865279642758037
vertices: []
indices:
edges: []
weights: []
outline: []
customData:
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

View File

@ -0,0 +1,156 @@
fileFormatVersion: 2
guid: db7185396c62fea4a9e4e5f4d54ebc1d
TextureImporter:
internalIDToNameTable:
- first:
213: 3121311038206801502
second: Main_Container__0
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 2
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: WebGL
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites:
- serializedVersion: 2
name: Main_Container__0
rect:
serializedVersion: 2
x: 0
y: 0
width: 1920
height: 1080
alignment: 0
pivot: {x: 0, y: 0}
border: {x: 0, y: 0, z: 0, w: 0}
customData:
outline: []
physicsShape: []
tessellationDetail: -1
bones: []
spriteID: e5672d11adf115b20800000000000000
internalID: 3121311038206801502
vertices: []
indices:
edges: []
weights: []
outline: []
customData:
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable:
Main_Container__0: 3121311038206801502
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

View File

@ -0,0 +1,156 @@
fileFormatVersion: 2
guid: 01776f7a17020134898f7ed7462e2af9
TextureImporter:
internalIDToNameTable:
- first:
213: 6839554522387699187
second: Main_Containerasdf_0
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 2
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: WebGL
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites:
- serializedVersion: 2
name: Main_Containerasdf_0
rect:
serializedVersion: 2
x: 0
y: 0
width: 1920
height: 1080
alignment: 0
pivot: {x: 0, y: 0}
border: {x: 0, y: 0, z: 0, w: 0}
customData:
outline: []
physicsShape: []
tessellationDetail: -1
bones: []
spriteID: 3f5d5d0c99afaee50800000000000000
internalID: 6839554522387699187
vertices: []
indices:
edges: []
weights: []
outline: []
customData:
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable:
Main_Containerasdf_0: 6839554522387699187
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

View File

@ -137,9 +137,23 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 1da056f246b185842aae317b0faf0a3b, type: 3} m_Script: {fileID: 11500000, guid: 1da056f246b185842aae317b0faf0a3b, type: 3}
m_Name: m_Name:
m_EditorClassIdentifier: m_EditorClassIdentifier:
_library:
imageBase64:
suit_name:
owner_id:
owner_name:
production_date:
_suit_image: {fileID: 0}
maker:
region:
animal_type:
suit_style:
suit_type:
suit_color: []
suitName: {fileID: 8144517625848204680} suitName: {fileID: 8144517625848204680}
ownerName: {fileID: 2525889181953908848} ownerName: {fileID: 2525889181953908848}
suitImage: {fileID: 6168474563181177313} suitImage: {fileID: 3834666193358897927}
loading: {fileID: 5262172002440681221}
--- !u!114 &748755465289565643 --- !u!114 &748755465289565643
MonoBehaviour: MonoBehaviour:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@ -236,7 +250,7 @@ GameObject:
m_Component: m_Component:
- component: {fileID: 104449160465615579} - component: {fileID: 104449160465615579}
- component: {fileID: 1422498389634370991} - component: {fileID: 1422498389634370991}
- component: {fileID: 6168474563181177313} - component: {fileID: 3834666193358897927}
m_Layer: 5 m_Layer: 5
m_Name: SuitImage m_Name: SuitImage
m_TagString: Untagged m_TagString: Untagged
@ -271,7 +285,7 @@ CanvasRenderer:
m_PrefabAsset: {fileID: 0} m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3874408075247954670} m_GameObject: {fileID: 3874408075247954670}
m_CullTransparentMesh: 1 m_CullTransparentMesh: 1
--- !u!114 &6168474563181177313 --- !u!114 &3834666193358897927
MonoBehaviour: MonoBehaviour:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0} m_CorrespondingSourceObject: {fileID: 0}
@ -280,7 +294,7 @@ MonoBehaviour:
m_GameObject: {fileID: 3874408075247954670} m_GameObject: {fileID: 3874408075247954670}
m_Enabled: 1 m_Enabled: 1
m_EditorHideFlags: 0 m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} m_Script: {fileID: 11500000, guid: 1344c3c82d62a2a41a3576d8abb8e3ea, type: 3}
m_Name: m_Name:
m_EditorClassIdentifier: m_EditorClassIdentifier:
m_Material: {fileID: 0} m_Material: {fileID: 0}
@ -291,16 +305,13 @@ MonoBehaviour:
m_OnCullStateChanged: m_OnCullStateChanged:
m_PersistentCalls: m_PersistentCalls:
m_Calls: [] m_Calls: []
m_Sprite: {fileID: 0} m_Texture: {fileID: 0}
m_Type: 0 m_UVRect:
m_PreserveAspect: 0 serializedVersion: 2
m_FillCenter: 1 x: 0
m_FillMethod: 4 y: 0
m_FillAmount: 1 width: 1
m_FillClockwise: 1 height: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
--- !u!1 &4491288937049649531 --- !u!1 &4491288937049649531
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@ -569,6 +580,81 @@ MonoBehaviour:
m_hasFontAssetChanged: 0 m_hasFontAssetChanged: 0
m_baseMaterial: {fileID: 0} m_baseMaterial: {fileID: 0}
m_maskOffset: {x: 0, y: 0, z: 0, w: 0} m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
--- !u!1 &5262172002440681221
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 7097115115093172578}
- component: {fileID: 3151196771925636361}
- component: {fileID: 4446388371920305231}
m_Layer: 5
m_Name: Loading
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &7097115115093172578
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5262172002440681221}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 716527630986831245}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 50, y: 50}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &3151196771925636361
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5262172002440681221}
m_CullTransparentMesh: 1
--- !u!114 &4446388371920305231
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5262172002440681221}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_Sprite: {fileID: 21300000, guid: 96ae92151615e4241b2e95873bbc5ede, type: 3}
m_Type: 0
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
--- !u!1 &6543022936957413842 --- !u!1 &6543022936957413842
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@ -601,13 +687,14 @@ RectTransform:
m_ConstrainProportionsScale: 0 m_ConstrainProportionsScale: 0
m_Children: m_Children:
- {fileID: 104449160465615579} - {fileID: 104449160465615579}
- {fileID: 7097115115093172578}
- {fileID: 6213423518440723368} - {fileID: 6213423518440723368}
m_Father: {fileID: 6212042657398888647} m_Father: {fileID: 6212042657398888647}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0} m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1} m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0} m_AnchoredPosition: {x: 0, y: 4}
m_SizeDelta: {x: 0, y: 0} m_SizeDelta: {x: -10, y: -10}
m_Pivot: {x: 0.5, y: 0.5} m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &493814710637605694 --- !u!222 &493814710637605694
CanvasRenderer: CanvasRenderer:
@ -616,7 +703,7 @@ CanvasRenderer:
m_PrefabInstance: {fileID: 0} m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0} m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6543022936957413842} m_GameObject: {fileID: 6543022936957413842}
m_CullTransparentMesh: 1 m_CullTransparentMesh: 0
--- !u!114 &7330084566650112225 --- !u!114 &7330084566650112225
MonoBehaviour: MonoBehaviour:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@ -646,7 +733,7 @@ MonoBehaviour:
m_FillClockwise: 1 m_FillClockwise: 1
m_FillOrigin: 0 m_FillOrigin: 0
m_UseSpriteMesh: 0 m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 4.5 m_PixelsPerUnitMultiplier: 5.25
--- !u!114 &4532091925091001432 --- !u!114 &4532091925091001432
MonoBehaviour: MonoBehaviour:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 09d8f500ccf67c94eb7b3ce8253b84bf
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: d5833b15817ba024f98834126b306833
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,62 @@
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System;
using System.Linq;
using System.Reflection;
using UnityEditor;
using UnityEngine;
namespace Cysharp.Threading.Tasks.Editor
{
// reflection call of UnityEditor.SplitterGUILayout
internal static class SplitterGUILayout
{
static BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static;
static Lazy<Type> splitterStateType = new Lazy<Type>(() =>
{
var type = typeof(EditorWindow).Assembly.GetTypes().First(x => x.FullName == "UnityEditor.SplitterState");
return type;
});
static Lazy<ConstructorInfo> splitterStateCtor = new Lazy<ConstructorInfo>(() =>
{
var type = splitterStateType.Value;
return type.GetConstructor(flags, null, new Type[] { typeof(float[]), typeof(int[]), typeof(int[]) }, null);
});
static Lazy<Type> splitterGUILayoutType = new Lazy<Type>(() =>
{
var type = typeof(EditorWindow).Assembly.GetTypes().First(x => x.FullName == "UnityEditor.SplitterGUILayout");
return type;
});
static Lazy<MethodInfo> beginVerticalSplit = new Lazy<MethodInfo>(() =>
{
var type = splitterGUILayoutType.Value;
return type.GetMethod("BeginVerticalSplit", flags, null, new Type[] { splitterStateType.Value, typeof(GUILayoutOption[]) }, null);
});
static Lazy<MethodInfo> endVerticalSplit = new Lazy<MethodInfo>(() =>
{
var type = splitterGUILayoutType.Value;
return type.GetMethod("EndVerticalSplit", flags, null, Type.EmptyTypes, null);
});
public static object CreateSplitterState(float[] relativeSizes, int[] minSizes, int[] maxSizes)
{
return splitterStateCtor.Value.Invoke(new object[] { relativeSizes, minSizes, maxSizes });
}
public static void BeginVerticalSplit(object splitterState, params GUILayoutOption[] options)
{
beginVerticalSplit.Value.Invoke(null, new object[] { splitterState, options });
}
public static void EndVerticalSplit()
{
endVerticalSplit.Value.Invoke(null, Type.EmptyTypes);
}
}
}

View File

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

View File

@ -0,0 +1,17 @@
{
"name": "UniTask.Editor",
"references": [
"UniTask"
],
"includePlatforms": [
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": false,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 4129704b5a1a13841ba16f230bf24a57
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,182 @@
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using UnityEngine;
using UnityEditor;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System;
using UnityEditor.IMGUI.Controls;
using Cysharp.Threading.Tasks.Internal;
using System.Text;
using System.Text.RegularExpressions;
namespace Cysharp.Threading.Tasks.Editor
{
public class UniTaskTrackerViewItem : TreeViewItem
{
static Regex removeHref = new Regex("<a href.+>(.+)</a>", RegexOptions.Compiled);
public string TaskType { get; set; }
public string Elapsed { get; set; }
public string Status { get; set; }
string position;
public string Position
{
get { return position; }
set
{
position = value;
PositionFirstLine = GetFirstLine(position);
}
}
public string PositionFirstLine { get; private set; }
static string GetFirstLine(string str)
{
var sb = new StringBuilder();
for (int i = 0; i < str.Length; i++)
{
if (str[i] == '\r' || str[i] == '\n')
{
break;
}
sb.Append(str[i]);
}
return removeHref.Replace(sb.ToString(), "$1");
}
public UniTaskTrackerViewItem(int id) : base(id)
{
}
}
public class UniTaskTrackerTreeView : TreeView
{
const string sortedColumnIndexStateKey = "UniTaskTrackerTreeView_sortedColumnIndex";
public IReadOnlyList<TreeViewItem> CurrentBindingItems;
public UniTaskTrackerTreeView()
: this(new TreeViewState(), new MultiColumnHeader(new MultiColumnHeaderState(new[]
{
new MultiColumnHeaderState.Column() { headerContent = new GUIContent("TaskType"), width = 20},
new MultiColumnHeaderState.Column() { headerContent = new GUIContent("Elapsed"), width = 10},
new MultiColumnHeaderState.Column() { headerContent = new GUIContent("Status"), width = 10},
new MultiColumnHeaderState.Column() { headerContent = new GUIContent("Position")},
})))
{
}
UniTaskTrackerTreeView(TreeViewState state, MultiColumnHeader header)
: base(state, header)
{
rowHeight = 20;
showAlternatingRowBackgrounds = true;
showBorder = true;
header.sortingChanged += Header_sortingChanged;
header.ResizeToFit();
Reload();
header.sortedColumnIndex = SessionState.GetInt(sortedColumnIndexStateKey, 1);
}
public void ReloadAndSort()
{
var currentSelected = this.state.selectedIDs;
Reload();
Header_sortingChanged(this.multiColumnHeader);
this.state.selectedIDs = currentSelected;
}
private void Header_sortingChanged(MultiColumnHeader multiColumnHeader)
{
SessionState.SetInt(sortedColumnIndexStateKey, multiColumnHeader.sortedColumnIndex);
var index = multiColumnHeader.sortedColumnIndex;
var ascending = multiColumnHeader.IsSortedAscending(multiColumnHeader.sortedColumnIndex);
var items = rootItem.children.Cast<UniTaskTrackerViewItem>();
IOrderedEnumerable<UniTaskTrackerViewItem> orderedEnumerable;
switch (index)
{
case 0:
orderedEnumerable = ascending ? items.OrderBy(item => item.TaskType) : items.OrderByDescending(item => item.TaskType);
break;
case 1:
orderedEnumerable = ascending ? items.OrderBy(item => double.Parse(item.Elapsed)) : items.OrderByDescending(item => double.Parse(item.Elapsed));
break;
case 2:
orderedEnumerable = ascending ? items.OrderBy(item => item.Status) : items.OrderByDescending(item => item.Elapsed);
break;
case 3:
orderedEnumerable = ascending ? items.OrderBy(item => item.Position) : items.OrderByDescending(item => item.PositionFirstLine);
break;
default:
throw new ArgumentOutOfRangeException(nameof(index), index, null);
}
CurrentBindingItems = rootItem.children = orderedEnumerable.Cast<TreeViewItem>().ToList();
BuildRows(rootItem);
}
protected override TreeViewItem BuildRoot()
{
var root = new TreeViewItem { depth = -1 };
var children = new List<TreeViewItem>();
TaskTracker.ForEachActiveTask((trackingId, awaiterType, status, created, stackTrace) =>
{
children.Add(new UniTaskTrackerViewItem(trackingId) { TaskType = awaiterType, Status = status.ToString(), Elapsed = (DateTime.UtcNow - created).TotalSeconds.ToString("00.00"), Position = stackTrace });
});
CurrentBindingItems = children;
root.children = CurrentBindingItems as List<TreeViewItem>;
return root;
}
protected override bool CanMultiSelect(TreeViewItem item)
{
return false;
}
protected override void RowGUI(RowGUIArgs args)
{
var item = args.item as UniTaskTrackerViewItem;
for (var visibleColumnIndex = 0; visibleColumnIndex < args.GetNumVisibleColumns(); visibleColumnIndex++)
{
var rect = args.GetCellRect(visibleColumnIndex);
var columnIndex = args.GetColumn(visibleColumnIndex);
var labelStyle = args.selected ? EditorStyles.whiteLabel : EditorStyles.label;
labelStyle.alignment = TextAnchor.MiddleLeft;
switch (columnIndex)
{
case 0:
EditorGUI.LabelField(rect, item.TaskType, labelStyle);
break;
case 1:
EditorGUI.LabelField(rect, item.Elapsed, labelStyle);
break;
case 2:
EditorGUI.LabelField(rect, item.Status, labelStyle);
break;
case 3:
EditorGUI.LabelField(rect, item.PositionFirstLine, labelStyle);
break;
default:
throw new ArgumentOutOfRangeException(nameof(columnIndex), columnIndex, null);
}
}
}
}
}

View File

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

View File

@ -0,0 +1,209 @@
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using UnityEngine;
using UnityEditor;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System;
using UnityEditor.IMGUI.Controls;
using Cysharp.Threading.Tasks.Internal;
namespace Cysharp.Threading.Tasks.Editor
{
public class UniTaskTrackerWindow : EditorWindow
{
static int interval;
static UniTaskTrackerWindow window;
[MenuItem("Window/UniTask Tracker")]
public static void OpenWindow()
{
if (window != null)
{
window.Close();
}
// will called OnEnable(singleton instance will be set).
GetWindow<UniTaskTrackerWindow>("UniTask Tracker").Show();
}
static readonly GUILayoutOption[] EmptyLayoutOption = new GUILayoutOption[0];
UniTaskTrackerTreeView treeView;
object splitterState;
void OnEnable()
{
window = this; // set singleton.
splitterState = SplitterGUILayout.CreateSplitterState(new float[] { 75f, 25f }, new int[] { 32, 32 }, null);
treeView = new UniTaskTrackerTreeView();
TaskTracker.EditorEnableState.EnableAutoReload = EditorPrefs.GetBool(TaskTracker.EnableAutoReloadKey, false);
TaskTracker.EditorEnableState.EnableTracking = EditorPrefs.GetBool(TaskTracker.EnableTrackingKey, false);
TaskTracker.EditorEnableState.EnableStackTrace = EditorPrefs.GetBool(TaskTracker.EnableStackTraceKey, false);
}
void OnGUI()
{
// Head
RenderHeadPanel();
// Splittable
SplitterGUILayout.BeginVerticalSplit(this.splitterState, EmptyLayoutOption);
{
// Column Tabble
RenderTable();
// StackTrace details
RenderDetailsPanel();
}
SplitterGUILayout.EndVerticalSplit();
}
#region HeadPanel
public static bool EnableAutoReload => TaskTracker.EditorEnableState.EnableAutoReload;
public static bool EnableTracking => TaskTracker.EditorEnableState.EnableTracking;
public static bool EnableStackTrace => TaskTracker.EditorEnableState.EnableStackTrace;
static readonly GUIContent EnableAutoReloadHeadContent = EditorGUIUtility.TrTextContent("Enable AutoReload", "Reload automatically.", (Texture)null);
static readonly GUIContent ReloadHeadContent = EditorGUIUtility.TrTextContent("Reload", "Reload View.", (Texture)null);
static readonly GUIContent GCHeadContent = EditorGUIUtility.TrTextContent("GC.Collect", "Invoke GC.Collect.", (Texture)null);
static readonly GUIContent EnableTrackingHeadContent = EditorGUIUtility.TrTextContent("Enable Tracking", "Start to track async/await UniTask. Performance impact: low", (Texture)null);
static readonly GUIContent EnableStackTraceHeadContent = EditorGUIUtility.TrTextContent("Enable StackTrace", "Capture StackTrace when task is started. Performance impact: high", (Texture)null);
// [Enable Tracking] | [Enable StackTrace]
void RenderHeadPanel()
{
EditorGUILayout.BeginVertical(EmptyLayoutOption);
EditorGUILayout.BeginHorizontal(EditorStyles.toolbar, EmptyLayoutOption);
if (GUILayout.Toggle(EnableAutoReload, EnableAutoReloadHeadContent, EditorStyles.toolbarButton, EmptyLayoutOption) != EnableAutoReload)
{
TaskTracker.EditorEnableState.EnableAutoReload = !EnableAutoReload;
}
if (GUILayout.Toggle(EnableTracking, EnableTrackingHeadContent, EditorStyles.toolbarButton, EmptyLayoutOption) != EnableTracking)
{
TaskTracker.EditorEnableState.EnableTracking = !EnableTracking;
}
if (GUILayout.Toggle(EnableStackTrace, EnableStackTraceHeadContent, EditorStyles.toolbarButton, EmptyLayoutOption) != EnableStackTrace)
{
TaskTracker.EditorEnableState.EnableStackTrace = !EnableStackTrace;
}
GUILayout.FlexibleSpace();
if (GUILayout.Button(ReloadHeadContent, EditorStyles.toolbarButton, EmptyLayoutOption))
{
TaskTracker.CheckAndResetDirty();
treeView.ReloadAndSort();
Repaint();
}
if (GUILayout.Button(GCHeadContent, EditorStyles.toolbarButton, EmptyLayoutOption))
{
GC.Collect(0);
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.EndVertical();
}
#endregion
#region TableColumn
Vector2 tableScroll;
GUIStyle tableListStyle;
void RenderTable()
{
if (tableListStyle == null)
{
tableListStyle = new GUIStyle("CN Box");
tableListStyle.margin.top = 0;
tableListStyle.padding.left = 3;
}
EditorGUILayout.BeginVertical(tableListStyle, EmptyLayoutOption);
this.tableScroll = EditorGUILayout.BeginScrollView(this.tableScroll, new GUILayoutOption[]
{
GUILayout.ExpandWidth(true),
GUILayout.MaxWidth(2000f)
});
var controlRect = EditorGUILayout.GetControlRect(new GUILayoutOption[]
{
GUILayout.ExpandHeight(true),
GUILayout.ExpandWidth(true)
});
treeView?.OnGUI(controlRect);
EditorGUILayout.EndScrollView();
EditorGUILayout.EndVertical();
}
private void Update()
{
if (EnableAutoReload)
{
if (interval++ % 120 == 0)
{
if (TaskTracker.CheckAndResetDirty())
{
treeView.ReloadAndSort();
Repaint();
}
}
}
}
#endregion
#region Details
static GUIStyle detailsStyle;
Vector2 detailsScroll;
void RenderDetailsPanel()
{
if (detailsStyle == null)
{
detailsStyle = new GUIStyle("CN Message");
detailsStyle.wordWrap = false;
detailsStyle.stretchHeight = true;
detailsStyle.margin.right = 15;
}
string message = "";
var selected = treeView.state.selectedIDs;
if (selected.Count > 0)
{
var first = selected[0];
var item = treeView.CurrentBindingItems.FirstOrDefault(x => x.id == first) as UniTaskTrackerViewItem;
if (item != null)
{
message = item.Position;
}
}
detailsScroll = EditorGUILayout.BeginScrollView(this.detailsScroll, EmptyLayoutOption);
var vector = detailsStyle.CalcSize(new GUIContent(message));
EditorGUILayout.SelectableLabel(message, detailsStyle, new GUILayoutOption[]
{
GUILayout.ExpandHeight(true),
GUILayout.ExpandWidth(true),
GUILayout.MinWidth(vector.x),
GUILayout.MinHeight(vector.y)
});
EditorGUILayout.EndScrollView();
}
#endregion
}
}

View File

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

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 836c9bdde0d7593438f0a224268896e5
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,245 @@
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System;
using System.Threading;
namespace Cysharp.Threading.Tasks
{
public class AsyncLazy
{
static Action<object> continuation = SetCompletionSource;
Func<UniTask> taskFactory;
UniTaskCompletionSource completionSource;
UniTask.Awaiter awaiter;
object syncLock;
bool initialized;
public AsyncLazy(Func<UniTask> taskFactory)
{
this.taskFactory = taskFactory;
this.completionSource = new UniTaskCompletionSource();
this.syncLock = new object();
this.initialized = false;
}
internal AsyncLazy(UniTask task)
{
this.taskFactory = null;
this.completionSource = new UniTaskCompletionSource();
this.syncLock = null;
this.initialized = true;
var awaiter = task.GetAwaiter();
if (awaiter.IsCompleted)
{
SetCompletionSource(awaiter);
}
else
{
this.awaiter = awaiter;
awaiter.SourceOnCompleted(continuation, this);
}
}
public UniTask Task
{
get
{
EnsureInitialized();
return completionSource.Task;
}
}
public UniTask.Awaiter GetAwaiter() => Task.GetAwaiter();
void EnsureInitialized()
{
if (Volatile.Read(ref initialized))
{
return;
}
EnsureInitializedCore();
}
void EnsureInitializedCore()
{
lock (syncLock)
{
if (!Volatile.Read(ref initialized))
{
var f = Interlocked.Exchange(ref taskFactory, null);
if (f != null)
{
var task = f();
var awaiter = task.GetAwaiter();
if (awaiter.IsCompleted)
{
SetCompletionSource(awaiter);
}
else
{
this.awaiter = awaiter;
awaiter.SourceOnCompleted(continuation, this);
}
Volatile.Write(ref initialized, true);
}
}
}
}
void SetCompletionSource(in UniTask.Awaiter awaiter)
{
try
{
awaiter.GetResult();
completionSource.TrySetResult();
}
catch (Exception ex)
{
completionSource.TrySetException(ex);
}
}
static void SetCompletionSource(object state)
{
var self = (AsyncLazy)state;
try
{
self.awaiter.GetResult();
self.completionSource.TrySetResult();
}
catch (Exception ex)
{
self.completionSource.TrySetException(ex);
}
finally
{
self.awaiter = default;
}
}
}
public class AsyncLazy<T>
{
static Action<object> continuation = SetCompletionSource;
Func<UniTask<T>> taskFactory;
UniTaskCompletionSource<T> completionSource;
UniTask<T>.Awaiter awaiter;
object syncLock;
bool initialized;
public AsyncLazy(Func<UniTask<T>> taskFactory)
{
this.taskFactory = taskFactory;
this.completionSource = new UniTaskCompletionSource<T>();
this.syncLock = new object();
this.initialized = false;
}
internal AsyncLazy(UniTask<T> task)
{
this.taskFactory = null;
this.completionSource = new UniTaskCompletionSource<T>();
this.syncLock = null;
this.initialized = true;
var awaiter = task.GetAwaiter();
if (awaiter.IsCompleted)
{
SetCompletionSource(awaiter);
}
else
{
this.awaiter = awaiter;
awaiter.SourceOnCompleted(continuation, this);
}
}
public UniTask<T> Task
{
get
{
EnsureInitialized();
return completionSource.Task;
}
}
public UniTask<T>.Awaiter GetAwaiter() => Task.GetAwaiter();
void EnsureInitialized()
{
if (Volatile.Read(ref initialized))
{
return;
}
EnsureInitializedCore();
}
void EnsureInitializedCore()
{
lock (syncLock)
{
if (!Volatile.Read(ref initialized))
{
var f = Interlocked.Exchange(ref taskFactory, null);
if (f != null)
{
var task = f();
var awaiter = task.GetAwaiter();
if (awaiter.IsCompleted)
{
SetCompletionSource(awaiter);
}
else
{
this.awaiter = awaiter;
awaiter.SourceOnCompleted(continuation, this);
}
Volatile.Write(ref initialized, true);
}
}
}
}
void SetCompletionSource(in UniTask<T>.Awaiter awaiter)
{
try
{
var result = awaiter.GetResult();
completionSource.TrySetResult(result);
}
catch (Exception ex)
{
completionSource.TrySetException(ex);
}
}
static void SetCompletionSource(object state)
{
var self = (AsyncLazy<T>)state;
try
{
var result = self.awaiter.GetResult();
self.completionSource.TrySetResult(result);
}
catch (Exception ex)
{
self.completionSource.TrySetException(ex);
}
finally
{
self.awaiter = default;
}
}
}
}

View File

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

View File

@ -0,0 +1,644 @@
using System;
using System.Threading;
namespace Cysharp.Threading.Tasks
{
public interface IReadOnlyAsyncReactiveProperty<T> : IUniTaskAsyncEnumerable<T>
{
T Value { get; }
IUniTaskAsyncEnumerable<T> WithoutCurrent();
UniTask<T> WaitAsync(CancellationToken cancellationToken = default);
}
public interface IAsyncReactiveProperty<T> : IReadOnlyAsyncReactiveProperty<T>
{
new T Value { get; set; }
}
[Serializable]
public class AsyncReactiveProperty<T> : IAsyncReactiveProperty<T>, IDisposable
{
TriggerEvent<T> triggerEvent;
#if UNITY_2018_3_OR_NEWER
[UnityEngine.SerializeField]
#endif
T latestValue;
public T Value
{
get
{
return latestValue;
}
set
{
this.latestValue = value;
triggerEvent.SetResult(value);
}
}
public AsyncReactiveProperty(T value)
{
this.latestValue = value;
this.triggerEvent = default;
}
public IUniTaskAsyncEnumerable<T> WithoutCurrent()
{
return new WithoutCurrentEnumerable(this);
}
public IUniTaskAsyncEnumerator<T> GetAsyncEnumerator(CancellationToken cancellationToken)
{
return new Enumerator(this, cancellationToken, true);
}
public void Dispose()
{
triggerEvent.SetCompleted();
}
public static implicit operator T(AsyncReactiveProperty<T> value)
{
return value.Value;
}
public override string ToString()
{
if (isValueType) return latestValue.ToString();
return latestValue?.ToString();
}
public UniTask<T> WaitAsync(CancellationToken cancellationToken = default)
{
return new UniTask<T>(WaitAsyncSource.Create(this, cancellationToken, out var token), token);
}
static bool isValueType;
static AsyncReactiveProperty()
{
isValueType = typeof(T).IsValueType;
}
sealed class WaitAsyncSource : IUniTaskSource<T>, ITriggerHandler<T>, ITaskPoolNode<WaitAsyncSource>
{
static Action<object> cancellationCallback = CancellationCallback;
static TaskPool<WaitAsyncSource> pool;
WaitAsyncSource nextNode;
ref WaitAsyncSource ITaskPoolNode<WaitAsyncSource>.NextNode => ref nextNode;
static WaitAsyncSource()
{
TaskPool.RegisterSizeGetter(typeof(WaitAsyncSource), () => pool.Size);
}
AsyncReactiveProperty<T> parent;
CancellationToken cancellationToken;
CancellationTokenRegistration cancellationTokenRegistration;
UniTaskCompletionSourceCore<T> core;
WaitAsyncSource()
{
}
public static IUniTaskSource<T> Create(AsyncReactiveProperty<T> parent, CancellationToken cancellationToken, out short token)
{
if (cancellationToken.IsCancellationRequested)
{
return AutoResetUniTaskCompletionSource<T>.CreateFromCanceled(cancellationToken, out token);
}
if (!pool.TryPop(out var result))
{
result = new WaitAsyncSource();
}
result.parent = parent;
result.cancellationToken = cancellationToken;
if (cancellationToken.CanBeCanceled)
{
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(cancellationCallback, result);
}
result.parent.triggerEvent.Add(result);
TaskTracker.TrackActiveTask(result, 3);
token = result.core.Version;
return result;
}
bool TryReturn()
{
TaskTracker.RemoveTracking(this);
core.Reset();
cancellationTokenRegistration.Dispose();
cancellationTokenRegistration = default;
parent.triggerEvent.Remove(this);
parent = null;
cancellationToken = default;
return pool.TryPush(this);
}
static void CancellationCallback(object state)
{
var self = (WaitAsyncSource)state;
self.OnCanceled(self.cancellationToken);
}
// IUniTaskSource
public T GetResult(short token)
{
try
{
return core.GetResult(token);
}
finally
{
TryReturn();
}
}
void IUniTaskSource.GetResult(short token)
{
GetResult(token);
}
public void OnCompleted(Action<object> continuation, object state, short token)
{
core.OnCompleted(continuation, state, token);
}
public UniTaskStatus GetStatus(short token)
{
return core.GetStatus(token);
}
public UniTaskStatus UnsafeGetStatus()
{
return core.UnsafeGetStatus();
}
// ITriggerHandler
ITriggerHandler<T> ITriggerHandler<T>.Prev { get; set; }
ITriggerHandler<T> ITriggerHandler<T>.Next { get; set; }
public void OnCanceled(CancellationToken cancellationToken)
{
core.TrySetCanceled(cancellationToken);
}
public void OnCompleted()
{
// Complete as Cancel.
core.TrySetCanceled(CancellationToken.None);
}
public void OnError(Exception ex)
{
core.TrySetException(ex);
}
public void OnNext(T value)
{
core.TrySetResult(value);
}
}
sealed class WithoutCurrentEnumerable : IUniTaskAsyncEnumerable<T>
{
readonly AsyncReactiveProperty<T> parent;
public WithoutCurrentEnumerable(AsyncReactiveProperty<T> parent)
{
this.parent = parent;
}
public IUniTaskAsyncEnumerator<T> GetAsyncEnumerator(CancellationToken cancellationToken = default)
{
return new Enumerator(parent, cancellationToken, false);
}
}
sealed class Enumerator : MoveNextSource, IUniTaskAsyncEnumerator<T>, ITriggerHandler<T>
{
static Action<object> cancellationCallback = CancellationCallback;
readonly AsyncReactiveProperty<T> parent;
readonly CancellationToken cancellationToken;
readonly CancellationTokenRegistration cancellationTokenRegistration;
T value;
bool isDisposed;
bool firstCall;
public Enumerator(AsyncReactiveProperty<T> parent, CancellationToken cancellationToken, bool publishCurrentValue)
{
this.parent = parent;
this.cancellationToken = cancellationToken;
this.firstCall = publishCurrentValue;
parent.triggerEvent.Add(this);
TaskTracker.TrackActiveTask(this, 3);
if (cancellationToken.CanBeCanceled)
{
cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(cancellationCallback, this);
}
}
public T Current => value;
ITriggerHandler<T> ITriggerHandler<T>.Prev { get; set; }
ITriggerHandler<T> ITriggerHandler<T>.Next { get; set; }
public UniTask<bool> MoveNextAsync()
{
// raise latest value on first call.
if (firstCall)
{
firstCall = false;
value = parent.Value;
return CompletedTasks.True;
}
completionSource.Reset();
return new UniTask<bool>(this, completionSource.Version);
}
public UniTask DisposeAsync()
{
if (!isDisposed)
{
isDisposed = true;
TaskTracker.RemoveTracking(this);
completionSource.TrySetCanceled(cancellationToken);
parent.triggerEvent.Remove(this);
}
return default;
}
public void OnNext(T value)
{
this.value = value;
completionSource.TrySetResult(true);
}
public void OnCanceled(CancellationToken cancellationToken)
{
DisposeAsync().Forget();
}
public void OnCompleted()
{
completionSource.TrySetResult(false);
}
public void OnError(Exception ex)
{
completionSource.TrySetException(ex);
}
static void CancellationCallback(object state)
{
var self = (Enumerator)state;
self.DisposeAsync().Forget();
}
}
}
public class ReadOnlyAsyncReactiveProperty<T> : IReadOnlyAsyncReactiveProperty<T>, IDisposable
{
TriggerEvent<T> triggerEvent;
T latestValue;
IUniTaskAsyncEnumerator<T> enumerator;
public T Value
{
get
{
return latestValue;
}
}
public ReadOnlyAsyncReactiveProperty(T initialValue, IUniTaskAsyncEnumerable<T> source, CancellationToken cancellationToken)
{
latestValue = initialValue;
ConsumeEnumerator(source, cancellationToken).Forget();
}
public ReadOnlyAsyncReactiveProperty(IUniTaskAsyncEnumerable<T> source, CancellationToken cancellationToken)
{
ConsumeEnumerator(source, cancellationToken).Forget();
}
async UniTaskVoid ConsumeEnumerator(IUniTaskAsyncEnumerable<T> source, CancellationToken cancellationToken)
{
enumerator = source.GetAsyncEnumerator(cancellationToken);
try
{
while (await enumerator.MoveNextAsync())
{
var value = enumerator.Current;
this.latestValue = value;
triggerEvent.SetResult(value);
}
}
finally
{
await enumerator.DisposeAsync();
enumerator = null;
}
}
public IUniTaskAsyncEnumerable<T> WithoutCurrent()
{
return new WithoutCurrentEnumerable(this);
}
public IUniTaskAsyncEnumerator<T> GetAsyncEnumerator(CancellationToken cancellationToken)
{
return new Enumerator(this, cancellationToken, true);
}
public void Dispose()
{
if (enumerator != null)
{
enumerator.DisposeAsync().Forget();
}
triggerEvent.SetCompleted();
}
public static implicit operator T(ReadOnlyAsyncReactiveProperty<T> value)
{
return value.Value;
}
public override string ToString()
{
if (isValueType) return latestValue.ToString();
return latestValue?.ToString();
}
public UniTask<T> WaitAsync(CancellationToken cancellationToken = default)
{
return new UniTask<T>(WaitAsyncSource.Create(this, cancellationToken, out var token), token);
}
static bool isValueType;
static ReadOnlyAsyncReactiveProperty()
{
isValueType = typeof(T).IsValueType;
}
sealed class WaitAsyncSource : IUniTaskSource<T>, ITriggerHandler<T>, ITaskPoolNode<WaitAsyncSource>
{
static Action<object> cancellationCallback = CancellationCallback;
static TaskPool<WaitAsyncSource> pool;
WaitAsyncSource nextNode;
ref WaitAsyncSource ITaskPoolNode<WaitAsyncSource>.NextNode => ref nextNode;
static WaitAsyncSource()
{
TaskPool.RegisterSizeGetter(typeof(WaitAsyncSource), () => pool.Size);
}
ReadOnlyAsyncReactiveProperty<T> parent;
CancellationToken cancellationToken;
CancellationTokenRegistration cancellationTokenRegistration;
UniTaskCompletionSourceCore<T> core;
WaitAsyncSource()
{
}
public static IUniTaskSource<T> Create(ReadOnlyAsyncReactiveProperty<T> parent, CancellationToken cancellationToken, out short token)
{
if (cancellationToken.IsCancellationRequested)
{
return AutoResetUniTaskCompletionSource<T>.CreateFromCanceled(cancellationToken, out token);
}
if (!pool.TryPop(out var result))
{
result = new WaitAsyncSource();
}
result.parent = parent;
result.cancellationToken = cancellationToken;
if (cancellationToken.CanBeCanceled)
{
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(cancellationCallback, result);
}
result.parent.triggerEvent.Add(result);
TaskTracker.TrackActiveTask(result, 3);
token = result.core.Version;
return result;
}
bool TryReturn()
{
TaskTracker.RemoveTracking(this);
core.Reset();
cancellationTokenRegistration.Dispose();
cancellationTokenRegistration = default;
parent.triggerEvent.Remove(this);
parent = null;
cancellationToken = default;
return pool.TryPush(this);
}
static void CancellationCallback(object state)
{
var self = (WaitAsyncSource)state;
self.OnCanceled(self.cancellationToken);
}
// IUniTaskSource
public T GetResult(short token)
{
try
{
return core.GetResult(token);
}
finally
{
TryReturn();
}
}
void IUniTaskSource.GetResult(short token)
{
GetResult(token);
}
public void OnCompleted(Action<object> continuation, object state, short token)
{
core.OnCompleted(continuation, state, token);
}
public UniTaskStatus GetStatus(short token)
{
return core.GetStatus(token);
}
public UniTaskStatus UnsafeGetStatus()
{
return core.UnsafeGetStatus();
}
// ITriggerHandler
ITriggerHandler<T> ITriggerHandler<T>.Prev { get; set; }
ITriggerHandler<T> ITriggerHandler<T>.Next { get; set; }
public void OnCanceled(CancellationToken cancellationToken)
{
core.TrySetCanceled(cancellationToken);
}
public void OnCompleted()
{
// Complete as Cancel.
core.TrySetCanceled(CancellationToken.None);
}
public void OnError(Exception ex)
{
core.TrySetException(ex);
}
public void OnNext(T value)
{
core.TrySetResult(value);
}
}
sealed class WithoutCurrentEnumerable : IUniTaskAsyncEnumerable<T>
{
readonly ReadOnlyAsyncReactiveProperty<T> parent;
public WithoutCurrentEnumerable(ReadOnlyAsyncReactiveProperty<T> parent)
{
this.parent = parent;
}
public IUniTaskAsyncEnumerator<T> GetAsyncEnumerator(CancellationToken cancellationToken = default)
{
return new Enumerator(parent, cancellationToken, false);
}
}
sealed class Enumerator : MoveNextSource, IUniTaskAsyncEnumerator<T>, ITriggerHandler<T>
{
static Action<object> cancellationCallback = CancellationCallback;
readonly ReadOnlyAsyncReactiveProperty<T> parent;
readonly CancellationToken cancellationToken;
readonly CancellationTokenRegistration cancellationTokenRegistration;
T value;
bool isDisposed;
bool firstCall;
public Enumerator(ReadOnlyAsyncReactiveProperty<T> parent, CancellationToken cancellationToken, bool publishCurrentValue)
{
this.parent = parent;
this.cancellationToken = cancellationToken;
this.firstCall = publishCurrentValue;
parent.triggerEvent.Add(this);
TaskTracker.TrackActiveTask(this, 3);
if (cancellationToken.CanBeCanceled)
{
cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(cancellationCallback, this);
}
}
public T Current => value;
ITriggerHandler<T> ITriggerHandler<T>.Prev { get; set; }
ITriggerHandler<T> ITriggerHandler<T>.Next { get; set; }
public UniTask<bool> MoveNextAsync()
{
// raise latest value on first call.
if (firstCall)
{
firstCall = false;
value = parent.Value;
return CompletedTasks.True;
}
completionSource.Reset();
return new UniTask<bool>(this, completionSource.Version);
}
public UniTask DisposeAsync()
{
if (!isDisposed)
{
isDisposed = true;
TaskTracker.RemoveTracking(this);
completionSource.TrySetCanceled(cancellationToken);
parent.triggerEvent.Remove(this);
}
return default;
}
public void OnNext(T value)
{
this.value = value;
completionSource.TrySetResult(true);
}
public void OnCanceled(CancellationToken cancellationToken)
{
DisposeAsync().Forget();
}
public void OnCompleted()
{
completionSource.TrySetResult(false);
}
public void OnError(Exception ex)
{
completionSource.TrySetException(ex);
}
static void CancellationCallback(object state)
{
var self = (Enumerator)state;
self.DisposeAsync().Forget();
}
}
}
public static class StateExtensions
{
public static ReadOnlyAsyncReactiveProperty<T> ToReadOnlyAsyncReactiveProperty<T>(this IUniTaskAsyncEnumerable<T> source, CancellationToken cancellationToken)
{
return new ReadOnlyAsyncReactiveProperty<T>(source, cancellationToken);
}
public static ReadOnlyAsyncReactiveProperty<T> ToReadOnlyAsyncReactiveProperty<T>(this IUniTaskAsyncEnumerable<T> source, T initialValue, CancellationToken cancellationToken)
{
return new ReadOnlyAsyncReactiveProperty<T>(initialValue, source, cancellationToken);
}
}
}

View File

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

View File

@ -0,0 +1,26 @@
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or
using System;
namespace Cysharp.Threading.Tasks
{
public readonly struct AsyncUnit : IEquatable<AsyncUnit>
{
public static readonly AsyncUnit Default = new AsyncUnit();
public override int GetHashCode()
{
return 0;
}
public bool Equals(AsyncUnit other)
{
return true;
}
public override string ToString()
{
return "()";
}
}
}

View File

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

View File

@ -0,0 +1,23 @@
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System.Collections.Generic;
using System.Threading;
namespace Cysharp.Threading.Tasks
{
public class CancellationTokenEqualityComparer : IEqualityComparer<CancellationToken>
{
public static readonly IEqualityComparer<CancellationToken> Default = new CancellationTokenEqualityComparer();
public bool Equals(CancellationToken x, CancellationToken y)
{
return x.Equals(y);
}
public int GetHashCode(CancellationToken obj)
{
return obj.GetHashCode();
}
}
}

View File

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

View File

@ -0,0 +1,182 @@
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System;
using System.Runtime.CompilerServices;
using System.Threading;
namespace Cysharp.Threading.Tasks
{
public static class CancellationTokenExtensions
{
static readonly Action<object> cancellationTokenCallback = Callback;
static readonly Action<object> disposeCallback = DisposeCallback;
public static CancellationToken ToCancellationToken(this UniTask task)
{
var cts = new CancellationTokenSource();
ToCancellationTokenCore(task, cts).Forget();
return cts.Token;
}
public static CancellationToken ToCancellationToken(this UniTask task, CancellationToken linkToken)
{
if (linkToken.IsCancellationRequested)
{
return linkToken;
}
if (!linkToken.CanBeCanceled)
{
return ToCancellationToken(task);
}
var cts = CancellationTokenSource.CreateLinkedTokenSource(linkToken);
ToCancellationTokenCore(task, cts).Forget();
return cts.Token;
}
public static CancellationToken ToCancellationToken<T>(this UniTask<T> task)
{
return ToCancellationToken(task.AsUniTask());
}
public static CancellationToken ToCancellationToken<T>(this UniTask<T> task, CancellationToken linkToken)
{
return ToCancellationToken(task.AsUniTask(), linkToken);
}
static async UniTaskVoid ToCancellationTokenCore(UniTask task, CancellationTokenSource cts)
{
try
{
await task;
}
catch (Exception ex)
{
UniTaskScheduler.PublishUnobservedTaskException(ex);
}
cts.Cancel();
cts.Dispose();
}
public static (UniTask, CancellationTokenRegistration) ToUniTask(this CancellationToken cancellationToken)
{
if (cancellationToken.IsCancellationRequested)
{
return (UniTask.FromCanceled(cancellationToken), default(CancellationTokenRegistration));
}
var promise = new UniTaskCompletionSource();
return (promise.Task, cancellationToken.RegisterWithoutCaptureExecutionContext(cancellationTokenCallback, promise));
}
static void Callback(object state)
{
var promise = (UniTaskCompletionSource)state;
promise.TrySetResult();
}
public static CancellationTokenAwaitable WaitUntilCanceled(this CancellationToken cancellationToken)
{
return new CancellationTokenAwaitable(cancellationToken);
}
public static CancellationTokenRegistration RegisterWithoutCaptureExecutionContext(this CancellationToken cancellationToken, Action callback)
{
var restoreFlow = false;
if (!ExecutionContext.IsFlowSuppressed())
{
ExecutionContext.SuppressFlow();
restoreFlow = true;
}
try
{
return cancellationToken.Register(callback, false);
}
finally
{
if (restoreFlow)
{
ExecutionContext.RestoreFlow();
}
}
}
public static CancellationTokenRegistration RegisterWithoutCaptureExecutionContext(this CancellationToken cancellationToken, Action<object> callback, object state)
{
var restoreFlow = false;
if (!ExecutionContext.IsFlowSuppressed())
{
ExecutionContext.SuppressFlow();
restoreFlow = true;
}
try
{
return cancellationToken.Register(callback, state, false);
}
finally
{
if (restoreFlow)
{
ExecutionContext.RestoreFlow();
}
}
}
public static CancellationTokenRegistration AddTo(this IDisposable disposable, CancellationToken cancellationToken)
{
return cancellationToken.RegisterWithoutCaptureExecutionContext(disposeCallback, disposable);
}
static void DisposeCallback(object state)
{
var d = (IDisposable)state;
d.Dispose();
}
}
public struct CancellationTokenAwaitable
{
CancellationToken cancellationToken;
public CancellationTokenAwaitable(CancellationToken cancellationToken)
{
this.cancellationToken = cancellationToken;
}
public Awaiter GetAwaiter()
{
return new Awaiter(cancellationToken);
}
public struct Awaiter : ICriticalNotifyCompletion
{
CancellationToken cancellationToken;
public Awaiter(CancellationToken cancellationToken)
{
this.cancellationToken = cancellationToken;
}
public bool IsCompleted => !cancellationToken.CanBeCanceled || cancellationToken.IsCancellationRequested;
public void GetResult()
{
}
public void OnCompleted(Action continuation)
{
UnsafeOnCompleted(continuation);
}
public void UnsafeOnCompleted(Action continuation)
{
cancellationToken.RegisterWithoutCaptureExecutionContext(continuation);
}
}
}
}

View File

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

View File

@ -0,0 +1,44 @@
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System.Threading;
using UnityEngine;
using Cysharp.Threading.Tasks.Triggers;
using System;
using Cysharp.Threading.Tasks.Internal;
namespace Cysharp.Threading.Tasks
{
public static partial class CancellationTokenSourceExtensions
{
readonly static Action<object> CancelCancellationTokenSourceStateDelegate = new Action<object>(CancelCancellationTokenSourceState);
static void CancelCancellationTokenSourceState(object state)
{
var cts = (CancellationTokenSource)state;
cts.Cancel();
}
public static IDisposable CancelAfterSlim(this CancellationTokenSource cts, int millisecondsDelay, DelayType delayType = DelayType.DeltaTime, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update)
{
return CancelAfterSlim(cts, TimeSpan.FromMilliseconds(millisecondsDelay), delayType, delayTiming);
}
public static IDisposable CancelAfterSlim(this CancellationTokenSource cts, TimeSpan delayTimeSpan, DelayType delayType = DelayType.DeltaTime, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update)
{
return PlayerLoopTimer.StartNew(delayTimeSpan, false, delayType, delayTiming, cts.Token, CancelCancellationTokenSourceStateDelegate, cts);
}
public static void RegisterRaiseCancelOnDestroy(this CancellationTokenSource cts, Component component)
{
RegisterRaiseCancelOnDestroy(cts, component.gameObject);
}
public static void RegisterRaiseCancelOnDestroy(this CancellationTokenSource cts, GameObject gameObject)
{
var trigger = gameObject.GetAsyncDestroyTrigger();
trigger.CancellationToken.RegisterWithoutCaptureExecutionContext(CancelCancellationTokenSourceStateDelegate, cts);
}
}
}

View File

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

View File

@ -0,0 +1,450 @@
using System;
using System.Collections.Generic;
using System.Threading;
namespace Cysharp.Threading.Tasks
{
public static class Channel
{
public static Channel<T> CreateSingleConsumerUnbounded<T>()
{
return new SingleConsumerUnboundedChannel<T>();
}
}
public abstract class Channel<TWrite, TRead>
{
public ChannelReader<TRead> Reader { get; protected set; }
public ChannelWriter<TWrite> Writer { get; protected set; }
public static implicit operator ChannelReader<TRead>(Channel<TWrite, TRead> channel) => channel.Reader;
public static implicit operator ChannelWriter<TWrite>(Channel<TWrite, TRead> channel) => channel.Writer;
}
public abstract class Channel<T> : Channel<T, T>
{
}
public abstract class ChannelReader<T>
{
public abstract bool TryRead(out T item);
public abstract UniTask<bool> WaitToReadAsync(CancellationToken cancellationToken = default(CancellationToken));
public abstract UniTask Completion { get; }
public virtual UniTask<T> ReadAsync(CancellationToken cancellationToken = default(CancellationToken))
{
if (this.TryRead(out var item))
{
return UniTask.FromResult(item);
}
return ReadAsyncCore(cancellationToken);
}
async UniTask<T> ReadAsyncCore(CancellationToken cancellationToken = default(CancellationToken))
{
if (await WaitToReadAsync(cancellationToken))
{
if (TryRead(out var item))
{
return item;
}
}
throw new ChannelClosedException();
}
public abstract IUniTaskAsyncEnumerable<T> ReadAllAsync(CancellationToken cancellationToken = default(CancellationToken));
}
public abstract class ChannelWriter<T>
{
public abstract bool TryWrite(T item);
public abstract bool TryComplete(Exception error = null);
public void Complete(Exception error = null)
{
if (!TryComplete(error))
{
throw new ChannelClosedException();
}
}
}
public partial class ChannelClosedException : InvalidOperationException
{
public ChannelClosedException() :
base("Channel is already closed.")
{ }
public ChannelClosedException(string message) : base(message) { }
public ChannelClosedException(Exception innerException) :
base("Channel is already closed", innerException)
{ }
public ChannelClosedException(string message, Exception innerException) : base(message, innerException) { }
}
internal class SingleConsumerUnboundedChannel<T> : Channel<T>
{
readonly Queue<T> items;
readonly SingleConsumerUnboundedChannelReader readerSource;
UniTaskCompletionSource completedTaskSource;
UniTask completedTask;
Exception completionError;
bool closed;
public SingleConsumerUnboundedChannel()
{
items = new Queue<T>();
Writer = new SingleConsumerUnboundedChannelWriter(this);
readerSource = new SingleConsumerUnboundedChannelReader(this);
Reader = readerSource;
}
sealed class SingleConsumerUnboundedChannelWriter : ChannelWriter<T>
{
readonly SingleConsumerUnboundedChannel<T> parent;
public SingleConsumerUnboundedChannelWriter(SingleConsumerUnboundedChannel<T> parent)
{
this.parent = parent;
}
public override bool TryWrite(T item)
{
bool waiting;
lock (parent.items)
{
if (parent.closed) return false;
parent.items.Enqueue(item);
waiting = parent.readerSource.isWaiting;
}
if (waiting)
{
parent.readerSource.SingalContinuation();
}
return true;
}
public override bool TryComplete(Exception error = null)
{
bool waiting;
lock (parent.items)
{
if (parent.closed) return false;
parent.closed = true;
waiting = parent.readerSource.isWaiting;
if (parent.items.Count == 0)
{
if (error == null)
{
if (parent.completedTaskSource != null)
{
parent.completedTaskSource.TrySetResult();
}
else
{
parent.completedTask = UniTask.CompletedTask;
}
}
else
{
if (parent.completedTaskSource != null)
{
parent.completedTaskSource.TrySetException(error);
}
else
{
parent.completedTask = UniTask.FromException(error);
}
}
if (waiting)
{
parent.readerSource.SingalCompleted(error);
}
}
parent.completionError = error;
}
return true;
}
}
sealed class SingleConsumerUnboundedChannelReader : ChannelReader<T>, IUniTaskSource<bool>
{
readonly Action<object> CancellationCallbackDelegate = CancellationCallback;
readonly SingleConsumerUnboundedChannel<T> parent;
CancellationToken cancellationToken;
CancellationTokenRegistration cancellationTokenRegistration;
UniTaskCompletionSourceCore<bool> core;
internal bool isWaiting;
public SingleConsumerUnboundedChannelReader(SingleConsumerUnboundedChannel<T> parent)
{
this.parent = parent;
TaskTracker.TrackActiveTask(this, 4);
}
public override UniTask Completion
{
get
{
if (parent.completedTaskSource != null) return parent.completedTaskSource.Task;
if (parent.closed)
{
return parent.completedTask;
}
parent.completedTaskSource = new UniTaskCompletionSource();
return parent.completedTaskSource.Task;
}
}
public override bool TryRead(out T item)
{
lock (parent.items)
{
if (parent.items.Count != 0)
{
item = parent.items.Dequeue();
// complete when all value was consumed.
if (parent.closed && parent.items.Count == 0)
{
if (parent.completionError != null)
{
if (parent.completedTaskSource != null)
{
parent.completedTaskSource.TrySetException(parent.completionError);
}
else
{
parent.completedTask = UniTask.FromException(parent.completionError);
}
}
else
{
if (parent.completedTaskSource != null)
{
parent.completedTaskSource.TrySetResult();
}
else
{
parent.completedTask = UniTask.CompletedTask;
}
}
}
}
else
{
item = default;
return false;
}
}
return true;
}
public override UniTask<bool> WaitToReadAsync(CancellationToken cancellationToken)
{
if (cancellationToken.IsCancellationRequested)
{
return UniTask.FromCanceled<bool>(cancellationToken);
}
lock (parent.items)
{
if (parent.items.Count != 0)
{
return CompletedTasks.True;
}
if (parent.closed)
{
if (parent.completionError == null)
{
return CompletedTasks.False;
}
else
{
return UniTask.FromException<bool>(parent.completionError);
}
}
cancellationTokenRegistration.Dispose();
core.Reset();
isWaiting = true;
this.cancellationToken = cancellationToken;
if (this.cancellationToken.CanBeCanceled)
{
cancellationTokenRegistration = this.cancellationToken.RegisterWithoutCaptureExecutionContext(CancellationCallbackDelegate, this);
}
return new UniTask<bool>(this, core.Version);
}
}
public void SingalContinuation()
{
core.TrySetResult(true);
}
public void SingalCancellation(CancellationToken cancellationToken)
{
TaskTracker.RemoveTracking(this);
core.TrySetCanceled(cancellationToken);
}
public void SingalCompleted(Exception error)
{
if (error != null)
{
TaskTracker.RemoveTracking(this);
core.TrySetException(error);
}
else
{
TaskTracker.RemoveTracking(this);
core.TrySetResult(false);
}
}
public override IUniTaskAsyncEnumerable<T> ReadAllAsync(CancellationToken cancellationToken = default)
{
return new ReadAllAsyncEnumerable(this, cancellationToken);
}
bool IUniTaskSource<bool>.GetResult(short token)
{
return core.GetResult(token);
}
void IUniTaskSource.GetResult(short token)
{
core.GetResult(token);
}
UniTaskStatus IUniTaskSource.GetStatus(short token)
{
return core.GetStatus(token);
}
void IUniTaskSource.OnCompleted(Action<object> continuation, object state, short token)
{
core.OnCompleted(continuation, state, token);
}
UniTaskStatus IUniTaskSource.UnsafeGetStatus()
{
return core.UnsafeGetStatus();
}
static void CancellationCallback(object state)
{
var self = (SingleConsumerUnboundedChannelReader)state;
self.SingalCancellation(self.cancellationToken);
}
sealed class ReadAllAsyncEnumerable : IUniTaskAsyncEnumerable<T>, IUniTaskAsyncEnumerator<T>
{
readonly Action<object> CancellationCallback1Delegate = CancellationCallback1;
readonly Action<object> CancellationCallback2Delegate = CancellationCallback2;
readonly SingleConsumerUnboundedChannelReader parent;
CancellationToken cancellationToken1;
CancellationToken cancellationToken2;
CancellationTokenRegistration cancellationTokenRegistration1;
CancellationTokenRegistration cancellationTokenRegistration2;
T current;
bool cacheValue;
bool running;
public ReadAllAsyncEnumerable(SingleConsumerUnboundedChannelReader parent, CancellationToken cancellationToken)
{
this.parent = parent;
this.cancellationToken1 = cancellationToken;
}
public IUniTaskAsyncEnumerator<T> GetAsyncEnumerator(CancellationToken cancellationToken = default)
{
if (running)
{
throw new InvalidOperationException("Enumerator is already running, does not allow call GetAsyncEnumerator twice.");
}
if (this.cancellationToken1 != cancellationToken)
{
this.cancellationToken2 = cancellationToken;
}
if (this.cancellationToken1.CanBeCanceled)
{
this.cancellationTokenRegistration1 = this.cancellationToken1.RegisterWithoutCaptureExecutionContext(CancellationCallback1Delegate, this);
}
if (this.cancellationToken2.CanBeCanceled)
{
this.cancellationTokenRegistration2 = this.cancellationToken2.RegisterWithoutCaptureExecutionContext(CancellationCallback2Delegate, this);
}
running = true;
return this;
}
public T Current
{
get
{
if (cacheValue)
{
return current;
}
parent.TryRead(out current);
return current;
}
}
public UniTask<bool> MoveNextAsync()
{
cacheValue = false;
return parent.WaitToReadAsync(CancellationToken.None); // ok to use None, registered in ctor.
}
public UniTask DisposeAsync()
{
cancellationTokenRegistration1.Dispose();
cancellationTokenRegistration2.Dispose();
return default;
}
static void CancellationCallback1(object state)
{
var self = (ReadAllAsyncEnumerable)state;
self.parent.SingalCancellation(self.cancellationToken1);
}
static void CancellationCallback2(object state)
{
var self = (ReadAllAsyncEnumerable)state;
self.parent.SingalCancellation(self.cancellationToken2);
}
}
}
}
}

View File

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

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 18a8e863d94b80f4d874fc7e5098f845
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,17 @@

#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
#pragma warning disable CS0436
namespace System.Runtime.CompilerServices
{
internal sealed class AsyncMethodBuilderAttribute : Attribute
{
public Type BuilderType { get; }
public AsyncMethodBuilderAttribute(Type builderType)
{
BuilderType = builderType;
}
}
}

View File

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

View File

@ -0,0 +1,269 @@

#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security;
namespace Cysharp.Threading.Tasks.CompilerServices
{
[StructLayout(LayoutKind.Auto)]
public struct AsyncUniTaskMethodBuilder
{
IStateMachineRunnerPromise runnerPromise;
Exception ex;
// 1. Static Create method.
[DebuggerHidden]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static AsyncUniTaskMethodBuilder Create()
{
return default;
}
// 2. TaskLike Task property.
public UniTask Task
{
[DebuggerHidden]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
if (runnerPromise != null)
{
return runnerPromise.Task;
}
else if (ex != null)
{
return UniTask.FromException(ex);
}
else
{
return UniTask.CompletedTask;
}
}
}
// 3. SetException
[DebuggerHidden]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SetException(Exception exception)
{
if (runnerPromise == null)
{
ex = exception;
}
else
{
runnerPromise.SetException(exception);
}
}
// 4. SetResult
[DebuggerHidden]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SetResult()
{
if (runnerPromise != null)
{
runnerPromise.SetResult();
}
}
// 5. AwaitOnCompleted
[DebuggerHidden]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
where TAwaiter : INotifyCompletion
where TStateMachine : IAsyncStateMachine
{
if (runnerPromise == null)
{
AsyncUniTask<TStateMachine>.SetStateMachine(ref stateMachine, ref runnerPromise);
}
awaiter.OnCompleted(runnerPromise.MoveNext);
}
// 6. AwaitUnsafeOnCompleted
[DebuggerHidden]
[SecuritySafeCritical]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
where TAwaiter : ICriticalNotifyCompletion
where TStateMachine : IAsyncStateMachine
{
if (runnerPromise == null)
{
AsyncUniTask<TStateMachine>.SetStateMachine(ref stateMachine, ref runnerPromise);
}
awaiter.UnsafeOnCompleted(runnerPromise.MoveNext);
}
// 7. Start
[DebuggerHidden]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Start<TStateMachine>(ref TStateMachine stateMachine)
where TStateMachine : IAsyncStateMachine
{
stateMachine.MoveNext();
}
// 8. SetStateMachine
[DebuggerHidden]
public void SetStateMachine(IAsyncStateMachine stateMachine)
{
// don't use boxed stateMachine.
}
#if DEBUG || !UNITY_2018_3_OR_NEWER
// Important for IDE debugger.
object debuggingId;
private object ObjectIdForDebugger
{
get
{
if (debuggingId == null)
{
debuggingId = new object();
}
return debuggingId;
}
}
#endif
}
[StructLayout(LayoutKind.Auto)]
public struct AsyncUniTaskMethodBuilder<T>
{
IStateMachineRunnerPromise<T> runnerPromise;
Exception ex;
T result;
// 1. Static Create method.
[DebuggerHidden]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static AsyncUniTaskMethodBuilder<T> Create()
{
return default;
}
// 2. TaskLike Task property.
public UniTask<T> Task
{
[DebuggerHidden]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
if (runnerPromise != null)
{
return runnerPromise.Task;
}
else if (ex != null)
{
return UniTask.FromException<T>(ex);
}
else
{
return UniTask.FromResult(result);
}
}
}
// 3. SetException
[DebuggerHidden]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SetException(Exception exception)
{
if (runnerPromise == null)
{
ex = exception;
}
else
{
runnerPromise.SetException(exception);
}
}
// 4. SetResult
[DebuggerHidden]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SetResult(T result)
{
if (runnerPromise == null)
{
this.result = result;
}
else
{
runnerPromise.SetResult(result);
}
}
// 5. AwaitOnCompleted
[DebuggerHidden]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
where TAwaiter : INotifyCompletion
where TStateMachine : IAsyncStateMachine
{
if (runnerPromise == null)
{
AsyncUniTask<TStateMachine, T>.SetStateMachine(ref stateMachine, ref runnerPromise);
}
awaiter.OnCompleted(runnerPromise.MoveNext);
}
// 6. AwaitUnsafeOnCompleted
[DebuggerHidden]
[SecuritySafeCritical]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
where TAwaiter : ICriticalNotifyCompletion
where TStateMachine : IAsyncStateMachine
{
if (runnerPromise == null)
{
AsyncUniTask<TStateMachine, T>.SetStateMachine(ref stateMachine, ref runnerPromise);
}
awaiter.UnsafeOnCompleted(runnerPromise.MoveNext);
}
// 7. Start
[DebuggerHidden]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Start<TStateMachine>(ref TStateMachine stateMachine)
where TStateMachine : IAsyncStateMachine
{
stateMachine.MoveNext();
}
// 8. SetStateMachine
[DebuggerHidden]
public void SetStateMachine(IAsyncStateMachine stateMachine)
{
// don't use boxed stateMachine.
}
#if DEBUG || !UNITY_2018_3_OR_NEWER
// Important for IDE debugger.
object debuggingId;
private object ObjectIdForDebugger
{
get
{
if (debuggingId == null)
{
debuggingId = new object();
}
return debuggingId;
}
}
#endif
}
}

View File

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

View File

@ -0,0 +1,137 @@

#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security;
namespace Cysharp.Threading.Tasks.CompilerServices
{
[StructLayout(LayoutKind.Auto)]
public struct AsyncUniTaskVoidMethodBuilder
{
IStateMachineRunner runner;
// 1. Static Create method.
[DebuggerHidden]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static AsyncUniTaskVoidMethodBuilder Create()
{
return default;
}
// 2. TaskLike Task property(void)
public UniTaskVoid Task
{
[DebuggerHidden]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
return default;
}
}
// 3. SetException
[DebuggerHidden]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SetException(Exception exception)
{
// runner is finished, return first.
if (runner != null)
{
#if ENABLE_IL2CPP
// workaround for IL2CPP bug.
PlayerLoopHelper.AddContinuation(PlayerLoopTiming.LastPostLateUpdate, runner.ReturnAction);
#else
runner.Return();
#endif
runner = null;
}
UniTaskScheduler.PublishUnobservedTaskException(exception);
}
// 4. SetResult
[DebuggerHidden]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SetResult()
{
// runner is finished, return.
if (runner != null)
{
#if ENABLE_IL2CPP
// workaround for IL2CPP bug.
PlayerLoopHelper.AddContinuation(PlayerLoopTiming.LastPostLateUpdate, runner.ReturnAction);
#else
runner.Return();
#endif
runner = null;
}
}
// 5. AwaitOnCompleted
[DebuggerHidden]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
where TAwaiter : INotifyCompletion
where TStateMachine : IAsyncStateMachine
{
if (runner == null)
{
AsyncUniTaskVoid<TStateMachine>.SetStateMachine(ref stateMachine, ref runner);
}
awaiter.OnCompleted(runner.MoveNext);
}
// 6. AwaitUnsafeOnCompleted
[DebuggerHidden]
[SecuritySafeCritical]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
where TAwaiter : ICriticalNotifyCompletion
where TStateMachine : IAsyncStateMachine
{
if (runner == null)
{
AsyncUniTaskVoid<TStateMachine>.SetStateMachine(ref stateMachine, ref runner);
}
awaiter.UnsafeOnCompleted(runner.MoveNext);
}
// 7. Start
[DebuggerHidden]
public void Start<TStateMachine>(ref TStateMachine stateMachine)
where TStateMachine : IAsyncStateMachine
{
stateMachine.MoveNext();
}
// 8. SetStateMachine
[DebuggerHidden]
public void SetStateMachine(IAsyncStateMachine stateMachine)
{
// don't use boxed stateMachine.
}
#if DEBUG || !UNITY_2018_3_OR_NEWER
// Important for IDE debugger.
object debuggingId;
private object ObjectIdForDebugger
{
get
{
if (debuggingId == null)
{
debuggingId = new object();
}
return debuggingId;
}
}
#endif
}
}

View File

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

View File

@ -0,0 +1,380 @@
#pragma warning disable CS1591
using Cysharp.Threading.Tasks.Internal;
using System;
using System.Linq;
using System.Diagnostics;
using System.Runtime.CompilerServices;
namespace Cysharp.Threading.Tasks.CompilerServices
{
// #ENABLE_IL2CPP in this file is to avoid bug of IL2CPP VM.
// Issue is tracked on https://issuetracker.unity3d.com/issues/il2cpp-incorrect-results-when-calling-a-method-from-outside-class-in-a-struct
// but currently it is labeled `Won't Fix`.
internal interface IStateMachineRunner
{
Action MoveNext { get; }
void Return();
#if ENABLE_IL2CPP
Action ReturnAction { get; }
#endif
}
internal interface IStateMachineRunnerPromise : IUniTaskSource
{
Action MoveNext { get; }
UniTask Task { get; }
void SetResult();
void SetException(Exception exception);
}
internal interface IStateMachineRunnerPromise<T> : IUniTaskSource<T>
{
Action MoveNext { get; }
UniTask<T> Task { get; }
void SetResult(T result);
void SetException(Exception exception);
}
internal static class StateMachineUtility
{
// Get AsyncStateMachine internal state to check IL2CPP bug
public static int GetState(IAsyncStateMachine stateMachine)
{
var info = stateMachine.GetType().GetFields(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)
.First(x => x.Name.EndsWith("__state"));
return (int)info.GetValue(stateMachine);
}
}
internal sealed class AsyncUniTaskVoid<TStateMachine> : IStateMachineRunner, ITaskPoolNode<AsyncUniTaskVoid<TStateMachine>>, IUniTaskSource
where TStateMachine : IAsyncStateMachine
{
static TaskPool<AsyncUniTaskVoid<TStateMachine>> pool;
#if ENABLE_IL2CPP
public Action ReturnAction { get; }
#endif
TStateMachine stateMachine;
public Action MoveNext { get; }
public AsyncUniTaskVoid()
{
MoveNext = Run;
#if ENABLE_IL2CPP
ReturnAction = Return;
#endif
}
public static void SetStateMachine(ref TStateMachine stateMachine, ref IStateMachineRunner runnerFieldRef)
{
if (!pool.TryPop(out var result))
{
result = new AsyncUniTaskVoid<TStateMachine>();
}
TaskTracker.TrackActiveTask(result, 3);
runnerFieldRef = result; // set runner before copied.
result.stateMachine = stateMachine; // copy struct StateMachine(in release build).
}
static AsyncUniTaskVoid()
{
TaskPool.RegisterSizeGetter(typeof(AsyncUniTaskVoid<TStateMachine>), () => pool.Size);
}
AsyncUniTaskVoid<TStateMachine> nextNode;
public ref AsyncUniTaskVoid<TStateMachine> NextNode => ref nextNode;
public void Return()
{
TaskTracker.RemoveTracking(this);
stateMachine = default;
pool.TryPush(this);
}
[DebuggerHidden]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
void Run()
{
stateMachine.MoveNext();
}
// dummy interface implementation for TaskTracker.
UniTaskStatus IUniTaskSource.GetStatus(short token)
{
return UniTaskStatus.Pending;
}
UniTaskStatus IUniTaskSource.UnsafeGetStatus()
{
return UniTaskStatus.Pending;
}
void IUniTaskSource.OnCompleted(Action<object> continuation, object state, short token)
{
}
void IUniTaskSource.GetResult(short token)
{
}
}
internal sealed class AsyncUniTask<TStateMachine> : IStateMachineRunnerPromise, IUniTaskSource, ITaskPoolNode<AsyncUniTask<TStateMachine>>
where TStateMachine : IAsyncStateMachine
{
static TaskPool<AsyncUniTask<TStateMachine>> pool;
#if ENABLE_IL2CPP
readonly Action returnDelegate;
#endif
public Action MoveNext { get; }
TStateMachine stateMachine;
UniTaskCompletionSourceCore<AsyncUnit> core;
AsyncUniTask()
{
MoveNext = Run;
#if ENABLE_IL2CPP
returnDelegate = Return;
#endif
}
public static void SetStateMachine(ref TStateMachine stateMachine, ref IStateMachineRunnerPromise runnerPromiseFieldRef)
{
if (!pool.TryPop(out var result))
{
result = new AsyncUniTask<TStateMachine>();
}
TaskTracker.TrackActiveTask(result, 3);
runnerPromiseFieldRef = result; // set runner before copied.
result.stateMachine = stateMachine; // copy struct StateMachine(in release build).
}
AsyncUniTask<TStateMachine> nextNode;
public ref AsyncUniTask<TStateMachine> NextNode => ref nextNode;
static AsyncUniTask()
{
TaskPool.RegisterSizeGetter(typeof(AsyncUniTask<TStateMachine>), () => pool.Size);
}
void Return()
{
TaskTracker.RemoveTracking(this);
core.Reset();
stateMachine = default;
pool.TryPush(this);
}
bool TryReturn()
{
TaskTracker.RemoveTracking(this);
core.Reset();
stateMachine = default;
return pool.TryPush(this);
}
[DebuggerHidden]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
void Run()
{
stateMachine.MoveNext();
}
public UniTask Task
{
[DebuggerHidden]
get
{
return new UniTask(this, core.Version);
}
}
[DebuggerHidden]
public void SetResult()
{
core.TrySetResult(AsyncUnit.Default);
}
[DebuggerHidden]
public void SetException(Exception exception)
{
core.TrySetException(exception);
}
[DebuggerHidden]
public void GetResult(short token)
{
try
{
core.GetResult(token);
}
finally
{
#if ENABLE_IL2CPP
// workaround for IL2CPP bug.
PlayerLoopHelper.AddContinuation(PlayerLoopTiming.LastPostLateUpdate, returnDelegate);
#else
TryReturn();
#endif
}
}
[DebuggerHidden]
public UniTaskStatus GetStatus(short token)
{
return core.GetStatus(token);
}
[DebuggerHidden]
public UniTaskStatus UnsafeGetStatus()
{
return core.UnsafeGetStatus();
}
[DebuggerHidden]
public void OnCompleted(Action<object> continuation, object state, short token)
{
core.OnCompleted(continuation, state, token);
}
}
internal sealed class AsyncUniTask<TStateMachine, T> : IStateMachineRunnerPromise<T>, IUniTaskSource<T>, ITaskPoolNode<AsyncUniTask<TStateMachine, T>>
where TStateMachine : IAsyncStateMachine
{
static TaskPool<AsyncUniTask<TStateMachine, T>> pool;
#if ENABLE_IL2CPP
readonly Action returnDelegate;
#endif
public Action MoveNext { get; }
TStateMachine stateMachine;
UniTaskCompletionSourceCore<T> core;
AsyncUniTask()
{
MoveNext = Run;
#if ENABLE_IL2CPP
returnDelegate = Return;
#endif
}
public static void SetStateMachine(ref TStateMachine stateMachine, ref IStateMachineRunnerPromise<T> runnerPromiseFieldRef)
{
if (!pool.TryPop(out var result))
{
result = new AsyncUniTask<TStateMachine, T>();
}
TaskTracker.TrackActiveTask(result, 3);
runnerPromiseFieldRef = result; // set runner before copied.
result.stateMachine = stateMachine; // copy struct StateMachine(in release build).
}
AsyncUniTask<TStateMachine, T> nextNode;
public ref AsyncUniTask<TStateMachine, T> NextNode => ref nextNode;
static AsyncUniTask()
{
TaskPool.RegisterSizeGetter(typeof(AsyncUniTask<TStateMachine, T>), () => pool.Size);
}
void Return()
{
TaskTracker.RemoveTracking(this);
core.Reset();
stateMachine = default;
pool.TryPush(this);
}
bool TryReturn()
{
TaskTracker.RemoveTracking(this);
core.Reset();
stateMachine = default;
return pool.TryPush(this);
}
[DebuggerHidden]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
void Run()
{
// UnityEngine.Debug.Log($"MoveNext State:" + StateMachineUtility.GetState(stateMachine));
stateMachine.MoveNext();
}
public UniTask<T> Task
{
[DebuggerHidden]
get
{
return new UniTask<T>(this, core.Version);
}
}
[DebuggerHidden]
public void SetResult(T result)
{
core.TrySetResult(result);
}
[DebuggerHidden]
public void SetException(Exception exception)
{
core.TrySetException(exception);
}
[DebuggerHidden]
public T GetResult(short token)
{
try
{
return core.GetResult(token);
}
finally
{
#if ENABLE_IL2CPP
// workaround for IL2CPP bug.
PlayerLoopHelper.AddContinuation(PlayerLoopTiming.LastPostLateUpdate, returnDelegate);
#else
TryReturn();
#endif
}
}
[DebuggerHidden]
void IUniTaskSource.GetResult(short token)
{
GetResult(token);
}
[DebuggerHidden]
public UniTaskStatus GetStatus(short token)
{
return core.GetStatus(token);
}
[DebuggerHidden]
public UniTaskStatus UnsafeGetStatus()
{
return core.UnsafeGetStatus();
}
[DebuggerHidden]
public void OnCompleted(Action<object> continuation, object state, short token)
{
core.OnCompleted(continuation, state, token);
}
}
}

View File

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

View File

@ -0,0 +1,34 @@
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System;
using System.Collections.Generic;
namespace Cysharp.Threading.Tasks
{
public static class EnumerableAsyncExtensions
{
// overload resolver - .Select(async x => { }) : IEnumerable<UniTask<T>>
public static IEnumerable<UniTask> Select<T>(this IEnumerable<T> source, Func<T, UniTask> selector)
{
return System.Linq.Enumerable.Select(source, selector);
}
public static IEnumerable<UniTask<TR>> Select<T, TR>(this IEnumerable<T> source, Func<T, UniTask<TR>> selector)
{
return System.Linq.Enumerable.Select(source, selector);
}
public static IEnumerable<UniTask> Select<T>(this IEnumerable<T> source, Func<T, int, UniTask> selector)
{
return System.Linq.Enumerable.Select(source, selector);
}
public static IEnumerable<UniTask<TR>> Select<T, TR>(this IEnumerable<T> source, Func<T, int, UniTask<TR>> selector)
{
return System.Linq.Enumerable.Select(source, selector);
}
}
}

View File

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

View File

@ -0,0 +1,287 @@
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System;
using System.Collections;
using System.Reflection;
using System.Runtime.ExceptionServices;
using System.Threading;
using Cysharp.Threading.Tasks.Internal;
using UnityEngine;
namespace Cysharp.Threading.Tasks
{
public static class EnumeratorAsyncExtensions
{
public static UniTask.Awaiter GetAwaiter<T>(this T enumerator)
where T : IEnumerator
{
var e = (IEnumerator)enumerator;
Error.ThrowArgumentNullException(e, nameof(enumerator));
return new UniTask(EnumeratorPromise.Create(e, PlayerLoopTiming.Update, CancellationToken.None, out var token), token).GetAwaiter();
}
public static UniTask WithCancellation(this IEnumerator enumerator, CancellationToken cancellationToken)
{
Error.ThrowArgumentNullException(enumerator, nameof(enumerator));
return new UniTask(EnumeratorPromise.Create(enumerator, PlayerLoopTiming.Update, cancellationToken, out var token), token);
}
public static UniTask ToUniTask(this IEnumerator enumerator, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
{
Error.ThrowArgumentNullException(enumerator, nameof(enumerator));
return new UniTask(EnumeratorPromise.Create(enumerator, timing, cancellationToken, out var token), token);
}
public static UniTask ToUniTask(this IEnumerator enumerator, MonoBehaviour coroutineRunner)
{
var source = AutoResetUniTaskCompletionSource.Create();
coroutineRunner.StartCoroutine(Core(enumerator, coroutineRunner, source));
return source.Task;
}
static IEnumerator Core(IEnumerator inner, MonoBehaviour coroutineRunner, AutoResetUniTaskCompletionSource source)
{
yield return coroutineRunner.StartCoroutine(inner);
source.TrySetResult();
}
sealed class EnumeratorPromise : IUniTaskSource, IPlayerLoopItem, ITaskPoolNode<EnumeratorPromise>
{
static TaskPool<EnumeratorPromise> pool;
EnumeratorPromise nextNode;
public ref EnumeratorPromise NextNode => ref nextNode;
static EnumeratorPromise()
{
TaskPool.RegisterSizeGetter(typeof(EnumeratorPromise), () => pool.Size);
}
IEnumerator innerEnumerator;
CancellationToken cancellationToken;
int initialFrame;
bool loopRunning;
bool calledGetResult;
UniTaskCompletionSourceCore<object> core;
EnumeratorPromise()
{
}
public static IUniTaskSource Create(IEnumerator innerEnumerator, PlayerLoopTiming timing, CancellationToken cancellationToken, out short token)
{
if (cancellationToken.IsCancellationRequested)
{
return AutoResetUniTaskCompletionSource.CreateFromCanceled(cancellationToken, out token);
}
if (!pool.TryPop(out var result))
{
result = new EnumeratorPromise();
}
TaskTracker.TrackActiveTask(result, 3);
result.innerEnumerator = ConsumeEnumerator(innerEnumerator);
result.cancellationToken = cancellationToken;
result.loopRunning = true;
result.calledGetResult = false;
result.initialFrame = -1;
token = result.core.Version;
// run immediately.
if (result.MoveNext())
{
PlayerLoopHelper.AddAction(timing, result);
}
return result;
}
public void GetResult(short token)
{
try
{
calledGetResult = true;
core.GetResult(token);
}
finally
{
if (!loopRunning)
{
TryReturn();
}
}
}
public UniTaskStatus GetStatus(short token)
{
return core.GetStatus(token);
}
public UniTaskStatus UnsafeGetStatus()
{
return core.UnsafeGetStatus();
}
public void OnCompleted(Action<object> continuation, object state, short token)
{
core.OnCompleted(continuation, state, token);
}
public bool MoveNext()
{
if (calledGetResult)
{
loopRunning = false;
TryReturn();
return false;
}
if (innerEnumerator == null) // invalid status, returned but loop running?
{
return false;
}
if (cancellationToken.IsCancellationRequested)
{
loopRunning = false;
core.TrySetCanceled(cancellationToken);
return false;
}
if (initialFrame == -1)
{
// Time can not touch in threadpool.
if (PlayerLoopHelper.IsMainThread)
{
initialFrame = Time.frameCount;
}
}
else if (initialFrame == Time.frameCount)
{
return true; // already executed in first frame, skip.
}
try
{
if (innerEnumerator.MoveNext())
{
return true;
}
}
catch (Exception ex)
{
loopRunning = false;
core.TrySetException(ex);
return false;
}
loopRunning = false;
core.TrySetResult(null);
return false;
}
bool TryReturn()
{
TaskTracker.RemoveTracking(this);
core.Reset();
innerEnumerator = default;
cancellationToken = default;
return pool.TryPush(this);
}
// Unwrap YieldInstructions
static IEnumerator ConsumeEnumerator(IEnumerator enumerator)
{
while (enumerator.MoveNext())
{
var current = enumerator.Current;
if (current == null)
{
yield return null;
}
else if (current is CustomYieldInstruction cyi)
{
// WWW, WaitForSecondsRealtime
while (cyi.keepWaiting)
{
yield return null;
}
}
else if (current is YieldInstruction)
{
IEnumerator innerCoroutine = null;
switch (current)
{
case AsyncOperation ao:
innerCoroutine = UnwrapWaitAsyncOperation(ao);
break;
case WaitForSeconds wfs:
innerCoroutine = UnwrapWaitForSeconds(wfs);
break;
}
if (innerCoroutine != null)
{
while (innerCoroutine.MoveNext())
{
yield return null;
}
}
else
{
goto WARN;
}
}
else if (current is IEnumerator e3)
{
var e4 = ConsumeEnumerator(e3);
while (e4.MoveNext())
{
yield return null;
}
}
else
{
goto WARN;
}
continue;
WARN:
// WaitForEndOfFrame, WaitForFixedUpdate, others.
UnityEngine.Debug.LogWarning($"yield {current.GetType().Name} is not supported on await IEnumerator or IEnumerator.ToUniTask(), please use ToUniTask(MonoBehaviour coroutineRunner) instead.");
yield return null;
}
}
static readonly FieldInfo waitForSeconds_Seconds = typeof(WaitForSeconds).GetField("m_Seconds", BindingFlags.Instance | BindingFlags.GetField | BindingFlags.NonPublic);
static IEnumerator UnwrapWaitForSeconds(WaitForSeconds waitForSeconds)
{
var second = (float)waitForSeconds_Seconds.GetValue(waitForSeconds);
var elapsed = 0.0f;
while (true)
{
yield return null;
elapsed += Time.deltaTime;
if (elapsed >= second)
{
break;
}
};
}
static IEnumerator UnwrapWaitAsyncOperation(AsyncOperation asyncOperation)
{
while (!asyncOperation.isDone)
{
yield return null;
}
}
}
}
}

View File

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

View File

@ -0,0 +1,14 @@

using System;
namespace Cysharp.Threading.Tasks
{
public static class ExceptionExtensions
{
public static bool IsOperationCanceledException(this Exception exception)
{
return exception is OperationCanceledException;
}
}
}

View File

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

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: fbaa8381b356df34d80b37704ab99037
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 28d1b1f94b7c8ff4092cbc7167f263e0
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,483 @@
// asmdef Version Defines, enabled when com.unity.addressables is imported.
#if UNITASK_ADDRESSABLE_SUPPORT
using Cysharp.Threading.Tasks.Internal;
using System;
using System.Runtime.CompilerServices;
using System.Runtime.ExceptionServices;
using System.Threading;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;
namespace Cysharp.Threading.Tasks
{
public static class AddressablesAsyncExtensions
{
#region AsyncOperationHandle
public static UniTask.Awaiter GetAwaiter(this AsyncOperationHandle handle)
{
return ToUniTask(handle).GetAwaiter();
}
public static UniTask WithCancellation(this AsyncOperationHandle handle, CancellationToken cancellationToken, bool cancelImmediately = false, bool autoReleaseWhenCanceled = false)
{
return ToUniTask(handle, cancellationToken: cancellationToken, cancelImmediately: cancelImmediately, autoReleaseWhenCanceled: autoReleaseWhenCanceled);
}
public static UniTask ToUniTask(this AsyncOperationHandle handle, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false, bool autoReleaseWhenCanceled = false)
{
if (cancellationToken.IsCancellationRequested) return UniTask.FromCanceled(cancellationToken);
if (!handle.IsValid())
{
// autoReleaseHandle:true handle is invalid(immediately internal handle == null) so return completed.
return UniTask.CompletedTask;
}
if (handle.IsDone)
{
if (handle.Status == AsyncOperationStatus.Failed)
{
return UniTask.FromException(handle.OperationException);
}
return UniTask.CompletedTask;
}
return new UniTask(AsyncOperationHandleConfiguredSource.Create(handle, timing, progress, cancellationToken, cancelImmediately, autoReleaseWhenCanceled, out var token), token);
}
public struct AsyncOperationHandleAwaiter : ICriticalNotifyCompletion
{
AsyncOperationHandle handle;
Action<AsyncOperationHandle> continuationAction;
public AsyncOperationHandleAwaiter(AsyncOperationHandle handle)
{
this.handle = handle;
this.continuationAction = null;
}
public bool IsCompleted => handle.IsDone;
public void GetResult()
{
if (continuationAction != null)
{
handle.Completed -= continuationAction;
continuationAction = null;
}
if (handle.Status == AsyncOperationStatus.Failed)
{
var e = handle.OperationException;
handle = default;
ExceptionDispatchInfo.Capture(e).Throw();
}
var result = handle.Result;
handle = default;
}
public void OnCompleted(Action continuation)
{
UnsafeOnCompleted(continuation);
}
public void UnsafeOnCompleted(Action continuation)
{
Error.ThrowWhenContinuationIsAlreadyRegistered(continuationAction);
continuationAction = PooledDelegate<AsyncOperationHandle>.Create(continuation);
handle.Completed += continuationAction;
}
}
sealed class AsyncOperationHandleConfiguredSource : IUniTaskSource, IPlayerLoopItem, ITaskPoolNode<AsyncOperationHandleConfiguredSource>
{
static TaskPool<AsyncOperationHandleConfiguredSource> pool;
AsyncOperationHandleConfiguredSource nextNode;
public ref AsyncOperationHandleConfiguredSource NextNode => ref nextNode;
static AsyncOperationHandleConfiguredSource()
{
TaskPool.RegisterSizeGetter(typeof(AsyncOperationHandleConfiguredSource), () => pool.Size);
}
readonly Action<AsyncOperationHandle> completedCallback;
AsyncOperationHandle handle;
CancellationToken cancellationToken;
CancellationTokenRegistration cancellationTokenRegistration;
IProgress<float> progress;
bool autoReleaseWhenCanceled;
bool cancelImmediately;
bool completed;
UniTaskCompletionSourceCore<AsyncUnit> core;
AsyncOperationHandleConfiguredSource()
{
completedCallback = HandleCompleted;
}
public static IUniTaskSource Create(AsyncOperationHandle handle, PlayerLoopTiming timing, IProgress<float> progress, CancellationToken cancellationToken, bool cancelImmediately, bool autoReleaseWhenCanceled, out short token)
{
if (cancellationToken.IsCancellationRequested)
{
return AutoResetUniTaskCompletionSource.CreateFromCanceled(cancellationToken, out token);
}
if (!pool.TryPop(out var result))
{
result = new AsyncOperationHandleConfiguredSource();
}
result.handle = handle;
result.progress = progress;
result.cancellationToken = cancellationToken;
result.cancelImmediately = cancelImmediately;
result.autoReleaseWhenCanceled = autoReleaseWhenCanceled;
result.completed = false;
if (cancelImmediately && cancellationToken.CanBeCanceled)
{
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
{
var promise = (AsyncOperationHandleConfiguredSource)state;
if (promise.autoReleaseWhenCanceled && promise.handle.IsValid())
{
Addressables.Release(promise.handle);
}
promise.core.TrySetCanceled(promise.cancellationToken);
}, result);
}
TaskTracker.TrackActiveTask(result, 3);
PlayerLoopHelper.AddAction(timing, result);
handle.Completed += result.completedCallback;
token = result.core.Version;
return result;
}
void HandleCompleted(AsyncOperationHandle _)
{
if (handle.IsValid())
{
handle.Completed -= completedCallback;
}
if (completed)
{
return;
}
completed = true;
if (cancellationToken.IsCancellationRequested)
{
if (autoReleaseWhenCanceled && handle.IsValid())
{
Addressables.Release(handle);
}
core.TrySetCanceled(cancellationToken);
}
else if (handle.Status == AsyncOperationStatus.Failed)
{
core.TrySetException(handle.OperationException);
}
else
{
core.TrySetResult(AsyncUnit.Default);
}
}
public void GetResult(short token)
{
try
{
core.GetResult(token);
}
finally
{
if (!(cancelImmediately && cancellationToken.IsCancellationRequested))
{
TryReturn();
}
else
{
TaskTracker.RemoveTracking(this);
}
}
}
public UniTaskStatus GetStatus(short token)
{
return core.GetStatus(token);
}
public UniTaskStatus UnsafeGetStatus()
{
return core.UnsafeGetStatus();
}
public void OnCompleted(Action<object> continuation, object state, short token)
{
core.OnCompleted(continuation, state, token);
}
public bool MoveNext()
{
if (completed)
{
return false;
}
if (cancellationToken.IsCancellationRequested)
{
completed = true;
if (autoReleaseWhenCanceled && handle.IsValid())
{
Addressables.Release(handle);
}
core.TrySetCanceled(cancellationToken);
return false;
}
if (progress != null && handle.IsValid())
{
progress.Report(handle.GetDownloadStatus().Percent);
}
return true;
}
bool TryReturn()
{
TaskTracker.RemoveTracking(this);
core.Reset();
handle = default;
progress = default;
cancellationToken = default;
cancellationTokenRegistration.Dispose();
return pool.TryPush(this);
}
}
#endregion
#region AsyncOperationHandle_T
public static UniTask<T>.Awaiter GetAwaiter<T>(this AsyncOperationHandle<T> handle)
{
return ToUniTask(handle).GetAwaiter();
}
public static UniTask<T> WithCancellation<T>(this AsyncOperationHandle<T> handle, CancellationToken cancellationToken, bool cancelImmediately = false, bool autoReleaseWhenCanceled = false)
{
return ToUniTask(handle, cancellationToken: cancellationToken, cancelImmediately: cancelImmediately, autoReleaseWhenCanceled: autoReleaseWhenCanceled);
}
public static UniTask<T> ToUniTask<T>(this AsyncOperationHandle<T> handle, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false, bool autoReleaseWhenCanceled = false)
{
if (cancellationToken.IsCancellationRequested) return UniTask.FromCanceled<T>(cancellationToken);
if (!handle.IsValid())
{
throw new Exception("Attempting to use an invalid operation handle");
}
if (handle.IsDone)
{
if (handle.Status == AsyncOperationStatus.Failed)
{
return UniTask.FromException<T>(handle.OperationException);
}
return UniTask.FromResult(handle.Result);
}
return new UniTask<T>(AsyncOperationHandleConfiguredSource<T>.Create(handle, timing, progress, cancellationToken, cancelImmediately, autoReleaseWhenCanceled, out var token), token);
}
sealed class AsyncOperationHandleConfiguredSource<T> : IUniTaskSource<T>, IPlayerLoopItem, ITaskPoolNode<AsyncOperationHandleConfiguredSource<T>>
{
static TaskPool<AsyncOperationHandleConfiguredSource<T>> pool;
AsyncOperationHandleConfiguredSource<T> nextNode;
public ref AsyncOperationHandleConfiguredSource<T> NextNode => ref nextNode;
static AsyncOperationHandleConfiguredSource()
{
TaskPool.RegisterSizeGetter(typeof(AsyncOperationHandleConfiguredSource<T>), () => pool.Size);
}
readonly Action<AsyncOperationHandle<T>> completedCallback;
AsyncOperationHandle<T> handle;
CancellationToken cancellationToken;
CancellationTokenRegistration cancellationTokenRegistration;
IProgress<float> progress;
bool autoReleaseWhenCanceled;
bool cancelImmediately;
bool completed;
UniTaskCompletionSourceCore<T> core;
AsyncOperationHandleConfiguredSource()
{
completedCallback = HandleCompleted;
}
public static IUniTaskSource<T> Create(AsyncOperationHandle<T> handle, PlayerLoopTiming timing, IProgress<float> progress, CancellationToken cancellationToken, bool cancelImmediately, bool autoReleaseWhenCanceled, out short token)
{
if (cancellationToken.IsCancellationRequested)
{
return AutoResetUniTaskCompletionSource<T>.CreateFromCanceled(cancellationToken, out token);
}
if (!pool.TryPop(out var result))
{
result = new AsyncOperationHandleConfiguredSource<T>();
}
result.handle = handle;
result.cancellationToken = cancellationToken;
result.completed = false;
result.progress = progress;
result.autoReleaseWhenCanceled = autoReleaseWhenCanceled;
result.cancelImmediately = cancelImmediately;
if (cancelImmediately && cancellationToken.CanBeCanceled)
{
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
{
var promise = (AsyncOperationHandleConfiguredSource<T>)state;
if (promise.autoReleaseWhenCanceled && promise.handle.IsValid())
{
Addressables.Release(promise.handle);
}
promise.core.TrySetCanceled(promise.cancellationToken);
}, result);
}
TaskTracker.TrackActiveTask(result, 3);
PlayerLoopHelper.AddAction(timing, result);
handle.Completed += result.completedCallback;
token = result.core.Version;
return result;
}
void HandleCompleted(AsyncOperationHandle<T> argHandle)
{
if (handle.IsValid())
{
handle.Completed -= completedCallback;
}
if (completed)
{
return;
}
completed = true;
if (cancellationToken.IsCancellationRequested)
{
if (autoReleaseWhenCanceled && handle.IsValid())
{
Addressables.Release(handle);
}
core.TrySetCanceled(cancellationToken);
}
else if (argHandle.Status == AsyncOperationStatus.Failed)
{
core.TrySetException(argHandle.OperationException);
}
else
{
core.TrySetResult(argHandle.Result);
}
}
public T GetResult(short token)
{
try
{
return core.GetResult(token);
}
finally
{
if (!(cancelImmediately && cancellationToken.IsCancellationRequested))
{
TryReturn();
}
else
{
TaskTracker.RemoveTracking(this);
}
}
}
void IUniTaskSource.GetResult(short token)
{
GetResult(token);
}
public UniTaskStatus GetStatus(short token)
{
return core.GetStatus(token);
}
public UniTaskStatus UnsafeGetStatus()
{
return core.UnsafeGetStatus();
}
public void OnCompleted(Action<object> continuation, object state, short token)
{
core.OnCompleted(continuation, state, token);
}
public bool MoveNext()
{
if (completed)
{
return false;
}
if (cancellationToken.IsCancellationRequested)
{
completed = true;
if (autoReleaseWhenCanceled && handle.IsValid())
{
Addressables.Release(handle);
}
core.TrySetCanceled(cancellationToken);
return false;
}
if (progress != null && handle.IsValid())
{
progress.Report(handle.GetDownloadStatus().Percent);
}
return true;
}
bool TryReturn()
{
TaskTracker.RemoveTracking(this);
core.Reset();
handle = default;
progress = default;
cancellationToken = default;
cancellationTokenRegistration.Dispose();
return pool.TryPush(this);
}
}
#endregion
}
}
#endif

View File

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

View File

@ -0,0 +1,28 @@
{
"name": "UniTask.Addressables",
"references": [
"UniTask",
"Unity.ResourceManager",
"Unity.Addressables"
],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [
{
"name": "com.unity.addressables",
"expression": "",
"define": "UNITASK_ADDRESSABLE_SUPPORT"
},
{
"name": "com.unity.addressables.cn",
"expression": "",
"define": "UNITASK_ADDRESSABLE_SUPPORT"
}
],
"noEngineReferences": false
}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 593a5b492d29ac6448b1ebf7f035ef33
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 05f2111a51bb2f24aa79aaf7ce0d2590
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

Some files were not shown because too many files have changed in this diff Show More