質問編集履歴

2

スクリプトを追記し、より具体的にしました

2020/10/19 10:25

投稿

911RSR
911RSR

スコア13

test CHANGED
@@ -1 +1 @@
1
- unity 3d ランタイム リアン演算 undo/redo やり直し 実装
1
+ unity 3D ランタイム ムモード オブジェクト生成 やり直し 実装 undo redo
test CHANGED
@@ -1,16 +1,94 @@
1
+ (10/19加筆、訂正しました。)
2
+
3
+ Unity 3Dで、
4
+
1
- 引き続きゲームモードでーリアン演算行うゲームを開発しています。
5
+ ゲームモードでクリックしたところにオジェクト生成しています。
6
+
7
+
8
+
2
-
9
+ このオブジェクト(プレハブ)の作成スクリプトは以下です。
10
+
11
+
12
+
3
-
13
+ ```ここに言語を入力
4
-
14
+
5
- 具体的には凹みtipsさんのページを参考に、
15
+ using System.Collections;
16
+
6
-
17
+ using System.Collections.Generic;
18
+
19
+ using UnityEngine;
20
+
21
+
22
+
23
+ public class SkewCreater : MonoBehaviour
24
+
25
+ {
26
+
27
+ public GameObject prefabobj;
28
+
29
+ public Renderer rend;
30
+
31
+
32
+
33
+ // Start is called before the first frame update
34
+
35
+ void Start()
36
+
37
+ {
38
+
39
+
40
+
41
+ }
42
+
43
+
44
+
45
+ // Update is called once per frame
46
+
47
+ void Update()
48
+
49
+ {
50
+
51
+ if (Input.GetMouseButtonDown(0))
52
+
53
+ {
54
+
55
+ Vector2 touchScreenPosition = Input.mousePosition;
56
+
57
+
58
+
7
- (http://tips.hecomi.com/entry/2016/09/10/191006)
59
+ touchScreenPosition.x = Mathf.Clamp(touchScreenPosition.x, 0.0f, Screen.width);
60
+
8
-
61
+ touchScreenPosition.y = Mathf.Clamp(touchScreenPosition.y, 0.0f, Screen.height);
62
+
63
+
64
+
65
+ Camera gameCamera = Camera.main;
66
+
67
+ Ray touchPointToRay = gameCamera.ScreenPointToRay(touchScreenPosition);
68
+
69
+
70
+
71
+ RaycastHit hitInfo = new RaycastHit();
72
+
73
+ if (Physics.Raycast(touchPointToRay, out hitInfo))
74
+
75
+ {
76
+
9
- 左クリックしたところに透明オブジェクトを発生させ、当たり判定を起こしたオブジェクトをくり抜く、それを繰り返していきます。
77
+ Instantiate(prefabobj, hitInfo.point, Quaternion.identity);
78
+
10
-
79
+ }
80
+
11
-
81
+ }
82
+
12
-
83
+ }
84
+
85
+ }
86
+
87
+ ```
88
+
89
+
90
+
13
- このゲームでのやり直し機能、すなわち undo / redo 機能の実装に苦慮しています。
91
+ このプレハブ生成のやり直し機能、すなわち undo / redo 機能の実装に苦慮しています。
14
92
 
15
93
 
16
94
 
@@ -22,14 +100,194 @@
22
100
 
23
101
 
24
102
 
