USER
In the following script, i can place and remove symbol. Everytime I place a symbol, it instantiates a prefab of the symbol type at the symbol slot index position. I want to instantiate those prefab on load if the player has already saved a current order.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class LovecraftianPuzzle : MonoBehaviour, IDataPersistence
{
public enum EldritchSymbols { Nyarlathotep, Azathoth, Cthulhu, ShubNiggurath, YogSothoth }
public Transform[] symbolSlots;
public GameObject[] eldritchSymbolPrefabs;
public GameObject[] glyphsGameObject;
public List<Glyphs> glyphs;
public List<Book> books;
public GameObject portal;
public Animator portalAnimator;
public AudioSource gatewayAudio;
public AudioClip placeSymbolSound;
public AudioClip puzzleSolvedSound;
public GameObject bookParticlePrefab;
public GameObject shadowPeoplePrefab;
private GameObject player;
private AudioSource playerAudioSource;
private InventoryManager InvManager;
private AudioSource puzzleAudio;
private FearSystem fearSystem;
private QuestSystem questSystem;
private void Awake()
{
glyphs = new List<Glyphs>
{
new Glyphs { symbolType = EldritchSymbols.Nyarlathotep, symbolGlyph = glyphsGameObject[0], isActive = false},
new Glyphs { symbolType = EldritchSymbols.Azathoth,symbolGlyph = glyphsGameObject[1], isActive = false},
new Glyphs { symbolType = EldritchSymbols.Cthulhu, symbolGlyph = glyphsGameObject[2], isActive = false},
new Glyphs { symbolType = EldritchSymbols.ShubNiggurath, symbolGlyph = glyphsGameObject[3], isActive = false},
new Glyphs { symbolType = EldritchSymbols.YogSothoth, symbolGlyph = glyphsGameObject[4], isActive = false}
};
}
private void Start()
{
player = GameObject.Find("Player");
playerAudioSource = player.GetComponent<AudioSource>();
puzzleAudio = GetComponent<AudioSource>();
InvManager = FindAnyObjectByType(typeof(InventoryManager)) as InventoryManager;
fearSystem = FindAnyObjectByType(typeof(FearSystem)) as FearSystem;
questSystem = FindAnyObjectByType(typeof(QuestSystem)) as QuestSystem;
books = new List<Book>
{
new Book { title = "Invocations of The Cosmic Horror", symbolType = EldritchSymbols.Nyarlathotep, symbolPrefab = eldritchSymbolPrefabs[0] },
new Book { title = "Mark Of The Old Gods", symbolType = EldritchSymbols.Azathoth, symbolPrefab = eldritchSymbolPrefabs[1] },
new Book { title = "The House Of R'lyeh", symbolType = EldritchSymbols.Cthulhu, symbolPrefab = eldritchSymbolPrefabs[2] },
new Book { title = "The Shadow People", symbolType = EldritchSymbols.ShubNiggurath, symbolPrefab = eldritchSymbolPrefabs[3] },
new Book { title = "The Unknown and The Deep Void", symbolType = EldritchSymbols.YogSothoth, symbolPrefab = eldritchSymbolPrefabs[4] }
};
}
private List<EldritchSymbols> correctOrder = new List<EldritchSymbols>()
{
EldritchSymbols.Nyarlathotep,
EldritchSymbols.Azathoth,
EldritchSymbols.Cthulhu,
EldritchSymbols.ShubNiggurath,
EldritchSymbols.YogSothoth
};
public List<EldritchSymbols> currentOrder = new List<EldritchSymbols>();
private Dictionary<EldritchSymbols, int> symbolToSlotIndex = new Dictionary<EldritchSymbols, int>()
{
{ EldritchSymbols.Nyarlathotep, 0 },
{ EldritchSymbols.Azathoth, 1 },
{ EldritchSymbols.Cthulhu, 2 },
{ EldritchSymbols.ShubNiggurath, 3 },
{ EldritchSymbols.YogSothoth, 4 }
};
[System.Serializable]
public class Glyphs
{
public EldritchSymbols symbolType;
public GameObject symbolGlyph;
public bool isActive;
}
[System.Serializable]
public class Book
{
public string title;
public EldritchSymbols symbolType;
public GameObject symbolPrefab;
}
/*[System.Serializable]
class PuzzleData
{
public List<Glyphs> glyphs;
public List<Book> books;
public List<EldritchSymbols> correctOrder;
public List<EldritchSymbols> currentOrder;
public Dictionary<EldritchSymbols, int> symbolToSlotIndex;
}*/
public void PlaceSymbol(EldritchSymbols symbol)
{
int bookIndex = books.FindIndex(b => b.symbolType == symbol);
Book book = books.Find(b => b.symbolType == symbol);
string title = book?.title;
// Check if the book index is valid and the corresponding slot is empty
if (bookIndex >= 0 && bookIndex < books.Count && symbolSlots[bookIndex].childCount == 0)
{
bool itemFound = false; // Flag variable to check if the item was found in the inventory
for (int t = 0; t < InvManager.MaxItems; t++) //Starting a loop in the slots of the inventory:
{
if (InvManager.Slots[t].IsTaken == true) //Checking if there's an item in this slot.
{
Item ItemScript = InvManager.Slots[t].Item.GetComponent<Item>(); //Getting the item script from the items inside the bag.
if (ItemScript.Name == title)
{
itemFound = true; // Set the flag to true
ItemScript.ItemDropType = Item.ItemDropTypes.Destroy;
InvManager.RemoveItem(ItemScript.gameObject.transform, 1);
break; // Break out of the loop since the item was found
}
}
}
if (itemFound) // Check if the item was found in the inventory
{
GameObject symbolObject = Instantiate(
books[bookIndex].symbolPrefab,
symbolSlots[bookIndex].position,
Quaternion.Euler(0, 24, -90), // Rotate 90 degrees around the Z axis
symbolSlots[bookIndex]);
Item itemScript = symbolObject.GetComponent<Item>();
itemScript.name = itemScript.Name;
if (!currentOrder.Contains(symbol)) // Check if the symbol is already in the list
{
currentOrder.Add(symbol); // Add it only if it's not present
// Check if the newly placed symbol is in the correct position
if (currentOrder.Count <= correctOrder.Count && currentOrder[currentOrder.Count - 1] == correctOrder[currentOrder.Count - 1])
{
// Find the Glyph that has the same symbol
Glyphs glyph = glyphs.Find(g => g.symbolType == symbol);
if (glyph != null)
{
// Define the emissive color
Color emissiveColor = Color.red; // replace with the desired color
glyph.isActive = true;
ActivateGlyph(glyph.symbolType);
// Get all children of the Glyph
foreach (Transform child in glyph.symbolGlyph.transform)
{
// Get the SpriteRenderer of the child
SpriteRenderer spriteRenderer = child.GetComponent<SpriteRenderer>();
if (spriteRenderer != null)
{
// Apply the emissive color to the SpriteRenderer
spriteRenderer.material.SetColor("_EmissionColor", emissiveColor);
}
}
}
}
}
playerAudioSource.PlayOneShot(placeSymbolSound);
}
else
{
NotificationUI notificationUI = FindObjectOfType(typeof(NotificationUI)) as NotificationUI;
notificationUI.SendMsg("<color=white>The book " + "<color=red>" + books[bookIndex].title + "</color> is missing");
}
}
NarrativeUI narrative = FindObjectOfType(typeof(NarrativeUI)) as NarrativeUI;
narrative.SendMsg("Symbol of " + books[bookIndex].symbolType, 4);
StartCoroutine(player.GetComponent<PlayerInteraction>().InteractionDelay());
CheckPuzzleSolved();
}
private void CheckPuzzleSolved()
{
if (currentOrder.Count == correctOrder.Count)
{
bool isSolved = true;
for (int i = 0; i < correctOrder.Count; i++)
{
if (currentOrder[i] != correctOrder[i])
{
isSolved = false;
break;
}
}
if (isSolved)
{
questSystem._quest3 = true;
StartCoroutine(GatewayAnimation());
}
}
}
public IEnumerator GatewayAnimation()
{
portalAnimator.SetBool("OpenGateway", true);
MeshCollider gatewayMeshFilter = portalAnimator.gameObject.GetComponent<MeshCollider>();
gatewayAudio.Play();
puzzleAudio.PlayOneShot(puzzleSolvedSound);
gatewayMeshFilter.enabled = false;
yield return new WaitForSeconds(1f);
portalAnimator.SetBool("OpenGateway", false);
foreach (Transform slot in symbolSlots)
{
if (slot.childCount > 0)
{
Vector3 effectPosition = slot.position; // Modify as needed to align with the symbol
Instantiate(bookParticlePrefab, effectPosition, Quaternion.identity, slot);
GameObject shadowPeople = Instantiate(shadowPeoplePrefab, effectPosition, Quaternion.identity, slot);
shadowPeople.GetComponent<AudioSource>().enabled = false;
shadowPeople.name = shadowPeoplePrefab.name;
fearSystem.currentFear += 100;
Destroy(slot.GetChild(1).gameObject, 5);
//Stop puzzle from working at all
}
}
}
public void ResetPuzzle()
{
currentOrder.Clear();
foreach (Transform slot in symbolSlots)
{
if (slot.childCount > 0)
{
Destroy(slot.GetChild(0).gameObject);
}
}
}
public void RemoveSymbol(EldritchSymbols symbol)
{
// Find the index of the symbol in the currentOrder list
int index = currentOrder.FindIndex(s => s == symbol);
int bookIndex = books.FindIndex(b => b.symbolType == symbol);
Book book = books.Find(b => b.symbolType == symbol);
string title = book?.title;
// Check that the index is valid
if (index >= 0 && index < currentOrder.Count)
{
// Find the corresponding symbol in the symbolSlots array
for (int i = 0; i < symbolSlots.Length; i++)
{
if (symbolSlots[i].childCount > 0)
{
GameObject symbolObject = symbolSlots[i].GetChild(0).gameObject;
EldritchSymbols symbolInSlot = symbolObject.GetComponent<EldritchSymbol>().symbolType;
if (symbolInSlot == symbol)
{
// Find the Glyph that has the same symbol
Glyphs glyph = glyphs.Find(g => g.symbolType == symbol);
if (glyph != null)
{
// Define the emissive color
Color emissiveColor = Color.green; // replace with the desired color
glyph.isActive = false;
DeactivateGlyph(glyph.symbolType);
// Get all children of the Glyph
foreach (Transform child in glyph.symbolGlyph.transform)
{
// Get the SpriteRenderer of the child
SpriteRenderer spriteRenderer = child.GetComponent<SpriteRenderer>();
if (spriteRenderer != null)
{
// Apply the emissive color to the SpriteRenderer
spriteRenderer.material.SetColor("_EmissionColor", emissiveColor);
}
}
}
// Remove the symbol from currentOrder and destroy the symbol object
currentOrder.RemoveAt(index);
playerAudioSource.PlayOneShot(placeSymbolSound);
// Instantiate a new instance of the book prefab and add it to inventory
GameObject bookPrefab = books.Find(b => b.symbolType == symbol).symbolPrefab;
// Instantiate an item from the Item prefab
GameObject bookInstantiate = Instantiate(bookPrefab);
Item bookItemScript = bookInstantiate.GetComponent<Item>();
EldritchSymbols bookSymbol = bookInstantiate.GetComponent<EldritchSymbol>().symbolType;
bookItemScript.name = bookItemScript.Name;
bookSymbol = symbolInSlot;
InvManager.AddItem(bookInstantiate.transform);
//InvManager.AddItem("AddItem(Transform item). How To Add The Book That Match The Symbol In Inventory?");
Destroy(symbolObject);
StartCoroutine(player.GetComponent<PlayerInteraction>().InteractionDelay());
break;
}
}
}
}
}
public void LoadData(GameData data)
{
//Loading Current Order
currentOrder = data.currentOrder;
// Load Glyphs isActive Bool State
foreach (var glyphData in data.glyphsState)
{
// Find the corresponding Glyph object in your scene or list
var glyph = glyphs.Find(g => g.symbolType == glyphData.Key);
if (glyph != null)
{
glyph.isActive = glyphData.Value;
UpdateGlyphDisplay(glyph); // Update the visual state according to isActive
}
}
}
public void SaveData(GameData data)
{
//Saving Current Order
data.currentOrder = this.currentOrder;
//Saving Glyphs isActive Bool
foreach (Glyphs glyph in glyphs)
{
// This check prevents trying to add the same key more than once.
if (!data.glyphsState.ContainsKey(glyph.symbolType))
{
data.glyphsState.Add(glyph.symbolType, glyph.isActive);
}
else
{
// If the key already exists, you can choose to update its value or throw an exception/warning.
data.glyphsState[glyph.symbolType] = glyph.isActive;
}
}
}
private void UpdateGlyphDisplay(Glyphs glyph)
{
Color emissiveColor = glyph.isActive ? Color.red : Color.green; // Red for active(True), Green for inactive(False)
Renderer[] childRenderers = glyph.symbolGlyph.GetComponentsInChildren<Renderer>();
foreach (Renderer renderer in childRenderers)
{
Material glyphMaterial = renderer.material;
glyphMaterial.SetColor("_EmissionColor", emissiveColor);
//glyphMaterial.EnableKeyword(“_EMISSION”);
}
}
public void ActivateGlyph(EldritchSymbols symbol)
{
Glyphs glyph = glyphs.Find(g => g.symbolType == symbol);
if (glyph != null)
{
glyph.isActive = true;
UpdateGlyphDisplay(glyph);
}
}
public void DeactivateGlyph(EldritchSymbols symbol)
{
Glyphs glyph = glyphs.Find(g => g.symbolType == symbol);
if (glyph != null)
{
glyph.isActive = false;
UpdateGlyphDisplay(glyph);
}
}
}