Advanced Cocos Class and properties Creation

Hi all. I am looking for some information about advanced component creation. In this example I want to create something like grid level editor by component, it mushes have a lot of cell types defined in enum:

enum CellType {
	Ground,
	High,
}

Then I want my component to create a particular prefab depend on what cell I chose:

private updateCell() {
    const { node, _instatiatedNodes, _currentCellNode, cellType, cellPrefabs } = this;

    node.removeChild(_currentCellNode);

    if (!_instatiatedNodes[cellType]) {
        _instatiatedNodes[cellType] = instantiate(cellPrefabs[CellType[cellType]]);
    }

    this._currentCellNode = _instatiatedNodes[cellType];

    node.addChild(_instatiatedNodes[cellType]);
}

Script works perfect, but I need to define every new enum type manually.
if I define new type in enum, I also need to define new property to custom cocos class what provide me assign particular prefab for particular type:

I am looking for some automatic implementation. Don’t know how to explain, so will try by script:
Something like this:

enum CellType {
	Ground,
	High,
}

@ccclass('CellTypePrefabs')
@decoratorEnum(CellType, Prefab)
class CellTypePrefabs {}

// CellTypePrefabs class now have all properties as keys of enum with prefab type

or:

@ccclass('CellBasicComponent')
@executeInEditMode()
export class CellBasicComponent extends Component {
	@property
	private cellPrefabs: { [key in CellType]: Prefab };
        
    // cellPrefabs property it is an object with keys of CellType what work in editor.
}

I can ask engineering to review this topic.

Which demo should I use to try this problem?

Maybe my text isn’t clear, but I am not sure demo needed here. Question mode if I can reduce manual writing by using some feature that will automatically create unique property.
Here as you see, if I need new type of cell, firstly I need to declare it in enum, then copy and paste name from enum and declare as CellTypePrefabs field. I want to do it in one change of code, just add new type in enum and field in CellTypePrefabs should be created automatically, but I don’t know if there is some feature to do so.

Or possibility to create the same @property(CellTypePrefabs) in other way what will be shorter.

// If I need declare new type of cell, firstly I need declare in it enum:
enum CellType {
    Ground,
    High,
}

// Then I need to declare its name in this class
@ccclass("CellTypePrefabs")
class CellTypePrefabs {
    @property(Prefab)
    Ground: Prefab = null;

    @property(Prefab)
    High: Prefab = null;
}

@ccclass("CellBasicComponent")
export class CellBasicComponent extends Component {
    @property(CellTypePrefabs)
    private cellPrefabs: CellTypePrefabs = new CellTypePrefabs();

    @property({ type: Enum(CellType) })
    private cellType: CellType = CellType.Ground;

    onLoad() {
        const prefabOfTypeCell = this.cellPrefabs[CellType[this.cellType]];

        console.log(prefabOfTypeCell);
    }
}

Here is demo project:
https://drive.google.com/file/d/1Kk5KhqMxk_YCwAXaz_1e7V3j88K6Rf9B/view?usp=sharing

Yes, if defined as an enumeration type, it is added manually in the way you did

There isn’t a shorter way to do so?

Your requirement should not be good to implement, because it is not good to dynamically modify the enumeration value, so you still need to modify it manually.
In addition, I did some other ways to try, but the results are not very satisfactory, so you still need to follow your manual configuration


import { _decorator, Component, Node, Prefab } from 'cc';
const { ccclass, property, executeInEditMode } = _decorator;
 
@ccclass('PrefabBase')
@executeInEditMode(true)
export class PrefabBase extends Component {
    
    @property([Prefab])
    prefabs : Prefab[] = [];

    _default : Prefab = null;
    @property(Prefab)
    set Default (prefab: Prefab) {
        if (!prefab) return;
        if (!this._default) {
            this.prefabs.push(prefab);
        } else if (this._default != prefab) {
            this.prefabs.push(prefab);
        }
        this._default = prefab;
    }
    get Default () {
        return this._default;
    }

    update () {
        // console.error(this.Default);
    }
}


But this way should still be far from the effect you want.
In addition, you can consider whether to change the enumeration to the index value of your prefabricated array, this will be simpler, the disadvantage is not smart

ok, thanks a lot. Problem with array aren’t particular name keys there, so can be confused for people who not wrote the code (for game designers for example).