103
+ 3つのスクリプトを書きました。
104
+
105
+ ・CommandManager
106
+
107
+ ```ここに言語を入力
108
+
109
+ using System.Collections;
110
+
111
+ using System.Collections.Generic;
112
+
113
+ using System.Runtime.InteropServices.WindowsRuntime;
114
+
115
+ using UnityEngine;
116
+
117
+
118
+
119
+ public class CommandManager : MonoBehaviour
120
+
121
+ {
122
+
123
+ private Stack<IAction> historyStack = new Stack<IAction>();
124
+
125
+ private Stack<IAction> redoHistoryStack = new Stack<IAction>();
126
+
127
+
128
+
129
+
130
+
131
+ public void ExecuteCommand(IAction action)
132
+
133
+ {
134
+
135
+ action.ExecuteCommand();
136
+
137
+ historyStack.Push(action);
138
+
139
+ redoHistoryStack.Clear();
140
+
141
+ }
142
+
143
+
144
+
145
+ public void UndoCommand()
146
+
147
+ {
148
+
149
+ if(historyStack.Count > 0)
150
+
151
+ {
152
+
153
+ redoHistoryStack.Push(historyStack.Peek());
154
+
155
+ historyStack.Pop().UndoCommand();
156
+
157
+ }
158
+
159
+ }
160
+
161
+
162
+
163
+ public void RedoCommand()
164
+
165
+ {
166
+
167
+ if(redoHistoryStack.Count > 0)
168
+
169
+ {
170
+
171
+ historyStack.Push(redoHistoryStack.Peek());
172
+
173
+ redoHistoryStack.Pop().ExecuteCommand();
174
+
175
+ }
176
+
177
+ }
178
+
179
+ }
180
+
181
+ ```
182
+
183
+ ・IAction
184
+
185
+ ```ここに言語を入力
186
+
187
+ using System.Collections;
188
+
189
+ using System.Collections.Generic;
190
+
191
+ using UnityEngine;
192
+
193
+
194
+
195
+ public interface IAction
196
+
197
+ {
198
+
199
+ void ExecuteCommand();
200
+
201
+
202
+
203
+ void UndoCommand();
204
+
205
+ }
206
+
207
+
208
+
209
+ ```
210
+
211
+
212
+
213
+ ・InstantiateCommand
214
+
215
+ ```ここに言語を入力
216
+
217
+ using System.Collections;
218
+
219
+ using System.Collections.Generic;
220
+
221
+ using System.Collections.Specialized;
222
+
223
+ using UnityEngine;
224
+
225
+
226
+
227
+ public class InstantiateCommand : IAction
228
+
229
+ {
230
+
231
+ private GameObject toSpawnGameObject;
232
+
233
+ private Vector3 positionToSpawn;
234
+
235
+
236
+
237
+ private GameObject spawnedGameObject;
238
+
239
+
240
+
241
+ public InstantiateCommand(GameObject toSpawnGameObject,Vector3 positionToSpawn)
242
+
243
+ {
244
+
245
+ this.toSpawnGameObject = toSpawnGameObject;
246
+
25
- オブジェクト生成のundo/redoは達成できたと思うのですが、
247
+ this.positionToSpawn = positionToSpawn;
248
+
26
-
249
+ }
250
+
251
+
252
+
27
- くりぬくのに使用したオブジェクトはundoで消えても、
253
+ public void ExecuteCommand()
254
+
28
-
255
+ {
256
+
257
+ spawnedGameObject = GameObject.Instantiate(toSpawnGameObject, positionToSpawn, Quaternion.identity);
258
+
259
+ }
260
+
261
+
262
+
263
+ public void UndoCommand()
264
+
265
+ {
266
+
267
+ GameObject.Destroy(spawnedGameObject);
268
+
269
+ }
270
+
271
+
272
+
273
+ }
274
+
275
+
276
+
277
+ ```
278
+
279
+
280
+
281
+ 次いでHierarchy windowに空のゲームオブジェクト<Player>を置き、これにCommandManagerをアタッチし、
282
+
283
+ UI Buttonを2つ作成、それぞれにOn Click()でシーン上のこの<Player>を指定、UndoCommandとRedoCommandをそれぞれアタッチしました。
284
+
285
+
286
+
29
- くりぬれたオブジェトは既にブーアン演算を終えくり抜かれ後なので、一見何も起こりません
287
+ しUndoボタンをクリックしもinstantiateしプレハブが消えません
30
-
288
+
289
+
290
+
31
- (くりぬれたまます)
291
+ どこがおしいしょうか
32
-
33
-
34
-
292
+
35
- 手詰まってしまっているのですが、アセットやスクリプトで何か解決方法をご教示頂けないしょうか
293
+ ご教示頂けますと幸甚

1

2020/10/19 10:25

投稿

911RSR
911RSR

スコア13

test CHANGED
@@ -1 +1 @@
1
- unity 3d ランタイム ブーリアン演算 くり抜き undo/redo やり直し 戻る の実装
1
+ unity 3d ランタイム ブーリアン演算 undo/redo やり直し 実装
test CHANGED
@@ -24,7 +24,7 @@
24
24
 
25
25
  オブジェクト生成のundo/redoは達成できたと思うのですが、
26
26
 
27
- くりぬたオブジェクトはundoで消えても、
27
+ くりぬくのに使用したオブジェクトはundoで消えても、
28
28
 
29
29
  くりぬかれたオブジェクトは既にブーリアン演算を終えてくり抜かれた後なので、一見何も起こりません
30
30