unity 人物身上绑点脚本

首先定义一个绑点的枚举脚本

using System.Collections.Generic;
using UnityEngine;

public enum DummyPoint
{
    DM_NONE = 0,   // 无
    DM_ACTOR_BIND,//根节点
    DM_ACTOR_BREAST,//胸部
    DM_ACTOR_HEAD,//头顶,名字挂载点
    DM_ACTOR_L_HAND,//左手
    DM_ACTOR_L_WEAPON,//左手武器
    DM_ACTOR_R_HAND,//右手
    DM_ACTOR_R_WEAPON,//右手武器
    DM_ACTOR_GLASS,//眼镜

    DM_MAX,
}

public static class AvatarDefine
{

    private static Dictionary<string, DummyPoint> m_dummyNameMap = null;
    private static Dictionary<int, string> m_dummyIdxMap = null;
    private static DummyPoint[] m_allDummyArray = null;


    private static void CheckInit()
    {
        if (m_dummyNameMap == null)
        {
            m_dummyNameMap = new Dictionary<string, DummyPoint>();
            m_dummyIdxMap = new Dictionary<int, string>();

            int allValidDummyCount = (int)DummyPoint.DM_MAX;
            m_allDummyArray = new DummyPoint[allValidDummyCount];

            int currDummyIndex = 0;
            for (int i = 0; i < (int)DummyPoint.DM_MAX; i++)
            {
                var dummy = (DummyPoint)i;
                var dummyName = dummy.ToString();
                m_dummyNameMap[dummyName] = dummy;
                m_dummyIdxMap[i] = dummyName;

                m_allDummyArray[currDummyIndex++] = (DummyPoint)i;
            }
        }
    }

    public static DummyPoint[] GetDummyPointArray()
    {
        CheckInit();
        return m_allDummyArray;
    }

    public static string GetDummyPointName(DummyPoint dm_point)
    {
        CheckInit();

        string name;
        if (m_dummyIdxMap.TryGetValue((int)dm_point, out name))
        {
            return name;
        }

        Debug.LogErrorFormat("Invalid dummy name: {0}", dm_point.ToString());
        return null;
    }

    public static DummyPoint GetDummyPointByName(string dm_point)
    {
        CheckInit();

        DummyPoint point;
        if (m_dummyNameMap.TryGetValue(dm_point, out point))
        {
            return point;
        }

        return DummyPoint.DM_NONE;
    }
}

再创建一个处理脚本。

using System.Collections.Generic;
using UnityEngine;

public class GoDummyListenData
{
    /// <summary>
    /// 绑点
    /// </summary>
    public DummyPoint m_dummyPoint;

    /// <summary>
    /// 绑定对应的Transfrom
    /// </summary>
    public Transform m_currTrans;

    /// <summary>
    /// 绑点上挂上的物体,key=物体名字或者路径对应的GetHashCode(),value=物体
    /// </summary>
    private Dictionary<int, GameObject> m_dm_bindObjDic = new Dictionary<int, GameObject>();


    public GoDummyListenData(DummyPoint dummyPoint, Transform bindTran)
    {
        m_dummyPoint = dummyPoint;
        m_currTrans = bindTran;
    }

    /// <summary>
    /// 绑点上增加物体
    /// </summary>
    /// <param name="dm"></param>
    /// <param name="obj"></param>
    public void AddDummyBindObj(string bindObjName, GameObject obj)
    {
        int hashCode = bindObjName.GetHashCode();
        if (m_dm_bindObjDic.ContainsKey(hashCode))
        {
            Debug.LogErrorFormat("GoDummyListenData AddDummyBindObj contain same key,bindObjName={0},obj={1}", bindObjName, obj.name);
            m_dm_bindObjDic[hashCode] = obj;
        }
        else
        {
            m_dm_bindObjDic.Add(hashCode, obj);
        }
    }

    /// <summary>
    /// 绑点上移除物体
    /// </summary>
    /// <param name="dm"></param>
    /// <param name="isDestroy"></param>
    public void RemoveDummyBindObj(string bindObjName, bool isDestroy = true)
    {
        int hashCode = bindObjName.GetHashCode();
        if (m_dm_bindObjDic.ContainsKey(hashCode))
        {
            if (isDestroy)
            {
                GameObject t = m_dm_bindObjDic[hashCode];
                GameObject.Destroy(t);
            }
            m_dm_bindObjDic.Remove(hashCode);
        }
    }

    /// <summary>
    /// 获取绑点上的物体
    /// </summary>
    /// <param name="dm"></param>
    /// <returns></returns>
    public GameObject GetDummyBindObj(string bindObjName)
    {
        int hashCode = bindObjName.GetHashCode();
        if (m_dm_bindObjDic.ContainsKey(hashCode))
        {
            return m_dm_bindObjDic[hashCode];
        }
        return null;
    }

    /// <summary>
    /// 删除所有绑定上的物体
    /// </summary>
    public void SafeDestroyDummyBindObj()
    {
        foreach (var obj in m_dm_bindObjDic)
        {
            GameObject.Destroy(obj.Value);
        }
        m_dm_bindObjDic.Clear();
    }
}

public class GoDummyPoint
{
    // 例如[eSoulFriend][649][649]
    private Transform m_goRootTrans = null;

    //绑定名字与绑点Transfrom对应关系
    private Dictionary<int, Transform> m_dummyCacheMap = new Dictionary<int, Transform>();

    //绑定数据对应列表
    private List<GoDummyListenData> m_listChangedListen = new List<GoDummyListenData>();

