-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDrawPhysicsLine.cs
More file actions
210 lines (154 loc) · 6.21 KB
/
DrawPhysicsLine.cs
File metadata and controls
210 lines (154 loc) · 6.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UniRx;
using System;
//オブジェクトを描くスクリプト(線を生成する部分の機能は社員の方が実装。それをもとにこのゲーム用に改良)
//私もメッシュ変形を用いて線を描く機能を実装したので、詳しくは下記を参照していただけると幸いです。
//https://unityroom.com/games/stopthecar
//https://github.com/taniyuji/StopTheCar_Scripts/blob/master/LineDrawer_v2.cs
public class DrawPhysicsLine : MonoBehaviour
{
[Header("線を構成するブロック")]
[SerializeField] GameObject linePrefab;
[Header("線の単位長")]
[SerializeField] float lineLength = 0.2f;
[Header("線の幅")]
[SerializeField] float lineWidth = 0.2f;
[Header("線の奥行き")]
[SerializeField] float lineZ = 1f;
[Header("線の単位長の延長(線がギザギザするときはこの値を調整)")]
[SerializeField] float lineLengthExtension = 0.1f;
[SerializeField] private int instantiateAmount;
[SerializeField]
private float minimumLength = 2;//線の最小の短さ
// 一つ前のタッチされたpositionを保持
private Vector3 touchPos;
Camera mainCamera;
//1つ前の線と生成中の線を二つのリストにして使い分け
public List<GameObject> lines1 { get; private set; } = new List<GameObject>();
public List<GameObject> lines2 { get; private set; } = new List<GameObject>();
private int index = 0;
private bool isUsingList1 = true;
private MeshRenderer mesh;
private BoxCollider boxCollider;
private float shapeLength = 0;
private bool canDraw = false;
private Subject<Unit> _changeShape = new Subject<Unit>();
public IObservable<Unit> changeShape
{
get { return _changeShape; }
}
void Awake()
{
mesh = GetComponent<MeshRenderer>();
boxCollider = GetComponent<BoxCollider>();
mainCamera = Camera.main;
//線生成に必要なオブジェクトをあらかじめプールする
for (int i = 0; i < instantiateAmount; i++)
{
GameObject obj = Instantiate(linePrefab) as GameObject;
obj.SetActive(false);
lines1.Add(obj);
}
for (int i = 0; i < instantiateAmount; i++)
{
GameObject obj = Instantiate(linePrefab) as GameObject;
obj.SetActive(false);
lines2.Add(obj);
}
}
public void ChangeShape()//Draw終了時に前の線と描いた線を入れ替えるメソッド。MouseButtonUp時に呼ばれる
{
ResourceProvider.i.ok.enabled = false;
if (!canDraw)//線の長さが足りなかった場合は描写途中だったオブジェクトを初期化し返す
{
for (int i = 0; i < index; i++)
{
if (isUsingList1)
{
lines1[i].SetActive(false);
lines1[i].transform.parent = null;
}
else
{
lines2[i].SetActive(false);
lines2[i].transform.parent = null;
}
}
index = 0;
shapeLength = 0;
return;
}
//初期状態の四角形メッシュを非表示にする
if (boxCollider.enabled)
{
mesh.enabled = false;
boxCollider.enabled = false;
}
//現在表示中の線のリストを非表示にし、もう一つの方のリストを表示する
for (int i = 0; i < instantiateAmount; i++)
{
if (!isUsingList1)
{
lines1[i].SetActive(false);
lines1[i].transform.parent = null;
if (i < index) lines2[i].SetActive(true);
}
else
{
lines2[i].SetActive(false);
lines2[i].transform.parent = null;
if (i < index) lines1[i].SetActive(true);
}
}
//変形終了したことをShapeAnimationスクリプトへ通知
_changeShape.OnNext(Unit.Default);
index = 0;
shapeLength = 0;
canDraw = false;
}
public void PenDown(Vector3 drawPos)//次に使用するリストを決めるメソッド。MouseButtonDown時に呼ばれる。
{
touchPos = drawPos;
if (!lines1[0].activeSelf && !lines2[0].activeSelf)
{
isUsingList1 = true;
}
else
{
isUsingList1 = !lines1[0].activeSelf ? true : false;
}
}
public void PenMove(Vector3 drawPos)//引数のPointerポジションをもとに線を生成していくメソッド。MouseButton時に呼ばれる。
{
Vector3 startPos = touchPos;
Vector3 endPos = drawPos;
float distance = Vector3.Distance(startPos, endPos);
//Debug.Log(shapeLength);
if (shapeLength > minimumLength && !canDraw)
{
SoundManager.i.PlayOneShot(6, 0.5f);
ResourceProvider.i.ok.enabled = true;
canDraw = true;
}
if (index >= lines1.Count || index >= lines2.Count)
{
Debug.Log("no More Objects to draw");
return;
}
//1フレーム前の入力と現在の入力の距離が線を構成する四角形プレファブ一個分より長い場合
if (distance > lineLength * Time.deltaTime / Time.fixedDeltaTime)
{
// GameObject obj = GameObject.CreatePrimitive(PrimitiveType.Cube);
shapeLength += distance;//線の長さを更新
GameObject obj = isUsingList1 ? lines1[index] : lines2[index];//使用されていないほうのリストを使う
obj.transform.parent = transform;
obj.transform.localPosition = (startPos + endPos) / 2;//2つの入力の間に配置
obj.transform.right = (endPos - startPos).normalized;//2つの入力のベクトル方向に傾ける
obj.transform.localScale = new Vector3(distance + lineLengthExtension, lineWidth, lineZ);
touchPos = endPos;
index++;
}
}
}