private void SetCustomAnim(CustomAnimationData customAnim, Vector2 dir) { toggledCustomAnim = false; currentCustomAnim = customAnim; customAnimStartTime = Time.time; customAnimStartDir = dir; customAnimStartPos = Character.mainShells.transform.position.xz(); }
private static void MergeMesh(GameObject go, AnimationClip clip) { //AnimationClipSettings setting = AnimationUtility.GetAnimationClipSettings(clip); //if (!setting.loopTime) //{ // return; //} AnimationClip copyClip = Object.Instantiate(clip); GameObject copyGo = Object.Instantiate(go); EditorCurveBinding[] bindings = AnimationUtility.GetCurveBindings(copyClip); m_aniData.Clear(); //存储动画数据,为后续检查做准备 for (int i = 0; i < bindings.Length; i++) { AnimationCurve curve = AnimationUtility.GetEditorCurve(copyClip, bindings[i]); CustomAnimationData caData; if (!m_aniData.TryGetValue(bindings[i].path, out caData)) { caData = new CustomAnimationData(); m_aniData.Add(bindings[i].path, caData); } if (bindings[i].propertyName.ToLower().Contains("scale.x")) { caData.BindScale[0] = bindings[i]; caData.CurveScale[0] = curve; } else if (bindings[i].propertyName.ToLower().Contains("scale.y")) { caData.BindScale[1] = bindings[i]; caData.CurveScale[1] = curve; } else if (bindings[i].propertyName.ToLower().Contains("scale.z")) { caData.BindScale[2] = bindings[i]; caData.CurveScale[2] = curve; } else if (bindings[i].propertyName.ToLower().Contains("position.x")) { caData.BindPosition[0] = bindings[i]; caData.CurvePosition[0] = curve; } else if (bindings[i].propertyName.ToLower().Contains("position.y")) { caData.BindPosition[1] = bindings[i]; caData.CurvePosition[1] = curve; } else if (bindings[i].propertyName.ToLower().Contains("position.z")) { caData.BindPosition[2] = bindings[i]; caData.CurvePosition[2] = curve; } else if (bindings[i].propertyName.ToLower().Contains("rotation.x")) { caData.BindRotation[0] = bindings[i]; caData.CurveRotation[0] = curve; } else if (bindings[i].propertyName.ToLower().Contains("rotation.y")) { caData.BindRotation[1] = bindings[i]; caData.CurveRotation[1] = curve; } else if (bindings[i].propertyName.ToLower().Contains("rotation.z")) { caData.BindRotation[2] = bindings[i]; caData.CurveRotation[2] = curve; } else if (bindings[i].propertyName.ToLower().Contains("rotation.w")) { caData.BindRotation[3] = bindings[i]; caData.CurveRotation[3] = curve; } } //检查是否可以删除curve,可以的话就删除 foreach (KeyValuePair <string, CustomAnimationData> item in m_aniData) { item.Value.DoCheck(); } //如果父节点有动画,则子节点不能合并的 foreach (KeyValuePair <string, CustomAnimationData> item in m_aniData) { item.Value.CanRemove = IsNodeCanRemove(item.Key, item.Value.CanRemove); } //删除curve foreach (KeyValuePair <string, CustomAnimationData> item in m_aniData) { if (item.Value.CanRemove) { for (int i = 0; i < item.Value.BindPosition.Length; i++) { if (null != item.Value.BindPosition[i] && !string.IsNullOrEmpty(item.Value.BindPosition[i].path)) { AnimationUtility.SetEditorCurve(copyClip, item.Value.BindPosition[i], null); } } for (int i = 0; i < item.Value.BindScale.Length; i++) { if (null != item.Value.BindScale[i] && !string.IsNullOrEmpty(item.Value.BindScale[i].path)) { AnimationUtility.SetEditorCurve(copyClip, item.Value.BindScale[i], null); } } for (int i = 0; i < item.Value.BindRotation.Length; i++) { if (null != item.Value.BindRotation[i] && !string.IsNullOrEmpty(item.Value.BindRotation[i].path)) { AnimationUtility.SetEditorCurve(copyClip, item.Value.BindRotation[i], null); } } } } //遍历可以删除的path,在go上找出来,设置key的值,并将这些网格合并 //TODO:暂时不处理材质不同的情况,默认go下所有材质都是同一个。 Material sharedMat = null; List <MeshFilter> filterList = new List <MeshFilter>(); //用于合并的 List <Transform> childrenList = new List <Transform>(); //待删除的 //所有被删除了curve的,加入到待删除列表和合并列表 foreach (KeyValuePair <string, CustomAnimationData> item in m_aniData) { Transform child = copyGo.transform.Find(item.Key); if (null == child) { Debug.LogError("can not find " + item.Key + " in " + copyGo.name); continue; } if (!item.Value.CanRemove) { continue; } MeshFilter childFilter = child.GetComponent <MeshFilter>(); if (null == childFilter) { continue; } if (item.Value.SignScale) { child.localScale = item.Value.Scale; } if (item.Value.SignPosition) { child.localPosition = item.Value.Position; } if (item.Value.SignRotation) { child.localRotation = item.Value.Rotation; } if (null == sharedMat) { MeshRenderer render = child.GetComponent <MeshRenderer>(); if (null != render) { sharedMat = render.sharedMaterial; } } else { MeshRenderer render = child.GetComponent <MeshRenderer>(); if (null != render && sharedMat != render.sharedMaterial) { Debug.LogError(copyGo.name + "存在两个以上的材质球,会导致合并错误。"); continue; } } childrenList.Add(child); filterList.Add(childFilter); } //找出所有原来就没有k帧的child List <Transform> tempList = new List <Transform>(); FindNoAnimationChildren(copyGo.transform, copyGo.transform, tempList); for (int i = 0; i < tempList.Count; i++) { MeshRenderer mr = tempList[i].GetComponent <MeshRenderer>(); if (mr == null) { continue; } if (sharedMat == null) { sharedMat = mr.sharedMaterial; } if (mr.sharedMaterial == sharedMat) { childrenList.Add(tempList[i]); filterList.Add(tempList[i].GetComponent <MeshFilter>()); } else { Debug.LogError(tempList[i].name + "有不一样的材质"); // if (tempList[i].transform.lossyScale.x <= 0.012f && tempList[i].transform.lossyScale.y <= 0.012f && tempList[i].transform.lossyScale.z <= 0.012f) { childrenList.Add(tempList[i]); } } } //去掉scale小于0.01的 for (int i = filterList.Count - 1; i >= 0; i--) { if (filterList[i].transform.lossyScale.x <= 0.012f && filterList[i].transform.lossyScale.y <= 0.012f && filterList[i].transform.lossyScale.z <= 0.012f) { filterList.RemoveAt(i); } } //combine GameObject combineGo = null; if (filterList.Count > 0) { CombineInstance[] combines = new CombineInstance[filterList.Count]; for (int i = 0; i < combines.Length; i++) { combines[i].mesh = filterList[i].sharedMesh; combines[i].transform = filterList[i].transform.localToWorldMatrix; } combineGo = new GameObject("combine"); combineGo.AddComponent <MeshRenderer>().sharedMaterial = sharedMat; MeshFilter combineFilter = combineGo.AddComponent <MeshFilter>(); combineFilter.sharedMesh = new Mesh(); combineFilter.sharedMesh.name = copyGo.name + "_combine"; combineFilter.sharedMesh.CombineMeshes(combines); } //移除已经被combine过的GameObject和Mesh(如果有子物体,则只移除MeshRenderer和MeshFilter) for (int i = 0; i < childrenList.Count; i++) { MeshRenderer childRenderer = childrenList[i].GetComponent <MeshRenderer>(); MeshFilter childFilter = childrenList[i].GetComponent <MeshFilter>(); if (null != childRenderer) { Object.DestroyImmediate(childRenderer); } if (null != childFilter) { Object.DestroyImmediate(childFilter); } } RemoveMeshRendererMeshFilter(copyGo.transform, copyGo.transform); if (null != combineGo) { combineGo.transform.SetParent(copyGo.transform); } //优化浮点数,主要是减少包体占用,内存不会变 OptmizeAnimationFloat(copyClip, 3); AssetDatabase.CreateAsset(copyClip, g_storeDir + go.name + "_" + clip.name + ".anim"); //删掉原来的Animation,用新的 Animation ani = copyGo.GetComponent <Animation>(); if (null != ani) { Object.DestroyImmediate(ani); } ani = copyGo.AddComponent <Animation>(); ani.clip = copyClip; //AnimationUtility.SetAnimationClips(ani, new AnimationClip[] { copyClip }); MeshFilter[] filters = copyGo.GetComponentsInChildren <MeshFilter>(); for (int i = 0; i < filters.Length; i++) { Mesh newMesh = Object.Instantiate(filters[i].sharedMesh); filters[i].sharedMesh = newMesh; if (i == 0) { AssetDatabase.CreateAsset(newMesh, g_storeDir + go.name + "_" + clip.name + "_" + "mesh.asset"); } else { AssetDatabase.AddObjectToAsset(filters[i].sharedMesh, g_storeDir + go.name + "_" + clip.name + "_" + "mesh.asset"); } } PrefabUtility.SaveAsPrefabAsset(copyGo, g_prefabDir + go.name + "_" + clip.name + ".prefab"); AssetDatabase.SaveAssets(); Object.DestroyImmediate(copyGo); }
void Update() { if (prevWeaponL != testWeaponL) { prevWeaponL = testWeaponL; EquipSlots.SetItem(testWeaponL, HumanoidEquipSlots.SlotSpace.leftHand); } if (prevWeaponR != testWeaponR) { prevWeaponR = testWeaponR; EquipSlots.SetItem(testWeaponR, HumanoidEquipSlots.SlotSpace.rightHand); } if ((Character.IsUnderwater || Character.astral || Character.InAstral || Character.IsFlying) && EquipSlots.isHeld) { EquipSlots.isHeld = false; } if (Time.time - lastAttack > currentAttackComboTime) { attackCombo = 0; } attackCombo %= 3; animator.SetInteger("AttackCombo", attackCombo); bool leftHanded; bool hasShield; int weaponType = GetWeaponType(EquipSlots.GetItem(HumanoidEquipSlots.SlotSpace.leftHand), EquipSlots.GetItem(HumanoidEquipSlots.SlotSpace.rightHand), out leftHanded, out hasShield); //Input stuff Vector2 input = new Vector2(Character.GetAxis("horizontal"), Character.GetAxis("vertical")); isStrafing = Character.GetToggle("r2Btn") && !Character.IsUnderwater && !Character.astral && !Character.InAstral && !Character.IsFlying; isBlocking = Character.GetToggle("l2Btn") && !Character.IsUnderwater && !Character.astral && !Character.InAstral && !Character.IsFlying; if ((!IsRunningCustomAnim || currentCustomAnim.canBeInterrupted) && !Character.IsUnderwater && !Character.astral && !Character.InAstral && !Character.IsFlying) { CustomAnimationData nextAnimData = null; Vector2 direction = Character.mainShells.transform.forward.xz().normalized; if (Character.GetToggle("circleBtn")) { if (!prevRoll) { prevRoll = true; nextAnimData = rollData; if (isStrafing && !input.IsZero()) { direction = input.normalized; } } } else { prevRoll = false; } if (Character.GetToggle("squareBtn")) { if (!prevAttack && (IsRunningCustomAnim && currentCustomAnim != attackData || !IsRunningCustomAnim) && !isBlocking && weaponType > WEAPON_NONE) { prevAttack = true; if (EquipSlots.isHeld) { nextAnimData = attackData; attackCombo++; lastAttack = Time.time; currentAttackComboTime = nextAnimData.executionTime + attackComboTime; } else { nextAnimData = unsheathData; } } } else { prevAttack = false; } if (Character.GetToggle("r1Btn")) { if (!prevSheath && weaponType > WEAPON_NONE) { prevSheath = true; if (EquipSlots.isHeld) { nextAnimData = sheathData; } else { nextAnimData = unsheathData; } } } else { prevSheath = false; } if (nextAnimData != null && (!IsRunningCustomAnim || (currentCustomAnim.canBeInterrupted && currentCustomAnim != nextAnimData))) { SetCustomAnim(nextAnimData, direction); } } animator.SetFloat("StrafeDir", PercentClockwise(Character.mainShells.transform.forward.xz().normalized, input.normalized)); animator.SetInteger("WeaponType", weaponType); animator.SetBool("LeftHanded", leftHanded); animator.SetBool("HasShield", hasShield); //Custom anim stuff animator.SetLayerWeight(animator.GetLayerIndex("Upperbody"), ((IsRunningCustomAnim && currentCustomAnim.isUpperbody) || EquipSlots.isHeld) ? 1 : 0); animator.SetBool("BlockMain", IsRunningCustomAnim && currentCustomAnim.blockMainLayerAnim); animator.SetBool("BlockUpper", (IsRunningCustomAnim && currentCustomAnim.blockUpperLayerAnim) || isBlocking); animator.SetBool("Block", isBlocking); Character.blockMovement = (IsRunningCustomAnim && currentCustomAnim.blockMovement) || isStrafing; Character.blockRotation = (IsRunningCustomAnim && currentCustomAnim.blockRotation) || isStrafing; if (IsRunningCustomAnim) { if (!toggledCustomAnim) { animator.SetTrigger(currentCustomAnim.animationToggleName); toggledCustomAnim = true; } if (currentCustomAnim.distanceTravelled > float.Epsilon) { Vector2 nextPosition = customAnimStartPos + customAnimStartDir * currentCustomAnim.distanceTravelled * currentCustomAnim.travelMap.Evaluate(CustomAnimPercentPlayed); Character.SetPosition(nextPosition); } } else { toggledCustomAnim = false; } //Strafe stuff animator.SetBool("Strafe", isStrafing && !input.IsZero()); if (isStrafing && (!IsRunningCustomAnim || (IsRunningCustomAnim && !currentCustomAnim.blockMovement))) { Vector2 nextPosition = Character.mainShells.transform.position.xz() + input.normalized * strafeSpeed * Time.deltaTime; Character.SetPosition(nextPosition); } }
private void SetCustomAnim(CustomAnimationData customAnim) { SetCustomAnim(customAnim, Character.mainShells.transform.forward.xz().normalized); }