    private bool m_isInit = false;

    public void OnInit(Transform goTrans)
    {
        if (!m_isInit)
        {
            m_goRootTrans = goTrans;
            m_dummyCacheMap.Clear();
            m_listChangedListen.Clear();
            m_isInit = true;
        }
    }

    public void OnDestory()
    {
        m_goRootTrans = null;
        for (int i = 0; i < m_listChangedListen.Count; i++)
        {
            var changeData = m_listChangedListen[i];
            changeData.SafeDestroyDummyBindObj();
        }
        m_dummyCacheMap.Clear();
        m_listChangedListen.Clear();
    }

    /// <summary>
    /// 获取绑定对应的Transfrom
    /// </summary>
    /// <param name="dummyPoint"></param>
    /// <returns></returns>
    public Transform GetDummyPoint(DummyPoint dummyPoint)
    {
        if (dummyPoint == DummyPoint.DM_NONE)
        {
            Debug.LogError("GoDummyPoint GetDummyPoint dummyPoint == DummyPoint.DM_NONE");
            return null;
        }

        Transform ret;
        if (!m_dummyCacheMap.TryGetValue((int)dummyPoint, out ret))
        {
            ret = FindChildInTransfromAllChild(m_goRootTrans, AvatarDefine.GetDummyPointName(dummyPoint));
            m_dummyCacheMap.Add((int)dummyPoint, ret);
        }

        return ret;
    }

    /// <summary>
    /// 获取绑定对应的Transfrom
    /// </summary>
    /// <param name="dummyName"></param>
    /// <returns></returns>
    public Transform GetDummyPoint(string dummyName)
    {
        var dummyPoint = AvatarDefine.GetDummyPointByName(dummyName);
        if (dummyPoint == DummyPoint.DM_NONE)
        {
            Debug.LogError("GoDummyPoint GetDummyPoint dummyPoint == DummyPoint.DM_NONE");
            return null;
        }

        return GetDummyPoint(dummyPoint);
    }

    #region 增加一些事件

    /// <summary>
    /// 绑点上增加物体
    /// </summary>
    /// <param name="dummyPoint"></param>
    /// <param name="obj"></param>
    public void AddDummyBindObj(DummyPoint dummyPoint, GameObject obj)
    {
        GoDummyListenData toAddListenData = null;
        for (int i = 0; i < m_listChangedListen.Count; i++)
        {
            var changeData = m_listChangedListen[i];
            if (changeData.m_dummyPoint == dummyPoint)
            {
                toAddListenData = changeData;
                break;
            }
        }

        if (toAddListenData == null)
        {
            Transform bind = GetDummyPoint(dummyPoint);
            toAddListenData = new GoDummyListenData(dummyPoint, bind);
            m_listChangedListen.Add(toAddListenData);
        }

        toAddListenData.AddDummyBindObj(obj.name, obj);
    }

    /// <summary>
    /// 绑点上移除物体
    /// </summary>
    /// <param name="dummyPoint"></param>
    /// <param name="objName">物体名字</param>
    public void RemoveDummyBindObj(DummyPoint dummyPoint, string objName)
    {
        GoDummyListenData toAddListenData = null;
        for (int i = 0; i < m_listChangedListen.Count; i++)
        {
            var changeData = m_listChangedListen[i];
            if (changeData.m_dummyPoint == dummyPoint)
            {
                toAddListenData = changeData;
                break;
            }
        }
        if (toAddListenData == null)
        {
            Debug.LogErrorFormat("GoDummyPoint RemoveDummyBindObj toAddListenData == null,dummyPoint={0},objName={1}", dummyPoint, objName);
            return;
        }
        toAddListenData.RemoveDummyBindObj(objName);
    }

    /// <summary>
    /// 获取绑点上的物体
    /// </summary>
    /// <param name="dummyPoint"></param>
    /// <param name="objName">物体名字</param>
    /// <returns></returns>
    public GameObject GetDummyBindObj(DummyPoint dummyPoint, string objName)
    {
        GoDummyListenData toAddListenData = null;
        for (int i = 0; i < m_listChangedListen.Count; i++)
        {
            var changeData = m_listChangedListen[i];
            if (changeData.m_dummyPoint == dummyPoint)
            {
                toAddListenData = changeData;
                break;
            }
        }
        if (toAddListenData == null)
        {
            Debug.LogErrorFormat("GoDummyPoint GetDummyBindObj toAddListenData == null,dummyPoint={0},objName={1}", dummyPoint, objName);
            return null;
        }
        return toAddListenData.GetDummyBindObj(objName);
    }
    #endregion

    #region 工具

    /// <summary>
    /// 找到物体所有子物体(包括孙物体所有等等)与 指定名字一样的物体
    /// </summary>
    /// <param name="transform"></param>
    /// <param name="name"></param>
    /// <returns></returns>
    private static Transform FindChildInTransfromAllChild(Transform transform, string name)
    {
        if (transform == null || string.IsNullOrEmpty(name))
        {
            return null;
        }
        Transform[] childArray = transform.GetComponentsInChildren<Transform>(true);
        for (int i = 0; i < childArray.Length; i++)
        {
            if (childArray[i] == null)
            {
                continue;
            }
            if (name.Equals(childArray[i].name))
            {
                return childArray[i];
            }
        }
        return null;
    }

    #endregion
}

使用时需要new一个GoDummyPoint。然后通过.OnInit()将需要绑点脚本的人物传入即可

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值