首先定义一个绑点的枚举脚本
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()将需要绑点脚本的人物传入即可