CharacterEntity_inspector.cs 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEditor;
  5. using System.IO;
  6. namespace SoftKitty.MasterCharacterCreator
  7. {
  8. [CustomEditor(typeof(CharacterEntity))]
  9. public class CharacterEntity_inspector : Editor
  10. {
  11. Color _activeColor = new Color(0.1F, 0.3F, 0.5F);
  12. Color _disableColor = new Color(0F, 0.1F, 0.3F);
  13. Color _actionColor = new Color(0F, 1F, 0.4F);
  14. Color _titleColor = new Color(0.3F, 0.5F, 1F);
  15. Color _buttonColor = new Color(0F, 0.8F, 0.3F);
  16. GUIStyle _titleButtonStyle;
  17. string _thePath;
  18. CharacterEntity myTarget;
  19. bool _showResult = false;
  20. List<string> _fileList = new List<string>();
  21. private void Awake()
  22. {
  23. var script = MonoScript.FromScriptableObject(this);
  24. _thePath = AssetDatabase.GetAssetPath(script);
  25. _thePath = _thePath.Replace("CharacterEntity_inspector.cs", "");
  26. myTarget = (CharacterEntity)target;
  27. myTarget.EditorRootPath = _thePath.Replace("Editor/", "Resources/MasterCharacterCreator/CustomBlueprints/").Replace("Assets", "");
  28. }
  29. public override void OnInspectorGUI()
  30. {
  31. GUI.changed = false;
  32. bool _valueChanged = false;
  33. _titleButtonStyle = new GUIStyle(GUI.skin.button);
  34. _titleButtonStyle.alignment = TextAnchor.MiddleLeft;
  35. Color _backgroundColor = GUI.backgroundColor;
  36. Texture logoIcon = (Texture)AssetDatabase.LoadAssetAtPath(_thePath + "Logo.png", typeof(Texture));
  37. Texture warningIcon = (Texture)AssetDatabase.LoadAssetAtPath(_thePath + "warning.png", typeof(Texture));
  38. GUILayout.BeginHorizontal();
  39. GUILayout.Box(logoIcon);
  40. GUILayout.EndHorizontal();
  41. GUILayout.BeginHorizontal();
  42. GUI.backgroundColor = _buttonColor;
  43. if (GUILayout.Button("User Guide", GUILayout.Width(100)))
  44. {
  45. Application.OpenURL(Application.dataPath.Replace("Assets", "") + _thePath.Replace("Editor/", "Documentation/UserGuide.pdf"));
  46. }
  47. GUI.backgroundColor = _titleColor;
  48. if (GUILayout.Button("Select Character Data Setting Prefab",GUILayout.Width(250)))
  49. {
  50. GameObject _data = Resources.Load<GameObject>("MasterCharacterCreator/Core/CharacterData");
  51. Selection.activeObject = _data;
  52. }
  53. GUI.backgroundColor = Color.white;
  54. GUILayout.EndHorizontal();
  55. EditorGUILayout.Separator();
  56. EditorGUILayout.BeginHorizontal();
  57. GUILayout.Label("uid:",GUILayout.Width(40));
  58. if (myTarget.mCharacterBoneControl != null)
  59. {
  60. GUI.backgroundColor = Color.black;
  61. GUILayout.Button(myTarget.uid);
  62. GUI.backgroundColor = Color.white;
  63. }
  64. else
  65. {
  66. myTarget.uid = EditorGUILayout.TextField(myTarget.uid);
  67. }
  68. if (GUILayout.Button("Copy", GUILayout.Width(60)))
  69. {
  70. EditorGUIUtility.systemCopyBuffer = myTarget.uid;
  71. }
  72. GUI.backgroundColor = myTarget.mCharacterBoneControl != null?Color.grey:_buttonColor;
  73. if (GUILayout.Button("Random",GUILayout.Width(60))) {
  74. if (myTarget.mCharacterBoneControl == null) myTarget.RandomUid();
  75. }
  76. GUI.backgroundColor = _backgroundColor;
  77. EditorGUILayout.EndHorizontal();
  78. if (myTarget.mCharacterBoneControl != null)
  79. {
  80. EditorGUILayout.BeginHorizontal();
  81. GUILayout.Box(warningIcon, GUILayout.Width(17), GUILayout.Height(17));
  82. GUI.color = Color.yellow;
  83. GUILayout.Label("uid is locked when preloaded character exists.");
  84. GUI.color = Color.white;
  85. EditorGUILayout.EndHorizontal();
  86. }
  87. if (myTarget.uid.Trim()=="") {
  88. EditorGUILayout.BeginHorizontal();
  89. GUILayout.Box(warningIcon, GUILayout.Width(17), GUILayout.Height(17));
  90. GUI.color = Color.yellow;
  91. GUILayout.Label("A unique id is required in order to customize this character.");
  92. GUI.color = Color.white;
  93. EditorGUILayout.EndHorizontal();
  94. }
  95. EditorGUILayout.Separator();
  96. if (myTarget.mCharacterBoneControl == null)
  97. {
  98. EditorGUILayout.BeginHorizontal();
  99. myTarget.LoadFromBlueprint = EditorGUILayout.Toggle(myTarget.LoadFromBlueprint, GUILayout.Width(20));
  100. GUILayout.Label("Load from preset file.");
  101. if (myTarget.LoadFromBlueprint)
  102. {
  103. GUI.backgroundColor = _buttonColor;
  104. if (GUILayout.Button("Select", GUILayout.Width(60)))
  105. {
  106. _fileList.Clear();
  107. _fileList.AddRange(Directory.GetFiles(_thePath.Replace("Editor", "Resources/MasterCharacterCreator"), "*.bytes", SearchOption.AllDirectories));
  108. _showResult = true;
  109. }
  110. GUI.backgroundColor = _backgroundColor;
  111. }
  112. EditorGUILayout.EndHorizontal();
  113. }
  114. if (myTarget.LoadFromBlueprint)
  115. {
  116. if (myTarget.mCharacterBoneControl == null)
  117. {
  118. EditorGUILayout.BeginHorizontal();
  119. myTarget.BlueprintPath = GUILayout.TextArea(myTarget.BlueprintPath);
  120. EditorGUILayout.EndHorizontal();
  121. if (_showResult)
  122. {
  123. EditorGUILayout.BeginHorizontal();
  124. GUI.color = _titleColor;
  125. GUILayout.Label("Preset files in <Resources>:", GUILayout.Width(160));
  126. GUI.color = Color.white;
  127. GUI.backgroundColor = _buttonColor;
  128. if (GUILayout.Button("X", GUILayout.Width(20)))
  129. {
  130. _fileList.Clear();
  131. _showResult = false;
  132. }
  133. GUI.backgroundColor = _backgroundColor;
  134. EditorGUILayout.EndHorizontal();
  135. for (int i = 0; i < _fileList.Count; i++)
  136. {
  137. string _path = _fileList[i].Replace(@"\", "/").Replace(_thePath.Replace("Editor/", "Resources/"), "").Replace(".bytes", "");
  138. TextAsset bindata = Resources.Load(_path) as TextAsset;
  139. BlurPrintType _bluePrintType = (BlurPrintType)bindata.bytes[0];
  140. if (_bluePrintType == BlurPrintType.AllAppearance)
  141. {
  142. EditorGUILayout.BeginHorizontal();
  143. GUI.backgroundColor = _titleColor;
  144. if (GUILayout.Button(_path, _titleButtonStyle))
  145. {
  146. myTarget.BlueprintPath = _path;
  147. _fileList.Clear();
  148. _showResult = false;
  149. }
  150. GUI.backgroundColor = _backgroundColor;
  151. EditorGUILayout.EndHorizontal();
  152. }
  153. }
  154. }
  155. }
  156. EditorGUILayout.BeginHorizontal();
  157. if (myTarget.mCharacterBoneControl != null)
  158. {
  159. GUI.backgroundColor = Color.red;
  160. if (GUILayout.Button("Clear Preloaded Character", GUILayout.Width(200)))
  161. {
  162. AssetDatabase.DeleteAsset("Assets/SoftKitty/MasterCharacterCreator/UniqueCharacterAssets/" + myTarget.uid);
  163. DestroyImmediate(myTarget.mCharacterBoneControl.gameObject);
  164. myTarget.mCharacterBoneControl = null;
  165. myTarget.GetComponent<Animator>().runtimeAnimatorController = null;
  166. myTarget.GetComponent<Animator>().avatar = null;
  167. myTarget.mCharacterAppearance = null;
  168. }
  169. EditorGUILayout.EndHorizontal();
  170. EditorGUILayout.BeginHorizontal();
  171. GUILayout.Label("Unique Assets Path:");
  172. EditorGUILayout.EndHorizontal();
  173. GUI.color = _buttonColor;
  174. EditorGUILayout.BeginHorizontal();
  175. GUILayout.Label("Assets/SoftKitty/MasterCharacterCreator/UniqueCharacterAssets/" +myTarget.uid+"/");
  176. }
  177. else
  178. {
  179. GUI.backgroundColor = myTarget.uid.Trim() == ""?Color.grey: _titleColor;
  180. if (GUILayout.Button("Preload Character", GUILayout.Width(200)))
  181. {
  182. if (myTarget.uid.Trim() != "") myTarget.LoadFromEditor(myTarget.BlueprintPath);
  183. }
  184. GUILayout.Box(warningIcon, GUILayout.Width(17),GUILayout.Height(17));
  185. GUI.color = Color.yellow;
  186. if (myTarget.uid.Trim() == "")
  187. {
  188. GUILayout.Label("Can not preload character without valid uid!");
  189. }
  190. else
  191. {
  192. GUILayout.Label("Read the notes below before click!");
  193. }
  194. }
  195. GUI.backgroundColor = Color.white;
  196. GUI.color = Color.yellow;
  197. EditorGUILayout.EndHorizontal();
  198. EditorGUILayout.BeginHorizontal();
  199. EditorGUILayout.HelpBox("Do not preload this character unless you plan to add unique components to it or your character controller requires reference of the renderer or bone transforms.\n" +
  200. "Preload this character into the scene, this will create unique material assets in 'UniqueCharacterAssets' folder.\n" +
  201. "The uid and gender of this character can not be changed after preload, but the other customizations are still avaliable.", MessageType.Info,true);
  202. EditorGUILayout.EndHorizontal();
  203. GUI.color = Color.white;
  204. }
  205. else
  206. {
  207. EditorGUILayout.BeginHorizontal();
  208. myTarget.AutoInitializeWithDefaultLooking = EditorGUILayout.Toggle(myTarget.AutoInitializeWithDefaultLooking, GUILayout.Width(20));
  209. GUILayout.Label("Auto Initialize with Default Appearance.");
  210. EditorGUILayout.EndHorizontal();
  211. EditorGUILayout.BeginHorizontal();
  212. EditorGUILayout.HelpBox("When [Load from preset file] is unchecked, you will have to manually call:\n" +
  213. "Initialize(CharacterAppearance) or Initialize(Sex)\n" +
  214. "to Initialize the character.", MessageType.Warning);
  215. EditorGUILayout.EndHorizontal();
  216. }
  217. EditorGUILayout.Separator();
  218. if (myTarget.mCharacterBoneControl == null)
  219. {
  220. EditorGUILayout.BeginHorizontal();
  221. GUILayout.Label("Animation Controller(Male):", GUILayout.Width(200));
  222. myTarget.MaleController = (RuntimeAnimatorController)EditorGUILayout.ObjectField(myTarget.MaleController, typeof(RuntimeAnimatorController), false, GUILayout.Width(200));
  223. EditorGUILayout.EndHorizontal();
  224. EditorGUILayout.BeginHorizontal();
  225. GUILayout.Label("Animation Controller(Female):", GUILayout.Width(200));
  226. myTarget.FemaleController = (RuntimeAnimatorController)EditorGUILayout.ObjectField(myTarget.FemaleController, typeof(RuntimeAnimatorController), false, GUILayout.Width(200));
  227. EditorGUILayout.EndHorizontal();
  228. EditorGUILayout.Separator();
  229. }
  230. EditorGUILayout.BeginHorizontal();
  231. GUI.color = _buttonColor;
  232. GUILayout.Label("Weapons:", GUILayout.Width(200));
  233. GUI.color = Color.white;
  234. EditorGUILayout.EndHorizontal();
  235. string[] WeaponTypes = new string[4] { "OneHanded", "TwoHanded", "Dual","Custom" };
  236. EditorGUILayout.BeginHorizontal();
  237. GUILayout.Space(20);
  238. GUILayout.Label("Weapon Equip Type:",GUILayout.Width(150));
  239. EditorGUI.BeginChangeCheck();
  240. myTarget.WeaponEquipType = EditorGUILayout.Popup(myTarget.WeaponEquipType, WeaponTypes, GUILayout.Width(200));
  241. if (EditorGUI.EndChangeCheck() || myTarget.Weapons == null || myTarget.Weapons.Length < (myTarget.WeaponEquipType == 2 ? 2 : 1)) {
  242. myTarget.Weapons = new WeaponController[myTarget.WeaponEquipType==2?2:1];
  243. _valueChanged = true;
  244. }
  245. EditorGUILayout.EndHorizontal();
  246. for (int i=0;i< myTarget.Weapons.Length;i++) {
  247. EditorGUILayout.BeginHorizontal();
  248. GUILayout.Space(20);
  249. if (myTarget.WeaponEquipType < 2)
  250. {
  251. GUILayout.Label(myTarget.WeaponEquipType == 0? "OneHanded Weapon:" : "TwoHanded Weapon:", GUILayout.Width(150));
  252. }
  253. else if (myTarget.WeaponEquipType==2) {
  254. GUILayout.Label(i == 0 ? "Left Hand Weapon:" : "Right Hand Weapon:", GUILayout.Width(150));
  255. }
  256. else
  257. {
  258. GUILayout.Label("Weapon #"+(i).ToString(), GUILayout.Width(150));
  259. }
  260. myTarget.Weapons[i] = (WeaponController)EditorGUILayout.ObjectField(myTarget.Weapons[i],typeof(WeaponController),false,GUILayout.Width(200));
  261. if (myTarget.WeaponEquipType == 3)
  262. {
  263. GUI.backgroundColor = Color.red;
  264. if (GUILayout.Button("X",GUILayout.Width(20))) {
  265. List<WeaponController> _tempList = new List<WeaponController>();
  266. _tempList.AddRange(myTarget.Weapons);
  267. _tempList.RemoveAt(i);
  268. myTarget.Weapons = _tempList.ToArray();
  269. _valueChanged = true;
  270. break;
  271. }
  272. GUI.backgroundColor = Color.white;
  273. }
  274. EditorGUILayout.EndHorizontal();
  275. if (myTarget.Weapons[i]!=null) {
  276. EditorGUILayout.BeginHorizontal();
  277. GUILayout.Space(30);
  278. GUI.color = _buttonColor;
  279. GUILayout.Label("> Type: [" + myTarget.Weapons[i].Type.ToString()+"] Hold Bone: ["+ myTarget.Weapons[i].Data.HoldParentTransform+ "] Carry Bone: [" + myTarget.Weapons[i].Data.CarryParentTransform + "]");
  280. GUI.color = Color.white;
  281. EditorGUILayout.EndHorizontal();
  282. if ((myTarget.Weapons[i].Type == WeaponType.TwoHanded && myTarget.WeaponEquipType != 1)
  283. || (myTarget.Weapons[i].Type != WeaponType.TwoHanded && myTarget.WeaponEquipType == 1)
  284. || (myTarget.Weapons[i].Type != WeaponType.LeftHand && myTarget.WeaponEquipType == 2 && i==0)
  285. || (myTarget.Weapons[i].Type != WeaponType.RightHand && myTarget.WeaponEquipType == 2 && i == 1)
  286. )
  287. {
  288. EditorGUILayout.BeginHorizontal();
  289. GUILayout.Space(20);
  290. GUI.color = Color.red;
  291. GUILayout.Label("The weapon prefab does not match the required [Type]");
  292. GUI.color = Color.white;
  293. EditorGUILayout.EndHorizontal();
  294. }
  295. string _error = "";
  296. for (int u=0;u<myTarget.Weapons.Length;u++) {
  297. if (u!=i && myTarget.Weapons[u]!=null ) {
  298. if (myTarget.Weapons[u].Data.CarryParentTransform == myTarget.Weapons[i].Data.CarryParentTransform) _error = "<Duplicated Carry Bone>";
  299. if (myTarget.Weapons[u].Data.HoldParentTransform == myTarget.Weapons[i].Data.HoldParentTransform && _error.Length<25) _error += " <Duplicated Hold Bone>";
  300. }
  301. }
  302. if (_error!="") {
  303. EditorGUILayout.BeginHorizontal();
  304. GUILayout.Space(20);
  305. GUI.color = Color.red;
  306. GUILayout.Label(_error);
  307. GUI.color = Color.white;
  308. EditorGUILayout.EndHorizontal();
  309. }
  310. }
  311. }
  312. if (myTarget.WeaponEquipType == 3)
  313. {
  314. EditorGUILayout.BeginHorizontal();
  315. GUILayout.Space(20);
  316. GUI.backgroundColor = _buttonColor;
  317. if (GUILayout.Button("Add Slot", GUILayout.Width(100)))
  318. {
  319. List<WeaponController> _tempList = new List<WeaponController>();
  320. _tempList.AddRange(myTarget.Weapons);
  321. _tempList.Add(null);
  322. myTarget.Weapons = _tempList.ToArray();
  323. _valueChanged = true;
  324. }
  325. GUI.backgroundColor = Color.white;
  326. EditorGUILayout.EndHorizontal();
  327. }
  328. EditorGUILayout.BeginHorizontal();
  329. GUILayout.Space(20);
  330. GUILayout.Label("Default State:", GUILayout.Width(150));
  331. myTarget.DefaultWeaponState = (WeaponState)EditorGUILayout.EnumPopup(myTarget.DefaultWeaponState,GUILayout.Width(200));
  332. EditorGUILayout.EndHorizontal();
  333. if ((_valueChanged || GUI.changed) && !Application.isPlaying) UnityEditor.EditorUtility.SetDirty(myTarget);
  334. EditorGUILayout.Separator();
  335. EditorGUILayout.HelpBox("How to save this character? Call:\n" +
  336. "SaveByteFileToDisk()\n" +
  337. "GetSaveBytes()\n" +
  338. "SavePngFileToDisk()\n\n" +
  339. "How to load saved data to this character? Call:\n" +
  340. "LoadFromByteFileFromDisk()\n" +
  341. "LoadFromBytes()\n" +
  342. "LoadFromPngFileFromDisk()", MessageType.Info);
  343. EditorGUILayout.Separator();
  344. base.OnInspectorGUI();
  345. }
  346. }
  347. }