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

質問編集履歴

2

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

2020/10/19 10:25

投稿

911RSR
911RSR

スコア13

title CHANGED
@@ -1,1 +1,1 @@
1
- unity 3d ランタイム リアン演算 undo/redo やり直し 実装
1
+ unity 3D ランタイム ムモード オブジェクト生成 やり直し 実装 undo redo
body CHANGED
@@ -1,18 +1,147 @@
1
+ (10/19加筆、訂正しました。)
2
+ Unity 3Dで、
1
- 引き続きゲームモードでのブーアン演算行うゲームを開発しています。
3
+ ゲームモードでックしたところにオブジェクト生成しています。
2
4
 
3
- 具体的には凹みtipsさんペーを参考に、
5
+ オブェクト(プレハブ)の作成スクリプトは以下です。
4
- (http://tips.hecomi.com/entry/2016/09/10/191006)
5
- 左クリックしたところに透明オブジェクトを発生させ、当たり判定を起こしたオブジェクトをくり抜く、それを繰り返していきます。
6
6
 
7
+ ```ここに言語を入力
8
+ using System.Collections;
7
- このゲームでのやり直し機能、すなわち undo / redo 機能の実装に苦慮しています。
9
+ using System.Collections.Generic;
10
+ using UnityEngine;
8
11
 
12
+ public class SkewCreater : MonoBehaviour
13
+ {
14
+ public GameObject prefabobj;
15
+ public Renderer rend;
16
+
17
+ // Start is called before the first frame update
18
+ void Start()
19
+ {
20
+
21
+ }
22
+
23
+ // Update is called once per frame
24
+ void Update()
25
+ {
26
+ if (Input.GetMouseButtonDown(0))
27
+ {
28
+ Vector2 touchScreenPosition = Input.mousePosition;
29
+
30
+ touchScreenPosition.x = Mathf.Clamp(touchScreenPosition.x, 0.0f, Screen.width);
31
+ touchScreenPosition.y = Mathf.Clamp(touchScreenPosition.y, 0.0f, Screen.height);
32
+
33
+ Camera gameCamera = Camera.main;
34
+ Ray touchPointToRay = gameCamera.ScreenPointToRay(touchScreenPosition);
35
+
36
+ RaycastHit hitInfo = new RaycastHit();
37
+ if (Physics.Raycast(touchPointToRay, out hitInfo))
38
+ {
39
+ Instantiate(prefabobj, hitInfo.point, Quaternion.identity);
40
+ }
41
+ }
42
+ }
43
+ }
44
+ ```
45
+
46
+ このプレハブ生成のやり直し機能、すなわち undo / redo 機能の実装に苦慮しています。
47
+
9
48
  以下のyoutube 、ウェブサイトを参考に、
10
49
  https://www.youtube.com/watch?v=gnyDH1kcZKQ
11
50
  https://mega.nz/file/aERhlSRY#f7iLx88J9ytc9l48P15v6peAmWghdQxjL1aQo-0QfEM
12
51
 
13
- オブジェクト生成のundo/redoは達成できたと思うのですが、
14
- くりぬくのに使用したオブジェクトはundoで消えても、
15
- くりぬかれたオブジェクトは既にブーリアン演算を終えてくり抜かれた後なので、一見何も起こりません
16
- (くりぬかれたまです)
52
+ 3つのスクリプトを書きした
53
+ ・CommandManager
54
+ ```ここに言語を入力
55
+ using System.Collections;
56
+ using System.Collections.Generic;
57
+ using System.Runtime.InteropServices.WindowsRuntime;
58
+ using UnityEngine;
17
59
 
60
+ public class CommandManager : MonoBehaviour
61
+ {
62
+ private Stack<IAction> historyStack = new Stack<IAction>();
63
+ private Stack<IAction> redoHistoryStack = new Stack<IAction>();
64
+
65
+
66
+ public void ExecuteCommand(IAction action)
67
+ {
68
+ action.ExecuteCommand();
69
+ historyStack.Push(action);
70
+ redoHistoryStack.Clear();
71
+ }
72
+
73
+ public void UndoCommand()
74
+ {
75
+ if(historyStack.Count > 0)
76
+ {
77
+ redoHistoryStack.Push(historyStack.Peek());
78
+ historyStack.Pop().UndoCommand();
79
+ }
80
+ }
81
+
82
+ public void RedoCommand()
83
+ {
84
+ if(redoHistoryStack.Count > 0)
85
+ {
86
+ historyStack.Push(redoHistoryStack.Peek());
87
+ redoHistoryStack.Pop().ExecuteCommand();
88
+ }
89
+ }
90
+ }
91
+ ```
92
+ ・IAction
93
+ ```ここに言語を入力
94
+ using System.Collections;
95
+ using System.Collections.Generic;
96
+ using UnityEngine;
97
+
98
+ public interface IAction
99
+ {
100
+ void ExecuteCommand();
101
+
102
+ void UndoCommand();
103
+ }
104
+
105
+ ```
106
+
107
+ ・InstantiateCommand
108
+ ```ここに言語を入力
109
+ using System.Collections;
110
+ using System.Collections.Generic;
111
+ using System.Collections.Specialized;
112
+ using UnityEngine;
113
+
114
+ public class InstantiateCommand : IAction
115
+ {
116
+ private GameObject toSpawnGameObject;
117
+ private Vector3 positionToSpawn;
118
+
119
+ private GameObject spawnedGameObject;
120
+
121
+ public InstantiateCommand(GameObject toSpawnGameObject,Vector3 positionToSpawn)
122
+ {
123
+ this.toSpawnGameObject = toSpawnGameObject;
124
+ this.positionToSpawn = positionToSpawn;
125
+ }
126
+
127
+ public void ExecuteCommand()
128
+ {
129
+ spawnedGameObject = GameObject.Instantiate(toSpawnGameObject, positionToSpawn, Quaternion.identity);
130
+ }
131
+
132
+ public void UndoCommand()
133
+ {
134
+ GameObject.Destroy(spawnedGameObject);
135
+ }
136
+
137
+ }
138
+
139
+ ```
140
+
141
+ 次いでHierarchy windowに空のゲームオブジェクト<Player>を置き、これにCommandManagerをアタッチし、
142
+ UI Buttonを2つ作成、それぞれにOn Click()でシーン上のこの<Player>を指定、UndoCommandとRedoCommandをそれぞれアタッチしました。
143
+
18
- 手詰まってまっているのですが、アセットやスクリプトで何解決方法ご教示頂けないでょうか
144
+ しかしUndoボタンクリックてもinstantiateしたプレハブが消えません
145
+
146
+ どこがおかしいでしょうか。
147
+ ご教示頂けますと幸甚です。

1

2020/10/19 10:25

投稿

911RSR
911RSR

スコア13

title CHANGED
@@ -1,1 +1,1 @@
1
- unity 3d ランタイム ブーリアン演算 くり抜き undo/redo やり直し 戻る の実装
1
+ unity 3d ランタイム ブーリアン演算 undo/redo やり直し 実装
body CHANGED
@@ -11,7 +11,7 @@
11
11
  https://mega.nz/file/aERhlSRY#f7iLx88J9ytc9l48P15v6peAmWghdQxjL1aQo-0QfEM
12
12
 
13
13
  オブジェクト生成のundo/redoは達成できたと思うのですが、
14
- くりぬたオブジェクトはundoで消えても、
14
+ くりぬくのに使用したオブジェクトはundoで消えても、
15
15
  くりぬかれたオブジェクトは既にブーリアン演算を終えてくり抜かれた後なので、一見何も起こりません
16
16
  (くりぬかれたままです)。
17
17