From df84ee7e568fa500fec7b1865b966345b814e68f Mon Sep 17 00:00:00 2001 From: chai Date: Wed, 21 Oct 2020 22:51:18 +0800 Subject: =?UTF-8?q?+=20=E6=AE=8B=E5=BD=B1=E7=89=B9=E6=95=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Assets/Scripts/Effects/ShurikenBakedMeshEmitter.cs | 124 +++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 Assets/Scripts/Effects/ShurikenBakedMeshEmitter.cs (limited to 'Assets/Scripts/Effects/ShurikenBakedMeshEmitter.cs') diff --git a/Assets/Scripts/Effects/ShurikenBakedMeshEmitter.cs b/Assets/Scripts/Effects/ShurikenBakedMeshEmitter.cs new file mode 100644 index 00000000..65a36d9d --- /dev/null +++ b/Assets/Scripts/Effects/ShurikenBakedMeshEmitter.cs @@ -0,0 +1,124 @@ +using UnityEngine; +using System.Collections; + +public class ShurikenBakedMeshEmitter : MonoBehaviour +{ + [Tooltip("パーティクルで使用したいメッシュ")] + public SkinnedMeshRenderer skin; + //使用するメッシュの現在の形を保存 + Mesh baked; + //再生に使用するパーティクルシステム + ParticleSystem particle; + ParticleSystemRenderer render; + [Tooltip("パーティクルの再生/停止")] + public bool emit; + [Tooltip("パーティクルを放出する間隔(秒)")] + public float coolDown = 0.5f; + //現在の待機時間 + float interval = 0; + + // Use this for initialization + void Start() + { + //元となるメッシュが指定されていなければ本スクリプトを停止 + if (!skin) + this.enabled = false; + //使用するパーティクルシステムへのアクセス + particle = GetComponent(); + render = GetComponent(); + } + + // Update is called once per frame + void Update() + { + //emitが[true]なら... + if (emit) + { + //待機時間の計算 + interval -= Time.deltaTime; + //必要分の待機時間が経過したなら... + if (interval < 0) + { + //シーンに新たなGameObjectを再生(本GameObjectのコピー) + GameObject newEmitter = Instantiate(gameObject, transform.position, transform.rotation) as GameObject; + //再生したGameObjectにEmitMesh()を指示 + newEmitter.GetComponent().EmitMesh(); + //待機時間のリセット + interval = coolDown; + } + //emitが[false]なら... + } + else + { + //待機時間のリセット + interval = coolDown; + } + } + + //外部からのアクセスでパーティクルの再生をさせる + public void EmitMesh() + { + //Update ()させない為に[false] + emit = false; + //メッシュの型をリセット + baked = new Mesh(); + //使用するメッシュの現在の形を保存 + skin.BakeMesh(baked); + + //自身のパーティクルシステムへのアクセス + particle = GetComponent(); + render = GetComponent(); + + Mesh mainMesh = baked; + Mesh meshToCopy = new Mesh(); + meshToCopy.vertices = mainMesh.vertices; + meshToCopy.triangles = mainMesh.triangles; + meshToCopy.normals = mainMesh.normals; + meshToCopy.uv = mainMesh.uv; + int amount = 8; + Matrix4x4[] matrix = new Matrix4x4[amount]; + for (int i = 0; i < amount; i++) + { + matrix[i].SetTRS(new Vector3(i * 10, 0, 0), Quaternion.Euler(new Vector3(Random.Range(-5, 5), Random.Range(0, 360), Random.Range(-5, 5))), Vector3.one); + } + + CombineInstance[] ci = new CombineInstance[amount]; + for (int i = 0; i < amount; i++) + { + ci[i] = new CombineInstance(); + ci[i].mesh = meshToCopy; + ci[i].transform = matrix[i]; + } + + Mesh batchedMesh = gameObject.AddComponent().mesh = new Mesh(); + batchedMesh.CombineMeshes(ci); + + int[] mainSubTri; + int[] newSubTri; + batchedMesh.subMeshCount = mainMesh.subMeshCount; + + for (int i = 0; i < mainMesh.subMeshCount; i++) + { + mainSubTri = mainMesh.GetTriangles(i); + + newSubTri = new int[mainSubTri.Length * amount]; + + for (int ii = 0; ii < amount; ii++) + { + for (int iii = 0; iii < mainSubTri.Length; iii++) + { + newSubTri[(ii * mainSubTri.Length) + iii] = mainSubTri[iii] + (ii * mainMesh.vertexCount); + } + } + batchedMesh.SetTriangles(newSubTri, i); + } + + + //パーティクルシステムで使用するメッシュを指定 + render.mesh = meshToCopy; + //パーティクルの再生 + particle.Play(); + //本GameObjectの破棄の指示 + Destroy(gameObject, particle.duration); + } +} \ No newline at end of file -- cgit v1.1-26-g67d0