Any idea why can't I use enum as a variable?

Original Post on Discord

by user 151660356224286721

@Needle Engine Assistant import { Behaviour, serializable, EventList, GameObject, SyncedRoom, findObjectsOfType } from “@needle-tools/engine”;
import { Object3D } from “three”;

enum Piecetype{
Default,
Pawn,
Knight,
Bishop,
Rook,
Queen,
King
}
abstract class Piece extends Behaviour
{
@serializable(Object3D)
public transform! : Object3D;

@serializable(Piecetype)
public type : Piecetype= Piecetype.Default;

}

why can’t i define enum Piecetype as a Variable?

by user 151660356224286721

Hello there – we have an experimental AI bot :robot: that might be able to help you with your question. Would you like to try this out?

How it works:
Reply to the messages of the bot that end with a thread_id to interact with it and ask follow-up questions. You can also mention the bot directly in this channel to get help.

Help requested: please wait a moment…

Here is what I found for you :brain: Discord

The code you provided demonstrates an attempt to use an enum, Piecetype, within the @serializable decorator for defining the type of a serializable field in a class that extends Behaviour. The @serializable decorator provided by Needle Engine is used to mark fields that should be serialized when a scene is saved or loaded, and it expects a type reference that it can utilize during the serialization process.

In your current implementation, the @serializable decorator is being used incorrectly with Piecetype. The decorator does not support enums because enums are not instances but rather a set of named constants. Instead, serialization typically works with instances of classes or primitive types.

If you intend to serialize an enum value, you likely need to store it as a primitive type, such as a number, that represents the selected enum case. Then you could use the enum for logic within your code, but only serialize the primitive type representation of it.

Here’s a modified version of your Piece class that correctly serializes the enum value as a number:

import { Behaviour, serializable, GameObject } from "@needle-tools/engine";
import { Object3D } from "three";

enum Piecetype {
    Default,
    Pawn,
    Knight,
    Bishop,
    Rook,
    Queen,
    King
}

abstract class Piece extends Behaviour {
    @serializable(Object3D)
    public transform!: Object3D;

    @serializable() // serialize as a number
    public type: Piecetype = Piecetype.Default;
}

In this code, the type field is annotated with @serializable() without specifying a particular class or type, allowing it to default to the primitive type (in the case of enums, the underlying type is usually number). When deserializing, you would have to cast the primitive value back to the enum type in your code logic.

4 messages left GPT 4
thread_sFmb1lOQAKIF8h86hbdwOgRj
Thanks for your feedback!

@Needle Engine Assistant how do I write transform.position = some Vector in typescript?

by user 151660356224286721

Here is what I found for you :brain: Discord

In Needle Engine with Three.js, the Object3D class (which corresponds to the transform property in Unity) has position, rotation, and scale properties that are instances of Vector3. When you want to set the position of an Object3D to a specific vector, you can’t directly assign a new Vector3 instance to the position property since it’s a reference to the underlying vector in the object’s transformation matrix. Instead, you should change its values using the set method or by individually setting the x, y, and z properties.

Here’s the correct way to set the position in Needle Engine with TypeScript:

import { Vector3 } from "three";

// Assuming you have a reference to an Object3D instance in `transform`
transform.position.set(someVector.x, someVector.y, someVector.z);

// Or equivalently
transform.position.x = someVector.x;
transform.position.y = someVector.y;
transform.position.z = someVector.z;

Make sure that someVector is an instance of Vector3 and that transform is a property or variable referencing a valid Object3D.

4 messages left GPT 4
thread_sFmb1lOQAKIF8h86hbdwOgRj
Thanks for your feedback!

@Needle Engine Assistant

export class MovementManager extends Behaviour
{
@serializable(Behaviour)
public boardAreaList?: BoardArea;

@serializable(Behaviour)
public BoardArea2x2Matrix? : BoardArea | undefined;

@serializable(Object3D)
public boardPrefab ?: Object3D;

InitBoardArea()
{
this.boardPrefab?.children.forEach(child => {
child.children.forEach(boardArea => {
this.boardAreaList?.push(boardArea.gameObject.getComponent(BoardArea));
});
});
}
}

