Untitled
unknown
plain_text
4 years ago
9.8 kB
9
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...