So Iām trying to generate red spheres on top of food items that are dragged onto a plate, but Iām having trouble generating the ācorrectā position of the food item, and I am not sure whether Iām approaching this correctly. I have some scripts that are meant to manage this spawning of red spheres, and theyāre working, but itās creating some odd results.
The positions are correct, in a technical sense but not in a practical sense. to demonstrate my point Iāll share a screencap
The Yellow circle is where the plate is, the blue circle is where the food item is, and the tiny red dot far off is the red sphere that is supposed to be on top of the food item.
The code that gets the position of the food item and sets the target for the red sphere is as such: ```ts
import * as THREE from āthreeā;
import { GameObject } from ā@needle-tools/engineā;
import { myEmitterInstance } from āā¦/ā¦/include/controlscripts/MyEmitter.jsā;
import { getWorldPosition } from ā@needle-tools/engineā; // Import the getWorldPosition function
class FoodCoordinateManager {
private targets: THREE.Object3D = ;
constructor() {
// Listen for the 'itemAddedToPlate' event
myEmitterInstance.on('itemAddedToPlate', this.handleItemAddedToPlate.bind(this));
}
private handleItemAddedToPlate(name: string, position: THREE.Vector3, gameObject: GameObject) {
// Get the accurate world position of the food item
const accuratePosition = getWorldPosition(gameObject);
// Create a new target position directly above the added food item
const newTargetPosition = accuratePosition.clone();
newTargetPosition.y += 0.05; // Adjust the Y value to set the height of the new target
// Create a new GameObject to represent the target
const targetObject = new GameObject();
targetObject.position.copy(newTargetPosition);
// Log to the console that a new target has been generated and emit its coordinates
console.log(`A new target has been generated at coordinates: x: ${newTargetPosition.x}, y: ${newTargetPosition.y}, z: ${newTargetPosition.z}`);
// Add the new target to the targets array
this.targets.push(targetObject);
}
// Method to get the next target for a food item
getNextTarget(): THREE.Object3D | null {
// Return and remove the first target from the targets array, or null if there are no targets
return this.targets.shift() || null;
}
}
// Export a single instance of FoodCoordinateManager
export const foodCoordinateManagerInstance = new FoodCoordinateManager(); ```
that coordinate manager communicates with the redspheregenerator component like so ```ts
import * as THREE from āthreeā;
import { Behaviour, GameObject } from ā@needle-tools/engineā;
import { getWorldPosition } from ā@needle-tools/engineā;
import { myEmitterInstance } from āā¦/ā¦/include/controlscripts/MyEmitter.jsā;
import { foodCoordinateManagerInstance } from ā./FoodCoordinateManagerā; // Adjust the import path accordingly
export class RedSphereGenerator extends Behaviour {
private redMaterial = new THREE.MeshStandardMaterial({ color: 0xff0000 });
private sphereGeometry = new THREE.SphereGeometry(0.05);
awake() {
// Listen for the 'itemAddedToPlate' event emitted by myEmitterInstance
myEmitterInstance.on('itemAddedToPlate', this.generateRedSphere.bind(this));
}
private generateRedSphere(itemName: string, itemPosition: THREE.Vector3, itemGameObject: GameObject): void {
// Get the next target position from the FoodCoordinateManager
const targetObject = foodCoordinateManagerInstance.getNextTarget();
if (!targetObject) {
console.warn('No target available for red sphere generation.');
return;
}
const redSphere = new GameObject();
const sphereMesh = new THREE.Mesh(this.sphereGeometry, this.redMaterial);
redSphere.add(sphereMesh);
redSphere.position.copy(targetObject.position); // Set the position of the red sphere to the target position
redSphere.scale.set(0.25, 0.25, 0.25);
this.gameObject.add(redSphere);
console.log(`Red sphere generated at target position due to ${itemName} being added!`);
}
but, practically this is not correct, because the system is not getting the actual in scene position of the food item, so it leads to the red sphere being spawned in a position that isnāt practically useful . If anyone can help point me in the right direction, so that I can solve this issue Iād be extremely appreciative.
Hi, the position here is local space but above that you get the world space of an item. I would guess this is the error and why your object is displayed in the wrong place. You can use setWorldPosition instead of doing position.copy(...)
If youāre familiar with Unity this might be unexpected (since position in Unity is worldspace and localPosition is local space - but in three.js thereās only a position property which is in localspace of each object (the same is true for rotation/quaternion/scale)
Knowing that you donāt get paid nearly enough to help me with my stupid little problems, would you be able to give me a little example of an implementation ?
I guess what I donāt understand is how can the gameobject that has been moved onto the plate have a position different than the position of the object that is cloning said gameobjects position
const accuratePosition = getWorldPosition(gameObject);
// Create a new target position directly above the added food item
const newTargetPosition = accuratePosition.clone();
newTargetPosition.y += 0.05; // Adjust the Y value to set the height of the new target
// Create a new GameObject to represent the target
const targetObject = new GameObject();
setWorldPosition(targetObject, newTargetPosition);
(you need to import setWorldPosition from needle-engine just as you do with getWorldPosition)