无法从另一个脚本实例化预制件 [英] Cant instantiate a prefab from another script

查看:123
本文介绍了无法从另一个脚本实例化预制件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法从另一个脚本实例化一个预制件,它什么也不做,也没有给我任何错误.在同一播放"中,我可以多次从同一脚本实例化相同的预制件,但如果我尝试通过从另一脚本执行相同的方法来执行此操作,则它将不起作用....我传递了一些变量并打印了它们(它可以工作),但无能为力....请帮助!

I cant instantiate a prefab from another script, it does nothing and gives me no errors. In the same "play" i can instantiate the same prefab from the same script multiple times but if i try to do it by executing the same method from another script it doesnt work.... i pass some variables and print them ( it work) but instatiation is doing nothing....please help!

我试图通过以下方法解决它:

I tried to solve it by:

GameObject公共参考, UnityEvents和 在一个对象中同时使用两个脚本

public GameObject reference, UnityEvents and Ataching both scripts in one object

脚本一

void OnEnable()
{
    EventSystemManager.StartListening("printMessage", AddMessage);     
}

public void AddMessage(string message ) 
{
    GameObject remoteMessage = Instantiate(localMessagePrefab, 
    chatTransform);
    remoteMessage.transform.GetChild(0).GetComponentInChildren<Text> 
    ().text = message;
}

第二脚本

public IEnumerator StartWebSocket() 
{
    using (ws = new WebSocket(serveradress))
    {
        ws.OnOpen += (sender, e) =>
        onOpenHandler();
        ws.OnMessage += (sender, e) =>
        onMessageHandler(e.Data);
        ws.OnError += (sender, e) =>
        onErrorHandler(e);
        ws.OnClose += (sender, e) =>
        onCloseHandler(e);
        ws.Connect();
        for (; ; )
        {
            yield return null;
        }
    }
} 

private async void onMessageHandler(string e)
{
    serverMessage = JsonUtility.FromJson<serverMssg>(e);
    EventSystemManager.TriggerEvent("printMessage", 
    serverMessage.normmsg);
    await miaApi.queueAnim(serverMessage.normmsg);
}

消息已传递,但实例化不起作用. 我在调试中检测到的唯一一件事是,尝试从其他脚本执行该操作时,变换消失了:

The message is passed but instantiation do nothing.... The only thing i detect in debugging is that transform dissapears when tryng to do it from other script:

来自同一脚本:

来自另一个脚本:

还有一个视频(没有声音) 该视频不使用事件,但行为完全相同 视频 TIA!

Also there is a video (without sound) The video doesnt use events but is exactly the same behavior Video TIA!

推荐答案

我不知道EventSystemManager的工作原理.

如果问题实际上是async和多线程,则可以尝试使用简单的调度程序"将回调传递回主线程:

In case the issue is actually the async and multi-threading you could try a simple "dispatcher" for passing callbacks back to the main thread:

public class MainThreadDispatcher : MonoBehaviour
{
    private static MainThreadDispatcher _instance;
    public static MainThreadDispatcher Instance
    {
        get 
        {
            if(!_instance)
            {
                _instance = new GameObject("MainThreadDispatcher").AddComponent<MainThreadDispatcher>();

                DontDestroyOnLoad(_instance.gameObject);
            }

            return _instance;
        }
    }

    private ConcurrentQueue<Action> actions = new ConcurrentQueue<Action>();

    private void Update()
    {
        // work the queue in the main thread
        while(actions.TryDequeue(out var action))
        {
            action?.Invoke();
        }
    }

    public void Dispatch(Action action)
    {
        actions.Enqueue(action);
    }
}

然后使用它来确保回调在主线程中完成

and then use it to make sure the callback is done in the main thread

private MainThreadDispatcher mainThreadDispatcher;

void OnEnable()
{
    // before dispatching stuff make sure an instance reference is optained
    // or is created in the main thread
    mainThreadDispatcher = MainThreadDispatcher.Instance;

    EventSystemManager.StartListening("printMessage", AddMessage);   
}

// might be executed in a thread
public void AddMessage(string message ) 
{
    // instead of directly executing the code wait for the main thread
    // either using a lambda expression
    mainThreadDispatcher.Dispatch(() =>
        {
            GameObject remoteMessage = Instantiate(localMessagePrefab, 
            chatTransform);
            remoteMessage.transform.GetChild(0).GetComponentInChildren<Text> 
            ().text = message;
        });

    // or if you prefer a method
    //mainThreadDispatcher.Dispatch(HandleAddMessage);
}

// should be only executed in the main thread
private void HandleAddMessage()
{
    GameObject remoteMessage = Instantiate(localMessagePrefab, 
    chatTransform);
    remoteMessage.transform.GetChild(0).GetComponentInChildren<Text> 
    ().text = message;
}

这篇关于无法从另一个脚本实例化预制件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