ActorAvatar.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505
  1. using UnityEngine;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. public class ActorAvatar
  5. {
  6. private GameObject mAvatarObject;
  7. private Animator mAnimator;
  8. private bool mIsLoaded = false;
  9. private bool mIsLoading = false;
  10. private BoxCollider mCollider;
  11. private ModelTopUI mModelTopUI;
  12. private HeroActorData mHeroData;
  13. private FellowActorData mFellowData;
  14. private Dictionary<BodyPart, GameObject> mPartGoes = null;
  15. private string mUIPrefabName = "Battle/HeadName";
  16. private bool mIsVisible = true;
  17. private RenderTexture mRT = null;
  18. private GameObject mRTCamGo = null;
  19. private Camera mRTCam = null;
  20. public ActorData Data { get; private set; }
  21. public RenderTexture RT
  22. {
  23. get { return mRT; }
  24. }
  25. public bool IsLoaded
  26. {
  27. get { return mIsLoaded; }
  28. }
  29. public GameObject AvatarGo
  30. {
  31. get { return mAvatarObject; }
  32. }
  33. public bool IsVisible
  34. {
  35. get
  36. {
  37. return mIsVisible;
  38. }
  39. set
  40. {
  41. if (mIsVisible == value) return;
  42. mIsVisible = value;
  43. mAvatarObject.SetSafeActive(mIsVisible);
  44. if (mModelTopUI != null)
  45. {
  46. mModelTopUI.SetVisible(mIsVisible);
  47. }
  48. if(mRTCamGo!=null)
  49. {
  50. mRTCamGo.SetActive(mIsVisible);
  51. if(mIsVisible)
  52. {
  53. if (mRT == null)
  54. {
  55. mRT = RenderTexture.GetTemporary(512, 512, 32);
  56. }
  57. mRTCam.targetTexture = mRT;
  58. }
  59. else
  60. {
  61. mRTCam.targetTexture = null;
  62. if (mRT != null)
  63. {
  64. RenderTexture.ReleaseTemporary(mRT);
  65. mRT = null;
  66. }
  67. }
  68. }
  69. }
  70. }
  71. Transform mFoot;
  72. private Transform Foot
  73. {
  74. get
  75. {
  76. if (mFoot == null)
  77. {
  78. mFoot = mAvatarObject.transform.Find("foot_point");
  79. Vector3 pos = mFoot.localPosition;
  80. mFoot.localPosition = pos;
  81. }
  82. return mFoot;
  83. }
  84. }
  85. int fighterLayer = 0;
  86. int effectId = 0;
  87. public ActorAvatar(ActorData data)
  88. {
  89. Data = data;
  90. if (Data != null)
  91. {
  92. if (Data.IsHero)
  93. mHeroData = Data as HeroActorData;
  94. else if (Data.IsFellow)
  95. mFellowData = Data as FellowActorData;
  96. }
  97. fighterLayer = LayerMask.NameToLayer(BattleCamera.FighterLayerName);
  98. mIsLoaded = false;
  99. mIsLoading = false;
  100. }
  101. public void ParseLoad()
  102. {
  103. if (mIsLoaded || Data == null || mIsLoading) return;
  104. mIsLoading = true;
  105. if (mHeroData != null)
  106. {
  107. if (mHeroData.PartResList != null)
  108. {
  109. foreach (var p in mHeroData.PartResList)
  110. {
  111. BattlePrepareManager.Instance.PrecacheModel(p.Value, Data.AType);
  112. }
  113. BattlePrepareManager.Instance.PrecacheAnimatorCtrl(mHeroData.ShowAnimCtrlName);
  114. //BattlePrepareManager.Instance.PrecacheEffect(GlobalConfig.Instance.GetConfigIntValue(GlobalConfig.c_arena_choosen_effectid));
  115. }
  116. }
  117. else if (mFellowData != null)
  118. {
  119. if (!string.IsNullOrEmpty(Data.AvatarData.prefab))
  120. {
  121. BattlePrepareManager.Instance.PrecacheModel(Data.AvatarData.prefab, Data.AType);
  122. BattlePrepareManager.Instance.PrecacheAnimatorCtrl(mFellowData.ShowAnimCtrlName);
  123. }
  124. }
  125. //BattlePrepareManager.Instance.PrecacheUIPrefab(mUIPrefabName);
  126. }
  127. public void CreateGo(Vector3 pos, Camera cam,bool createName = false)
  128. {
  129. if (IsLoaded || Data == null)
  130. {
  131. mAvatarObject.transform.position = pos;
  132. IsVisible = true;
  133. return;
  134. }
  135. if (mHeroData != null)
  136. {
  137. if (mHeroData.PartResList != null && mHeroData.PartResList.Count > 0)
  138. {
  139. mPartGoes = new Dictionary<BodyPart, GameObject>();
  140. foreach (var p in mHeroData.PartResList)
  141. {
  142. LoadBodyPartGo(p.Key, p.Value);
  143. }
  144. InitAvatar();
  145. }
  146. else
  147. {
  148. GameObject go = ResourceMgr.Instance.GetGoFromPool(Constants.ModelPath, mHeroData.AvatarData.prefab);
  149. OnAvatarLoaded(go, Constants.ModelPath, mHeroData.AvatarData.prefab);
  150. }
  151. }
  152. else if (mFellowData != null)
  153. {
  154. GameObject go = ResourceMgr.Instance.GetGoFromPool(Constants.ModelPath, Data.AvatarData.prefab);
  155. OnAvatarLoaded(go, Constants.ModelPath, Data.AvatarData.prefab);
  156. }
  157. if (mAvatarObject != null)
  158. {
  159. mAvatarObject.transform.position = pos;
  160. if(createName)
  161. {
  162. mModelTopUI = new ModelTopUI(mAvatarObject, cam, mUIPrefabName);
  163. mModelTopUI.SetNameAndLevel(Data.Name, Data.Level);
  164. }
  165. }
  166. }
  167. public void GenerateRT()
  168. {
  169. if (mRTCamGo != null)
  170. {
  171. Vector3 camPos = mAvatarObject.transform.position;
  172. camPos.y += 1.1f;
  173. camPos.z -= 2;
  174. mRTCamGo.transform.position = camPos;
  175. return;
  176. }
  177. if(mRTCamGo == null)
  178. {
  179. mRTCamGo = new GameObject(Data.Name + "_RTCam");
  180. }
  181. mRTCamGo.transform.SetParent(PreviewTeamMgr.Instance.transform);
  182. mRTCam = mRTCamGo.GetComponent<Camera>();
  183. if(mRTCam == null)
  184. {
  185. mRTCam = mRTCamGo.AddComponent<Camera>();
  186. }
  187. mRTCam.cullingMask = LayerMask.GetMask("Model");
  188. mRTCam.farClipPlane = 10;
  189. mRTCam.orthographicSize = 1.5f;
  190. mRTCam.useOcclusionCulling = false;
  191. mRTCam.clearFlags = CameraClearFlags.SolidColor;
  192. mRTCam.orthographic = true;
  193. if (mRT == null)
  194. {
  195. mRT = RenderTexture.GetTemporary(512, 512, 32);
  196. }
  197. mRTCam.targetTexture = mRT;
  198. if(GameMgr.Instance.IsBadDevice)
  199. {
  200. mRTCam.allowMSAA = false;
  201. }
  202. else
  203. {
  204. mRTCam.allowMSAA = true;
  205. }
  206. Vector3 pos = mAvatarObject.transform.position;
  207. pos.y += 1.1f;
  208. pos.z -= 2;
  209. mRTCamGo.transform.position = pos;
  210. }
  211. public void LookAt(Vector3 pos)
  212. {
  213. if (mAvatarObject == null) return;
  214. mAvatarObject.transform.LookAt(pos);
  215. }
  216. public void Update(Camera cam)
  217. {
  218. if (mModelTopUI != null)
  219. {
  220. mModelTopUI.Update(cam);
  221. }
  222. }
  223. public void Dispose()
  224. {
  225. mRTCam = null;
  226. if(mRTCamGo != null)
  227. {
  228. GameObject.Destroy(mRTCamGo);
  229. mRTCamGo = null;
  230. }
  231. if(mRT!=null)
  232. {
  233. RenderTexture.ReleaseTemporary(mRT);
  234. mRT = null;
  235. }
  236. StopEffect();
  237. if (mCollider != null)
  238. {
  239. GameObject.DestroyImmediate(mCollider);
  240. mCollider = null;
  241. }
  242. if (mModelTopUI != null)
  243. {
  244. mModelTopUI.Dispose();
  245. mModelTopUI = null;
  246. }
  247. if (mHeroData != null)
  248. {
  249. RecyclePartGo();
  250. if (mAvatarObject != null)
  251. {
  252. GameObject.Destroy(mAvatarObject);
  253. mAvatarObject = null;
  254. }
  255. }
  256. else if (mFellowData != null)
  257. {
  258. if (mAvatarObject != null)
  259. {
  260. ResourceMgr.Instance.RecycleGO(Constants.ModelPath, mFellowData.AvatarData.prefab, mAvatarObject);
  261. }
  262. }
  263. Data = null;
  264. mAvatarObject = null;
  265. mHeroData = null;
  266. mFellowData = null;
  267. mIsLoaded = false;
  268. mIsLoading = false;
  269. }
  270. public void PlayEffect()
  271. {
  272. if (effectId == 0)
  273. effectId = EffectManager.Instance.PlayEffect(GlobalConfig.Instance.GetConfigIntValue(GlobalConfig.c_arena_choosen_effectid), Foot, Foot);
  274. }
  275. public void SetBattleFlag(bool inBattle)
  276. {
  277. if (mModelTopUI != null)
  278. mModelTopUI.SetBattleFlag(inBattle);
  279. }
  280. public void StopEffect()
  281. {
  282. if (effectId > 0)
  283. {
  284. EffectManager.Instance.RemoveEffectByInstanceID(effectId);
  285. effectId = 0;
  286. }
  287. }
  288. public void PlayAnim(string animName)
  289. {
  290. if (mAnimator == null) return;
  291. mAnimator.CrossFade(animName,0.1f);
  292. }
  293. private void LoadBodyPartGo(BodyPart part, string prefabName)
  294. {
  295. if (string.IsNullOrEmpty(prefabName) || mPartGoes.ContainsKey(part)) return;
  296. GameObject go = ResourceMgr.Instance.GetGoFromPool(Constants.ModelPath, prefabName);
  297. if (go != null)
  298. {
  299. mPartGoes.Add(part, go);
  300. }
  301. }
  302. private void InitAvatar()
  303. {
  304. GameObject skeletonGo = mPartGoes[BodyPart.Skeleton];
  305. if (skeletonGo == null)
  306. {
  307. DebugHelper.LogError(string.Format("{0}的基础骨骼加载失败!", Data.Name));
  308. return;
  309. }
  310. foreach (var p in mPartGoes)
  311. {
  312. BodyPart part = p.Key;
  313. if (part == BodyPart.Skeleton) continue;
  314. if (part == BodyPart.Hair)
  315. {
  316. HeroActorData hero = Data as HeroActorData;
  317. ChangeHairColor(mPartGoes[part], hero.FashionData.hairClrParam);
  318. }
  319. if (part == BodyPart.Face || part == BodyPart.HairStyle
  320. || part == BodyPart.Pupil || part == BodyPart.Eye
  321. || part == BodyPart.Hair || part == BodyPart.Cloth)
  322. {
  323. ResetMeshBones(skeletonGo, part);
  324. }
  325. else
  326. {
  327. LinkPart(skeletonGo, part);
  328. }
  329. }
  330. OnAvatarLoaded(skeletonGo, Constants.ModelPath, Data.AvatarData.prefab);
  331. }
  332. private void ResetMeshBones(GameObject skeleton, BodyPart part)
  333. {
  334. if (!mPartGoes.ContainsKey(part)) return;
  335. GameObject src = mPartGoes[part];
  336. if (src == null) return;
  337. string tmpName = string.Empty;
  338. string tmpName2 = string.Empty;
  339. string srcName = src.name;
  340. SkinnedMeshRenderer[] smrs = src.GetComponentsInChildren<SkinnedMeshRenderer>(true);
  341. if (smrs.Length > 0)
  342. {
  343. for (int i = 0; i < smrs.Length; ++i)
  344. {
  345. Transform smrsparent = smrs[i].transform.parent;
  346. tmpName = smrsparent.name;
  347. if (tmpName.Equals(srcName))
  348. {
  349. Transform[] bones = smrs[i].bones;
  350. int bonesCount = bones.Length;
  351. Transform[] newbones = new Transform[bonesCount];
  352. for (int j = 0; j < bonesCount; ++j)
  353. {
  354. string path = UnityEngineUtils.GetParentPath(bones[j], src.transform);
  355. newbones[j] = skeleton.transform.Find(path);
  356. }
  357. string path2 = UnityEngineUtils.GetParentPath(smrs[i].rootBone, src.transform);
  358. Transform tr = skeleton.transform.Find(path2);
  359. smrs[i].bones = newbones;
  360. smrs[i].rootBone = tr;
  361. smrs[i].transform.SetParentNormalize(skeleton.transform);
  362. }
  363. }
  364. }
  365. }
  366. private void LinkPart(GameObject skeleton, BodyPart part)
  367. {
  368. if (!mPartGoes.ContainsKey(part)) return;
  369. GameObject src = mPartGoes[part];
  370. if (src == null) return;
  371. BodyPartParam partParam = mHeroData.GetBodyPartParam(part);
  372. if (string.IsNullOrEmpty(partParam.linkPoint)) return;
  373. Transform partTrans = src.transform;
  374. string linkPoint = partParam.linkPoint;
  375. Transform linkTrans = UnityEngineUtils.RecurisiveFindTransformChild(skeleton.transform, linkPoint);
  376. if (linkTrans == null) return;
  377. partTrans.SetParent(linkTrans);
  378. partTrans.localPosition = partParam.pos;
  379. partTrans.localRotation = Quaternion.Euler(partParam.rot);
  380. partTrans.localScale = partParam.scale;
  381. }
  382. void ChangeHairColor(GameObject go, HairColorParam colorParam)
  383. {
  384. SkinnedMeshRenderer smr = go.GetComponentInChildren<SkinnedMeshRenderer>();
  385. if (smr == null) return;
  386. Material mat = smr.material;
  387. if (mat == null) return;
  388. mat.SetTextureOffset("_MainTex", colorParam.uvOffset);
  389. }
  390. private void OnAvatarLoaded(GameObject go, string path, params string[] assetName)
  391. {
  392. if (go != null)
  393. {
  394. go.transform.SetParent(PreviewTeamMgr.Instance.transform);
  395. go.transform.localPosition = Data.Offset;
  396. go.transform.localEulerAngles = new Vector3(0,180,0);
  397. go.transform.localScale = Vector3.one * Data.AvatarData.scale;
  398. CommonUtil.SetGameObjectLayer(go, "Model");
  399. go.name = Data.Name;
  400. mAvatarObject = go;
  401. mCollider = mAvatarObject.GetComponent<BoxCollider>();
  402. if (mCollider == null)
  403. mCollider = mAvatarObject.AddComponent<BoxCollider>();
  404. mCollider.center = new Vector3(0, 0.5f, 0);
  405. mCollider.size = new Vector3(2, 2, 2);
  406. go.SetActive(true);
  407. mAnimator = go.GetComponent<Animator>();
  408. if (mAnimator != null)
  409. {
  410. UnityEngine.Object asset = ResourceMgr.Instance.GetAsset(Constants.AnimatorPath, Data.ShowAnimCtrlName);
  411. if (asset != null)
  412. {
  413. mAnimator.runtimeAnimatorController = asset as RuntimeAnimatorController;
  414. }
  415. mAnimator.cullingMode = AnimatorCullingMode.AlwaysAnimate;
  416. }
  417. }
  418. else
  419. {
  420. DebugHelper.LogError("{0}/{1} 加载失败", path, assetName[0]);
  421. }
  422. mIsLoading = false;
  423. mIsLoaded = true;
  424. }
  425. private void RecyclePartGo()
  426. {
  427. if (mPartGoes == null) return;
  428. foreach (var p in mPartGoes)
  429. {
  430. GameObject.Destroy(p.Value);
  431. }
  432. mPartGoes.Clear();
  433. }
  434. }