Compare commits
11 Commits
feature-as
...
master
| Author | SHA1 | Date |
|---|---|---|
|
|
1f24f3ad99 | |
|
|
1269673cf7 | |
|
|
e016254acb | |
|
|
fedc3551e3 | |
|
|
97183a184a | |
|
|
2e215f080e | |
|
|
6771b0aa81 | |
|
|
740bb595ab | |
|
|
8107321f04 | |
|
|
31b5804fd8 | |
|
|
a8cdc427f1 |
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: fef2c46c5ce9b124bbaf48ad0f128730
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 5fbc49285d6699848b5befdb66a6ba82
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
|
|
@ -152,7 +359,7 @@ public class SearchCtrl : SingletonMonoBehaviour<SearchCtrl>
|
||||||
suitType.value = 0;
|
suitType.value = 0;
|
||||||
region.value = 0;
|
region.value = 0;
|
||||||
animalTypes.value = 0;
|
animalTypes.value = 0;
|
||||||
for(int n = 0; n < colors.Length; n++)
|
for (int n = 0; n < colors.Length; n++)
|
||||||
{
|
{
|
||||||
colors[n].isOn = false;
|
colors[n].isOn = false;
|
||||||
colors[n].image.sprite = isOnSprite[0];
|
colors[n].image.sprite = isOnSprite[0];
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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>";
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: bd699c354f1fbc24ab3d3d6821f6bdaa
|
||||||
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 061efe05400e6e34c8d1e9dc2bc05eb8
|
||||||
|
|
@ -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()
|
||||||
|
|
|
||||||
|
After Width: | Height: | Size: 380 B |
|
|
@ -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:
|
||||||
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
|
|
@ -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
|
||||||
|
After Width: | Height: | Size: 729 B |
|
|
@ -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:
|
||||||
|
After Width: | Height: | Size: 1.2 KiB |
|
|
@ -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:
|
||||||
|
After Width: | Height: | Size: 1.1 KiB |
|
|
@ -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:
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: 8e7e8f5a82a3a134e91c54efd2274ea9
|
guid: a77e3012f37e98f4fb0c9f538d96d114
|
||||||
folderAsset: yes
|
folderAsset: yes
|
||||||
DefaultImporter:
|
DefaultImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
|
After Width: | Height: | Size: 12 KiB |
|
|
@ -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:
|
||||||
|
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.7 KiB |
|
|
@ -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
|
||||||
|
After Width: | Height: | Size: 225 B |
|
|
@ -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:
|
||||||
|
After Width: | Height: | Size: 907 B |
|
|
@ -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:
|
||||||
|
After Width: | Height: | Size: 54 KiB |
|
|
@ -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:
|
||||||
|
After Width: | Height: | Size: 73 KiB |
|
|
@ -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:
|
||||||
|
Before Width: | Height: | Size: 223 KiB After Width: | Height: | Size: 165 KiB |
|
After Width: | Height: | Size: 1023 KiB |
|
|
@ -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:
|
||||||
|
After Width: | Height: | Size: 1.3 MiB |
|
|
@ -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:
|
||||||
|
After Width: | Height: | Size: 1.1 MiB |
|
|
@ -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:
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 09d8f500ccf67c94eb7b3ce8253b84bf
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: d5833b15817ba024f98834126b306833
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 40ef2e46f900131419e869398a8d3c9d
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
{
|
||||||
|
"name": "UniTask.Editor",
|
||||||
|
"references": [
|
||||||
|
"UniTask"
|
||||||
|
],
|
||||||
|
"includePlatforms": [
|
||||||
|
"Editor"
|
||||||
|
],
|
||||||
|
"excludePlatforms": [],
|
||||||
|
"allowUnsafeCode": false,
|
||||||
|
"overrideReferences": false,
|
||||||
|
"precompiledReferences": [],
|
||||||
|
"autoReferenced": false,
|
||||||
|
"defineConstraints": [],
|
||||||
|
"versionDefines": [],
|
||||||
|
"noEngineReferences": false
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 4129704b5a1a13841ba16f230bf24a57
|
||||||
|
AssemblyDefinitionImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 52e2d973a2156674e8c1c9433ed031f7
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 5bee3e3860e37484aa3b861bf76d129f
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 836c9bdde0d7593438f0a224268896e5
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 01d1404ca421466419a7db7340ff5e77
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 8ef320b87f537ee4fb2282e765dc6166
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -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 "()";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 4f95ac245430d304bb5128d13b6becc8
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 7d739f510b125b74fa7290ac4335e46e
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 4be7209f04146bd45ac5ee775a5f7c26
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 22d85d07f1e70ab42a7a4c25bd65e661
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 5ceb3107bbdd1f14eb39091273798360
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 18a8e863d94b80f4d874fc7e5098f845
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 02ce354d37b10454e8376062f7cbe57a
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 68d72a45afdec574ebc26e7de2c38330
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: e891aaac17b933a47a9d7fa3b8e1226f
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 98649642833cabf44a9dc060ce4c84a1
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: ff50260d74bd54c4b92cf99895549445
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: bc661232f11e4a741af54ba1c175d5ee
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 930800098504c0d46958ce23a0495202
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: fbaa8381b356df34d80b37704ab99037
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 28d1b1f94b7c8ff4092cbc7167f263e0
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
483
Assets/Plugins/UniTask/Runtime/External/Addressables/AddressablesAsyncExtensions.cs
vendored
Normal 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
|
||||||
11
Assets/Plugins/UniTask/Runtime/External/Addressables/AddressablesAsyncExtensions.cs.meta
vendored
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 3dc6441f9094f354b931dc3c79fb99e5
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
28
Assets/Plugins/UniTask/Runtime/External/Addressables/UniTask.Addressables.asmdef
vendored
Normal 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
|
||||||
|
}
|
||||||
7
Assets/Plugins/UniTask/Runtime/External/Addressables/UniTask.Addressables.asmdef.meta
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 593a5b492d29ac6448b1ebf7f035ef33
|
||||||
|
AssemblyDefinitionImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 05f2111a51bb2f24aa79aaf7ce0d2590
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||