The entire ‘IsUnique’ function depends on that, though, so I just deleted it as well. That aside, I’ll continue anyway with the instructions
We don’t throw the new script anywhere in the scene, right?
That aside, the Doppelgangers still die with the death of the NPC I just killed, and I suspect its because the change of the Unique ID happens in ‘OnEnable’ in your new Editor script (although to my big surprise, this problem doesn’t exist for NPCs on land), whereas the respawning of these guys when returning from the save happens in RestoreFromJToken, which is before start, which is before OnEnable, so everything that matters happens before the Unique IDs are checked for, and that’s some twisted logic
So now I have a serious problem. Any idea how to solve this? @Brian_Trotter (Unfortunately I can’t ignore this one, as its a game-breaking bug)
The bigger problem is, this doesn’t happen with NPCs spawned on the ground, and I am guessing its because Boats Respawn the AggroGroup, RespawnManager and the enemy (this had to be done to avoid a game-breaking bug) alltogether, whereas the ground NPCs have AggroGroup and RespawnManager static, but the enemies are the ones being respawned
Edit: OK I barely got something to work for a moment before I got confused again, so here’s what I’m trying to do:
- Ensure the boat allies (NPCs with boat state machines as their parents) have unique Identifiers. I got that covered when they respawn
Here’s how I check for Unique Identifiers the moment these boat allies respawn (because that’s the only way to get this check to work before ‘Start()’):
// in 'JSONSaveableEntity.cs':
// TEST 22/11/2024
/// <summary>
/// Determines if a given unique identifier is unique in the scene.
/// </summary>
public bool IsUnique(string id)
{
if (string.IsNullOrWhiteSpace(id)) return false;
var allEntities = FindObjectsOfType<JSONSaveableEntity>();
return allEntities.All(entity => entity.GetUniqueIdentifier() != id);
}
// TEST 22/11/2024
public void SetUniqueIdentifier(string id) => uniqueIdentifier = id;
// in 'RespawnManager.BoatAllyRespawn()' (the function responsible for respawning boat allies):
// This code runs the moment the NPC is instantiated in the game scene
// TEST 22/11/2024 - Make sure the Unique Identifier is Unique
if (spawnedEnemy.GetComponent<JSONSaveableEntity>() != null)
{
if (spawnedEnemy.GetComponent<JSONSaveableEntity>().GetUniqueIdentifier() != null)
{
var jsonSaveableEntity = spawnedEnemy.GetComponent<JSONSaveableEntity>();
var uniqueIdentifier = spawnedEnemy.GetComponent<JSONSaveableEntity>().GetUniqueIdentifier();
if (!jsonSaveableEntity.IsUnique(uniqueIdentifier))
{
var newUniqueID = System.Guid.NewGuid().ToString();
jsonSaveableEntity.SetUniqueIdentifier(newUniqueID);
}
}
}
- Block the Capture and Restore (I don’t know how to block a Capture, returning a null messes up the game drastically) for the RespawnManager from working for NPCs that are on a boat, and call that in the boat respawn manager as well. The problem is, I have absolutely no idea how to do that efficiently
For step 2, here’s my current attempt with that so far:
// In 'CaptureAsJToken():
// TEST 23/11/2024
foreach (IJsonSaveable JSONSaveable in spawnedBoat.GetComponentsInChildren<IJsonSaveable>())
{
JToken token = JSONSaveable.CaptureAsJToken();
string component = JSONSaveable.GetType().ToString();
stateDict[component] = token;
Debug.Log($"Component Saved: {component}, Token: {token}");
}
// in 'LoadEnemyState(called in 'RestoreFromJToken())':
// TEST 23/11/2024
foreach (IJsonSaveable jsonSaveable in spawnedBoat.GetComponentsInChildren<IJsonSaveable>())
{
string component = jsonSaveable.GetType().ToString();
if (stateDict.ContainsKey(component))
{
Debug.Log($"Restoring component: {component}, Token: {stateDict[component]}");
jsonSaveable.RestoreFromJToken(stateDict[component]);
Debug.Log($"{spawnedBoat.gameObject.name} has been restored");
}
else
{
Debug.Log($"Component not found in stateDict: {component}");
}
}
I also tried messing with the script execution order, where I try to get the Enemy’s RespawnManager to work before the Boat’s Respawn Manager (as a way to ensure that the restoring for the boat has the higher hand in the end, which was theoretically supposed to ensure that the boat allies don’t go crazy), but that failed too
Edit 2: Why do I have a funny feeling that this line in ‘BoatRespawnManager.cs’:
spawnedEnemyRespawnManager.BoatAllyRespawn();
Which spawns enemies, just like this line in ‘RespawnManager.cs’:
Respawn();
Overwrites the ‘Respawn()’ and hence it causes the nightmare I’m dealing with? (Problem is, testing this theory is very difficult because the fix code is insanely complicated…)