I think I’ve tracked it down, although I don’t quite understand why this only occurs after a Portal traversal.
Look at ISaveable.RestoreState()
in PickupSpawner.cs
:
void ISaveable.RestoreState(object state)
{
bool shouldBeCollected = (bool)state;
if (shouldBeCollected && !isCollected())
{
DestroyPickup();
}
if (!shouldBeCollected && isCollected())
{
SpawnPickup();
}
}
In the situation I’ve described, for reasons I don’t understand yet we end up with this function being called with state
set to false
and isCollected()
also returning false
. Given this logic, the pickup is neither spawned nor destroyed, however due to the SpawnPickup()
call in Awake()
, it remains spawned.
The fix is to make sure the spawned pickup is destroyed in this situation:
void ISaveable.RestoreState(object state)
{
bool shouldBeCollected = (bool)state;
if (shouldBeCollected && !isCollected())
{
DestroyPickup();
}
if (!shouldBeCollected && !isCollected())
{
DestroyPickup();
}
if (!shouldBeCollected && isCollected())
{
SpawnPickup();
}
}
But what I really don’t know yet is why we end up in this situation after restarting the game following a Portal traversal, but not after restarting the game after hitting “S” to save. Any ideas?
EDIT: I’ve been able to reproduce this without stopping/starting the game, but I still need to walk through a portal:
- Delete any save file and start the game fresh
- Pick up a spawned item (in my case a sword) then drop it on the ground somewhere nearby
- Walk through a portal, then turn around and walk back through it again to return
- You should see your discarded item on the ground
- Hit “L” to load the save (which was created by walking through the portal) - lo and behold the original item will appear, and your dropped item will remain - you now have two of them.
Alas, my workaround above doesn’t work in this case - only when starting/stopping the game, so I’m starting to think Race Condition…