public bool ParseFile(string file) { strfile = file; TextAsset asset = Resources.Load <TextAsset>(file); if (asset == null) { asset = Resources.Load <TextAsset>(file + ".ef"); } if (asset == null) { SFXLoader.Instance.Miss++; Debug.LogError("sfx:" + file + " missed"); return(false); } int offset = 0; if (asset != null && asset.bytes == null) { Debug.LogError("asset or it content is null file is " + file); return(false); } MemoryStream ms = new MemoryStream(asset.bytes); BinaryReader reader = new BinaryReader(ms); string ver = new string(reader.ReadChars(11)); //System.Text.Encoding.UTF8.GetString(asset.bytes, offset, 11); //offset += 11; int effectNum = reader.ReadInt32(); //int effectNum = System.BitConverter.ToInt32(asset.bytes, offset); //offset += 4; //只读一个特效的。 //if (effectNum != 1) // return false; for (int i = 0; i < effectNum; i++) { SfxEffect sfx = new SfxEffect(); sfx.EffectType = readNextString(reader, 16, false); int len = reader.ReadInt32(); sfx.EffectName = readNextString(reader, len); reader.BaseStream.Seek(12, SeekOrigin.Current); sfx.localSpace = reader.ReadInt32(); { int headlen = 4; int haveBone = reader.ReadInt32(); sfx.Bone0 = readNextString(reader, haveBone); headlen += haveBone; haveBone = reader.ReadInt32(); sfx.Bone1 = readNextString(reader, haveBone); headlen += 4; headlen += haveBone; haveBone = reader.ReadInt32(); sfx.Texture = readNextString(reader, haveBone); reader.BaseStream.Seek(60, SeekOrigin.Current);//这60字节分别是 环境光 镜面光 漫反射 自发光 还有未知的3字节 headlen += 4; headlen += haveBone; reader.BaseStream.Seek(5, SeekOrigin.Current); sfx.Active = reader.ReadInt32(); sfx.Hidden = reader.ReadInt32(); sfx.uSpeed = reader.ReadSingle(); sfx.vSpeed = reader.ReadSingle(); sfx.BlendType = reader.ReadInt32(); sfx.Unknown2 = reader.ReadInt32(); sfx.Unknown3 = reader.ReadInt32(); sfx.FrameCnt = reader.ReadInt32(); for (int y = 0; y < sfx.FrameCnt; y++) { EffectFrame frame = new EffectFrame(); frame.startTime = reader.ReadSingle(); // asset.bytes, offset);//可能是int可能是float //offset += 4; frame.pos.x = reader.ReadSingle(); //可能是int可能是float offset += 4; frame.pos.z = reader.ReadSingle(); //可能是int可能是float offset += 4; frame.pos.y = reader.ReadSingle(); //可能是int可能是float offset += 4; frame.quat.x = -reader.ReadSingle(); //可能是int可能是float offset += 4; frame.quat.z = -reader.ReadSingle(); //可能是int可能是float offset += 4; frame.quat.y = -reader.ReadSingle(); //可能是int可能是float offset += 4; frame.quat.w = reader.ReadSingle(); //可能是int可能是float offset += 4; frame.scale.x = reader.ReadSingle(); //可能是int可能是float offset += 4; frame.scale.z = reader.ReadSingle(); //可能是int可能是float offset += 4; frame.scale.y = reader.ReadSingle(); //可能是int可能是float offset += 4; frame.colorRGB.r = reader.ReadSingle(); //可能是int可能是float offset += 4; frame.colorRGB.g = reader.ReadSingle(); //可能是int可能是float offset += 4; frame.colorRGB.b = reader.ReadSingle(); //可能是int可能是float offset += 4; frame.colorRGB.a = reader.ReadSingle(); //4 15*4 = 60 offset += 4; //offset += 52;//后面52字节暂时不知道什么意思.13个float for (int j = 0; j < 13; j++) { frame.TailFlags[j] = reader.ReadSingle(); } sfx.frames.Add(frame); } int TailSectionLength = reader.ReadInt32(); if (sfx.EffectType == "AUDIO") { int regionCnt = reader.ReadInt32(); string sBone = readNextString(reader, regionCnt); sfx.audioLoop = reader.ReadInt32(); sfx.Tails[0] = sBone; } else if (sfx.EffectType == "BILLBOARD" || sfx.EffectType == "PLANE") { sfx.origScale.x = reader.ReadSingle(); offset += 4; sfx.origScale.y = reader.ReadSingle(); offset += 4; } else if (sfx.EffectType == "CYLINDER") { sfx.origAtt.x = reader.ReadSingle(); //底部半径 offset += 4; sfx.origAtt.y = reader.ReadSingle(); //顶部半径 offset += 4; sfx.origScale.x = reader.ReadSingle(); //高度 offset += 4; sfx.origScale.y = reader.ReadSingle(); //90 offset += 4; sfx.origScale.z = reader.ReadSingle(); //450 offset += 4; //sfx.TailLength = 24; } else if (sfx.EffectType == "BOX") { sfx.origScale.x = reader.ReadSingle(); //System.BitConverter.ToSingle(asset.bytes, offset);//可能是int可能是float offset += 4; sfx.origScale.y = reader.ReadSingle(); //System.BitConverter.ToSingle(asset.bytes, offset);//可能是int可能是float offset += 4; sfx.origScale.z = reader.ReadSingle(); //System.BitConverter.ToSingle(asset.bytes, offset);//可能是int可能是float offset += 4; //sfx.TailLength = 16; } else if (sfx.EffectType == "PARTICLE") { //reader.BaseStream.Seek(4, SeekOrigin.Current); //读4个字节长度,读100个字节,在读这个长度 最后面就是3个变长串 //就是100 +X+尾部变长。 int endRegionCnt = TailSectionLength; //sfx.TailLength = 100 + endRegionCnt; reader.BaseStream.Seek(96 + endRegionCnt, SeekOrigin.Current);//到终点 //offset += sfx.TailLength; //后面还有3个变长串,可为空的 int regionCnt = reader.ReadInt32();// (asset.bytes, offset); //offset += 4; //sfx.TailLength += 4; string sBone = readNextString(reader, regionCnt); //string sBone = System.Text.Encoding.UTF8.GetString(asset.bytes, offset, regionCnt); sfx.Tails[0] = sBone; //offset += regionCnt; //sfx.TailLength += regionCnt; regionCnt = reader.ReadInt32(); //offset += 4; //sfx.TailLength += 4; sBone = readNextString(reader, regionCnt);// System.Text.Encoding.UTF8.GetString(asset.bytes, offset, regionCnt); sfx.Tails[1] = sBone; //offset += regionCnt; //sfx.TailLength += regionCnt; regionCnt = reader.ReadInt32();// (asset.bytes, offset); offset += 4; //sfx.TailLength += 4; sBone = readNextString(reader, regionCnt);// System.Text.Encoding.UTF8.GetString(asset.bytes, offset, regionCnt); sfx.Tails[2] = sBone; offset += regionCnt; //sfx.TailLength += regionCnt; } else if (sfx.EffectType == "DONUT") { reader.BaseStream.Seek(24, SeekOrigin.Current); //sfx.TailLength = 28; } else if (sfx.EffectType == "DRAG") { //sfx.TailLength += 8; offset += 8; reader.BaseStream.Seek(4, SeekOrigin.Current); int len4 = reader.ReadInt32();// (asset.bytes, offset); offset += 4; //sfx.TailLength += 4; sfx.Tails[0] = readNextString(reader, len4); // (asset.bytes, offset, len4); //sfx.TailLength += len4; offset += len4; len4 = reader.ReadInt32();// System.BitConverter.ToInt32(asset.bytes, offset); offset += 4; //sfx.TailLength += 4; sfx.Tails[1] = readNextString(reader, len4);// System.Text.Encoding.UTF8.GetString(asset.bytes, offset, len4); //sfx.TailLength += len4; offset += len4; } else if (sfx.EffectType == "MODEL") { //4 + 4 + 长度 //sfx.TailLength += 4; int len4 = reader.ReadInt32();// System.BitConverter.ToInt32(asset.bytes, offset); offset += 4; //sfx.TailLength += 4; sfx.Tails[0] = readNextString(reader, len4);// System.Text.Encoding.UTF8.GetString(asset.bytes, offset, len4); //sfx.TailLength += len4; } else if (sfx.EffectType == "SPHERE") { sfx.SphereScale = reader.ReadSingle(); sfx.sphereAttr.x = reader.ReadSingle(); sfx.sphereAttr.y = reader.ReadSingle(); sfx.sphereAttr.z = reader.ReadSingle(); sfx.sphereAttr.w = reader.ReadSingle(); //reader.BaseStream.Seek(16, SeekOrigin.Current); } else { Debug.LogError(sfx.EffectType + " can not parse: file " + file); } effectList.Add(sfx); } } ms.Close(); reader.Close(); return(true); }
//public void SaveParticle(string file) //{ // if (source != null && source.particle != null) // { // System.IO.FileStream fs = System.IO.File.OpenWrite(file); // System.IO.BinaryWriter w = new System.IO.BinaryWriter(fs); // w.Write(source.particle); // w.Flush(); // w.Close(); // fs.Close(); // } //} //原粒子系统是右手坐标系的,转移到左手坐标系后非常多问题,特别是父子关系以及,跟随和子物体旋转叠加 public void Init(SfxEffect effect, SFXEffectPlay parent, int index, float timePlayed = 0.0f, bool preLoad = false) { playedTime = timePlayed; PlayDone = false; transform.rotation = Quaternion.identity; effectIndex = index; parentSfx = parent;//当找不到跟随者的时候,向父询问其他特效是否包含此名称. name = effect.EffectName; EffectType = effect.EffectType; //一个是跟随移动,一个是跟随旋转 mOwner = parent.GetComponent <MeteorUnit>(); source = effect; if (effect.EffectType.Equals("PARTICLE")) { particle = Instantiate(Resources.Load <GameObject>("SFXParticles"), Vector3.zero, Quaternion.identity, transform).GetComponent <ParticleSystem>(); ParticleSystem.MainModule mainModule = particle.main; ParticleSystem.EmissionModule emissionModule = particle.emission; ParticleSystem.ShapeModule shapeModule = particle.shape; emissionModule.rateOverTime = new ParticleSystem.MinMaxCurve(effect.MaxParticles, effect.MaxParticles); mainModule.startLifetime = effect.StartLifetime; mainModule.maxParticles = effect.MaxParticles; mainModule.startSize3D = false; mainModule.startSize = new ParticleSystem.MinMaxCurve(effect.startSizeMin, effect.startSizeMax); mainModule.startSpeed = new ParticleSystem.MinMaxCurve(effect.startSpeedMin, effect.startSpeedMax); mainModule.loop = true; mainModule.duration = 1.0f; //124字节的,烟雾特效,旋转角度 0-360,shape使用box, render使用billboard if (effect.version == 1) { mainModule.startRotation = new ParticleSystem.MinMaxCurve(0, 360); shapeModule.shapeType = ParticleSystemShapeType.Box; shapeModule.box = new Vector3(effect.startSizeMin, 0, effect.startSizeMax); ParticleSystemRenderer r = particle.GetComponent <ParticleSystemRenderer>(); r.renderMode = ParticleSystemRenderMode.Billboard; r.minParticleSize = 0.1f; r.maxParticleSize = 0.1f; } } if (string.IsNullOrEmpty(effect.Bone0)) { PositionFollow = mOwner == null ? parentSfx.transform : mOwner.transform; } else if (effect.Bone0.Equals("ROOT")) { PositionFollow = mOwner == null ? parent.transform : mOwner.ROOTNull; } else if (effect.Bone0.Equals("Character"))//根骨骼上一级,角色,就是不随着b骨骼走,但是随着d_base走 { PositionFollow = mOwner == null ? parent.transform: mOwner.RootdBase; } else { PositionFollow = FindFollowed(effect.Bone0); } if (string.IsNullOrEmpty(effect.Bone1)) { RotateFollow = mOwner == null ? parent.transform : mOwner.transform; } else if (effect.Bone1.Equals("ROOT")) { RotateFollow = mOwner == null ? parent.transform : mOwner.ROOTNull; } else if (effect.Bone1.Equals("Character")) { RotateFollow = mOwner == null ? parent.transform : mOwner.RootdBase; } else { RotateFollow = FindFollowed(effect.Bone1); } if (PositionFollow != null) { transform.position = PositionFollow.transform.position; } mRender = gameObject.GetComponent <MeshRenderer>(); mFilter = gameObject.GetComponent <MeshFilter>(); int meshIndex = -1; if (effect.EffectType.Equals("DONUT")) { //Debug.LogError("find Donut Effect"); } //部分模型是要绕X旋转270的,这样他的缩放,和移动,都只能靠自己 if (effect.EffectType.Equals("PLANE")) { meshIndex = 0; } else if (effect.EffectType.Equals("BOX")) { meshIndex = 1; } else if (effect.EffectType.Equals("DONUT")) { transform.localScale = effect.frames[0].scale; meshIndex = 2; } else if (effect.EffectType.Equals("MODEL"))//自行加载模型 { transform.localScale = effect.frames[0].scale; transform.rotation = RotateFollow.rotation * effect.frames[0].quat; transform.position = PositionFollow.position + effect.frames[0].pos; if (!string.IsNullOrEmpty(effect.Tails[0])) { string[] des = effect.Tails[0].Split(new char[] { '\\' }, System.StringSplitOptions.RemoveEmptyEntries); if (des.Length != 0) { WsGlobal.ShowMeteorObject(des[des.Length - 1], transform); } } //这个时候,不要用自带的meshfilter了,让他自己处理显示问题,只要告诉他在哪个地方显示 meshIndex = 100; } else if (effect.EffectType.Equals("SPHERE")) { meshIndex = 3; } else if (effect.EffectType.Equals("PARTICLE")) { if (!string.IsNullOrEmpty(effect.Tails[0])) { PositionFollow = FindFollowed(effect.Tails[0]); } if (!string.IsNullOrEmpty(effect.Tails[1])) { RotateFollow = FindFollowed(effect.Tails[1]); } if (PositionFollow != null) { transform.position = PositionFollow.transform.position; } meshIndex = 101; } else if (effect.EffectType.Equals("CYLINDER")) { meshIndex = 4; } else if (effect.EffectType.Equals("BILLBOARD")) { LookAtC = true; meshIndex = 5; } else if (effect.EffectType.Equals("DRAG")) { meshIndex = 6; } //决定模型 if (meshIndex != -1 && meshIndex < GamePool.Instance.MeshMng.Meshes.Length) { if (meshIndex == 4) { mFilter.mesh = Main.Ins.SfxMeshGenerator.CreateCylinder(source.origAtt.y, source.origAtt.x, source.origScale.x); } else if (meshIndex == 3) { mFilter.mesh = Main.Ins.SfxMeshGenerator.CreateSphere(source.SphereRadius); } else if (meshIndex == 0) { mFilter.mesh = Main.Ins.SfxMeshGenerator.CreatePlane(source.origScale.x, source.origScale.y); } else { mFilter.mesh = GamePool.Instance.MeshMng.Meshes[meshIndex]; } } if (effect.Texture.ToLower().EndsWith(".bmp") || effect.Texture.ToLower().EndsWith(".jpg") || effect.Texture.ToLower().EndsWith(".tga")) { texture = effect.Texture.Substring(0, effect.Texture.Length - 4); tex = Resources.Load <Texture>(texture); } else if (effect.Texture.ToLower().EndsWith(".ifl")) { iflTexture = gameObject.AddComponent <IFLLoader>(); iflTexture.IFLFile = Resources.Load <TextAsset>(effect.Texture); if (effect.EffectType.Equals("PARTICLE")) { iflTexture.SetTargetMeshRenderer(particle.GetComponent <ParticleSystemRenderer>()); } iflTexture.LoadIFL();//传递false表示由特效控制每一帧的切换时间. tex = iflTexture.GetTexture(0); } //else // print("effect contains other prefix:" + effect.Texture == null ? " texture is null" : effect.Texture); if (tex != null) { if (effect.EffectType.Equals("PARTICLE")) { ParticleSystemRenderer render = particle.GetComponent <ParticleSystemRenderer>(); if (effect.BlendType == 0) { render.material.shader = Shader.Find("Unlit/Texture");//普通不透明无光照 } else if (effect.BlendType == 1) { render.material.shader = Shader.Find("UnlitAdditive");//滤色 加亮 不透明 } else if (effect.BlendType == 2) { render.material.shader = Shader.Find("UnlitAdditive");//反色+透明度 } else if (effect.BlendType == 3) { render.material.shader = Shader.Find("Mobile/Particles/Alpha Blended");//不滤色,支持透明 } else if (effect.BlendType == 4) { render.material.shader = Shader.Find("Custom/MeteorBlend4");//滤色,透明 } else { render.material.shader = Shader.Find("Unlit/Texture");//普通不透明无光照 } if (texture.Equals("AItem09")) { render.enabled = false; particle.Stop(); /* 应该是有一个地裂的粒子特效,但是这个特效参数没分析出来. * tex = Resources.Load<Texture>("AItemParticle"); * render.material.SetTexture("_MainTex", tex); */ } else { render.material.SetTexture("_MainTex", tex); } render.material.SetColor("_Color", effect.frames[0].colorRGB); render.material.SetColor("_TintColor", effect.frames[0].colorRGB); render.material.SetFloat("_Intensity", effect.frames[0].TailFlags[9]); if (Main.Ins.GameStateMgr.gameStatus != null && !Main.Ins.GameStateMgr.gameStatus.DisableParticle) { particle.Play(); } } else { if (effect.BlendType == 0) { mRender.material.shader = Shader.Find("Unlit/Texture");//普通不透明无光照 } else if (effect.BlendType == 1) { mRender.material.shader = Shader.Find("UnlitAdditive");//滤色 加亮 不透明 } else if (effect.BlendType == 2) { mRender.material.shader = Shader.Find("UnlitAdditive");//反色+透明度 } else if (effect.BlendType == 3) { mRender.material.shader = Shader.Find("Mobile/Particles/Alpha Blended");//不滤色,支持透明 } else if (effect.BlendType == 4) { mRender.material.shader = Shader.Find("Custom/MeteorBlend4");//滤色,透明 } else { mRender.material.shader = Shader.Find("Unlit/Texture");//普通不透明无光照 } if (effect.BlendType == 2) { mRender.material.SetColor("_InvColor", effect.frames[0].colorRGB); } else { mRender.material.SetColor("_Color", effect.frames[0].colorRGB); mRender.material.SetColor("_TintColor", effect.frames[0].colorRGB); } mRender.material.SetFloat("_Intensity", effect.frames[0].TailFlags[9]); mRender.material.SetTexture("_MainTex", tex); if (effect.uSpeed != 0.0f || effect.vSpeed != 0.0f) { tex.wrapMode = TextureWrapMode.Repeat; } else { tex.wrapMode = TextureWrapMode.Clamp; } mRender.material.SetFloat("_u", effect.uSpeed); mRender.material.SetFloat("_v", effect.vSpeed); } } else { mRender.enabled = false; } //drag不知道有什么作用,可能只是定位用的挂载点 if (effect.Hidden == 1 || meshIndex == 6) { if (particle != null) { ParticleSystemRenderer render = particle.GetComponent <ParticleSystemRenderer>(); if (render != null) { render.enabled = false; } } mRender.enabled = false; } if (effect.EffectName.StartsWith("Attack")) { if (effect.EffectType.ToUpper() == "BOX") { BoxCollider bo = gameObject.AddComponent <BoxCollider>(); bo.center = Vector3.zero; bo.size = Vector3.one; damageBox = bo; } else { //SphereCollider sph = gameObject.AddComponent<SphereCollider>(); //damageBox = sph; //sph.radius = 1.0f; //sph.center = Vector3.zero; MeshCollider co = gameObject.AddComponent <MeshCollider>(); co.convex = true; co.isTrigger = true; damageBox = co; } damageBox.enabled = false; } if (preLoad) { PlayDone = true; if (parentSfx != null) { parentSfx.OnPlayDone(this); } else { Destroy(gameObject); } return; } }
public void SetEffect(SfxEffect effect) { this.effect = effect; }
private void PullNode() { lastNote = note; int noteAddr = sfxPointer + sfxOffset; note = GetNote(noteAddr); arpeggiator.Active = false; activeInstrument = -1; for (int i = 0; i < instruments.Length; i++) { var waveform = (AudioSynth.Waveform)note.waveform; if (instruments[i].Waveform == waveform) { SfxEffect effect = null; switch (note.effect) { case 1: //slide effect = new SfxEffectLerp(lastNote.hz, note.hz, lastNote.Volume01, note.Volume01, noteLength); break; case 2: //vibrato effect = new SfxEffectVibrato(AudioNote.PitchToHz(note.pitch - 0.25f), AudioNote.PitchToHz(note.pitch + 0.25f), 8); break; case 3: //drop effect = new SfxEffectLerp(note.hz, 0, note.Volume01, note.Volume01, noteLength); break; case 4: //Fade In effect = new SfxEffectLerp(note.hz, note.hz, 0, note.Volume01, noteLength); break; case 5: //Fade Out effect = new SfxEffectLerp(note.hz, note.hz, note.Volume01, 0, noteLength); break; case 6: //fast arpeggio case 7: //slow arpeggio int addr = sfxPointer + (sfxOffset >> 3); //sfxOffset >> 2 equals to division by 8 but faster var n0 = GetNote(addr); var n1 = GetNote(addr + 2); var n2 = GetNote(addr + 4); var n3 = GetNote(addr + 6); float hz = mem.Peek(sfxPointer + 65) > 8 ? 128 / 4 : 128 / 2; if (note.effect == 7) { hz = hz / 2; } arpeggiator.NoteTime = 1 / hz; arpeggiator.SetNotes(n0.hz, n1.hz, n2.hz, n3.hz); arpeggiator.Active = true; effect = null; break; } if (note.volume == 0) { instruments[i].Stop(); } else { activeInstrument = i; instruments[i].Play(note.hz, note.Volume01, effect); } } else { instruments[i].Stop(); } } //reset the arpeggiator if not in use if (!arpeggiator.Active) { arpeggiator.Reset(); } }
public bool ParseFile(string file) { strfile = file; TextAsset asset = Resources.Load <TextAsset>(string.Format("{0}", file)); if (asset == null) { Main.Ins.SFXLoader.Miss++; //Debug.LogError(string.Format("sfx:{0} missed", file)); error = true; return(false); } if (asset != null && asset.bytes == null) { //Debug.LogError(string.Format("asset or it content is null file is {0}", file)); error = true; return(false); } MemoryStream ms = new MemoryStream(asset.bytes); BinaryReader reader = new BinaryReader(ms); reader.ReadChars(11); int effectNum = reader.ReadInt32(); for (int i = 0; i < effectNum; i++) { SfxEffect sfx = new SfxEffect(); sfx.EffectType = readNextString(reader, 16, false); int len = reader.ReadInt32(); sfx.EffectName = readNextString(reader, len); reader.BaseStream.Seek(12, SeekOrigin.Current); sfx.localSpace = reader.ReadInt32(); { int headlen = 4; int haveBone = reader.ReadInt32(); sfx.Bone0 = readNextString(reader, haveBone); headlen += haveBone; haveBone = reader.ReadInt32(); sfx.Bone1 = readNextString(reader, haveBone); headlen += 4; headlen += haveBone; haveBone = reader.ReadInt32(); sfx.Texture = readNextString(reader, haveBone); reader.BaseStream.Seek(60, SeekOrigin.Current); headlen += 4; headlen += haveBone; reader.BaseStream.Seek(5, SeekOrigin.Current); sfx.Active = reader.ReadInt32(); sfx.Hidden = reader.ReadInt32(); sfx.uSpeed = reader.ReadSingle(); sfx.vSpeed = reader.ReadSingle(); sfx.BlendType = reader.ReadInt32(); sfx.Unknown2 = reader.ReadInt32(); sfx.Unknown3 = reader.ReadInt32(); sfx.FrameCnt = reader.ReadInt32(); for (int y = 0; y < sfx.FrameCnt; y++) { EffectFrame frame = new EffectFrame(); frame.startTime = reader.ReadSingle(); frame.pos.x = reader.ReadSingle(); frame.pos.z = reader.ReadSingle(); frame.pos.y = reader.ReadSingle(); frame.quat.x = -reader.ReadSingle(); frame.quat.z = -reader.ReadSingle(); frame.quat.y = -reader.ReadSingle(); frame.quat.w = reader.ReadSingle(); frame.scale.x = reader.ReadSingle(); frame.scale.z = reader.ReadSingle(); frame.scale.y = reader.ReadSingle(); frame.colorRGB.r = reader.ReadSingle(); frame.colorRGB.g = reader.ReadSingle(); frame.colorRGB.b = reader.ReadSingle(); frame.colorRGB.a = reader.ReadSingle(); for (int j = 0; j < 13; j++) { frame.TailFlags[j] = reader.ReadSingle(); } sfx.frames.Add(frame); } int TailSectionLength = reader.ReadInt32(); if (sfx.EffectType.Equals("AUDIO")) { int regionCnt = reader.ReadInt32(); string sBone = readNextString(reader, regionCnt); sfx.audioLoop = reader.ReadInt32(); sfx.Tails[0] = sBone; } else if (sfx.EffectType.Equals("BILLBOARD") || sfx.EffectType.Equals("PLANE")) { sfx.origScale.x = reader.ReadSingle(); sfx.origScale.y = reader.ReadSingle(); } else if (sfx.EffectType.Equals("CYLINDER")) { sfx.origAtt.x = reader.ReadSingle(); //底部半径 sfx.origAtt.y = reader.ReadSingle(); //顶部半径 sfx.origScale.x = reader.ReadSingle(); //高度 sfx.origScale.y = reader.ReadSingle(); //90 sfx.origScale.z = reader.ReadSingle(); //450 } else if (sfx.EffectType.Equals("BOX")) { sfx.origScale.x = reader.ReadSingle(); sfx.origScale.y = reader.ReadSingle(); sfx.origScale.z = reader.ReadSingle(); } else if (sfx.EffectType.Equals("PARTICLE")) { //reader.BaseStream.Seek(4, SeekOrigin.Current); //读4个字节长度,读100个字节,在读这个长度 最后面就是3个变长串 //就是100 +X+尾部变长。 int endRegionCnt = TailSectionLength; //sfx.TailLength = 100 + endRegionCnt; //粒子细节=96+endRegionCnt sfx.version = endRegionCnt == 0 ? 0 : 1; int particleBytes = 96 + endRegionCnt; if (particleBytes == 96) { sfx.version = 0; } else if (particleBytes == 124) { sfx.version = 1; } else if (particleBytes == 112) { sfx.version = 2; } reader.ReadBytes(particleBytes); //前面的28字节不知道干啥的。 reader.BaseStream.Seek(-96, SeekOrigin.Current); sfx.MaxParticles = reader.ReadInt32(); sfx.startSizeMin = reader.ReadSingle(); sfx.startSizeMax = reader.ReadSingle(); sfx.unknwon2 = reader.ReadSingle(); //1 sfx.unknown3 = reader.ReadSingle(); //5 sfx.unknown0 = reader.ReadSingle(); //30?可能是重力系数.其大于0时,粒子往下朝,其小于=0时,粒子向上 sfx.StartLifetime = reader.ReadSingle(); //粒子生命周期 sfx.unknown1 = reader.ReadSingle(); //1 sfx.startSpeedMin = reader.ReadSingle(); //50 - startSpeed sfx.startSpeedMax = reader.ReadSingle(); //80 - startSpeed2 sfx.unknown4 = reader.ReadSingle(); //0.1f sfx.unknown5 = reader.ReadSingle(); //0.1f; sfx.unknown6 = reader.ReadSingle(); //-1.0f; sfx.unknown7 = reader.ReadSingle(); //-1.0f; sfx.unknown8 = reader.ReadSingle(); //-1.0f; sfx.unknown9 = reader.ReadSingle(); //+1.0f; sfx.unknown10 = reader.ReadSingle(); //+1.0f; sfx.unknown11 = reader.ReadSingle(); //+1.0f; sfx.unknown12 = reader.ReadInt32(); //0 sfx.unknown13 = reader.ReadInt32(); //1 sfx.unknown14 = reader.ReadInt32(); //1 sfx.unknown15 = reader.ReadSingle(); //0.5f sfx.multiplyAlpha = reader.ReadInt32(); //1 sfx.alpha = reader.ReadSingle(); //0.3 int regionCnt = reader.ReadInt32(); string sBone = readNextString(reader, regionCnt); sfx.Tails[0] = sBone; regionCnt = reader.ReadInt32(); sBone = readNextString(reader, regionCnt); sfx.Tails[1] = sBone; regionCnt = reader.ReadInt32(); sBone = readNextString(reader, regionCnt); sfx.Tails[2] = sBone; } else if (sfx.EffectType.Equals("DONUT")) { reader.BaseStream.Seek(24, SeekOrigin.Current); } else if (sfx.EffectType.Equals("DRAG")) { reader.BaseStream.Seek(4, SeekOrigin.Current); int len4 = reader.ReadInt32(); sfx.Tails[0] = readNextString(reader, len4); len4 = reader.ReadInt32(); sfx.Tails[1] = readNextString(reader, len4); } else if (sfx.EffectType.Equals("MODEL")) { int len4 = reader.ReadInt32(); sfx.Tails[0] = readNextString(reader, len4); } else if (sfx.EffectType.Equals("SPHERE")) { sfx.SphereRadius = reader.ReadSingle(); sfx.sphereAttr.x = reader.ReadSingle(); sfx.sphereAttr.y = reader.ReadSingle(); sfx.sphereAttr.z = reader.ReadSingle(); sfx.sphereAttr.w = reader.ReadSingle(); } else { Debug.LogError(string.Format("{0} can not parse: file {1}", sfx.EffectType, file)); error = true; } effectList.Add(sfx); } } ms.Close(); reader.Close(); return(true); }
public void PlayEffect(SfxEffect effect) { audioEffect[(int)effect].Play(); }
public bool ParseFile(string file) { strfile = file; byte[] body = null; TextAsset asset = Resources.Load <TextAsset>(string.Format("{0}", file)); if (asset == null) { if (System.IO.File.Exists(file)) { body = File.ReadAllBytes(file); } } else { body = asset.bytes; } if (body == null) { //Debug.LogError(string.Format("asset or it content is null file is {0}", file)); error = true; return(false); } MemoryStream ms = new MemoryStream(body); BinaryReader reader = new BinaryReader(ms); reader.ReadChars(11); int effectNum = reader.ReadInt32(); for (int i = 0; i < effectNum; i++) { SfxEffect sfx = new SfxEffect(); sfx.EffectType = readNextString(reader, 16, false); int len = reader.ReadInt32(); sfx.EffectName = readNextString(reader, len); reader.BaseStream.Seek(12, SeekOrigin.Current); sfx.localSpace = reader.ReadInt32(); { int headlen = 4; int haveBone = reader.ReadInt32(); sfx.Bone0 = readNextString(reader, haveBone); headlen += haveBone; haveBone = reader.ReadInt32(); sfx.Bone1 = readNextString(reader, haveBone); headlen += 4; headlen += haveBone; haveBone = reader.ReadInt32(); sfx.Texture = readNextString(reader, haveBone); reader.BaseStream.Seek(60, SeekOrigin.Current); headlen += 4; headlen += haveBone; reader.BaseStream.Seek(5, SeekOrigin.Current); sfx.DoubleSide = reader.ReadInt32(); sfx.Hidden = reader.ReadInt32(); sfx.uSpeed = reader.ReadSingle(); sfx.vSpeed = reader.ReadSingle(); sfx.BlendType = reader.ReadInt32(); sfx.BlendType2 = reader.ReadInt32(); sfx.BlendType3 = reader.ReadInt32(); sfx.FrameCnt = reader.ReadInt32(); for (int y = 0; y < sfx.FrameCnt; y++) { EffectFrame frame = new EffectFrame(); frame.startTime = reader.ReadSingle(); frame.pos.x = reader.ReadSingle(); frame.pos.z = reader.ReadSingle(); frame.pos.y = reader.ReadSingle(); frame.quat.x = -reader.ReadSingle(); frame.quat.z = -reader.ReadSingle(); frame.quat.y = -reader.ReadSingle(); frame.quat.w = reader.ReadSingle(); frame.scale.x = reader.ReadSingle(); frame.scale.z = reader.ReadSingle(); frame.scale.y = reader.ReadSingle(); frame.colorRGB.r = reader.ReadSingle(); frame.colorRGB.g = reader.ReadSingle(); frame.colorRGB.b = reader.ReadSingle(); frame.colorRGB.a = reader.ReadSingle(); for (int j = 0; j < 13; j++) { frame.TailFlags[j] = reader.ReadSingle(); } sfx.frames.Add(frame); } int TailSectionLength = reader.ReadInt32(); if (sfx.EffectType.Equals("AUDIO")) { int regionCnt = reader.ReadInt32(); string sBone = readNextString(reader, regionCnt); sfx.audioLoop = reader.ReadInt32(); sfx.Tails[0] = sBone; } else if (sfx.EffectType.Equals("BILLBOARD") || sfx.EffectType.Equals("PLANE")) { sfx.origScale.x = reader.ReadSingle(); sfx.origScale.y = reader.ReadSingle(); } else if (sfx.EffectType.Equals("CYLINDER")) { sfx.origAtt.x = reader.ReadSingle(); //底部半径 sfx.origAtt.y = reader.ReadSingle(); //顶部半径 sfx.origScale.x = reader.ReadSingle(); //高度 sfx.origScale.y = reader.ReadSingle(); //90 sfx.origScale.z = reader.ReadSingle(); //450 } else if (sfx.EffectType.Equals("BOX")) { sfx.origScale.x = reader.ReadSingle(); sfx.origScale.y = reader.ReadSingle(); sfx.origScale.z = reader.ReadSingle(); } else if (sfx.EffectType.Equals("PARTICLE")) { //reader.BaseStream.Seek(4, SeekOrigin.Current); //读4个字节长度,读100个字节,在读这个长度 最后面就是3个变长串 //就是100 +X+尾部变长。 int endRegionCnt = TailSectionLength; //sfx.TailLength = 100 + endRegionCnt; //粒子细节=96+endRegionCnt sfx.version = endRegionCnt == 0 ? 0 : 1; sfx.ParticleBytes = 96 + endRegionCnt; if (sfx.ParticleBytes == 96) { sfx.version = 0; } else if (sfx.ParticleBytes == 124) { sfx.version = 1; sfx.EnableParticleRotate = reader.ReadInt32(); sfx.Skew = reader.ReadInt32(); sfx.HRotateSpeed = reader.ReadSingle(); sfx.VRotateSpeed = reader.ReadSingle(); sfx.RotateAxis.x = reader.ReadSingle(); sfx.RotateAxis.y = reader.ReadSingle(); sfx.RotateAxis.z = reader.ReadSingle(); } else if (sfx.ParticleBytes == 112) { sfx.version = 2; sfx.FirstUnk112_0 = reader.ReadInt32(); sfx.FirstUnk112_1 = reader.ReadInt32(); sfx.FirstUnk112_2 = reader.ReadInt32(); sfx.FirstUnk112_3 = reader.ReadInt32(); } sfx.MaxParticles = reader.ReadInt32(); sfx.startSizeMin = reader.ReadSingle(); sfx.startSizeMax = reader.ReadSingle(); sfx.unknwon2 = reader.ReadSingle(); //1 sfx.unknown3 = reader.ReadSingle(); //5 sfx.gravity = reader.ReadSingle(); //30?可能是重力系数.其大于0时,粒子往下朝,其小于=0时,粒子向上 sfx.StartLifetime = reader.ReadSingle(); //粒子生命周期 sfx.StartLifetime2 = reader.ReadSingle(); //1 sfx.emitWidth = reader.ReadSingle(); //50 - startSpeed sfx.emitLong = reader.ReadSingle(); //80 - startSpeed2 sfx.linear0 = reader.ReadSingle(); //0.1f sfx.linear1 = reader.ReadSingle(); //0.1f; sfx.EmitStartAxis.x = reader.ReadSingle(); //-1.0f; sfx.EmitStartAxis.y = reader.ReadSingle(); //-1.0f; sfx.EmitStartAxis.z = reader.ReadSingle(); //-1.0f; sfx.EmitEndAxis.x = reader.ReadSingle(); //+1.0f; sfx.EmitEndAxis.y = reader.ReadSingle(); //+1.0f; sfx.EmitEndAxis.z = reader.ReadSingle(); //+1.0f; sfx.particleNotLoop = reader.ReadInt32(); //0 sfx.Speed = reader.ReadInt32(); //1 sfx.FadeIn = reader.ReadInt32(); //1 sfx.FadeInAlpha = reader.ReadSingle(); //0.5f sfx.FadeOut = reader.ReadInt32(); //1 sfx.FadeOutAlpha = reader.ReadSingle(); //0.3 int regionCnt = reader.ReadInt32(); string sBone = readNextString(reader, regionCnt); sfx.Tails[0] = sBone; regionCnt = reader.ReadInt32(); sBone = readNextString(reader, regionCnt); sfx.Tails[1] = sBone; regionCnt = reader.ReadInt32(); sBone = readNextString(reader, regionCnt); sfx.Tails[2] = sBone; } else if (sfx.EffectType.Equals("DONUT")) { reader.BaseStream.Seek(24, SeekOrigin.Current); } else if (sfx.EffectType.Equals("DRAG")) { reader.BaseStream.Seek(4, SeekOrigin.Current); int len4 = reader.ReadInt32(); sfx.Tails[0] = readNextString(reader, len4); len4 = reader.ReadInt32(); sfx.Tails[1] = readNextString(reader, len4); } else if (sfx.EffectType.Equals("MODEL")) { int len4 = reader.ReadInt32(); sfx.Tails[0] = readNextString(reader, len4); } else if (sfx.EffectType.Equals("SPHERE")) { sfx.SphereRadius = reader.ReadSingle(); sfx.sphereAttr.x = reader.ReadSingle(); sfx.sphereAttr.y = reader.ReadSingle(); sfx.sphereAttr.z = reader.ReadSingle(); sfx.sphereAttr.w = reader.ReadSingle(); } else { Debug.LogError(string.Format("{0} can not parse: file {1}", sfx.EffectType, file)); error = true; } effectList.Add(sfx); } } ms.Close(); reader.Close(); return(true); }
//原粒子系统是右手坐标系的,转移到左手坐标系后非常多问题,特别是父子关系以及,跟随和子物体旋转叠加 public void Init(SfxEffect effect, SFXEffectPlay parent, int index, float timePlayed = 0.0f) { playedTime = timePlayed; PlayDone = false; transform.rotation = Quaternion.identity; effectIndex = index; parentSfx = parent;//当找不到跟随者的时候,向父询问其他特效是否包含此名称. name = effect.EffectName; EffectType = effect.EffectType; //一个是跟随移动,一个是跟随旋转 mOwner = parent.GetComponent <MeteorUnit>(); source = effect; if (effect.EffectType == "PARTICLE") { particle = Instantiate(Resources.Load <GameObject>("SFXParticles"), Vector3.zero, Quaternion.identity, transform).GetComponent <ParticleSystem>(); } if (string.IsNullOrEmpty(effect.Bone0)) { PositionFollow = mOwner == null ? parentSfx.transform : mOwner.transform; } else if (effect.Bone0 == "ROOT") { PositionFollow = mOwner == null ? parent.transform : mOwner.ROOTNull; } else if (effect.Bone0 == "Character")//根骨骼上一级,角色,就是不随着b骨骼走,但是随着d_base走 { PositionFollow = mOwner == null ? parent.transform: mOwner.RootdBase; } else { PositionFollow = FindFollowed(effect.Bone0); } if (string.IsNullOrEmpty(effect.Bone1)) { RotateFollow = mOwner == null ? parent.transform : mOwner.transform; } else if (effect.Bone1 == "ROOT") { RotateFollow = mOwner == null ? parent.transform : mOwner.ROOTNull; } else if (effect.Bone1 == "Character") { RotateFollow = mOwner == null ? parent.transform : mOwner.RootdBase; } else { RotateFollow = FindFollowed(effect.Bone1); } if (PositionFollow != null) { transform.position = PositionFollow.transform.position; } mRender = gameObject.GetComponent <MeshRenderer>(); mFilter = gameObject.GetComponent <MeshFilter>(); int meshIndex = -1; if (effect.EffectType == "DONUT") { //Debug.LogError("find Donut Effect"); } //部分模型是要绕X旋转270的,这样他的缩放,和移动,都只能靠自己 if (effect.EffectType == "PLANE") { meshIndex = 0; } else if (effect.EffectType == "BOX") { meshIndex = 1; } else if (effect.EffectType == "DONUT") { transform.localScale = effect.frames[0].scale; meshIndex = 2; } else if (effect.EffectType == "MODEL")//自行加载模型 { transform.localScale = effect.frames[0].scale; transform.rotation = RotateFollow.rotation * effect.frames[0].quat; transform.position = PositionFollow.position + effect.frames[0].pos; if (!string.IsNullOrEmpty(effect.Tails[0])) { string[] des = effect.Tails[0].Split(new char[] { '\\' }, System.StringSplitOptions.RemoveEmptyEntries); if (des.Length != 0) { WsGlobal.ShowMeteorObject(des[des.Length - 1], transform); } } //这个时候,不要用自带的meshfilter了,让他自己处理显示问题,只要告诉他在哪个地方显示 meshIndex = 100; } else if (effect.EffectType == "SPHERE") { meshIndex = 3; } else if (effect.EffectType == "PARTICLE") { if (!string.IsNullOrEmpty(effect.Tails[0])) { PositionFollow = FindFollowed(effect.Tails[0]); } if (!string.IsNullOrEmpty(effect.Tails[1])) { RotateFollow = FindFollowed(effect.Tails[1]); } if (PositionFollow != null) { transform.position = PositionFollow.transform.position; } meshIndex = 101; } else if (effect.EffectType == "CYLINDER") { //InitializeQuat = new Quaternion(0.7170f, 0, 0, -0.7170f); //InitializeQuat = Quaternion.identity; meshIndex = 4; } else if (effect.EffectType == "BILLBOARD") { LookAtC = true; meshIndex = 5; } else if (effect.EffectType == "DRAG") { meshIndex = 6; } //决定模型 if (meshIndex != -1 && meshIndex < mesh.Length) { if (meshIndex == 4) { mFilter.mesh = SfxMeshGenerator.Instance.CreateCylinder(source.origAtt.y, source.origAtt.x, source.origScale.x); } else if (meshIndex == 3) { mFilter.mesh = SfxMeshGenerator.Instance.CreateSphere(source.SphereScale); } else if (meshIndex == 0) { mFilter.mesh = SfxMeshGenerator.Instance.CreatePlane(source.origScale.x, source.origScale.y); } else { mFilter.mesh = mesh[meshIndex]; } } if (effect.Texture.ToLower().EndsWith(".bmp") || effect.Texture.ToLower().EndsWith(".jpg") || effect.Texture.ToLower().EndsWith(".tga")) { texture = effect.Texture.Substring(0, effect.Texture.Length - 4); tex = Resources.Load <Texture>(texture); } else if (effect.Texture.ToLower().EndsWith(".ifl")) { iflTexture = gameObject.AddComponent <IFLLoader>(); iflTexture.IFLFile = Resources.Load <TextAsset>(effect.Texture); if (effect.EffectType == "PARTICLE") { iflTexture.SetTargetMeshRenderer(particle.GetComponent <ParticleSystemRenderer>()); } iflTexture.LoadIFL();//传递false表示由特效控制每一帧的切换时间. tex = iflTexture.GetTexture(0); } //else // print("effect contains other prefix:" + effect.Texture == null ? " texture is null" : effect.Texture); if (tex != null) { if (effect.EffectType == "PARTICLE") { ParticleSystemRenderer render = particle.GetComponent <ParticleSystemRenderer>(); if (effect.BlendType == 0) { render.material.shader = Shader.Find("Unlit/Texture");//普通不透明无光照 } else if (effect.BlendType == 1) { render.material.shader = Shader.Find("UnlitAdditive");//滤色 加亮 不透明 } else if (effect.BlendType == 2) { render.material.shader = Shader.Find("UnlitAdditive");//反色+透明度 } else if (effect.BlendType == 3) { render.material.shader = Shader.Find("Mobile/Particles/Alpha Blended");//不滤色,支持透明 } else if (effect.BlendType == 4) { render.material.shader = Shader.Find("Custom/MeteorBlend4");//滤色,透明 } else { render.material.shader = Shader.Find("Unlit/Texture");//普通不透明无光照 } render.material.SetTexture("_MainTex", tex); render.material.SetColor("_Color", effect.frames[0].colorRGB); render.material.SetColor("_TintColor", effect.frames[0].colorRGB); render.material.SetFloat("_Intensity", effect.frames[0].TailFlags[9]); //particle.Emit(1); } else { if (effect.BlendType == 0) { mRender.material.shader = Shader.Find("Unlit/Texture");//普通不透明无光照 } else if (effect.BlendType == 1) { mRender.material.shader = Shader.Find("UnlitAdditive");//滤色 加亮 不透明 } else if (effect.BlendType == 2) { mRender.material.shader = Shader.Find("UnlitAdditive");//反色+透明度 } else if (effect.BlendType == 3) { mRender.material.shader = Shader.Find("Mobile/Particles/Alpha Blended");//不滤色,支持透明 } else if (effect.BlendType == 4) { mRender.material.shader = Shader.Find("Custom/MeteorBlend4");//滤色,透明 } else { mRender.material.shader = Shader.Find("Unlit/Texture");//普通不透明无光照 } if (effect.BlendType == 2) { mRender.material.SetColor("_InvColor", effect.frames[0].colorRGB); } else { mRender.material.SetColor("_Color", effect.frames[0].colorRGB); mRender.material.SetColor("_TintColor", effect.frames[0].colorRGB); } mRender.material.SetFloat("_Intensity", effect.frames[0].TailFlags[9]); mRender.material.SetTexture("_MainTex", tex); if (effect.uSpeed != 0.0f || effect.vSpeed != 0.0f) { tex.wrapMode = TextureWrapMode.Repeat; } else { tex.wrapMode = TextureWrapMode.Clamp; } mRender.material.SetFloat("_u", effect.uSpeed); mRender.material.SetFloat("_v", effect.vSpeed); } } if (effect.Hidden == 1) { if (particle != null) { ParticleSystemRenderer render = particle.GetComponent <ParticleSystemRenderer>(); if (render != null) { render.enabled = false; } } mRender.enabled = false; } if (effect.EffectName.StartsWith("Attack")) { if (effect.EffectType == "SPHERE") { damageBox = gameObject.AddComponent <SphereCollider>(); } else { damageBox = gameObject.AddComponent <BoxCollider>(); } damageBox.enabled = false; } playCoroutine = StartCoroutine(PlayEffectFrame()); }