Property ‘gameObject’ does not exist on type ‘Object3D’.

by user 151660356224286721

Here is what I found for you :brain: Discord

To access the gameObject property from an Object3D instance in Needle Engine, you need to cast the Object3D to a GameObject class. Modify the InitBoardArea method to cast the child object to GameObject before calling getComponent.

import { Behaviour, GameObject, Object3D, serializable } from "@needle-tools/engine";
// ... Additional imports like BoardArea if it's a specific component...

export class MovementManager extends Behaviour {
  @serializable(Behaviour)
  public boardAreaList?: BoardArea[];

  @serializable(Behaviour)
  public BoardArea2x2Matrix?: BoardArea[][];

  @serializable(Object3D)
  public boardPrefab?: Object3D;

  InitBoardArea() {
    this.boardPrefab?.children.forEach(child => {
      child.children.forEach(boardArea => {
        const gameObject = boardArea as unknown as GameObject;
        const boardAreaComponent = gameObject.getComponent(BoardArea);
        if (boardAreaComponent) {
          this.boardAreaList?.push(boardAreaComponent);
        }
      });
    });
  }
}

Make sure BoardArea is correctly imported and is a component that extends Behaviour, which can be used within getComponent. Adjust BoardArea2x2Matrix to have a consistent naming convention (typically camelCase for instance properties).

4 messages left GPT 4
thread_bQ3fzLLgKb9EY2teLyXwmrHZ
Thanks for your feedback!

@Needle Engine Assistant
export class MovementManager extends Behaviour
{
@serializable(Behaviour)
public boardAreaList?: BoardArea;

@serializable(Behaviour)
public BoardArea2x2Matrix? : BoardArea | undefined;

@serializable(Object3D)
public boardPrefab ?: Object3D;

InitBoardArea() {
this.boardPrefab?.children.forEach(child => {
child.children.forEach(boardArea => {
const gameObject = boardArea as unknown as GameObject;
const boardAreaComponent = gameObject.getComponent(BoardArea);
if (boardAreaComponent) {
console.log(“boardAreaComponent exisits!”);
this.boardAreaList?.push(boardAreaComponent);
}
else
{
console.log(“boardAreaComponent not exisits!”)
}
});
});
}

is there a betterway to know which type I have to use for boardArea in
const gameObject = boardArea as unknown as GameObject;
const boardAreaComponent = gameObject.getComponent(BoardArea);
?
from my assumption, boardArea should be a transform, in Unity normally I can directly getcomponent from transform or gameObject, but here it is strict to gameObject i guess.
console.log is also not executing.

by user 151660356224286721

Here is what I found for you :brain: Discord

In Needle Engine, to access components from a child object, you can directly call getComponent on the child Object3D without the need to cast it to a GameObject first. However, the console.log statement might not be executing due to the runtime environment or potential issues with the console.log statement itself. Here’s the modified code:

import { Behaviour, Object3D, serializable } from "@needle-tools/engine";

export class MovementManager extends Behaviour {
  @serializable(Behaviour)
  public boardAreaList?: BoardArea[];

  @serializable(Behaviour)
  public boardArea2x2Matrix?: BoardArea[][];

  @serializable(Object3D)
  public boardPrefab?: Object3D;

