0
\$\begingroup\$

In my game I'm trying to make a series of mock web pages. To make it easier, I thought I'd make all the webpage UI into Scriptable Objects and have a game manager script determining what content to display on the UI. However, I'm doing a small test that isn't going as planned.

Because the content, style, and layout of each page may be quite different, I decided to make a webpage-styled template and have the content manager switch out scriptable object properties as a GameObject so that it takes everything that will be in the prefab. This doesn't seem to be working and I'm not sure what I'm doing wrong.

For now, I'm just testing this method with a very basic script. It's not changing the main content as a GameObject, though it is doing it on my tab textmesh property. It seems to have an issue with transplanting a prefab into the defined content space, but no errors are popping up. I'd appreciate some advice here.

Web Content Scriptable Object Script:

using UnityEngine;
using UnityEngine.UI;

[CreateAssetMenu]
public class WebContent : ScriptableObject
{
    public string tabTitle; //WebPage Title
    public GameObject canvasContent; //Web Page UI Content I want to change via prefab attached to a  Scriptable Object
}

Content Display Script:

using UnityEngine;
using UnityEngine.UI;
using TMPro;

public class ContentDisplay : MonoBehaviour
{
    public WebContent content;
    public TextMeshProUGUI TabName;
    public GameObject mainContent;


    // Update is called once per frame
    void Update()
    {
        TabName.text = content.tabTitle.ToString(); //This works
        mainContent = content.canvasContent; // This doesn't work

    }
}
\$\endgroup\$
1
\$\begingroup\$

In order to put a prefab into your scene, you need to Instantiate it. This also applies to UI elements.

Assuming mainContent is a child-node of the content display game object, you need to destroy the old child-node, instantiate the new and make it the new child-node. This code is untested, but should work:

 Destroy(mainContent);
 GameObject newContent = Instantiate(content.canvasContent, this.transform);
 mainContent = newContent;

But destroying and instantiating a game object is costly and might have unintended side-effects. So you should not do that in Update(). You should only do this when the content actually changed. You can actually do that by turning content into a property. This allows you to run some code whenever that value gets changed.

private WebContent content;
public WebContent Content {
      get => content;
      set {
            content = value;
            TabName.text = content.tabTitle.ToString(); 
            Destroy(mainContent);
            GameObject newContent = Instantiate(content.canvasContent, this.transform);
            mainContent = newContent;
      }
}

(again, untested code)

| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.