OS: Windows 11
Unity: 2022.3.15f1
Needle Version: 3.47.10 NE: 3.48.3
Hi Hoping you’re all doing really fine, It’s me DiegoEloko again hehe.
I’m aware that currently, Needle doesn’t support physics networking but I remember that a guy said something about network an object’s position with the aim of reproduce locally the same physics. Now, I’m trying to do a multiplayer soccer-like test where the players can bounce a ball against walls and against players. I don’t know almost nothing about physics but I could get a bounce reaction like in a billiard ball (thats the movement which I am looking for) and let me explain what do I have:
- The ball has a
NetworkBounce
script. - The general idea : Each time that the ball bounce with a player (an object with a
PlayerState
script) it checks if that player is local, if that is true then it bounce normally (in local) and sends the information about the normal vector of the contact to the other players. - The other players receive that normal and calculate its own physics.
This is my current script :
import { Behaviour, Collision,Rigidbody,serializable,} from "@needle-tools/engine";
import {NetworkConnection, PlayerState} from "@needle-tools/engine";
import { Vector3 } from "three";
class VectorData{
x : number;
y : number;
z : number;
constructor(x:number,y:number,z:number){
this.x=x;
this.y=y;
this.z=z;
}
}
export class NetworkBounce extends Behaviour{
@serializable()
rb! : Rigidbody;
private surfaceNormal : Vector3 = new Vector3(0,0,0);
private net !: NetworkConnection;
start(): void {
this.net = this.context.connection;
this.setBeginListen();
this.rb= this.gameObject.getComponent(Rigidbody)!;
}
update(): void {
if(this.context.input.isKeyUp("z")){
console.log("Initial impulse");
if(this.rb){
//this.rb.applyForce(new Vector3(1,0,1));
this.rb.applyImpulse(new Vector3(3,0,3));
//EXPERIMENTAL>>>
this.net.send("initialImpulse", new VectorData(0,0,0))
}
}
}
onCollisionEnter(col: Collision) {
//If hit a player
if(col.gameObject.getComponent(PlayerState)!){
//Only if the player is in local, it broadcast the collision with the normal information
if(col.gameObject.getComponent(PlayerState)!.isLocalPlayer==true){
//Local bounce
this.bounce(col);
//Send information
this.sendNormalSuperficieData(this.surfaceNormal);
}else{
//Nothing happens
}
}else{
//Then it bounce with a static object
this.bounce(col);
}
}
bounce(col: Collision){
this.surfaceNormal = col.contacts[0].normal;
//console.log("Normal local: ("+this.surfaceNormal.x+", "+this.surfaceNormal.y+", "+this.surfaceNormal.z+")");
//this.sendNormalSuperficieData(this.surfaceNormal);
const velNormal = this.rb.getVelocity().dot(this.surfaceNormal);
const normalMultiplied = this.surfaceNormal.multiplyScalar(2*velNormal);
const newVelocity = this.rb.getVelocity().sub(normalMultiplied);
// console.log("Velocidad local calculada: ("+newVelocity.x+", "+newVelocity.y+", "+newVelocity.z+")");
this.rb.setVelocity(newVelocity)
}
bounceByNormal(){
//console.log(this.surfaceNormal);
//console.log("Normal recibida: ("+this.surfaceNormal.x+", "+this.surfaceNormal.y+", "+this.surfaceNormal.z+")");
const velNormal = this.rb.getVelocity().dot(this.surfaceNormal);
const normalMultiplied = this.surfaceNormal.multiplyScalar(2*velNormal);
const newVelocity = this.rb.getVelocity().sub(normalMultiplied);
// console.log("Velocidad recibida calculada: ("+newVelocity.x+", "+newVelocity.y+", "+newVelocity.z+")");
this.rb.setVelocity(newVelocity)
// console.log("Velocidad recibida final: "+this.rb.getVelocity());
// console.log("DEBERIA APLICAR NUEVA VELOCIDAD");
// console.log(this.rb.getVelocity());
}
//NetworkBehavior :
sendNormalSuperficieData(normal :Vector3){
this.net.send("normalData", new VectorData(normal.x, normal.y, normal.z))
}
setBeginListen(){
this.net.beginListen("normalData",(data)=>{
this.surfaceNormal.x = data.x;
this.surfaceNormal.y = data.y;
this.surfaceNormal.z = data.z;
this.bounceByNormal();
})
this.net.beginListen("initialImpulse",(data)=>{
this.rb.applyImpulse(new Vector3(3,0,3));
})
}
setStopListen(){
this.net.stopListen("normalData",(data)=>{})
this.net.stopListen("initialImpulse",(data)=>{})
}
onDisable(): void {
this.setStopListen();
}
}
The problem is : Let it be my two players P1 and P2. While I’m in multiplayer, I produce an initial impulse
which produce a movement to the ball which is the same in both player while any of the player interact with the ball.
When P1 hits the ball, locally, the movement is not the expected but when the remote clone of P2 in the local context of P2 hits the ball , the bounce is the expected. I let you a video about the described behavior : MultiplayerBouncing.mp4 - Google Drive
So, if someone has tried this experiment before and have a clue about how network the bounce of a ball between players, please lets share knowledge