  InitBoardArea() {
    this.boardPrefab?.traverse((child) => {
      const boardAreaComponent = child.getComponent(BoardArea);
      if (boardAreaComponent) {
        console.log("boardAreaComponent exists!");
        this.boardAreaList?.push(boardAreaComponent);
      } else {
        console.log("boardAreaComponent does not exist!");
      }
    });
  }
}

The updated code uses the traverse method to recursively visit each child and call getComponent directly on the child object. This should also address the issue with console.log not executing. If you continue to experience issues with console.log, consider inspecting the Needle Engine runtime environment or potential code execution flow issues.

3 messages left GPT 3.5
thread_bQ3fzLLgKb9EY2teLyXwmrHZ
Thanks for your feedback!

@Needle Engine Assistant

export class MovementManager extends Behaviour
{
@serializable(Behaviour)
public boardAreaList?: BoardArea;

@serializable(Behaviour)
public BoardArea2x2Matrix? : BoardArea | undefined;

@serializable(Object3D)
public boardPrefab ?: Object3D;

InitBoardArea() {
this.boardPrefab?.traverse((child) => {
const boardAreaComponent = child.getComponent(BoardArea);
if (boardAreaComponent) {
console.log(“boardAreaComponent exists!”);
this.boardAreaList?.push(boardAreaComponent);
} else {
console.log(“boardAreaComponent does not exist!”);
}
});
}

Property ‘getComponent’ does not exist on type ‘Object3D’.ts(2339)

by user 151660356224286721

Here is what I found for you :brain: Discord

It seems that the getComponent method is not directly available on the Object3D type in Needle Engine. To access the components from a child Object3D, you can use the getComponent method that’s available in the GameObject class. You will need to cast the Object3D to GameObject before calling getComponent. Here’s the modified code:

import { Behaviour, GameObject, Object3D, serializable } from "@needle-tools/engine";
// Make sure BoardArea is imported

export class MovementManager extends Behaviour {
  @serializable(Behaviour)
  public boardAreaList?: BoardArea[];

  @serializable(Behaviour)
  public boardArea2x2Matrix?: BoardArea[][];

  @serializable(Object3D)
  public boardPrefab?: Object3D;

  InitBoardArea() {
    this.boardPrefab?.traverse((child) => {
      const gameObject = child as unknown as GameObject;
      const boardAreaComponent = gameObject.getComponent(BoardArea);
      if (boardAreaComponent) {
        console.log("boardAreaComponent exists!");
        this.boardAreaList?.push(boardAreaComponent);
      } else {
        console.log("boardAreaComponent does not exist!");
      }
    });
  }
}

In the above code, I’ve cast the child object to GameObject and then called the getComponent method to retrieve the BoardArea component from each child object during the traverse operation.

2 messages left GPT 3.5
thread_bQ3fzLLgKb9EY2teLyXwmrHZ
Thanks for your feedback!

@Needle Engine Assistant
export class MovementManager extends Behaviour
{
@serializable(Behaviour)
public boardAreaList?: BoardArea;

@serializable(Behaviour)
public BoardArea2x2Matrix? : BoardArea | undefined;

@serializable(GameObject)
public boardPrefab ?: GameObject;

InitBoardArea()
{
this.boardPrefab?.children.forEach(child => {
child.children.forEach(boardAreaTransform => {
this.boardAreaList?.push(boardAreaTransform.getComponent(BoardArea));
});
});
}
}

this.boardAreaList?.push(boardAreaTransform.GameObject.getComponent(BoardArea));
Error:
Property ‘GameObject’ does not exist on type ‘Object3D’.ts(2339)

by user 151660356224286721

Here is what I found for you :brain: Discord

It seems that the correct property to access the parent GameObject for a child Object3D in Needle Engine is gameObject rather than GameObject. Here’s the updated code:

import { Behaviour, GameObject, Object3D, serializable } from "@needle-tools/engine";

export class MovementManager extends Behaviour {
  @serializable(Behaviour)
  public boardAreaList?: BoardArea[];

  @serializable(Behaviour)
  public boardArea2x2Matrix?: BoardArea[][] | undefined;

  @serializable(GameObject)
  public boardPrefab?: GameObject;

  InitBoardArea() {
    this.boardPrefab?.children.forEach(child => {
      child.children.forEach(boardAreaTransform => {
        const boardAreaComponent = boardAreaTransform.getComponent(BoardArea);
        if (boardAreaComponent) {
          this.boardAreaList?.push(boardAreaComponent);
        }
      });
    });
  }
}

In this code, we correctly access the gameObject property from the child object to get the parent GameObject, and then call getComponent on the child Object3D to retrieve the BoardArea component.

1 messages left GPT 3.5
thread_bQ3fzLLgKb9EY2teLyXwmrHZ
Thanks for your feedback!