Hi everyone one!
I am trying to move a cube on a scene by clicking on a plane using lerp. It works but the cube position is not replicated in other screens. But if I move the cube using DragControls component it works fine.
Is that a way to replicate some GameObject position without using DragControls component?
Original Post on Discord
by user 918470773134483507
marcel
(marwi)
January 7, 2023, 12:00am
2
Hey, i think you need to request ownership on the synctransform - its what the drag controls does when you start the drag. Im not at the pc anymore so can not look it up right now but take a look at the drag controls source
marcel
(marwi)
January 7, 2023, 12:00am
3
(you can click the blue link on drag controls in unity to open the typescript source)
marcel
(marwi)
January 7, 2023, 12:00am
4
(in other scenes i assume you mean for other clients in a networked room / multiple people visiting the same url, right?)
marcel
(marwi)
January 7, 2023, 12:00am
5
SyncTransform.requestOwnership() is the method you need to call
Thank God! It worked!
by user 918470773134483507
Here the component that I wrote:
import { Behaviour, GameObject, serializable, SyncedTransform } from "@needle-tools/engine"
import { IPointerEventHandler, PointerEventData } from "@needle-tools/engine/engine-components/ui/PointerEvents";
import { Vector3 } from "three"
export class Teste extends Behaviour implements IPointerEventHandler {
@serializable(GameObject)
cube?: GameObject;
lerpAlpha = 1
lerpDestination: Vector3 | undefined
start() {
}
onPointerClick(args: PointerEventData) {
this.lerpAlpha = 0;
this.lerpDestination = this.context.physics.raycast()[0].point;
}
update() {
if (this.lerpAlpha < 1) {
GameObject.getComponentInChildren(this.cube, SyncedTransform)?.requestOwnership()
this.cube?.position.lerp(this.lerpDestination, this.lerpAlpha += 1)
}
}
}
by user 918470773134483507
Thanks @marcel to answer me so quickly!
by user 918470773134483507
marcel
(marwi)
January 7, 2023, 12:00am
9
Sure thing.
Could you wrap your code in 3 backticks that way its easier to read
You can also add ts after the first 3 ` to add typescript syntax highlighting
Like this:
marcel
(marwi)
January 7, 2023, 12:00am
10
Oh another tip: you should only request ownership once when you start doing something (e.g. onPointerClick)
marcel
(marwi)
January 7, 2023, 12:00am
11
Otherwise youll send network requests every frame which could get expensive and also make the backend slow if you have a lot of those cases
Hi again @marcel
Now I am trying to move two objects on the scene and replicate their positions. But when I try, they has the same position on the replicated screen.
Here the component code:
import { AssetReference, Behaviour, GameObject, serializable, SyncedTransform } from "@needle-tools/engine"
import { IPointerEventHandler } from "@needle-tools/engine/engine-components/ui/PointerEvents";
import { IGameObject } from "@needle-tools/engine/engine/engine_types";
import { Object3D } from "three"
export class Teste extends Behaviour implements IPointerEventHandler {
@serializable(AssetReference)
cube?: AssetReference;
@serializable(AssetReference)
capsule?: AssetReference;
private instantiatedCube: IGameObject | undefined;
private instantiatedCapsule: IGameObject | undefined;
private i = 0;
async start() {
this.instantiatedCube = await this.cube?.instantiate() as IGameObject;
this.instantiatedCube.addNewComponent(SyncedTransform);
this.instantiatedCapsule = await this.capsule?.instantiate() as IGameObject;
this.instantiatedCapsule.addNewComponent(SyncedTransform);
}
// @ts-ignore
async onPointerClick(args: PointerEventData) {
if (this.i++ % 2) {
await this.instantiatedCube?.getComponent(SyncedTransform)?.requestOwnership();
this.instantiatedCube?.position.setY(this.instantiatedCube.position.y + 0.1);
} else {
await this.instantiatedCapsule?.getComponent(SyncedTransform)?.requestOwnership();
this.instantiatedCapsule?.position.setY(this.instantiatedCapsule.position.y + 0.1);
}
}
update() {
}
}
Can you help me to replicate the movement correctly?
by user 918470773134483507
marcel
(marwi)
January 10, 2023, 12:00am
13
You need to give the synced transforms a guid for each object. Use an InstanceIdProvider for it (i can give you better info later, im not yet at the pc). You should initialize it with a known seed (e.g. new InstanceIdProvider(this.guid))
Basically what happens is (i think) that the synced transform component is created with the same guid and so they take the networking events for both objects.
I didn’t understand how to use the InstaceIdProvider in my code. Can you be more specific?
by user 918470773134483507
marcel
(marwi)
January 10, 2023, 12:00am
15
So in general if you dont need to add components on the fly like you do above you could also just add it in Unity as a component on your prefab (e.g. add a SyncedTransform component on the cube
asset that you reference).
marcel
(marwi)
January 10, 2023, 12:00am
16
Here is a little codesnippet that should work for how you do it right now:
const idProvider = new InstantiateIdProvider(this.guid);
const st = GameObject.addNewComponent(this.gameObject, SyncedTransform, false);
st.guid = idProvider.generateUUID();
marcel
(marwi)
January 10, 2023, 12:00am
17
the this.guid
I pass in the id provider here is the seed (it can be either a string or a number)
I am adding components in this way because I intend to download the assets from the internet in the project that I am working, so then I will not have access to them through Unity editor
by user 918470773134483507
This part brakes my code with ‘Invalid assignment target’ error
st.guid = idProvider.generateUUID();
by user 918470773134483507