From f780b81a4dc334ea13ffe95c721c38325ad300bf Mon Sep 17 00:00:00 2001
From: hch <305670599@qq.com>
Date: 星期四, 20 十一月 2025 18:42:45 +0800
Subject: [PATCH] 331 子 【主界面】坐骑系统 / 【主界面】座骑系统-客户端

---
 Main/Config/Configs/HorseSkinConfig.cs    |   24 ++++
 Main/System/Horse/HorseController.cs      |  191 ++++++++++++++++++++++++++++++++++++++
 Main/System/Horse/HorseManager.cs         |    7 +
 Main/System/Main/HomeWin.cs               |    4 
 Main/System/Horse/HorseController.cs.meta |   11 ++
 Main/System/Horse/HorseWin.cs             |    4 
 6 files changed, 233 insertions(+), 8 deletions(-)

diff --git a/Main/Config/Configs/HorseSkinConfig.cs b/Main/Config/Configs/HorseSkinConfig.cs
index d39ef3f..4f73c0f 100644
--- a/Main/Config/Configs/HorseSkinConfig.cs
+++ b/Main/Config/Configs/HorseSkinConfig.cs
@@ -1,6 +1,6 @@
 锘�//--------------------------------------------------------
 //    [Author]:           YYL
-//    [  Date ]:           2025骞�11鏈�16鏃�
+//    [  Date ]:           2025骞�11鏈�20鏃�
 //--------------------------------------------------------
 
 using System.Collections.Generic;
@@ -27,7 +27,9 @@
 	public int[] AttrIDList;
 	public int[] InitAttrValueList;
 	public int[] AttrPerStarAddList;
-	public string Icon;
+	public string Spine;
+	public int[] Poses;
+	public int heroFirst;
 
     public override int LoadKey(string _key)
     {
@@ -97,7 +99,23 @@
 				}
 			}
 
-			Icon = tables[11];
+			Spine = tables[11];
+
+			if (tables[12].Contains("["))
+			{
+				Poses = JsonMapper.ToObject<int[]>(tables[12]);
+			}
+			else
+			{
+				string[] PosesStringArray = tables[12].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries);
+				Poses = new int[PosesStringArray.Length];
+				for (int i=0;i<PosesStringArray.Length;i++)
+				{
+					 int.TryParse(PosesStringArray[i],out Poses[i]);
+				}
+			}
+
+			int.TryParse(tables[13],out heroFirst); 
         }
         catch (Exception exception)
         {
diff --git a/Main/System/Horse/HorseController.cs b/Main/System/Horse/HorseController.cs
new file mode 100644
index 0000000..e26a83d
--- /dev/null
+++ b/Main/System/Horse/HorseController.cs
@@ -0,0 +1,191 @@
+
+using System;
+using Spine.Unity;
+using UnityEngine;
+using UnityEngine.UI;
+
+public class HorseController : MonoBehaviour
+{
+	private GameObjectPoolManager.GameObjectPool pool;
+	private int skinID;
+	protected SkeletonGraphic skeletonGraphic;
+
+	protected Spine.AnimationState spineAnimationState;
+	private GameObject instanceGO;
+
+	protected UIHeroController hero;
+
+	private Action onComplete;
+
+	private bool isHeroShowBefore = false;
+
+	public void Create(int _skinID, int _heroSkinID = 0, float scale = 1f, Action _onComplete = null, string motionName = "idle")
+	{
+		if (skinID == _skinID)
+		{
+			//閬垮厤閲嶅鍒涘缓
+			return;
+		}
+
+		skinID = _skinID;
+		var skinConfig = HorseSkinConfig.Get(skinID);
+
+		this.transform.localScale = Vector3.one * scale;
+
+		onComplete = _onComplete;
+		pool = GameObjectPoolManager.Instance.RequestPool(UILoader.LoadPrefab("UIHorse"));
+
+		if (!transform.gameObject.activeSelf)
+		{
+			transform.SetActive(true);
+		}
+		if (instanceGO == null)
+		{
+			instanceGO = pool.Request();
+			instanceGO.transform.SetParent(transform);
+			//transform 鐨凱ivot Y鏄�0锛岃instanceGO 灞呬腑
+			instanceGO.transform.localPosition = new Vector3(0, instanceGO.GetComponent<RectTransform>().sizeDelta.y * 0.5f);
+
+			//instanceGO.transform.localPosition = Vector3.zero;
+			instanceGO.transform.localScale = Vector3.one;
+			instanceGO.transform.localRotation = Quaternion.identity;
+		}
+
+		skeletonGraphic = instanceGO.GetComponentInChildren<SkeletonGraphic>(true);
+
+		skeletonGraphic.skeletonDataAsset = ResManager.Instance.LoadAsset<SkeletonDataAsset>("UIEffect/Spine/Horse/", skinConfig.Spine);
+		if (skeletonGraphic.skeletonDataAsset == null)
+		{
+
+			transform.SetActive(false);
+			if (pool != null)
+				pool.Release(instanceGO);
+			skeletonGraphic = null;
+			Destroy(instanceGO);
+			Debug.LogError("鏈厤缃畇pine");
+			return;
+		}
+		skeletonGraphic.Initialize(true);
+
+		skeletonGraphic.transform.localPosition = new Vector3(skinConfig.Poses[0], skinConfig.Poses[1], 0);
+		isHeroShowBefore = skinConfig.heroFirst == 1;
+		spineAnimationState = skeletonGraphic.AnimationState;
+		spineAnimationState.Data.DefaultMix = 0f;
+		if (motionName == "")
+			motionName = GetFistSpineAnim();
+		PlayAnimation(motionName, true);
+		CreateHero(_heroSkinID);
+		spineAnimationState.Complete -= OnAnimationComplete;
+		spineAnimationState.Complete += OnAnimationComplete;
+	}
+
+	public void CreateHero(int heroSkinID)
+	{
+		hero = instanceGO.GetComponentInChildren<UIHeroController>(true);
+		if (heroSkinID == 0)
+		{
+			hero.SetActive(false);
+			return;
+		}
+		hero.SetActive(true);
+		hero.Create(heroSkinID);
+		//绾﹀畾楠戜箻鐐归楠煎悕
+		hero.GetComponent<BoneFollowerGraphic>().boneName = "mountPoint";
+		if (isHeroShowBefore)
+		{
+			hero.transform.SetAsLastSibling();
+		}
+		else
+		{
+			hero.transform.SetAsFirstSibling();
+		}
+	}
+
+	public void HeroPlay(string motionName, bool loop = false, bool replay=true)
+	{
+		hero.PlayAnimation(motionName, loop, replay);
+	}
+
+
+	protected void OnDestroy()
+	{
+		if (spineAnimationState != null)
+		{
+			spineAnimationState.Complete -= OnAnimationComplete;
+		}
+		if (pool != null)
+			pool.Release(instanceGO);
+		skeletonGraphic = null;
+		pool = null;
+	}
+
+	/// <summary>
+	/// 鎾斁 Spine 鍔ㄧ敾
+	/// </summary>
+	/// <param name="motionName">鍔ㄤ綔鍚�</param>
+	/// <param name="loop">寰幆</param>
+	/// <param name="replay">濡傛灉鐩稿悓鍔ㄤ綔鏄惁鍐嶆閲嶆挱锛屾瘮濡傝窇姝ラ噸鎾氨浼氳烦甯т笉椤烘粦</param>
+	public virtual void PlayAnimation(string motionName, bool loop = false, bool replay=true)
+	{
+		if (spineAnimationState == null) return;
+
+		if (GetCurrentAnimationName() == motionName && !replay)
+			return;
+
+		// 鐩存帴浣跨敤 ToString() 鑰屼笉鏄皟鐢� GetAnimationName
+		spineAnimationState.SetAnimation(0, motionName.ToString(), loop);
+	}
+
+	// 鎾斁绗竴涓姩鐢伙紙浣滀负榛樿鍔ㄧ敾锛�
+	string GetFistSpineAnim()
+	{
+		var skeletonData = skeletonGraphic.Skeleton.Data;
+		if (skeletonData.Animations.Count > 0)
+		{
+			return skeletonData.Animations.Items[0].Name;
+		}
+		else
+		{
+			Debug.LogError("Spine 鏁版嵁涓病鏈夋壘鍒颁换浣曞姩鐢伙紒姝﹀皢鐨偆锛�" + skinID);
+		}
+		return "";
+	}
+
+	/// <summary>
+	/// 鑾峰彇褰撳墠姝e湪鎾斁鐨� Spine 鍔ㄧ敾鍚嶇О
+	/// </summary>
+	/// <returns>褰撳墠鍔ㄧ敾鍚嶇О锛屽鏋滄病鏈夊姩鐢诲垯杩斿洖绌哄瓧绗︿覆</returns>
+	public string GetCurrentAnimationName()
+	{
+		if (spineAnimationState == null || spineAnimationState.GetCurrent(0) == null)
+		{
+			return string.Empty;
+		}
+		return spineAnimationState.GetCurrent(0).Animation.Name;
+	}
+
+
+
+	/// <summary>
+	/// 鍔ㄧ敾瀹屾垚浜嬩欢澶勭悊
+	/// </summary>
+	protected virtual void OnAnimationComplete(Spine.TrackEntry trackEntry)
+	{
+		onComplete?.Invoke();
+	}
+
+	//瓒婂ぇ瓒婂揩
+	public void SetSpeed(float speed)
+	{
+		spineAnimationState.TimeScale = speed;
+	}
+
+	public void SetEnabled(bool isEnable)
+	{ 
+		if (skeletonGraphic == null)
+		{
+			return;
+		}
+		skeletonGraphic.enabled = isEnable;
+	}
+}
\ No newline at end of file
diff --git a/Main/System/Horse/HorseController.cs.meta b/Main/System/Horse/HorseController.cs.meta
new file mode 100644
index 0000000..f959473
--- /dev/null
+++ b/Main/System/Horse/HorseController.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 3a19cf54a40ad4348a228c032b8b6964
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/Horse/HorseManager.cs b/Main/System/Horse/HorseManager.cs
index c9a935c..3ffeb8c 100644
--- a/Main/System/Horse/HorseManager.cs
+++ b/Main/System/Horse/HorseManager.cs
@@ -66,7 +66,12 @@
 
     public int GetHorseSkinID()
     {
-        return (int)PlayerDatas.Instance.baseData.equipShowSwitch%1000;
+        var id = (int)PlayerDatas.Instance.baseData.equipShowSwitch % 1000;
+        if (id == 0)
+        {
+            id = 1;
+        }
+        return id;
     }
 
     public void UpdateHorseInfo(HA303_tagSCHorseClassInfo netPack)
diff --git a/Main/System/Horse/HorseWin.cs b/Main/System/Horse/HorseWin.cs
index 336e7fe..c244fa3 100644
--- a/Main/System/Horse/HorseWin.cs
+++ b/Main/System/Horse/HorseWin.cs
@@ -9,7 +9,7 @@
 /// </summary>
 public class HorseWin : UIBase
 {
-    [SerializeField] Image modelImg;
+    [SerializeField] HorseController modelImg;
     [SerializeField] UIEffectPlayer lvUPEffect;
     [SerializeField] Text nameText;
     [SerializeField] Text specialAttrText;
@@ -100,7 +100,7 @@
     void Display()
     {
         var skinConfig = HorseSkinConfig.Get(HorseManager.Instance.GetHorseSkinID());
-        modelImg.SetOrgSprite(skinConfig.Icon, "Horse");
+        modelImg.Create(skinConfig.SkinID, 5400010);
         nameText.text = skinConfig.Name;
         specialAttrText.text = GetSpecialAttr();
 
diff --git a/Main/System/Main/HomeWin.cs b/Main/System/Main/HomeWin.cs
index 7414a96..151229e 100644
--- a/Main/System/Main/HomeWin.cs
+++ b/Main/System/Main/HomeWin.cs
@@ -65,7 +65,7 @@
     //鍧愰獞
     [SerializeField] Image horseBGImg;
     [SerializeField] Button horseBtn;
-    [SerializeField] Image horseImg;
+    [SerializeField] HorseController horseImg;
     [SerializeField] Text horseLVText;
     
     /// <summary>
@@ -505,7 +505,7 @@
             horseBGImg.SetActive(true);
             //equipShowSwitch;//褰撳墠閰嶇疆鐨勫潗楠戝瑙侷D瀛樺偍鍦紙鏈�澶ф敮鎸� 1~999锛�
             var skinConfig = HorseSkinConfig.Get(HorseManager.Instance.GetHorseSkinID());
-            horseImg.SetOrgSprite(skinConfig.Icon, "Horse");
+            horseImg.Create(skinConfig.SkinID, 0, 0.6f);
             horseLVText.text = Language.Get("Horse8",HorseManager.Instance.classLV, HorseManager.Instance.horseLV);
         }
         else

--
Gitblit v1.8.0