The thing you want to instantiate must be an object是怎么回事呢

跟着B站的视频学小游戏,点击的时候会报错,一直找不到原因

点击的时候会调用这个onOpenSetting方法

onOpenSetting(){

    //打开UISetting

    UIManager.instance.openDialog(DialogDef.UISetting);

}

然后就会报这个错误:

TypeError: The thing you want to instantiate must be an object

说你想要实例化的东西必须是一个对象

但是我没找到问题,大佬们帮忙看下

【源码】

//UIGame

import { _decorator, Component, Node, director, resources, find, Prefab, instantiate } from ‘cc’;

import { DialogDef, UIManager } from ‘./UIManagers’;

const { ccclass, property } = _decorator;

@ccclass(‘UIGame’)

export class UIGame extends Component {

start() {



}



update(deltaTime: number) {

   

}



//点击设置时执行的方法:

onOpenSetting(){

    //打开UISetting

    UIManager.instance.openDialog(DialogDef.UISetting);



}



//点击退出游戏执行的方法:

onExitGame(){

    console.log("点击了Exit");



    //释放此包中的所有没有用到的资源:

    resources.releaseUnusedAssets();



    //退出游戏,即回到startup开始界面:

    director.loadScene("startup");

}



//暂停游戏执行的方法:

onPauseGame(){

    console.log("点击了Pause");



    //进行判断,如果当前游戏暂停,则恢复暂停。isPaused表示是否暂停,resume表示恢复暂停。否则暂停游戏。

    if(director.isPaused()){

        director.resume();



        //return可以将代码格式化吗?

        return;

    }else{

        director.pause();

    }



}

}

//UIManager

import { find, instantiate, Node, Prefab, resources } from “cc”;

//枚举的作用是列举类型中包含的各个值,一般用它来管理多个相同系列的常量(即不能被修改的变量),用于状态的判断。

export enum DialogDef{

UISetting = 'UISetting',

UISkillUpgrade = 'UISkillUpgrade',

}

export class UIManager{

/*

把UIManager设置为单例类。

public表示公开,private表示私有,protected表示只有自己以及继承关系的才可以访问。

*/

private static _instance:UIManager = null;



//static表示这个方法是静态的。并且允许外界通过get来获取这个方法。

static get instance():UIManager{

    //如果这个实例为空,则将UIManager实例化。

    if (this._instance == null) {

        this._instance = new UIManager();

    }

    return this._instance;

   

}



//声明uiRoot,类型为节点,初始值为空,用于实例化UIRoot节点。

uiRoot:Node = null;



/*

把加载的数据存放到内存中,避免重复加载。Map()是一种数据结构。

Map 对象存有键值对,其中的键可以是任何数据类型。Map 对象记得键的原始插入顺序。

可以把对象放在Map中,方便后续取用,效率更高。

详细解释可以参考JS文档:https://www.w3school.com.cn/js/js_object_maps.asp

panels是参数,:后面是类型,类型是Map,Map有两个参数,string字符串和Node节点。

*/

panels : Map<string, Node> = new Map();



//打开面板的方法,传入2个参数:name:string表示预制体的名称,bringToTop:Boolean = true表示是否调整预制体的层级:

openPanel(name:string, bringToTop:Boolean = true){



    /*

    当uiRoot == null时,就是没有实例化时,查找UIRoot并赋值给uiRoot。

    通过if语句进行判断,防止重复初始化。

    */

    if (this.uiRoot == null) {

        this.uiRoot = find("UIRoot");

    }

   

    /*

    后续执行时,因为resources.load中已经将该资源放入Map,因此这里可以直接取出来利用。

    然后再进行激活。

    这个方法的目的时进行判断,如果Map中存在Panel,则直接取出,进行实例化,

    不再执行resources.load,避免重复加载预制体。

    */

    if (this.panels.has(name)) {

        //从Map中取出name,name是panel并实例化。

        let panel = this.panels.get(name);



        //把panel的状态进行激活。

        panel.active = true;



        //判断是否需要将panel的层级进行提升。

        if (bringToTop) {

            //当bringToTop为真时,panel.parent.children.length - 1表示panel所有父节点的子节点场层级-1,就是往上移动一个层级。

            const index = panel.parent.children.length - 1;

            //向上移动一个层级后,将index参数传入,setSiblingIndex表示设置置当前节点在父节点的 children 数组中的位置。

            panel.setSiblingIndex(index);

        }

        //中止函数,不再往下执行。

        return;

    }

    /*

    1.加载面板

    resources.load可以通过相对路径加载资源。

    "ui\prefab" + name表示ui/prefa/这个路径下某个名字的资源,Prefab表示是预制体。

    =>表示箭头函数,这里相当于:

    function(err:Error, data:Prefab) {}

    */

    resources.load("ui/prefab/" + name, Prefab, (err:Error, data:Prefab)=>{

        /*

        实例化预制体并赋值给panel:

        data就是(err:Error,data:Prefab)里面的data,就是从预制体里面取出来的数据。

        */

        let panel = instantiate(data);



        //在uiRoot节点下增加panel子节点:

        this.uiRoot.addChild(panel);



        //this.panels.set就是给Map()设置一个键值,内容是name,而这个name就是节点panel。

        this.panels.set(name,panel);



        if (bringToTop) {



            //当bringToTop为真时,panel.parent.children.length - 1表示panel所有父节点的子节点场层级-1,就是往上移动一个层级。

            const index = panel.parent.children.length - 1;

            //向上移动一个层级后,将index参数传入,setSiblingIndex表示设置置当前节点在父节点的 children 数组中的位置。

            panel.setSiblingIndex(index);

        }



    });

}



//关闭面板的方法:

closePanel(name:string, destory:boolean = false){



    //判断面板是否存在,如果不存在,直接中断函数。

    if(!this.panels.has(name)){

        return;

    }



    //如果存在,则从Map中取出预制体。

    let panel = this.panels.get(name);



    /*

    如果需要销毁预制体,则聪Map中删除相关预制体,并从父节点移除

   

    0该节点。

    是否销毁根据closePanel(name:string, destory:boolean = false)传入的

    destory:boolean = false参数决定,如果=true则销毁。这里是false则表示不销毁,

    当前代码只是示例。

    */

    if (destory) {

        this.panels.delete(name);

        panel.removeFromParent();

        return;

    }



    //如果不销毁,只是隐藏,则关闭该节点。

    panel.active = false;



}



/*打开弹框:

通过名字来获取弹框。怎么获取弹框的名字呢,可以通过enum枚举来定义,然后再从枚举中获取。

*/

openDialog(name:string){

    for(let  dialogDef in DialogDef){

        if (dialogDef == name) {

            this.openPanel(name);

        } else {

            this.closePanel(dialogDef);

        }



    }



}



//关闭弹框:

CloseDialog(destory: boolean =false){

    for (let  dialogDef in DialogDef) {

        this.closePanel(dialogDef,destory);    

    }



}

}

应该是这个路径下没有加载到,打印一下这个路径,和下边的类型

1赞

感谢,谢谢啦