From af575ff07fa29a5d8ab4c9782e477922397110d8 Mon Sep 17 00:00:00 2001 From: Tim Dinh Date: Sat, 21 Oct 2023 20:29:23 +0200 Subject: [PATCH] onboarding --- .../SEE/Controls/Actions/ActionStateTypes.cs | 6 + Assets/SEE/Controls/Actions/MarkAction.cs | 164 ++++++++++++++++++ .../SEE/Controls/Actions/MarkAction.cs.meta | 11 ++ .../Game/SceneManipulation/GameNodeMarker.cs | 54 ++++++ .../SceneManipulation/GameNodeMarker.cs.meta | 11 ++ Assets/SEE/Net/Actions/MarkNetAction.cs | 71 ++++++++ Assets/SEE/Net/Actions/MarkNetAction.cs.meta | 11 ++ 7 files changed, 328 insertions(+) create mode 100644 Assets/SEE/Controls/Actions/MarkAction.cs create mode 100644 Assets/SEE/Controls/Actions/MarkAction.cs.meta create mode 100644 Assets/SEE/Game/SceneManipulation/GameNodeMarker.cs create mode 100644 Assets/SEE/Game/SceneManipulation/GameNodeMarker.cs.meta create mode 100644 Assets/SEE/Net/Actions/MarkNetAction.cs create mode 100644 Assets/SEE/Net/Actions/MarkNetAction.cs.meta diff --git a/Assets/SEE/Controls/Actions/ActionStateTypes.cs b/Assets/SEE/Controls/Actions/ActionStateTypes.cs index f78e1c9b92..0258d8e703 100644 --- a/Assets/SEE/Controls/Actions/ActionStateTypes.cs +++ b/Assets/SEE/Controls/Actions/ActionStateTypes.cs @@ -168,6 +168,11 @@ static ActionStateTypes() Color.blue.Darker(), "Materials/ModernUIPack/Document", SaveBoardAction.CreateReversibleAction, parent: MetricBoard); + Mark = + new("Mark", "Mark a node", + Color.gray, "Materials/ModernUIPack/Pencil", + MarkAction.CreateReversibleAction, + parent: MetricBoard); } @@ -192,6 +197,7 @@ static ActionStateTypes() public readonly static ActionStateType DeleteWidget; public readonly static ActionStateType LoadBoard; public readonly static ActionStateType SaveBoard; + public readonly static ActionStateType Mark; #endregion diff --git a/Assets/SEE/Controls/Actions/MarkAction.cs b/Assets/SEE/Controls/Actions/MarkAction.cs new file mode 100644 index 0000000000..2f3231bcb9 --- /dev/null +++ b/Assets/SEE/Controls/Actions/MarkAction.cs @@ -0,0 +1,164 @@ +using SEE.Utils.History; +using System.Collections.Generic; +using UnityEngine; +using SEE.GO; +using SEE.Utils; +using SEE.Game.Scenemanipulation; +using SEE.Net.Actions; +using SEE.Audio; +using SEE.Game.SceneManipulation; + +namespace SEE.Controls.Actions { + public class MarkAction : AbstractPlayerAction + { + /// + /// Returns a new instance of . + /// + /// new instance + public static IReversibleAction CreateReversibleAction() + { + return new MarkAction(); + } + + /// + /// Returns the of this action. + /// + /// + public override ActionStateType GetActionStateType() + { + return ActionStateTypes.Mark; + } + + /// + /// If the user clicks with the mouse hitting a game object representing a graph node, + /// will be marked. A sphere will appear above the marked node. + /// . + /// + /// true if completed + public override bool Update() + { + bool result = false; + + // FIXME: Needs adaptation for VR where no mouse is available. + if (Input.GetMouseButtonDown(0) + && Raycasting.RaycastGraphElement(out RaycastHit raycastHit, out GraphElementRef _) == HitGraphElement.Node) + { + // the hit object is the parent in which to create the sphere + GameObject parent = raycastHit.collider.gameObject; + Vector3 position = parent.transform.position; + Vector3 scale = parent.transform.lossyScale; + // create or delete the sphere + addedSphere = GameNodeMarker.CreateOrDeleteSphere(parent, scale); + memento = new Memento(parent, position: position, scale: scale); + memento.NodeID = addedSphere.name; + new MarkNetAction(memento.Parent, memento.Position, memento.Scale).Execute(); + result = true; + CurrentState = IReversibleAction.Progress.Completed; + AudioManagerImpl.EnqueueSoundEffect(IAudioManager.SoundEffect.NewNodeSound, parent); + } + return result; + } + + /// + /// The node that was added when this action was executed. It is saved so + /// that it can be removed on Undo(). + /// + private GameObject addedSphere; + + /// + /// Memento capturing the data necessary to re-do this action. + /// + private Memento memento; + + /// + /// The information we need to re-add a node whose addition was undone. + /// + private struct Memento + { + /// + /// The parent of the new node. + /// + public readonly GameObject Parent; + + /// + /// The position of the new node in world space. + /// + public readonly Vector3 Position; + + /// + /// The scale of the new node in world space. + /// + public readonly Vector3 Scale; + + /// + /// The node ID for the added node. It must be kept to re-use the + /// original name of the node in Redo(). + /// + public string NodeID; + + /// + /// Constructor setting the information necessary to re-do this action. + /// + /// The marked node + public Memento(GameObject parent, Vector3 position, Vector3 scale) + { + Parent = parent; + Position = position; + Scale = scale; + NodeID = null; + } + } + + /// + /// Returns all IDs of gameObjects manipulated by this action. + /// + /// all IDs of gameObjects manipulated by this action + public override HashSet GetChangedObjects() + { + return new HashSet + { + memento.Parent.name, + memento.NodeID + }; + } + + /// + /// Returns a new instance of . + /// + /// new instance + public override IReversibleAction NewInstance() + { + return CreateReversibleAction(); + } + + /// + /// Undoes this MarkAction. + /// + public override void Undo() + { + base.Undo(); + if (addedSphere != null) + { + new DeleteNetAction(addedSphere.name).Execute(); + Destroyer.Destroy(addedSphere); + addedSphere = null; + } + } + + /// + /// Redoes this MarkAction. + /// + public override void Redo() + { + base.Redo(); + addedSphere = GameNodeAdder.AddChild(memento.Parent, worldSpacePosition: memento.Position, worldSpaceScale: memento.Scale, nodeID: memento.NodeID); + if (addedSphere != null) + { + new MarkNetAction(memento.Parent, memento.Position, memento.Scale).Execute(); + } + } + } + +} + + diff --git a/Assets/SEE/Controls/Actions/MarkAction.cs.meta b/Assets/SEE/Controls/Actions/MarkAction.cs.meta new file mode 100644 index 0000000000..ab692371bc --- /dev/null +++ b/Assets/SEE/Controls/Actions/MarkAction.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e3343ced081912e4ea17588e0f757233 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SEE/Game/SceneManipulation/GameNodeMarker.cs b/Assets/SEE/Game/SceneManipulation/GameNodeMarker.cs new file mode 100644 index 0000000000..bda6b7372f --- /dev/null +++ b/Assets/SEE/Game/SceneManipulation/GameNodeMarker.cs @@ -0,0 +1,54 @@ +using SEE.Game.City; +using SEE.GO; +using SEE.Utils; +using System; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +namespace SEE.Game.Scenemanipulation +{ + /// + /// Creates or deletes sphere to mark certain nodes. + /// + public static class GameNodeMarker + { + /// + /// Creates a sphere above the selected node or deletes if a sphere exist. + /// + /// selected node + /// scale of the node + /// + public static GameObject CreateOrDeleteSphere(GameObject parent, Vector3 scale) + { + GameObject sphere = null; + //Search for sphere + foreach(Transform child in parent.transform) + { + if(child.name == "Sphere") + { + sphere = child.gameObject; + break; + } + } + //Delete sphere if one existed + if(sphere != null) + { + Destroyer.Destroy(sphere); + return null; + } + //Create and scale sphere + else + { + sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere); + sphere.transform.position = GameObjectExtensions.GetTop(parent); + sphere.transform.localScale = scale; + sphere.transform.SetParent(parent.transform); + sphere.SetColor(parent.GetColor().Darker()); + + return sphere; + } + } + } +} + diff --git a/Assets/SEE/Game/SceneManipulation/GameNodeMarker.cs.meta b/Assets/SEE/Game/SceneManipulation/GameNodeMarker.cs.meta new file mode 100644 index 0000000000..fc3d2751c8 --- /dev/null +++ b/Assets/SEE/Game/SceneManipulation/GameNodeMarker.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cf226ed20a94fa348ba99cc4ec89cd26 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SEE/Net/Actions/MarkNetAction.cs b/Assets/SEE/Net/Actions/MarkNetAction.cs new file mode 100644 index 0000000000..292735ae7d --- /dev/null +++ b/Assets/SEE/Net/Actions/MarkNetAction.cs @@ -0,0 +1,71 @@ +using SEE.Game.Scenemanipulation; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + + +namespace SEE.Net.Actions +{ + /// + /// This class is responsible for marking a node via network from one client to all others and + /// to the server. + /// + public class MarkNetAction : AbstractNetAction + { + // Note: All attributes are made public so that they will be serialized + // for the network transfer. + + /// + /// The Parent gameObject. + /// + public GameObject Parent; + + /// + /// The position of the node. + /// + public Vector3 Position; + + /// + /// The scale of the node. + /// + public Vector3 Scale; + + /// + /// Constructor. + /// + /// parent in which to mark the new node + /// the position for the parent node + /// the scale of the parent node in world space + public MarkNetAction + (GameObject parent, + Vector3 position, + Vector3 scale) + : base() + { + this.Parent = parent; + this.Position = position; + this.Scale = scale; + } + + /// + /// Marks a new GameObject on each client. + /// + protected override void ExecuteOnClient() + { + if (!IsRequester()) + { + GameObject markSphere = GameNodeMarker.CreateOrDeleteSphere(Parent, Scale); + } + } + + /// + /// Things to execute on the server (none for this class). Necessary because it is abstract + /// in the superclass. + /// + protected override void ExecuteOnServer() + { + // Intentionally left blank. + } + } +} + diff --git a/Assets/SEE/Net/Actions/MarkNetAction.cs.meta b/Assets/SEE/Net/Actions/MarkNetAction.cs.meta new file mode 100644 index 0000000000..03f54c1084 --- /dev/null +++ b/Assets/SEE/Net/Actions/MarkNetAction.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 80bd75152c10e0342b05382bcda6b095 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: