implemented basic UI skeleton for the text placer along with basic raycast-based placing functionality

This commit is contained in:
FreezeDriedMangoes 2022-06-01 22:23:45 -04:00
parent c1a7750ad5
commit 4e7330ce09
10 changed files with 310 additions and 69 deletions

View File

@ -19,6 +19,22 @@ namespace NewHorizons.Builder.Props
private static GameObject _computerPrefab;
private static GameObject _cairnPrefab;
private static GameObject _recorderPrefab;
private static Dictionary<PropModule.NomaiTextArcInfo, GameObject> arcInfoToCorrespondingSpawnedGameObject = new Dictionary<PropModule.NomaiTextArcInfo, GameObject>();
public static GameObject GetSpawnedGameObjectByNomaiTextArcInfo(PropModule.NomaiTextArcInfo arc)
{
if (!arcInfoToCorrespondingSpawnedGameObject.ContainsKey(arc)) return null;
return arcInfoToCorrespondingSpawnedGameObject[arc];
}
private static Dictionary<PropModule.NomaiTextInfo, GameObject> conversationInfoToCorrespondingSpawnedGameObject = new Dictionary<PropModule.NomaiTextInfo, GameObject>();
public static GameObject GetSpawnedGameObjectByNomaiTextInfo(PropModule.NomaiTextInfo convo)
{
Logger.Log("retrieving wall text obj for " + convo);
if (!conversationInfoToCorrespondingSpawnedGameObject.ContainsKey(convo)) return null;
return conversationInfoToCorrespondingSpawnedGameObject[convo];
}
private static void InitPrefabs()
{
@ -283,6 +299,9 @@ namespace NewHorizons.Builder.Props
nomaiWallText.SetTextAsset(text);
Logger.Log("adding to wall text dict: "+info + ", " + nomaiWallTextObj);
conversationInfoToCorrespondingSpawnedGameObject[info] = nomaiWallTextObj;
return nomaiWallText;
}
@ -372,6 +391,7 @@ namespace NewHorizons.Builder.Props
arc.SetActive(true);
arcsByID.Add(textEntryID, arc);
arcInfoToCorrespondingSpawnedGameObject[arcInfo] = arc;
}
}

View File

@ -273,7 +273,8 @@ namespace NewHorizons
private void OnSystemReady(bool shouldWarpIn)
{
Locator.GetPlayerBody().gameObject.AddComponent<DebugRaycaster>();
Locator.GetPlayerBody().gameObject.AddComponent<DebugPropPlacer>();
Locator.GetPlayerBody().gameObject.AddComponent<DebugPropPlacer>();
Locator.GetPlayerBody().gameObject.AddComponent<DebugNomaiTextPlacer>();
Locator.GetPlayerBody().gameObject.AddComponent<DebugMenu>();
if (shouldWarpIn) _shipWarpController.WarpIn(WearingSuit);

View File

@ -20,9 +20,9 @@ namespace NewHorizons.Utility.DebugMenu
{
private static IModButton pauseMenuButton;
GUIStyle _editorMenuStyle;
GUIStyle _tabBarStyle;
GUIStyle _submenuStyle;
public GUIStyle _editorMenuStyle;
public GUIStyle _tabBarStyle;
public GUIStyle _submenuStyle;
internal Vector2 EditorMenuSize = new Vector2(600, 900);
bool menuOpen = false;
static bool openMenuOnPause;
@ -125,6 +125,7 @@ namespace NewHorizons.Utility.DebugMenu
if (GUILayout.Button(mod.ModHelper.Manifest.UniqueName))
{
LoadMod(mod);
submenus[activeSubmenu].GainActive();
}
}
@ -167,7 +168,13 @@ namespace NewHorizons.Utility.DebugMenu
GUI.enabled = i != activeSubmenu;
var style = i == activeSubmenu ? _submenuStyle : _tabBarStyle;
if (GUILayout.Button(" "+submenus[i].SubmenuName()+" ", style, GUILayout.ExpandWidth(false)))
{
GUI.enabled = true;
submenus[activeSubmenu].LoseActive();
activeSubmenu = i;
submenus[activeSubmenu].GainActive();
}
GUI.enabled = true;
// if (i < submenus.Count-1) GUILayout.Label("|", GUILayout.ExpandWidth(false));

View File

@ -9,11 +9,21 @@ namespace NewHorizons.Utility.DebugMenu
{
class DebugMenuDummySubmenu : DebugSubmenu
{
internal override void GainActive()
{
}
internal override void LoseActive()
{
}
internal override void LoadConfigFile(DebugMenu menu, PlanetConfig config)
{
}
internal override void OnAwake(DebugMenu menu)
{
}

View File

@ -1,3 +1,4 @@
using NewHorizons.Builder.Props;
using NewHorizons.External.Configs;
using NewHorizons.External.Modules;
using NewHorizons.Utility.DebugUtilities;
@ -7,6 +8,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using static NewHorizons.External.Modules.PropModule;
namespace NewHorizons.Utility.DebugMenu
{
@ -20,19 +22,35 @@ namespace NewHorizons.Utility.DebugMenu
class DebugMenuNomaiText : DebugSubmenu
{
internal DebugRaycaster _drc;
internal DebugNomaiTextPlacer _dnp;
class NomaiTextTree
class ConversationMetadata
{
public GameObject text;
public int variation;
public float arcLengthLocationOnParent;
public NomaiTextInfo conversation;
public GameObject conversationGo;
public PlanetConfig planetConfig;
public List<NomaiTextTree> children = new List<NomaiTextTree>();
public List<SpiralMetadata> spirals;
public bool collapsed;
}
List<NomaiTextTree> textTrees = new List<NomaiTextTree>();
NomaiTextTree currentTree;
class SpiralMetadata
{
public NomaiTextArcInfo spiral;
public GameObject spiralGo;
public NomaiTextInfo conversation;
public PlanetConfig planetConfig;
public string planetName;
public int id;
}
List<ConversationMetadata> conversations = new List<ConversationMetadata>();
// menu stuff
Vector2 conversationsScrollPosition = new Vector2();
internal override string SubmenuName()
{
@ -42,87 +60,223 @@ namespace NewHorizons.Utility.DebugMenu
internal override void OnInit(DebugMenu menu)
{
_drc = menu.GetComponent<DebugRaycaster>();
_dnp = menu.GetComponent<DebugNomaiTextPlacer>();
}
internal override void OnAwake(DebugMenu menu)
{
_drc = menu.GetComponent<DebugRaycaster>();
_dnp = menu.GetComponent<DebugNomaiTextPlacer>();
}
internal override void OnBeginLoadMod(DebugMenu debugMenu)
internal override void OnBeginLoadMod(DebugMenu debugMenu) {}
internal override void GainActive() {} // intentionally blank. do not set `DebugNomaiTextPlacer.active = true;` here
internal override void LoseActive()
{
DebugPropPlacer.active = true;
DebugNomaiTextPlacer.active = false;
}
internal override void LoadConfigFile(DebugMenu menu, PlanetConfig config)
{
// TODO: populate textTrees
if (config?.Props?.nomaiText == null) return;
foreach(NomaiTextInfo conversation in config.Props.nomaiText)
{
ConversationMetadata conversationMetadata = new ConversationMetadata()
{
conversation = conversation,
conversationGo = NomaiTextBuilder.GetSpawnedGameObjectByNomaiTextInfo(conversation),
planetConfig = config,
spirals = new List<SpiralMetadata>(),
collapsed = true
};
Logger.Log("adding go " + conversationMetadata.conversationGo);
conversations.Add(conversationMetadata);
var numArcs = conversation.arcInfo == null
? 0
: conversation.arcInfo.Length;
for(int id = 0; id < numArcs; id++)
{
NomaiTextArcInfo arcInfo = conversation.arcInfo[id];
SpiralMetadata metadata = new SpiralMetadata()
{
spiral = arcInfo,
spiralGo = NomaiTextBuilder.GetSpawnedGameObjectByNomaiTextArcInfo(arcInfo),
conversation = conversation,
planetConfig = config,
planetName = config.name,
id = id
};
conversationMetadata.spirals.Add(metadata);
}
}
}
/*
Conversations:
+---------------------------+
|1) comment |
| |o Visible| |Place| | // replace is greyed out if the user is currently replacing this plane (replacing is done after the user presses G
|2) ... |
+---------------------------+
Spirals:
+---------------------------+
| v Planet - Comment |
| +----------------------+ |
| | v ID | |
| | | |
| | | > Surface 2 | | |
| | x: 5 ---o--- | |
| | y: 2 ---o--- | |
| | theta: 45 ---o--- | |
| | | |
| | o Child o Adult o ...| |
| | variation: o1 o2 o3..| |
| +----------------------+ |
| |
| +----------------------+ |
| | > ID | |
| +----------------------+ |
| |
| ... |
+---------------------------+
+---------------------------+
| > Planet - Comment |
+---------------------------+
...
*/
internal override void OnGUI(DebugMenu menu)
{
GUILayout.Space(5);
conversationsScrollPosition = GUILayout.BeginScrollView(conversationsScrollPosition);
for(int i = 0; i < conversations.Count(); i++)
{
ConversationMetadata conversationMeta = conversations[i];
GUILayout.Space(5);
GUILayout.BeginHorizontal();
GUILayout.Space(5);
GUILayout.BeginVertical(menu._editorMenuStyle);
var arrow = conversationMeta.collapsed ? " > " : " v ";
if (GUILayout.Button(arrow + conversationMeta.planetConfig.name + " - " + i))
{
conversationMeta.collapsed = !conversationMeta.collapsed;
Logger.Log("BUTTON " + i);
}
if (!conversationMeta.collapsed)
{
GUILayout.Space(5);
// button to set this one to place with a raycast
GUILayout.Label("Conversation");
// only show the button if this conversation is a wall text, do not show it if it is a scroll text or something
if (
conversationMeta.conversation.type == PropModule.NomaiTextInfo.NomaiTextType.Wall &&
GUILayout.Button("Place conversation with G")
) {
Logger.Log(conversationMeta.conversationGo+" 0");
DebugNomaiTextPlacer.active = true;
_dnp.onRaycast = (DebugRaycastData data) =>
{
var sectorObject = data.hitBodyGameObject.GetComponentInChildren<Sector>()?.gameObject;
if (sectorObject == null) sectorObject = data.hitBodyGameObject.GetComponentInParent<Sector>()?.gameObject;
conversationMeta.conversation.position = data.pos;
conversationMeta.conversation.normal = data.norm;
conversationMeta.conversation.rotation = null;
DebugNomaiTextPlacer.active = false;
UpdateConversationTransform(conversationMeta, sectorObject);
};
}
//
// spirals
//
for(int j = 0; j < conversationMeta.spirals.Count(); j++)
{
GUILayout.BeginHorizontal();
GUILayout.Space(5);
GUILayout.BeginVertical(menu._submenuStyle);
// spiral controls
GUILayout.Label("Spiral");
GUILayout.EndVertical();
GUILayout.Space(5);
GUILayout.EndHorizontal();
GUILayout.Space(10);
}
}
GUILayout.EndVertical();
GUILayout.Space(5);
GUILayout.EndHorizontal();
GUILayout.Space(10);
}
GUILayout.EndScrollView();
}
void DrawSpiralControls(int indentationLevel, NomaiTextTree tree)
void UpdateConversationTransform(ConversationMetadata conversationMetadata, GameObject sectorParent)
{
GUILayout.BeginHorizontal();
GUILayout.Space(5*indentationLevel);
var nomaiWallTextObj = conversationMetadata.conversationGo;
var planetGO = sectorParent;
var info = conversationMetadata.conversation;
Logger.Log(nomaiWallTextObj + " 1");
Logger.Log(nomaiWallTextObj?.transform + " 2");
Logger.Log(planetGO + " 3");
Logger.Log(planetGO?.transform + " 4");
Logger.Log(info + " 5");
Logger.Log(info?.position + " 6");
nomaiWallTextObj.transform.position = planetGO.transform.TransformPoint(info.position);
if (info.normal != null)
{
// In global coordinates (normal was in local coordinates)
var up = (nomaiWallTextObj.transform.position - planetGO.transform.position).normalized;
var forward = planetGO.transform.TransformDirection(info.normal).normalized;
GUILayout.EndHorizontal();
tree.children.ForEach(child => DrawSpiralControls(indentationLevel+1, child));
nomaiWallTextObj.transform.up = up;
nomaiWallTextObj.transform.forward = forward;
}
if (info.rotation != null)
{
nomaiWallTextObj.transform.rotation = planetGO.transform.TransformRotation(Quaternion.Euler(info.rotation));
}
}
internal override void PreSave(DebugMenu menu)
{
UpdateLoadedConfigsForRecentSystem(menu);
}
conversations.ForEach(metadata =>
{
metadata.conversation.position = metadata.conversationGo.transform.localPosition;
metadata.conversation.rotation = metadata.conversationGo.transform.localEulerAngles;
});
private void UpdateLoadedConfigsForRecentSystem(DebugMenu menu)
{
//var newDetails = _dpp.GetPropsConfigByBody();
//Logger.Log("Updating config files. New Details Counts by planet: " + string.Join(", ", newDetails.Keys.Select(x => x + $" ({newDetails[x].Length})")));
//Dictionary<string, string> planetToConfigPath = new Dictionary<string, string>();
//// Get all configs
//foreach (var filePath in menu.loadedConfigFiles.Keys)
// Spirals' configs do not need to be updated. They are always up to date
//spirals.ForEach(metadata =>
//{
// Logger.Log("potentially updating copy of config at " + filePath);
// if (menu.loadedConfigFiles[filePath].starSystem != Main.Instance.CurrentStarSystem) return;
// if (menu.loadedConfigFiles[filePath].name == null || AstroObjectLocator.GetAstroObject(menu.loadedConfigFiles[filePath].name) == null) { Logger.Log("Failed to update copy of config at " + filePath); continue; }
// var astroObjectName = DebugPropPlacer.GetAstroObjectName(menu.loadedConfigFiles[filePath].name);
// planetToConfigPath[astroObjectName] = filePath;
// if (!newDetails.ContainsKey(astroObjectName)) continue;
// if (menu.loadedConfigFiles[filePath].Props == null) menu.loadedConfigFiles[filePath].Props = new External.Modules.PropModule();
// menu.loadedConfigFiles[filePath].Props.details = newDetails[astroObjectName];
// Logger.Log("successfully updated copy of config file for " + astroObjectName);
//}
//// find all new planets that do not yet have config paths
//var planetsThatDoNotHaveConfigFiles = newDetails.Keys.Where(x => !planetToConfigPath.ContainsKey(x)).ToList();
//foreach (var astroObjectName in planetsThatDoNotHaveConfigFiles)
//{
// Logger.Log("Fabricating new config file for " + astroObjectName);
// var filepath = "planets/" + Main.Instance.CurrentStarSystem + "/" + astroObjectName + ".json";
// PlanetConfig c = new PlanetConfig();
// c.starSystem = Main.Instance.CurrentStarSystem;
// c.name = astroObjectName;
// c.Props = new PropModule();
// c.Props.details = newDetails[astroObjectName];
// menu.loadedConfigFiles[filepath] = c;
//}
// metadata.spiral.position = metadata.spiral.position;
// metadata.spiral.zRotation = metadata.spiral.zRotation;
//});
}
}
}

View File

@ -39,9 +39,19 @@ namespace NewHorizons.Utility.DebugMenu
}
internal override void OnBeginLoadMod(DebugMenu debugMenu)
{
}
internal override void GainActive()
{
DebugPropPlacer.active = true;
}
internal override void LoseActive()
{
DebugPropPlacer.active = false;
}
internal override void LoadConfigFile(DebugMenu menu, PlanetConfig config)
{

View File

@ -18,5 +18,9 @@ namespace NewHorizons.Utility.DebugMenu
internal abstract string SubmenuName();
internal abstract void GainActive();
internal abstract void LoseActive();
}
}

View File

@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.InputSystem;
namespace NewHorizons.Utility.DebugUtilities
{
class DebugNomaiTextPlacer : MonoBehaviour
{
public static bool active;
public Action<DebugRaycastData> onRaycast;
private DebugRaycaster _rc;
private void Awake()
{
_rc = this.GetComponent<DebugRaycaster>();
}
void Update()
{
if (!Main.Debug) return;
if (!active) return;
if (Keyboard.current[Key.G].wasReleasedThisFrame)
{
DebugRaycastData data = _rc.Raycast();
if (onRaycast != null) onRaycast.Invoke(data);
}
}
}
}

View File

@ -12,7 +12,7 @@ namespace NewHorizons.Utility.DebugUtilities
public bool hit;
public Vector3 pos;
public Vector3 norm;
public Plane plane;
public DebugRaycastPlane plane;
public string bodyName;
public string bodyPath;
@ -20,7 +20,7 @@ namespace NewHorizons.Utility.DebugUtilities
public GameObject hitObject;
}
struct Plane
struct DebugRaycastPlane
{
public Vector3 origin;
public Vector3 normal;

View File

@ -103,7 +103,7 @@ namespace NewHorizons.Utility.DebugUtilities
}
internal Plane ConstructPlane(DebugRaycastData data)
internal DebugRaycastPlane ConstructPlane(DebugRaycastData data)
{
var U = data.pos - Vector3.zero; // U is the local "up" direction. the direction directly away from the center of the planet at this point. // pos is always relative to the body, so the body is considered to be at 0,0,0.
var R = data.pos; // R is our origin point for the plane
@ -123,7 +123,7 @@ namespace NewHorizons.Utility.DebugUtilities
var u = Vector3.Cross(N, v);
Plane p = new Plane()
DebugRaycastPlane p = new DebugRaycastPlane()
{
origin = R,
normal = N,