質問するログイン新規登録

回答編集履歴

1

位置を移動する例を追記

2019/06/28 18:58

投稿

Bongo
Bongo

スコア10818

answer CHANGED
@@ -1,4 +1,81 @@
1
1
  流れを曲げる手段の候補として[Particle System Force Field](https://docs.unity3d.com/ja/current/Manual/class-ParticleSystemForceField.html)はいかがでしょうか?
2
2
  フィールドをちまちま並べるのは少々面倒かもしれませんが、一応それらしくなりそうな気がします。
3
3
 
4
- ![結果](47df00cecfc7bfb98241e6b944bab8cd.gif)
4
+ ![結果](47df00cecfc7bfb98241e6b944bab8cd.gif)
5
+
6
+ **追記**
7
+ ParticleSystemForceFieldを付けたオブジェクトを移動・回転・拡大縮小すると効果範囲もちゃんと変形しますので、たとえば下記コードのようにフィールドオブジェクトを数珠つなぎに参照させて、常に次のオブジェクトの方を向くようにしてやれば、オブジェクトの位置を調整するだけで向きを自動的に合わせてくれるでしょうからレイアウトが楽になりそうです。
8
+
9
+ ```C#
10
+ using UnityEngine;
11
+
12
+ [RequireComponent(typeof(ParticleSystemForceField))]
13
+ [ExecuteAlways]
14
+ public class FieldDirector : MonoBehaviour
15
+ {
16
+ // インスペクター上でnextFieldに次の目標となるオブジェクトをセットしておき
17
+ // 全体としてフィールドオブジェクトが数珠つなぎになるようにする
18
+ public Transform nextField;
19
+ private ParticleSystemForceField field;
20
+
21
+ private void OnEnable()
22
+ {
23
+ this.field = this.GetComponent<ParticleSystemForceField>();
24
+ }
25
+
26
+ private void Update()
27
+ {
28
+ if (this.nextField == null)
29
+ {
30
+ return;
31
+ }
32
+
33
+ // Y軸を次の目標の方角へ向ける(Y軸方向に力をかけるよう設定されていることを前提としています)
34
+ this.transform.rotation = Quaternion.LookRotation(this.nextField.position - this.transform.position) *
35
+ Quaternion.Euler(90.0f, 0.0f, 0.0f);
36
+ }
37
+
38
+ private void OnDrawGizmos()
39
+ {
40
+ // 次の目標に向かって線を引き、また効果範囲をわかりやすくするため枠線を描く
41
+ Gizmos.color = Color.yellow;
42
+ if (this.nextField != null)
43
+ {
44
+ Gizmos.DrawLine(this.transform.position, this.nextField.position);
45
+ }
46
+
47
+ Gizmos.matrix = this.transform.localToWorldMatrix;
48
+ Gizmos.DrawWireCube(Vector3.zero, new Vector3(2.0f, this.field.length, 2.0f));
49
+ }
50
+ }
51
+ ```
52
+
53
+ 手動操作に限らず、スクリプトで位置を操作しても問題ないはずです。下記のようなスクリプトでフィールドを移動させると...
54
+
55
+ ```C#
56
+ using UnityEngine;
57
+
58
+ public class FieldMotor : MonoBehaviour
59
+ {
60
+ [SerializeField] private float amplitude = 3.0f;
61
+ [SerializeField] private float angularSpeed = 15.0f;
62
+ private float phase;
63
+
64
+ private void Start()
65
+ {
66
+ this.phase = Mathf.Asin(Mathf.Clamp(this.transform.position.x / this.amplitude, -1.0f, 1.0f));
67
+ }
68
+
69
+ private void Update()
70
+ {
71
+ this.phase += this.angularSpeed * Mathf.Deg2Rad * Time.deltaTime;
72
+ var position = this.transform.position;
73
+ position.x = Mathf.Sin(this.phase) * this.amplitude;
74
+ this.transform.position = position;
75
+ }
76
+ }
77
+ ```
78
+
79
+ 下図のように流れが変化しました。フィールドの形状はある程度長くして、雨どいを並べるような感じでレイアウトするのがよさそうに思います。
80
+
81
+ ![結果](2d3c859bff36570f6ec1d20dbbcc63a1.gif)