- Home /
Efficient way to find a specific function instantiated into the game by information from the hierarchy
So my game is a story based game. The way I set it up is that the game is divided into "days," and each day a new scene is instantiated. A story manager script makes sure the story runs smoothly, and here is the code for it.
using System.Collections;
using System;
using System.Collections.Generic;
using UnityEngine;
//Controls order in which scripts are called
public class StoryManager : MonoBehaviour
{
//Creates instance of Dialogue Manager, allows it to be get from anywhere but only set in the class. Part of singleton instantiation
public static StoryManager Instance { get; private set; }
//Destroys duplicate GOs and preserves this one throughout scenes, part of singleton instantiation.
private void Awake()
{
if (Instance == null)
{
Instance = this;
DontDestroyOnLoad(gameObject);
}
else
{
Destroy(gameObject);
}
}
//Calls the Story Coroutine on start
private void Start()
{
StartCoroutine("Story");
}
/*
Functions for each day, so that precise timing can be preserved.
*/
//A class to keep necessary data on each function (So it can be called) and how long after the last function it will occur.
[System.Serializable]
public class FunctionData
{
//Name of the function GameObject (*note* figure out a better way to find the function) because if name of a GO is changed the function becomes unreachable.
//Maybe check for a current active instance of the SCRIPT instead of finding the function.
[HideInInspector]
public string FuncGOName;
//Name of the function
[HideInInspector]
public string FuncName;
//Delay after this function is called and before the next one is called
[HideInInspector]
public float delay;
//Sprite used to display character
[HideInInspector]
public Sprite dialogueSprite;
//Is this dialogue or a normal function?
public bool DialogueTrigger;
}
//Stores all availible information on the day, drawn from to determine what happens that day and what order it happens in.
[System.Serializable]
public class DayData
{
//The day
public int day;
//The scene elements
public GameObject scene;
//Functions to run on each day
public FunctionData[] functionDatas;
//The dialogues
public Dialogue[] dialogue;
//A final delay to make sure all functions finish running before day is changed
public float finalDelay;
}
//Stores all the days in the project
[System.Serializable]
public struct Days
{
public DayData TakeOff;
public DayData Attack;
}
//Defines a "day" struct (in hierarchy)
public Days days;
//Coroutine to run a day
IEnumerator RunDay(DayData thisDay)
{
//Instantiates the scene for this day, checks to make sure one is found
if (thisDay.scene != null) {
Instantiate(thisDay.scene);
} else {
Debug.LogError("No scene found for day " + thisDay.day);
}
/*
* Dialogue # keeps track of which dialogue is going on. Dialogue changes everytime dialogue switches to another character.
* Example: Joe: "Hey Guys" Dialogue# = 0
* Joe: "What's up?" Dialogue# = 0
* Jared: "The sky." Dialogue# = 1
* Joe: "Haha, super funny Jared." Dialogue# = 2
*
* NOTE: A large gap or cutscene can also result in a dialogue # change.
*/
int DialogueNumber = 0;
//Calls DayManager to change day, waits until it does so to do anything.
yield return StartCoroutine(DayManager.Instance.ChangeDay(thisDay.day));
//Foreach function in functiondata...
foreach (FunctionData fData in thisDay.functionDatas)
{
//Defines a GameObject, initially null
GameObject FuncGO = null;
//If statement to distinguish between dialogue and non-dialogue (called in different ways)
if (fData.DialogueTrigger == true)
{
//Calls dialogue, gives a delay between next dialogue if necessary.
yield return StartCoroutine(DialogueManager.Instance.StartDialogueWDelay(thisDay.dialogue[DialogueNumber], fData.delay, fData.dialogueSprite));
//Increments DialogueNumber when a character finishes talking
DialogueNumber++;
}
else
{
//Looks to see if a GameObject by that name has been instantiated
//Only temporary, if a better method to do this is found, replace
if (GameObject.Find(fData.FuncGOName) != null)
{
//Sets FuncGO
FuncGO = GameObject.Find(fData.FuncGOName);
//Calls the function
FuncGO.SendMessage(fData.FuncName);
//Function delay
yield return new WaitForSecondsRealtime(fData.delay);
} else
{
Debug.LogWarning("A GameObject by the name of " + fData.FuncGOName + "has not been found!");
}
}
}
//Final delay if necessary
yield return new WaitForSecondsRealtime(thisDay.finalDelay);
}
//Coroutine for calling all the days.
IEnumerator Story()
{
yield return StartCoroutine(RunDay(days.TakeOff));
yield return StartCoroutine(RunDay(days.Attack));
}
}
Everything is working well, but the solution I have to find the function is kind of rough. I have to find a game object by name, then find a function it has. I don't like this solution because it's not certain that the gameobject or function will be there. So what I was wondering was this: is there an easier way to find a function from an instantiated object using variables from the hierarchy?
Thank you for your help.
Your answer
![](https://koobas.hobune.stream/wayback/20220612203150im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
How of these two methods are more efficient? 2 Answers
Efficient Electrical Grid in Tiled Game 0 Answers