- Home /
Trigger a function when player String input is same as name of object
I am working on a Zoo game for an assignment, in this game you can feed the animals, let them do tricks and let them say hello to you. This is done by pressing these buttons:
The first buttons all work fine but I need to add a function that allows the user to make a specific animal say Hello, for example there is an Elephant called Dombo, so when the user types Dombo in the inputfield and presses the Hello button, only Dombo should say Hello.
The animals are instantiated from a prefab like this:
namespace Zoo
{
class Spawner : MonoBehaviour
{
// Variables
[SerializeField]
private GameObject lion, hippo, pig, tiger, zebra, elephant, giraffe;
private void Start()
{
Lion henk = Instantiate(lion, transform).GetComponent<Lion>();
henk.name = "henk";
Hippo elsa = Instantiate(hippo, transform).GetComponent<Hippo>();
elsa.name = "elsa";
Pig dora = Instantiate(pig, transform).GetComponent<Pig>();
dora.name = "dora";
Tiger wally = Instantiate(tiger, transform).GetComponent<Tiger>();
wally.name = "wally";
Zebra marty = Instantiate(zebra, transform).GetComponent<Zebra>();
marty.name = "marty";
Elephant dombo = Instantiate(elephant, transform).GetComponent<Elephant>();
dombo.name = "dombo";
Giraffe donald = Instantiate(giraffe, transform).GetComponent<Giraffe>();
donald.name = "donald";
}
}
}
I honestly have no idea how to handle this, but here is an example of one of the animal's scripts:
namespace Zoo
{
public class Giraffe : MonoBehaviour
{
// Variables
[SerializeField]
private GameObject Balloon;
[SerializeField]
private Text text;
public new string name;
LeavesButton leavesButton;
private void Start()
{
Balloon.SetActive(false);
GameObject Leaves = GameObject.Find("Leaves");
leavesButton = Leaves.GetComponent<LeavesButton>();
}
private void Update()
{
if(leavesButton.leaves == true)
{
EatLeaves();
}
}
public void SayHello()
{
Balloon.SetActive(true);
text.text = "giraffe giraffe";
}
public void EatLeaves()
{
Balloon.SetActive(true);
text.text = "munch munch good stuff";
}
}
}
How would you guys handle this??
Answer by Tobychappell · May 27, 2018 at 11:11 AM
This is ONE way of doing it using inheritence:
Animal.cs (base class)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
namespace Zoo
{
public class Animal : MonoBehaviour
{
[SerializeField]
protected Text text;
public string animalName;
public virtual void Start() { Debug.Log("Animal Base Class : Start()"); }
public virtual void Update() { }
public virtual void SayHello() { }
public virtual void Eat() { }
}
}
Spawner.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Zoo
{
public class Spawner : MonoBehaviour
{
// Variables
[SerializeField]
private GameObject[] animalPrefabs;
private Dictionary<string, Animal> animals;
private void Start()
{
animals = new Dictionary<string, Animal>();
for (int i = 0; i < animalPrefabs.Length; i++)
{
Animal animal = Instantiate(animalPrefabs[i], transform).GetComponent<Animal>();
animals.Add(animal.animalName, animal);
}
}
public void MakeAnimalSayHello(string nAnimalName)
{
if (animals.ContainsKey(nAnimalName))
{
animals[nAnimalName].SayHello();
}
}
public void MakeAnimalEat(string nAnimalName)
{
if (animals.ContainsKey(nAnimalName))
{
animals[nAnimalName].Eat();
}
}
}
}
Giraffe.cs (inherits from Animal.cs)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Zoo
{
public class Giraffe : Animal
{
[SerializeField]
private GameObject balloon;
LeavesButton leavesButton;
public override void Start()
{
base.Start();
animalName = "donald";
balloon.SetActive(false);
GameObject Leaves = GameObject.Find("Leaves");
leavesButton = Leaves.GetComponent<LeavesButton>();
}
public override void Update()
{
base.Update();
if (leavesButton.leaves == true)
{
Eat();
}
}
public override void SayHello()
{
base.SayHello();
balloon.SetActive(true);
text.text = "giraffe giraffe";
}
public override void Eat()
{
balloon.SetActive(true);
text.text = "munch munch good stuff";
}
}
}
// Delete this to resolve compile errors
public class LeavesButton : MonoBehaviour { public bool leaves; }
It was difficult to tell if the EatLeaves method on the giraffe was something that all animals shared, as i dont think all animals IRL eat leaves as their primary food source.
Oh yeah, that was just one example, it's different for each animal, like the tiger has an eat meat method for example.
The Animal Class could have a
public virtual void Eat() {}
method which all the other classes can override. So ins$$anonymous$$d of talking to the giraffe object as a giraffe, you'd talk to it like it was an Animal and just call Eat() and ploymorphism will do the rest do call Eat() on the Giraffe and not the base class.
Thanks for this solution, will check if it works but I have one question. The animal.cs should be used on the Inputfield?
I don't fully understand when you say 'used on the input field'. An Animal has a Text field that is serialized so it should show in the inspector. I'm finding it difficult to visualize your setup.
Oh sorry, what I meant was should I put the script Animal on the inputfield? The inputfield is the one under the buttons.
I am now trying to implement your code but I have an issue with the array, it only instantiates 1 animal, after that I get a NullReference.