Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unity - pass parameters on instantiation

I made a simple message box that should show a message to the user. It's a prefab and does a couple of things, mostly animations upon instantiation. To run code upon instantiation I used the Start() function. It worked when I already knew what to message but I need something like a constructor, that runs before Start(), but upon instantiation and can take parameters. Now, I'm fully aware that I could instantiate, set the message and run everything - so using 3 lines of code where I instantiate it, but I'm curious if there is another, more proper solution? All I found on the net was that instantiate, then do something.

EDIT:

My calling of a messagebox to show up:

var timeBox =
    Instantiate(messageBox, penaltySpawnLoc.position, penaltyPrefab.transform.rotation, transform);
    var scr = timeBox.GetComponent<MessageBox>();
    scr.OnCreated(message);

OnCreated does the initialization, show up animations, so basically everything. But it needs a string input to know what to show up and I don't want to set the text value "on the fly" - it would make appear some weird flickering when the messagebox is visible but the text isn't set.

EDIT2:

the last parameter transform in the Instantiation is the Canvas this script is on as this is a UI script. That parameter means that the freshly instantiated GameObject is the child of that.

EDIT3:

timeBox is just an instance of messageBox, they are GameObjects. One message box is used only once. Its purpose is to appear with the message and after like 0.5 seconds fade out and move away. After moving away it destroys itself.

like image 488
agiro Avatar asked Feb 11 '17 18:02

agiro


2 Answers

You can do this with a function or extension method.

In this case, extension method is more appropriate.

We will make an extension object with Object instead of GameObject. Since GameObject inherits from Object, this extension method should work for both Object, GameObject and Transform.

Create a class called ExtensionMethod then paste everything below inside it.

using UnityEngine;

public static class ExtensionMethod
{
    public static Object Instantiate(this Object thisObj, Object original, Vector3 position, Quaternion rotation, Transform parent, string message)
    {
        GameObject timeBox = Object.Instantiate(original, position, rotation, parent) as GameObject;
        MessageBox scr = timeBox.GetComponent<MessageBox>();
        scr.OnCreated(message);
        return timeBox;
    }
}

Usage:

Only one line call in the Start function should handle all other tasks.

public class Test: MonoBehaviour
{
    GameObject messageBox = null;
    Transform penaltySpawnLoc = null;
    GameObject penaltyPrefab = null;

    void Start()
    {
        gameObject.Instantiate(messageBox, penaltySpawnLoc.position, penaltyPrefab.transform.rotation, transform, "Hello");
    }
}
like image 110
Programmer Avatar answered Sep 25 '22 03:09

Programmer


I'd use a Factory for the message boxes, so something like

var timebox = MessageBoxFactory.Create(message);
timebox.Show();

and in the factory class do your setup and return the message box

public static MessageBox Create(string message) {
   var newTimeBox = Instantiate(messageBox, penaltySpawnLoc.position, penaltyPrefab.transform.rotation, transform);
   var scr = newTimeBox.GetComponent<MessageBox>();
   scr.SetMessage(message);
   return scr;

where Show() is the new OnCreated(). I find this pattern helps out with reducing the calling code and if I need tweaks to how the thing I want gets created it is all in one place with the shared factory code.

like image 39
niksga Avatar answered Sep 21 '22 03:09

niksga