CharacterCusUI.cs 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEngine.UI;
  5. using System.Text.RegularExpressions;
  6. using UnityEngine.EventSystems;
  7. using System.IO;
  8. using UnityEngine.SceneManagement;
  9. namespace SoftKitty.MasterCharacterCreator
  10. {
  11. public struct CharacterCusSetting
  12. {
  13. public bool AllowCustomOutfit;
  14. public bool AllowSexSwitch;
  15. public bool AllowNameChange;
  16. public bool AllowRaceChange;
  17. public bool BackCategoryVisible;
  18. public bool TailCategoryVisible;
  19. public bool RaceSettingVisible;
  20. }
  21. public class CharacterCusUI : MonoBehaviour
  22. {
  23. #region varaibles
  24. public GameObject DevWarning;
  25. public GameObject OutfitCategoryPanel;
  26. public GameObject OutfitSavePanel;
  27. public GameObject SexPanel;
  28. public GameObject NamePanel;
  29. public GameObject RacePanel;
  30. public GameObject BackPanel;
  31. public GameObject TailPanel;
  32. public static CharacterCusUI instance;
  33. public CharacterCusSliders [] MyLeftSliders;
  34. public Button[] MainBts;
  35. public GameObject[] BtSels;
  36. public GameObject[] SexSels;
  37. public cc_Mat_Setting MatScript;
  38. public InputField NameInput;
  39. public Sex mSex =0;
  40. public RectTransform PhotoCenter;
  41. public Animation PhotoResult;
  42. public RawImage PhotoImage;
  43. public Text PhotoName;
  44. public Text PhotoPath;
  45. public GameObject BlueprintList;
  46. public Text BlueprintListPath;
  47. public GameObject BluePrintItem;
  48. public GameObject ByteFileList;
  49. public Text ByteFileListPath;
  50. public GameObject ByteFileItem;
  51. public InputField PhotoNameInput;
  52. public static string SaveRootPath;
  53. public static SaveMethod SaveFormat;
  54. public static CharacterCusSetting Settings;
  55. public static CharacterAppearance InitialData;
  56. private int CurrentSlider = -1;
  57. private float CanClose = 0F;
  58. public CharacterAppearance AppearanceData;
  59. private OutfitSlots CurrentSlot;
  60. private List<GameObject> BlueprintItems = new List<GameObject>();
  61. private List<GameObject> ByteFileItems = new List<GameObject>();
  62. [HideInInspector]
  63. public bool Initialized = false;
  64. public delegate void OnSwitchUI();
  65. public static event OnSwitchUI onSwitchUI;
  66. #endregion
  67. #region internal methods
  68. private void Awake()
  69. {
  70. instance = this;
  71. GetComponent<CanvasGroup>().alpha = 0F;
  72. }
  73. private IEnumerator Start()
  74. {
  75. while (TransitionUI.instance != null) yield return 1;
  76. Initialize();
  77. yield return new WaitForSeconds(0.3F);
  78. GetComponent<Animation>().Play("cc_in");
  79. GetComponent<CanvasGroup>().alpha = 1F;
  80. CameraControl.instance.Initialized = true;
  81. }
  82. public OutfitColorSetting GetOutfitSetting()
  83. {
  84. return CharacterDataSetting.instance.GetOutfitColorSetting((Sex)AppearanceData._CharacterData.Sex, CurrentSlot, AppearanceData._OutfitID[(int)CurrentSlot]);
  85. }
  86. public int GetCurrentOutfitSettingId()
  87. {
  88. switch (CurrentSlider)
  89. {
  90. default: return -1;
  91. case 5: return 0;
  92. case 4: return 1;
  93. case 6: return 2;
  94. case 7: return 3;
  95. case 8: return 4;
  96. case 9:return 5;
  97. case 10:return 6;
  98. }
  99. }
  100. public void ButtonSetSex(int _sex)
  101. {
  102. SetSex((Sex)_sex);
  103. }
  104. private void OnDestroy()
  105. {
  106. CharacterManager.instance.RemovePreviewCharacter("cc_" + mSex.ToString());
  107. }
  108. private void Update()
  109. {
  110. if (!Initialized) return;
  111. MyCharacter.GetComponent<Animator>().SetBool("Static", CurrentSlider == 0 || PhotoCenter.gameObject.activeSelf);
  112. for (int i = 0; i < MainBts.Length; i++)
  113. {
  114. MainBts[i].transform.localScale = Vector3.Lerp(MainBts[i].transform.localScale, Vector3.one * (CurrentSlider == i ? 1F : 0.7F), Time.deltaTime * 8F);
  115. BtSels[i].SetActive(CurrentSlider == i);
  116. }
  117. CanClose += Time.deltaTime;
  118. if (Input.GetKeyDown(KeyCode.Escape) && CanClose > 5F)
  119. {
  120. }
  121. if (EventSystem.current.currentSelectedGameObject == NameInput.gameObject)
  122. {
  123. AppearanceData._Name = NameInput.text;
  124. }
  125. }
  126. IEnumerator SaveCharacterWithPhotoCo(string _path, string _fileName, BlurPrintType _type)
  127. {
  128. PhotoResult.gameObject.SetActive(false);
  129. PhotoNameInput.text = _fileName;
  130. CharacterManager.SetPhotoMode(_type == BlurPrintType.Outfits ? 1 : 2);
  131. PhotoCenter.gameObject.SetActive(true);
  132. bool _done = false;
  133. bool _process = false;
  134. while (!_done)
  135. {
  136. if (EventSystem.current.currentSelectedGameObject == null && Input.GetKeyDown(KeyCode.Space))
  137. {
  138. _process = true;
  139. _done = true;
  140. }
  141. if (Input.GetKeyDown(KeyCode.Escape))
  142. {
  143. _process = false;
  144. _done = true;
  145. }
  146. yield return 1;
  147. }
  148. if (_process)
  149. {
  150. SoundManager.Play2D("Photo");
  151. _fileName = PhotoNameInput.text;
  152. yield return new WaitForEndOfFrame();
  153. Texture2D _tex = CaptureAvatar();
  154. CharacterManager.SaveCharacterDataWithPhoto(MyCharacter, _tex, _path + _fileName + ".png", _type);
  155. PhotoName.text = _fileName + ".png";
  156. PhotoPath.text = _path;
  157. PhotoImage.texture = _tex;
  158. PhotoResult.gameObject.SetActive(true);
  159. yield return 1;
  160. while (PhotoResult.isPlaying)
  161. {
  162. yield return 1;
  163. }
  164. float _time = 0F;
  165. while (_time < 2F && !Input.GetKeyDown(KeyCode.Space))
  166. {
  167. yield return 1;
  168. _time += Time.deltaTime;
  169. }
  170. PhotoResult.gameObject.SetActive(false);
  171. }
  172. CharacterManager.SetPhotoMode(0);
  173. yield return 1;
  174. PhotoCenter.gameObject.SetActive(false);
  175. }
  176. public void BluePrintClick(Text _file)
  177. {
  178. CameraControl.instance.DisableForTime(0.3F);
  179. CharacterManager.instance.RemovePreviewCharacter("cc_" + mSex.ToString());
  180. CharacterManager.LoadCharacterDataWithPhoto(ref AppearanceData, BlueprintListPath.text + _file.text);
  181. mSex = (Sex)AppearanceData._Sex;
  182. MyCharacter.Initialize(AppearanceData);
  183. RefreshData();
  184. ToggleBlueprintList(false);
  185. SoundManager.Play2D("Load");
  186. }
  187. public void ByteFileClick(Text _file)
  188. {
  189. CameraControl.instance.DisableForTime(0.3F);
  190. CharacterManager.instance.RemovePreviewCharacter("cc_" + mSex.ToString());
  191. #if UNITY_EDITOR
  192. AppearanceData = CharacterManager.LoadCharacterDataFromResources(ByteFileListPath.text + _file.text.Replace(".bytes", ""), AppearanceData).Copy();
  193. #else
  194. AppearanceData = CharacterManager.LoadCharacterDataFromFile(AppearanceData,ByteFileListPath.text + _file.text).Copy();
  195. #endif
  196. mSex = (Sex)AppearanceData._CharacterData.Sex;
  197. MyCharacter.Initialize(AppearanceData);
  198. RefreshData();
  199. ToggleByteFileList(false);
  200. SoundManager.Play2D("Load");
  201. }
  202. private void InitBlueprintList(string _path)
  203. {
  204. foreach (GameObject obj in BlueprintItems)
  205. {
  206. if (obj != null) Destroy(obj);
  207. }
  208. BlueprintItems.Clear();
  209. BlueprintListPath.text = _path;
  210. string[] _files = Directory.GetFiles(_path, "*.png", SearchOption.TopDirectoryOnly);
  211. foreach (string _file in _files)
  212. {
  213. GameObject _newItem = Instantiate(BluePrintItem, BluePrintItem.transform.parent);
  214. byte[] _bytes = File.ReadAllBytes(_file);
  215. Texture2D _tex = new Texture2D(256, 256, TextureFormat.RGB24, false);
  216. ImageConversion.LoadImage(_tex, _bytes);
  217. _newItem.SetActive(true);
  218. _newItem.GetComponentInChildren<RawImage>(true).texture = _tex;
  219. _newItem.GetComponentInChildren<Text>(true).text = Path.GetFileName(_file);
  220. BlueprintItems.Add(_newItem);
  221. }
  222. SoundManager.Play2D("Paper");
  223. }
  224. private void InitByteFileList(string _path, string _resourcePath)
  225. {
  226. foreach (GameObject obj in ByteFileItems)
  227. {
  228. if (obj != null) Destroy(obj);
  229. }
  230. ByteFileItems.Clear();
  231. #if UNITY_EDITOR
  232. ByteFileListPath.text = _resourcePath;
  233. #else
  234. ByteFileListPath.text = _path;
  235. #endif
  236. string[] _files = Directory.GetFiles(_path, "*.bytes", SearchOption.TopDirectoryOnly);
  237. foreach (string _file in _files)
  238. {
  239. byte[] _bytes = File.ReadAllBytes(_file);
  240. if (_bytes[1] == AppearanceData._CharacterData.Sex)
  241. {
  242. GameObject _newItem = Instantiate(ByteFileItem, ByteFileItem.transform.parent);
  243. _newItem.SetActive(true);
  244. _newItem.GetComponentInChildren<Text>(true).text = Path.GetFileName(_file);
  245. ByteFileItems.Add(_newItem);
  246. }
  247. }
  248. SoundManager.Play2D("Paper");
  249. }
  250. #endregion
  251. public CharacterBoneControl MyCharacter
  252. {
  253. get
  254. {
  255. if (CharacterManager.instance.GetPreviewCharacter("cc_" + mSex.ToString()) != null)
  256. {
  257. return CharacterManager.instance.GetPreviewCharacter("cc_" + mSex.ToString());
  258. }
  259. else
  260. {
  261. return CharacterManager.instance.CreatePreviewCharacter("cc_" + mSex.ToString(), mSex);
  262. }
  263. }
  264. }
  265. public void Initialize()
  266. {
  267. if (InitialData == null)
  268. {
  269. if(Application.isEditor) DevWarning.SetActive(true);
  270. InitialData = new CharacterAppearance(CharacterData.Create(0));
  271. }
  272. AppearanceData = InitialData.Copy();
  273. mSex = (Sex)InitialData._CharacterData.Sex;
  274. SwitchUI(1);
  275. InitializeCharacter();
  276. NamePanel.SetActive(Settings.AllowNameChange);
  277. OutfitCategoryPanel.SetActive(Settings.AllowCustomOutfit);
  278. OutfitSavePanel.SetActive(Settings.AllowCustomOutfit);
  279. SexPanel.SetActive(Settings.AllowSexSwitch);
  280. RacePanel.SetActive(Settings.AllowRaceChange && Settings.RaceSettingVisible);
  281. if(BackPanel) BackPanel.SetActive(Settings.BackCategoryVisible);
  282. if (TailPanel) TailPanel.SetActive(Settings.TailCategoryVisible);
  283. Initialized = true;
  284. }
  285. public void CloseDeveWarning()
  286. {
  287. DevWarning.SetActive(false);
  288. }
  289. public void OpenHelp()
  290. {
  291. Application.OpenURL(Application.dataPath.Replace("Assets", "") + "Assets/SoftKitty/MasterCharacterCreator/Documentation/UserGuide.pdf");
  292. }
  293. public void InitializeCharacter()
  294. {
  295. MyCharacter.Initialize(AppearanceData);
  296. MyCharacter.transform.localEulerAngles = new Vector3(0F, -5F, 0F);
  297. RefreshData();
  298. MyCharacter.GetComponent<Animator>().SetTrigger("Enter");
  299. }
  300. public void RefreshData()
  301. {
  302. foreach (CharacterCusSliders obj in MyLeftSliders)
  303. {
  304. obj.InitData(AppearanceData);
  305. }
  306. MatScript.UpdateValue();
  307. SexSels[0].SetActive(mSex == Sex.Male);
  308. SexSels[1].SetActive(mSex == Sex.Female);
  309. NameInput.text = AppearanceData._Name;
  310. }
  311. public void SwitchOutfit(OutfitSlots _slot, int _id)
  312. {
  313. AppearanceData._OutfitID[(int)_slot] = (byte)_id;
  314. if ((int)_slot < 5)
  315. {
  316. AppearanceData._CusColor1[(int)_slot] = Uint8Color.Set(CharacterDataSetting.instance.GetOutfitColorSetting((Sex)AppearanceData._CharacterData.Sex, _slot, _id).DefaultColor1);
  317. AppearanceData._CusColor2[(int)_slot] = Uint8Color.Set(CharacterDataSetting.instance.GetOutfitColorSetting((Sex)AppearanceData._CharacterData.Sex, _slot, _id).DefaultColor2);
  318. AppearanceData._CusColor3[(int)_slot] = Uint8Color.Set(CharacterDataSetting.instance.GetOutfitColorSetting((Sex)AppearanceData._CharacterData.Sex, _slot, _id).DefaultColor3);
  319. }
  320. SoundManager.Play2D("Clothes");
  321. }
  322. public void SetSex(Sex _sex)
  323. {
  324. CharacterManager.instance.RemovePreviewCharacter("cc_" + mSex.ToString());
  325. if (mSex != _sex)AppearanceData = new CharacterAppearance(CharacterData.Create((byte)_sex));
  326. mSex = _sex;
  327. InitializeCharacter();
  328. SexSels[0].SetActive(_sex == Sex.Male);
  329. SexSels[1].SetActive(_sex == Sex.Female);
  330. SoundManager.Play2D("Load");
  331. }
  332. public void SaveClothes()
  333. {
  334. string _rootPath = SaveRootPath + "/Clothes/";
  335. if (!Directory.Exists(_rootPath)) Directory.CreateDirectory(_rootPath);
  336. string _photoName = AppearanceData._Name;
  337. int _index = 2;
  338. while (File.Exists(_rootPath + _photoName + ".png"))
  339. {
  340. _photoName = AppearanceData._Name + "_" + _index.ToString();
  341. _index++;
  342. }
  343. if (SaveFormat == SaveMethod.PngFile)
  344. {
  345. SaveCharacterWithPhoto(_rootPath, _photoName, BlurPrintType.Outfits);
  346. }
  347. else
  348. {
  349. CharacterManager.SaveCharacterDataToResources(MyCharacter, _rootPath + _photoName, BlurPrintType.Outfits);
  350. SimpleDynamicMsg.PopMsg("Character saved in ["+SaveRootPath + "/Clothes/" + _photoName + "]");
  351. #if UNITY_EDITOR
  352. UnityEditor.AssetDatabase.Refresh();
  353. #endif
  354. }
  355. }
  356. public void LoadClothes()
  357. {
  358. string _rootPath = SaveRootPath + "/Clothes/";
  359. if (!Directory.Exists(_rootPath)) Directory.CreateDirectory(_rootPath);
  360. if (SaveFormat == SaveMethod.PngFile)
  361. {
  362. InitBlueprintList(_rootPath);
  363. ToggleBlueprintList(true);
  364. }
  365. else
  366. {
  367. InitByteFileList(_rootPath, "MasterCharacterCreator/CustomBlueprints/Clothes/");
  368. ToggleByteFileList(true);
  369. }
  370. }
  371. public void SaveData()
  372. {
  373. string _rootPath = SaveRootPath + "/Characters/";
  374. if (!Directory.Exists(_rootPath)) Directory.CreateDirectory(_rootPath);
  375. string _photoName = AppearanceData._Name;
  376. int _index = 2;
  377. while (File.Exists(_rootPath + _photoName + ".png"))
  378. {
  379. _photoName = AppearanceData._Name + "_" + _index.ToString();
  380. _index++;
  381. }
  382. if (SaveFormat == SaveMethod.PngFile)
  383. {
  384. SaveCharacterWithPhoto(_rootPath, _photoName, BlurPrintType.AllAppearance);
  385. }
  386. else
  387. {
  388. CharacterManager.SaveCharacterDataToResources(MyCharacter, _rootPath+ _photoName, BlurPrintType.AllAppearance);
  389. SimpleDynamicMsg.PopMsg("Character saved in ["+SaveRootPath + "/Characters/" + _photoName+"]");
  390. #if UNITY_EDITOR
  391. UnityEditor.AssetDatabase.Refresh();
  392. #endif
  393. }
  394. }
  395. public void LoadData()
  396. {
  397. string _rootPath = SaveRootPath + "/Characters/";
  398. if (!Directory.Exists(_rootPath)) Directory.CreateDirectory(_rootPath);
  399. if (SaveFormat == SaveMethod.PngFile)
  400. {
  401. InitBlueprintList(_rootPath);
  402. ToggleBlueprintList(true);
  403. }
  404. else
  405. {
  406. InitByteFileList(_rootPath, "MasterCharacterCreator/CustomBlueprints/Characters/");
  407. ToggleByteFileList(true);
  408. }
  409. }
  410. public void SaveCharacterWithPhoto(string _path, string _fileName, BlurPrintType _type)
  411. {
  412. StartCoroutine(SaveCharacterWithPhotoCo(_path,_fileName, _type));
  413. }
  414. public Texture2D CaptureAvatar()
  415. {
  416. Vector3[] corners = new Vector3[4];
  417. PhotoCenter.GetWorldCorners(corners);
  418. var bl = RectTransformUtility.WorldToScreenPoint(null, corners[0]);
  419. var tl = RectTransformUtility.WorldToScreenPoint(null, corners[1]);
  420. var tr = RectTransformUtility.WorldToScreenPoint(null, corners[2]);
  421. var height = tl.y - bl.y;
  422. var width = tr.x - bl.x;
  423. //Debug.Log(bl.x+","+ bl.y+" > "+width + ","+height);
  424. Texture2D tex = new Texture2D((int)width, (int)height, TextureFormat.RGB24, false);
  425. Rect rex = new Rect(bl.x, bl.y, width, height);
  426. tex.ReadPixels(rex, 0, 0);
  427. tex.Apply();
  428. return tex;
  429. }
  430. public void ToggleBlueprintList(bool _visible)
  431. {
  432. BlueprintList.SetActive(_visible);
  433. }
  434. public void ToggleByteFileList(bool _visible)
  435. {
  436. ByteFileList.SetActive(_visible);
  437. }
  438. public void RestoreData()
  439. {
  440. CharacterManager.instance.RemovePreviewCharacter("cc_" + mSex.ToString());
  441. Initialize();
  442. SimpleDynamicMsg.PopMsg("Character has been reset.");
  443. SoundManager.Play2D("Load");
  444. }
  445. public void Preset(int _id)
  446. {
  447. AppearanceData = CharacterManager.LoadCharacterDataFromResources( "MasterCharacterCreator/Presets/shape_"+_id.ToString()+"_"+mSex.ToString(), AppearanceData).Copy();
  448. MyCharacter.Initialize(AppearanceData);
  449. RefreshData();
  450. ToggleByteFileList(false);
  451. SoundManager.Play2D("Load");
  452. }
  453. public void RandomLook()
  454. {
  455. Color[] _colors = ColorPicker.GetColorPalette();
  456. List<Color> _skinColors = new List<Color>();
  457. List<Color> _hairColors = new List<Color>();
  458. for (int i=0;i<50;i++) {
  459. if(i<=12 || (i>=20 && i<=24) || (i>=30 && i<=34)) _skinColors.Add(_colors[i]);
  460. if (i <= 12 || (i >= 15 && i <= 24) || i >= 35) _hairColors.Add(_colors[i]);
  461. }
  462. AppearanceData._CharacterData.Random(_skinColors.ToArray(),_hairColors.ToArray());
  463. MyCharacter.Initialize(AppearanceData);
  464. RefreshData();
  465. SoundManager.Play2D("Load");
  466. }
  467. public void RandomClothes()
  468. {
  469. Color[] _colors = ColorPicker.GetColorPalette();
  470. Uint8Color _outfitColor1 = Uint8Color.Set(_colors[Random.Range(0, _colors.Length)]);
  471. Uint8Color _outfitColor2 = Uint8Color.Set(_colors[Random.Range(0, _colors.Length)]);
  472. Uint8Color _outfitColor3 = Uint8Color.Set(_colors[Random.Range(0, _colors.Length)]);
  473. bool _default = Random.Range(0, 100) < 30;
  474. for (int i = 0; i < 5; i++)
  475. {
  476. OutfitInfo [] _infos= CharacterDataSetting.instance.GetOutfitSettings((Sex)AppearanceData._CharacterData.Sex, (OutfitSlots)i);
  477. AppearanceData._OutfitID[i] = (byte)Random.Range(0,_infos.Length);
  478. AppearanceData._CusColor1[i] = _default? Uint8Color.Set(_infos[AppearanceData._OutfitID[i]].ColorSetting.DefaultColor1): _outfitColor1;
  479. AppearanceData._CusColor2[i] = _default ? Uint8Color.Set(_infos[AppearanceData._OutfitID[i]].ColorSetting.DefaultColor2) : _outfitColor2;
  480. AppearanceData._CusColor3[i] = _default ? Uint8Color.Set(_infos[AppearanceData._OutfitID[i]].ColorSetting.DefaultColor3) : _outfitColor3;
  481. }
  482. RefreshData();
  483. SoundManager.Play2D("Load");
  484. }
  485. public void SwitchUI(int _id)
  486. {
  487. foreach (CharacterCusSliders obj in MyLeftSliders)
  488. {
  489. if (obj.gameObject.activeSelf)
  490. obj.FadeAway();
  491. }
  492. if (CurrentSlider != _id)
  493. {
  494. MyLeftSliders[_id].gameObject.SetActive(true);
  495. CurrentSlider = _id;
  496. }
  497. else
  498. {
  499. CurrentSlider = -1;
  500. }
  501. CurrentSlot = MyLeftSliders[_id].OutfitSlot;
  502. MyCharacter.GetComponent<Animator>().SetBool("Static", CurrentSlider==0);
  503. if (_id != -1 && onSwitchUI!=null) onSwitchUI();
  504. if (ColorPicker.instance != null) ColorPicker.instance.Cancel();
  505. SoundManager.Play2D("MenuOff");
  506. }
  507. public void Close()
  508. {
  509. GetComponent<Animation>().Play("cc_out");
  510. CharacterManager.OnCharacterCustomized(AppearanceData);
  511. }
  512. }
  513. }