質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Q&A

解決済

1回答

1584閲覧

unity 3D ランタイム ゲームモード オブジェクト生成 やり直し 実装 undo redo

911RSR

総合スコア13

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

0グッド

0クリップ

投稿2020/10/16 03:51

編集2020/10/19 10:25

(10/19加筆、訂正しました。)
Unity 3Dで、
ゲームモードでクリックしたところにオブジェクトを生成していきます。

このオブジェクト(プレハブ)の作成スクリプトは以下です。

using System.Collections; using System.Collections.Generic; using UnityEngine; public class SkewCreater : MonoBehaviour { public GameObject prefabobj; public Renderer rend; // Start is called before the first frame update void Start() { } // Update is called once per frame void Update() { if (Input.GetMouseButtonDown(0)) { Vector2 touchScreenPosition = Input.mousePosition; touchScreenPosition.x = Mathf.Clamp(touchScreenPosition.x, 0.0f, Screen.width); touchScreenPosition.y = Mathf.Clamp(touchScreenPosition.y, 0.0f, Screen.height); Camera gameCamera = Camera.main; Ray touchPointToRay = gameCamera.ScreenPointToRay(touchScreenPosition); RaycastHit hitInfo = new RaycastHit(); if (Physics.Raycast(touchPointToRay, out hitInfo)) { Instantiate(prefabobj, hitInfo.point, Quaternion.identity); } } } }

このプレハブ生成のやり直し機能、すなわち undo / redo 機能の実装に苦慮しています。

以下のyoutube 、ウェブサイトを参考に、
https://www.youtube.com/watch?v=gnyDH1kcZKQ
https://mega.nz/file/aERhlSRY#f7iLx88J9ytc9l48P15v6peAmWghdQxjL1aQo-0QfEM

3つのスクリプトを書きました。
・CommandManager

using System.Collections; using System.Collections.Generic; using System.Runtime.InteropServices.WindowsRuntime; using UnityEngine; public class CommandManager : MonoBehaviour { private Stack<IAction> historyStack = new Stack<IAction>(); private Stack<IAction> redoHistoryStack = new Stack<IAction>(); public void ExecuteCommand(IAction action) { action.ExecuteCommand(); historyStack.Push(action); redoHistoryStack.Clear(); } public void UndoCommand() { if(historyStack.Count > 0) { redoHistoryStack.Push(historyStack.Peek()); historyStack.Pop().UndoCommand(); } } public void RedoCommand() { if(redoHistoryStack.Count > 0) { historyStack.Push(redoHistoryStack.Peek()); redoHistoryStack.Pop().ExecuteCommand(); } } }

・IAction

using System.Collections; using System.Collections.Generic; using UnityEngine; public interface IAction { void ExecuteCommand(); void UndoCommand(); }

・InstantiateCommand

using System.Collections; using System.Collections.Generic; using System.Collections.Specialized; using UnityEngine; public class InstantiateCommand : IAction { private GameObject toSpawnGameObject; private Vector3 positionToSpawn; private GameObject spawnedGameObject; public InstantiateCommand(GameObject toSpawnGameObject,Vector3 positionToSpawn) { this.toSpawnGameObject = toSpawnGameObject; this.positionToSpawn = positionToSpawn; } public void ExecuteCommand() { spawnedGameObject = GameObject.Instantiate(toSpawnGameObject, positionToSpawn, Quaternion.identity); } public void UndoCommand() { GameObject.Destroy(spawnedGameObject); } }

次いでHierarchy windowに空のゲームオブジェクト<Player>を置き、これにCommandManagerをアタッチし、
UI Buttonを2つ作成、それぞれにOn Click()でシーン上のこの<Player>を指定、UndoCommandとRedoCommandをそれぞれアタッチしました。

しかしUndoボタンをクリックしてもinstantiateしたプレハブが消えません。

どこがおかしいでしょうか。
ご教示頂けますと幸甚です。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

導入したundoシステムはオブジェクト自体のinstantiateをしているのではなく、オブジェクト生成のスクリプトをinstantiateしていました。
従ってクリックしてオブジェクト生成のスクリプトをinstantiateするようにしたらうまくいきました。

従来のundo/redoでは膨大なメモリを消費していましたが、この方法ではメモリ消費は少なく非常に有用だと思いました。

投稿2020/10/21 05:50

911RSR

総合スコア13

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問