//TODO:需要添加参数控制是否立即播放,这关系到声音在什么位置出现 public FXController CreateFxAndBuildParent(string filePath) { GameObject obj = PoolManager.Instance.Spawm(filePath, ClientCommon.AssetType.PFX, ClientCommon.AssetType.PFX.ToString()); // obj.name = System.IO.Path.GetFileName(filePath); // 注意,不能更改名字 FXController fx = obj.GetComponent <FXController>(); if (fx == null) { Transform parentTrans = new GameObject(obj.name).transform; ObjectUtility.AttachToParentAndResetLocalPosAndRotation(parentTrans, obj.transform); // Reset root transform parentTrans.localPosition = Vector3.zero; parentTrans.localRotation = Quaternion.identity; parentTrans.localScale = Vector3.one; fx = parentTrans.gameObject.AddComponent <FXController>(); fx.loop = true; fx.autoDestroy = true; obj = parentTrans.gameObject; } if (fx) { fx.Start(); } return(fx); }
public FXController PlayFX(string fxName, GameObject parent, bool attachedToParent, bool autoDestroy, bool isResetLocalPos, bool startImmediately, bool setLayerAsParent = true) { // string fxPath = PathUtility.Combine(baseFxPath, fxName); FXController fx = CreateFxNonStart(fxName); // AssertHelper.Check(fx != null, fxName + " not exist!"); if (fx == null) { return(null); } // Attach to parent if (attachedToParent) { if (isResetLocalPos) { ObjectUtility.AttachToParentAndResetLocalPosAndRotation(parent.transform, fx.Root); } else { ObjectUtility.AttachToParentAndKeepLocalTrans(parent.transform, fx.Root); } } else { if (isResetLocalPos) { ObjectUtility.UnifyWorldTrans(parent.transform, fx.Root); } } // Set layer if (setLayerAsParent) { ObjectUtility.SetObjectLayer(fx.gameObject, parent.layer); } if (autoDestroy) { // Set auto destroy flag to FX script. FXController pfxScp = fx.GetComponentInChildren <FXController>(); if (pfxScp != null) { pfxScp.autoDestroy = true; pfxScp.loop = false; } } if (startImmediately) { fx.Start(); } return(fx); }
// Attach style mesh, return the new game object. private GameObject AttachSkinComponent(GameObject attachingObject) { // Create one new object for this mesh renderer. GameObject attachingRoot = new GameObject(attachingObject.name); // Attach to avatar object. Vector3 oldScale = avatar.gameObject.transform.localScale; avatar.gameObject.transform.localScale = new Vector3(1, 1, 1); ObjectUtility.AttachToParentAndResetLocalPosAndRotation(avatar.AvatarObject, attachingRoot); // Copy SkinnedMeshRenderer. foreach (SkinnedMeshRenderer renderer in attachingObject.GetComponentsInChildren <SkinnedMeshRenderer>(true)) { // Create one new object for this mesh renderer. GameObject newSubMsh = new GameObject(renderer.sharedMesh.name); ObjectUtility.AttachToParentAndResetLocalPosAndRotation(attachingRoot, newSubMsh); // Copy renderer. SkinnedMeshRenderer newRenderer = newSubMsh.AddComponent <SkinnedMeshRenderer>(); newRenderer.sharedMesh = renderer.sharedMesh; newRenderer.sharedMaterials = renderer.sharedMaterials; newRenderer.quality = renderer.quality; newRenderer.updateWhenOffscreen = renderer.updateWhenOffscreen; Transform[] bones = new Transform[renderer.bones.Length]; for (int i = 0; i < renderer.bones.Length; i++) { var bone = ObjectUtility.FindChildObject(avatar.AvatarObject, renderer.bones[i].name); if (bone == null) { Debug.LogError(string.Format("Bone {0} is missing", renderer.bones[i].name)); continue; } bones[i] = bone; } newRenderer.bones = bones; } // Reset local scale. avatar.gameObject.transform.localScale = oldScale; // Set to current layer. ObjectUtility.SetObjectLayer(attachingRoot, avatar.gameObject.layer); return(attachingRoot); }
// Mount style mesh. private GameObject MountComponent(Transform mountingObject, string mountBoneName, string mountingMakerName) { // Find mount mountBone. var mountBone = ObjectUtility.FindChildObject(avatar.AvatarObject, mountBoneName); if (mountBone == null) { #if ENABLE_AVATAR_COMPONENT_LOG Debug.LogWarning("Not found the mount bone on base object : " + mountBoneName); #endif return(null); } // Find mount mountBone in first depth children. var mountingBone = ObjectUtility.FindChildObject(mountingObject, mountingMakerName, true); if (mountingBone == null) { #if ENABLE_AVATAR_COMPONENT_LOG Debug.LogWarning("Not found the mount mountBone in usedComponent model: " + mountingObject.name + " " + mountingMakerName); #endif return(null); } // Create one new object for this usedComponent. Transform mountingRoot = new GameObject(mountingObject.gameObject.name).transform; ObjectUtility.UnifyWorldTrans(mountingBone, mountingRoot); // Attach to mounting root ObjectUtility.AttachToParentAndKeepWorldTrans(mountingRoot, mountingObject); // Set to layer. ObjectUtility.SetObjectLayer(mountingRoot.gameObject, avatar.gameObject.layer); // Attach to mount bone. Transform avatarTrans = avatar.gameObject.transform; Vector3 oldScale = avatarTrans.localScale; avatarTrans.localScale = Vector3.one; ObjectUtility.AttachToParentAndResetLocalPosAndRotation(mountBone, mountingRoot); avatarTrans.localScale = oldScale; return(mountingRoot.gameObject); }
// Play Pfx. public void PlayPfx(FXController fx, int destroyMode, int userData, string modelBone, string bone, bool boneFollow, Vector3 offset, Vector3 rotate, bool useSpecificPosition, Vector3 specificPosition) { // Set Render layer /** * Bug 记录。 * * 对于魔化卫庄的组合技,这个技能在主Action中有目标选择,但是每一个伤害事件都有自己的目标选择,最终可能有一种情况,即所有的EventTargetRecord中的目标均不包含Action选择的目标 * 在主Action中配置了一些播放特效的事件,这些事件服务器不作处理,也不会发给客户端,而是由客户端自己根据配置文件构建,构建时使用ActionRecord的TargetAvtarIndexs里的AvatarIndex, * 指定的AvatarIndex可能不在任何EventTargetRecord中,所以SkillCombatRound在遮罩屏幕时不会将这个角色点亮,导致“由这个角色”释放的特效也没有被点亮 * * 修改逻辑,如果正处于屏幕遮罩中,那么所有的特效都有应该具有SceneMaskLayer */ //BattleScene bs = BattleScene.GetBattleScene(); //int Layer = 0; //if (bs != null && bs.IsEnableSceneMask) // Layer = GameDefines.SceneMaskLayer; //else Layer = avatar.gameObject.layer; int Layer = avatar.gameObject.layer; // Set Render layer fx.Root.gameObject.layer = Layer; foreach (var subObj in fx.Root.GetComponentsInChildren <Transform>()) { subObj.gameObject.layer = Layer; } // If bone follow, attach to this bone. if (boneFollow) { var attachingGO = fx.Root; // Try to find specified if (modelBone != "") { var modelBoneObj = ObjectUtility.FindChildObject(attachingGO, modelBone); if (modelBoneObj != null) { attachingGO = modelBoneObj; } } // If specify bone, to this bone. if (bone != "") { var boneGO = ObjectUtility.FindChildObject(avatar.AvatarObject, bone); if (boneGO == null) { Debug.LogWarning(string.Format("Can not find bone:{0} in avatar", bone)); } ObjectUtility.AttachToParentAndResetLocalPosAndRotation(boneGO, attachingGO); } // Has no specify bone, to the root bone. else { ObjectUtility.AttachToParentAndResetLocalPosAndRotation(avatar.CachedTransform, attachingGO); } } // If not bone follow, just play at this bone position. else { // If specify bone, use this bone position. if (bone != "") { var boneGO = ObjectUtility.FindChildObject(avatar.CachedTransform, bone); if (boneGO == null) { Debug.LogWarning(string.Format("Can not find bone:{0} in avatar", bone)); } ObjectUtility.UnifyWorldTrans(boneGO, fx.Root); } // Has specific transform, use the transform. else if (useSpecificPosition) { fx.Root.position = specificPosition; } // Has no specify bone, use the root bone position. else { ObjectUtility.UnifyWorldTrans(avatar.CachedTransform, fx.Root); } } fx.Root.Translate(offset); fx.Root.Rotate(rotate); if (destroyMode != AvatarAction.Effect._DestroyType.Normal) { // Add to dictionary. var fxInst = new FxInst(fx, destroyMode, userData); fxMap[fxInst.instanceId] = fxInst; // Set auto destroy flag to Pfx script. //FXController PfxScript = fx.GetComponentInChildren<FXController>(); //if (PfxScript != null) { fx.autoDestroy = true; // Pfx will not loop except buff. if (destroyMode == AvatarAction.Effect._DestroyType.Buff) { fx.loop = true; } if (destroyMode == AvatarAction.Effect._DestroyType.BlockAction) { fx.AddFinishCallback(PfxFinishedBb, fxInst); } } } }