-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
#479 Added implemented MarkAction, MarkNetAction and GameModeMarker
Marker sphere placement needs to be fixed yet.
- Loading branch information
Showing
3 changed files
with
270 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
using System.Collections.Generic; | ||
using SEE.Game; | ||
using SEE.GO; | ||
using SEE.Net; | ||
using SEE.Utils; | ||
using UnityEngine; | ||
|
||
namespace SEE.Controls.Actions | ||
{ | ||
/// <summary> | ||
/// Action to visually mark/unmark a node as selected via a floating sphere above it. | ||
/// </summary> | ||
internal class MarkAction : AbstractPlayerAction | ||
{ | ||
/// <summary> | ||
/// If the user clicks with the mouse hitting a game object representing a graph node, | ||
/// the graphs selection status is toggled. Being selected means a sphere is floating above the node. | ||
/// <see cref="ReversibleAction.Update"/>. | ||
/// </summary> | ||
/// <returns>true if completed</returns> | ||
public override bool Update() | ||
{ | ||
bool result = false; | ||
|
||
// FIXME: Needs adaptation for VR where no mouse is available. (applies here too) | ||
if (Input.GetMouseButtonDown(0) | ||
&& Raycasting.RaycastGraphElement(out RaycastHit raycastHit, out GraphElementRef _) == HitGraphElement.Node) | ||
{ | ||
// the hit object that is either selected or unselected | ||
GameObject targetNode = raycastHit.collider.gameObject; | ||
|
||
GameObject markerSphere = GameNodeMarker.TryMarking(targetNode); | ||
|
||
memento = new Memento(markerSphere); | ||
|
||
new MarkNetAction(markerSphere).Execute(); | ||
|
||
// propagate (MarkNetAction) | ||
result = true; | ||
currentState = ReversibleAction.Progress.Completed; | ||
|
||
} | ||
return result; | ||
} | ||
|
||
/// <summary> | ||
/// Memento capturing the data necessary to re-do this action. | ||
/// </summary> | ||
private Memento memento; | ||
|
||
/// <summary> | ||
/// The information we need to re-add a marker whose addition was undone. | ||
/// </summary> | ||
private struct Memento | ||
{ | ||
/// <summary> | ||
/// The node marked by the marker. | ||
/// </summary> | ||
public readonly GameObject MarkedNode; | ||
|
||
/// <summary> | ||
/// The node ID for the added node. It must be kept to re-use the | ||
/// original name of the node in Redo(). | ||
/// </summary> | ||
public string MarkerID; | ||
|
||
/// <summary> | ||
/// Constructor setting the information necessary to re-do this action. | ||
/// </summary> | ||
/// <param name="parent">the node targeted by our MarkAction</param> | ||
public Memento(GameObject markedNode) | ||
{ | ||
MarkedNode = markedNode; | ||
MarkerID = markedNode.ID(); | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// Undoes this MarkAction. | ||
/// </summary> | ||
public override void Undo() | ||
{ | ||
base.Undo(); | ||
GameNodeMarker.TryMarking(memento.MarkedNode); | ||
new MarkNetAction(memento.MarkedNode).Execute(); | ||
} | ||
|
||
/// <summary> | ||
/// Redoes this MarkAction. | ||
/// </summary> | ||
public override void Redo() | ||
{ | ||
base.Redo(); | ||
GameNodeMarker.TryMarking(memento.MarkedNode); | ||
new MarkNetAction(memento.MarkedNode).Execute(); | ||
} | ||
|
||
/// <summary> | ||
/// Returns a new instance of <see cref="MarkAction"/>. | ||
/// </summary> | ||
/// <returns>new instance</returns> | ||
public static ReversibleAction CreateReversibleAction() | ||
{ | ||
return new MarkAction(); | ||
} | ||
|
||
/// <summary> | ||
/// Returns a new instance of <see cref="MarkAction"/>. | ||
/// </summary> | ||
/// <returns>new instance</returns> | ||
public override ReversibleAction NewInstance() | ||
{ | ||
return CreateReversibleAction(); | ||
} | ||
|
||
/// <summary> | ||
/// Returns the <see cref="ActionStateType"/> of this action. | ||
/// </summary> | ||
/// <returns><see cref="ActionStateType.NewNode"/></returns> | ||
public override ActionStateType GetActionStateType() | ||
{ | ||
return ActionStateType.Mark; | ||
} | ||
|
||
/// <summary> | ||
/// Returns all IDs of gameObjects manipulated by this action. | ||
/// </summary> | ||
/// <returns>all IDs of gameObjects manipulated by this action</returns> | ||
public override HashSet<string> GetChangedObjects() | ||
{ | ||
return new HashSet<string> | ||
{ | ||
memento.MarkedNode.name, | ||
memento.MarkerID | ||
}; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
using System; | ||
using SEE.DataModel; | ||
using SEE.DataModel.DG; | ||
using SEE.Game.City; | ||
using SEE.GO; | ||
using SEE.Utils; | ||
using UnityEngine; | ||
|
||
namespace SEE.Game | ||
{ | ||
/// <summary> | ||
/// Creates new game objects representing graph nodes or deleting these again, | ||
/// respectively. | ||
/// </summary> | ||
public static class GameNodeMarker | ||
{ | ||
|
||
/// <summary> | ||
/// Check the transfered target node whether it was been marked already, and toggle it to the other state. | ||
/// <param name="targetNode">the node that was targeted for marking.</param> | ||
/// </summary> | ||
/// <returns>new instance</returns> | ||
public static GameObject TryMarking(GameObject targetNode) | ||
{ | ||
|
||
// save the sphere that was used as a marker | ||
GameObject markerSphere = null; | ||
|
||
// iterate over all children of the targeted node | ||
foreach (Transform child in targetNode.transform) | ||
{ | ||
// exit the loop if a (/the) marker was found | ||
if (child.name == "MarkerSphere" + targetNode.name) | ||
{ | ||
markerSphere = child.gameObject; | ||
break; | ||
} | ||
} | ||
|
||
if (markerSphere != null) | ||
{ | ||
// delete existing marker sphere | ||
Destroyer.DestroyGameObject(markerSphere); | ||
return null; | ||
} | ||
else | ||
{ | ||
// create a new marker sphere because there is none currently | ||
GameObject newMarkerSphere = GameObject.CreatePrimitive(PrimitiveType.Sphere); | ||
|
||
Debug.Log("X is:" + newMarkerSphere.transform.localScale.x); | ||
Debug.Log("Y is:" + newMarkerSphere.transform.localScale.y); | ||
Debug.Log("Z is:" + newMarkerSphere.transform.localScale.z); | ||
|
||
// the diameter of the is the minimum of the width (x-axis) and depth (y-axis) of the marked node | ||
newMarkerSphere.transform.localScale = Math.Min(targetNode.transform.localScale.x, targetNode.transform.localScale.z) * .5f * Vector3.one; | ||
|
||
// the position of the marker sphere is above the marked node | ||
newMarkerSphere.transform.position = new Vector3(targetNode.transform.position.x, | ||
targetNode.transform.position.y, | ||
// + targetNode.transform.localScale.y | ||
// + newMarkerSphere.GetComponent<SphereCollider>().radius, | ||
// + 0.1f, | ||
targetNode.transform.position.z); | ||
|
||
// FIXME: (?) ensure markers are not blocking us from unmarking or marking other nodes | ||
newMarkerSphere.GetComponent<SphereCollider>().radius = 0; | ||
|
||
newMarkerSphere.SetColor(Color.magenta); | ||
|
||
// marker spheres can be recognized by their name-prefix "MarkerSphere" | ||
newMarkerSphere.name = "MarkerSphere" + targetNode.name; | ||
|
||
// assign the marker sphere to the node it marks | ||
newMarkerSphere.transform.SetParent(targetNode.transform); | ||
|
||
return newMarkerSphere; | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
using SEE.Game; | ||
using UnityEngine; | ||
|
||
namespace SEE.Net | ||
{ | ||
/// <summary> | ||
/// This class is responsible for marking a node via network from one client to all others and | ||
/// to the server. | ||
/// </summary> | ||
public class MarkNetAction : AbstractNetAction | ||
{ | ||
// Note: All attributes are made public so that they will be serialized | ||
// for the network transfer. | ||
|
||
/// <summary> | ||
/// The GameObject that is targeted for marking. | ||
/// </summary> | ||
public GameObject TargetNode; | ||
|
||
/// <summary> | ||
/// Constructor. | ||
/// </summary> | ||
/// <param name="targetNode">the node that was targeted for marking.</param> | ||
public MarkNetAction | ||
(GameObject targetNode) | ||
: base() | ||
{ | ||
this.TargetNode = targetNode; | ||
} | ||
|
||
/// <summary> | ||
/// Things to execute on the server (none for this class). Necessary because it is abstract | ||
/// in the superclass. | ||
/// </summary> | ||
protected override void ExecuteOnServer() | ||
{ | ||
// Intentionally left blank. | ||
} | ||
|
||
/// <summary> | ||
/// Tries marking on each client. | ||
/// </summary> | ||
protected override void ExecuteOnClient() | ||
{ | ||
if (!IsRequester()) | ||
{ | ||
GameObject markerSphere = GameNodeMarker.TryMarking(TargetNode); | ||
} | ||
} | ||
} | ||
} |