hch
5 小时以前 f780b81a4dc334ea13ffe95c721c38325ad300bf
331 子 【主界面】坐骑系统 / 【主界面】座骑系统-客户端
4个文件已修改
2个文件已添加
241 ■■■■■ 已修改文件
Main/Config/Configs/HorseSkinConfig.cs 24 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Horse/HorseController.cs 191 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Horse/HorseController.cs.meta 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Horse/HorseManager.cs 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Horse/HorseWin.cs 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Main/HomeWin.cs 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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)
        {
Main/System/Horse/HorseController.cs
New file
@@ -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 的Pivot 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("未配置spine");
            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>
    /// 获取当前正在播放的 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;
    }
}
Main/System/Horse/HorseController.cs.meta
New file
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3a19cf54a40ad4348a228c032b8b6964
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
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)
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();
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;//当前配置的坐骑外观ID存储在(最大支持 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