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
Original Post on Discord
by user 962902844049096704
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.
by user 962902844049096704
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(); ```
by user 962902844049096704
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!`);
}
}
*by user 962902844049096704*
and technically this is all working correctly as reported by the console.
by user 962902844049096704
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.
by user 962902844049096704
Iām sure Iām just missing something really obvious here.
by user 962902844049096704
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 ? 
by user 962902844049096704
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
by user 962902844049096704
Can you try changing the code above to this:
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)
Yep, I pushed those changed and nothing happened, which I assumed because I was implementing incorrectly, but no⦠no luck yet
by user 962902844049096704