Untitled
unknown
plain_text
3 years ago
9.8 kB
8
Indexable
#define TEMPLATE_DRESS_CODE using System; using System.Collections.Generic; using UnityEngine; using Newtonsoft.Json.Linq; using Sirenix.OdinInspector; using Spine; using Spine.Unity; using Spine.Unity.AttachmentTools; namespace GogogaieV2.CoreSystem.MainRole { // 服裝 Sate public enum ROLE_SLOT_INDEX { HEAD = 0, BODY, LEFT_HAND, RIGHT_HAND, HEAD_DECORATION, BACK_DECORATION, NONE, }; // 總共有十三個動作 // 這邊的名稱是根據 Spine 上面的名稱做對應 // 雖然我覺得有時候名詞 有時候動詞 很奇怪= = // 8 種互動 + 5 種其他動作 // 0 就當作 None public enum MainRoleAnimState { // 其他動作 IDLING = 9, WALK, CAT, DOG, JUMP, // 互動的 SIT = 1, HAPPY, SHOCK, WORRY, SLEEP, LOVE, SAD, SPEECHLESS, // 例外狀況使用 NONE = 0 } [RequireComponent(typeof(SkeletonAnimation))] public class MainRoleController : MonoBehaviour { public float u1 = 1; public float v1 = 1; private static GameObject MainRoleOutterSpace; private static int OutSideIndex = 0; #region 主角雞相關變數 private SkeletonAnimation anim; private Skeleton skeleton; // 各個部位的資料 private Slot[] Parts; private Material[] PartsNewMaterial; // 由於要換裝 // 美術圖又沒給好 // 這裡你們自己想辦法優化 [System.NonSerialized] public RenderTexture renderT; // 這個也太好笑了吧XD // 原來是要程式自己解壓縮並蓋圖檔XD private string[] DefaultName = { "hand_L", "hair", "mouth", "eye_L", "eye_R", "head", "body", "hand_R", "tail", "foot_L", "foot_R", "shadow", }; #endregion #region 暫時給他們編輯使用的功能 #if UNITY_EDITOR #if TEMPLATE_DRESS_CODE [Space(10)] [System.NonSerialized, ShowInInspector] public long DressID; [System.NonSerialized, ShowInInspector] public float Rotate = -90; [System.NonSerialized, ShowInInspector] public Vector2 Offset; [System.NonSerialized, ShowInInspector] public Vector2 Scale = Vector2.one; private bool IsDebugMode = false; private void Update() { if (IsDebugMode) { TakeOffAllCloth(); var dict = FindClothingByID(DressID); ROLE_SLOT_INDEX SlotIndex = MainRoleController.PartsMapping((int)(long)dict["Part"]); WearClothing(SlotIndex, Helper.SpriteDB.GetSprite(dict["ReferenceAtlas"].ToString(), dict["ReferenceKey"].ToString()), Offset, Rotate, Scale); } } [Button("開啟 or 關閉編輯模式", ButtonSizes.Gigantic)] public void DressButton() { IsDebugMode = !IsDebugMode; } #endif #endif #endregion private void OnDestroy() { if (PartsNewMaterial != null) for (int i = 0; i < PartsNewMaterial.Length; i++) Destroy(PartsNewMaterial[i]); } /// <summary> /// 初始化 /// </summary> public void Init() { #region 初始化 anim = this.GetComponent<SkeletonAnimation>(); skeleton = anim.Skeleton; Parts = new Slot[] { skeleton.FindSlot("suit1_hat"), skeleton.FindSlot("cloth"), skeleton.FindSlot("suit1_hand_L"), skeleton.FindSlot("suit1_hand_R"), skeleton.FindSlot("glasses"), skeleton.FindSlot("decroation_back") }; // Camera & Render Texture renderT = new RenderTexture(1280 / 2, 720 / 2, 0); this.transform.parent.GetComponent<Camera>().targetTexture = renderT; this.transform.parent.GetComponent<Camera>().depth = -10; if (MainRoleOutterSpace == null) { MainRoleOutterSpace = new GameObject(); MainRoleOutterSpace.name = "MainRoleOutterSpace"; MainRoleOutterSpace.transform.position = new Vector3(-10000, 0, 0); DontDestroyOnLoad(MainRoleOutterSpace); } this.transform.parent.SetParent(MainRoleOutterSpace.transform); this.transform.parent.position = new Vector3(MainRoleController.OutSideIndex * -2000, 0, 0); MainRoleController.OutSideIndex++; // 脫衣服 TakeOffAllCloth(); SwitchAnimation(MainRoleAnimState.IDLING); anim.AnimationState.SetAnimation(0, "idling1", true); // 初始化其他部件的裝備 PartsNewMaterial = new Material[Parts.Length]; for (int i = 0; i < Parts.Length; i++) PartsNewMaterial[i] = new Material(Shader.Find("Spine/Skeleton")); #endregion } /// <summary> /// 把所有的衣服脫光 /// </summary> public void TakeOffAllCloth() { // 要先卻把這邊的所有的狀態都清空 anim.ClearState(); for (int i = 0; i < skeleton.Slots.Items.Length; i++) { bool IsFind = false; for (int j = 0; j < DefaultName.Length; j++) if (skeleton.Slots.Items[i].Data.Name == DefaultName[j]) { IsFind = true; break; } if (!IsFind) skeleton.Slots.Items[i].Attachment = null; } } /// <summary> /// 主角雞跟據穿裝備 /// </summary> public void MainRoleWear() { foreach(var key in Helper.UserDB.CacheDressedIndex.Keys) { int DressedIndex = Helper.UserDB.CacheDressedIndex[key]; long ClothingID = Helper.UserDB.Clothing[key][DressedIndex].Value<long>("ClothingId"); var dict = FindClothingByID(ClothingID); ROLE_SLOT_INDEX SlotIndex = MainRoleController.PartsMapping((int)(long)dict["Part"]); if (MainRoleController.IsOffsetInfo(dict)) WearClothing(SlotIndex, Helper.SpriteDB.GetSprite(dict["ReferenceAtlas"].ToString(), dict["ReferenceKey"].ToString()), new Vector2(Convert.ToSingle(dict["OffsetX"]), Convert.ToSingle(dict["OffsetY"])), Convert.ToSingle(dict["Rotate"]), new Vector2(Convert.ToSingle(dict["ScaleX"]), Convert.ToSingle(dict["ScaleY"]))); else WearClothing(SlotIndex, Helper.SpriteDB.GetSprite(dict["ReferenceAtlas"].ToString(), dict["ReferenceKey"].ToString())); } } /// <summary> /// 穿衣服 /// </summary> /// <param name="SlotIndex">放到哪一個位置</param> /// <param name="sprite">哪一張圖片</param> public void WearClothing(ROLE_SLOT_INDEX SlotIndex, Sprite sprite) { WearClothing(SlotIndex, sprite, Vector2.zero, -90, new Vector2(4.0f, 4.0f)); } public void WearClothing(ROLE_SLOT_INDEX SlotIndex, Sprite sprite, Vector2 offset, float rotate, Vector2 scale) { // 更新資料 if (SlotIndex == ROLE_SLOT_INDEX.NONE) return; int index = (int)SlotIndex; PartsNewMaterial[index].mainTexture = sprite.texture; var NewAttachment = sprite.ToRegionAttachment(PartsNewMaterial[index], rotate); NewAttachment.RegionWidth = (int)sprite.textureRect.width; NewAttachment.RegionHeight = (int)sprite.textureRect.height; NewAttachment.RegionOffsetX = sprite.textureRectOffset.x;; NewAttachment.RegionOffsetY = sprite.textureRectOffset.y;; var boneRotate = Parts[index].Bone.WorldRotationX; var bonePos = Quaternion.AngleAxis(boneRotate, Vector3.forward) * new Vector2(Parts[index].Bone.WorldX, Parts[index].Bone.WorldY); NewAttachment.X = offset.x + bonePos.x * 0.05f * u1; NewAttachment.Y = offset.y + bonePos.y * 0.05f * v1; NewAttachment.Rotation = -boneRotate; NewAttachment.ScaleX = scale.x; NewAttachment.ScaleY = scale.y; NewAttachment.UpdateOffset(); Parts[(int)index].Attachment = NewAttachment; } /// <summary> /// 接換動作 /// </summary> /// <param name=""></param> public void SwitchAnimation(MainRoleAnimState state, bool IsLoop = true) { anim.AnimationState.SetAnimation(0, System.Enum.GetName(typeof(MainRoleAnimState), state).ToLower() + "1", IsLoop); } /// <summary> /// 根據位置轉向 /// </summary> /// <param name="Sign">方向</param> public void FilpSpine(float Sign) { this.gameObject.transform.localScale = new Vector3(Sign * Mathf.Abs(this.gameObject.transform.localScale.x), this.gameObject.transform.localScale.y, 1); } /// <summary> /// 根據服飾表的 ID /// 找出對應的圖 /// </summary> /// <param name="ID">服飾表</param> /// <returns>檔案</returns> public static Dictionary<string, object> FindClothingByID(long ID) { Dictionary<string, object>[] clothingArray = (Dictionary<string, object>[])Helper.GameDB.Data["MainRoleClothingID"]; for (int i = 0; i < clothingArray.Length; i++) { Dictionary<string, object> clothingObj = clothingArray[i] as Dictionary<string, object>; if ((long)clothingObj["ID"] == ID) return clothingObj; } return null; } /// <summary> /// 部位對應關係 /// </summary> /// <param name="index">從 JSON 傳來的 Parts</param> /// <returns>實際對應的程式的 Index</returns> public static ROLE_SLOT_INDEX PartsMapping(int index) { switch (index) { case 1: return ROLE_SLOT_INDEX.HEAD; case 2: return ROLE_SLOT_INDEX.BODY; case 3: return ROLE_SLOT_INDEX.LEFT_HAND; case 4: return ROLE_SLOT_INDEX.RIGHT_HAND; case 5: return ROLE_SLOT_INDEX.HEAD_DECORATION; case 7: return ROLE_SLOT_INDEX.BACK_DECORATION; } Debug.LogError("Parts Mapping Error: " + index.ToString()); return ROLE_SLOT_INDEX.NONE; } /// <summary> /// 是否有從編輯器中 /// 編輯位移資訊 /// </summary> /// <returns> Boolean </returns> public static bool IsOffsetInfo(Dictionary<string, object> dict) { if (dict.ContainsKey("OffsetX") && dict.ContainsKey("OffsetY") && dict.ContainsKey("Rotate") && dict.ContainsKey("ScaleX") && dict.ContainsKey("ScaleY")) return true; return false; } } }
Editor is loading...