Unity3d 单击时Unity Unet更新转换

Unity3d 单击时Unity Unet更新转换,unity3d,unity3d-unet,unet,Unity3d,Unity3d Unet,Unet,我目前正在尝试制作一个小的绘图游戏,两名玩家可以在网络上同时绘图 我用一个GameObject和一个TrailRenderer来画线 现在,两台机器上只显示主机播放器的图形 如果客户端玩家单击并尝试绘制,我可以看到生成了一个新对象,但转换没有得到更新。生成的预置有一个NetworkIdentity(选中本地玩家权限)和NetworkTransform。以下脚本由两个玩家生成,并且还具有NetworkIdentity(选中本地玩家权限) 我认为我实际上在使用CmdTrailUpdate以及如何处理

我目前正在尝试制作一个小的绘图游戏,两名玩家可以在网络上同时绘图

我用一个
GameObject
和一个
TrailRenderer
来画线

现在,两台机器上只显示主机播放器的图形

如果客户端玩家单击并尝试绘制,我可以看到生成了一个新对象,但转换没有得到更新。生成的预置有一个
NetworkIdentity
(选中本地玩家权限)和
NetworkTransform
。以下脚本由两个玩家生成,并且还具有
NetworkIdentity
(选中本地玩家权限)

我认为我实际上在使用
CmdTrailUpdate
以及如何处理它时犯了一些错误,但我真的不知道是什么原因

使用系统集合;
使用System.Collections.Generic;
使用UnityEngine;
使用UnityEngine。联网;
公共类TrailDrawer:网络行为{
私人飞机;
私人游戏对象;
私人Vector3 startPos;
公共游戏对象轨迹;
公开作废开始()
{
objPlane=新平面(Camera.main.transform.forward*-1,this.transform.position);
}
//每帧调用一次更新
void FixedUpdate(){
if(IsLocalLayer){
if(Input.GetMouseButtonDown(0)){
CmdSpawn();
}else if(Input.GetMouseButton(0)){
CmdTrailUpdate();
}
}
}
[命令]
私有void CmdTrailUpdate(){
Ray mRay=Camera.main.ScreenPointRoay(输入.鼠标位置);
浮动射线距离;
if(objPlane.Raycast(mRay,外光线距离)){
currentTrail.transform.position=mRay.GetPoint(光线距离);
}
}
[命令]
私有void CmdSpawn(){
Ray mRay=Camera.main.ScreenPointRoay(输入.鼠标位置);
浮动射线距离;
if(objPlane.Raycast(mRay,外光线距离)){
startPos=mRay.GetPoint(光线距离);
currentTrail=(游戏对象)实例化(trail、startPos、Quaternion.identity);
NetworkServer.Spawn(currentTrail);
}
}
}

我想你的问题是:

[命令]
表示:从客户端调用方法,但仅在服务器上执行

=>您仅在服务器上执行
CmdSpawn
CmdTrailUpdate
两种方法

但是:

  • 服务器应该如何知道客户端的
    输入。鼠标位置

  • 您不希望从服务器的
    camera.main
    进行光线投射,而是从客户端的

  • 解决方案:

  • 在客户端本地执行这两项操作,并将位置作为
    [Cmd]
    方法上的参数传递给服务器

  • 既然您说对象已经有了
    NetworkTransform
    ,您就不需要将更新后的位置传输到服务器,因为
    NetworkTransform
    已经为您完成了。因此,无需从客户端调用
    CmdTrailUpdate

    但是:生成对象后,您必须告诉正在调用
    CmdSpawn
    的客户端,这是他的本地
    currentTrail
    ,他必须更新的位置。我只需将调用的客户端
    gameObject
    也传递给
    CmdSpawn
    方法,然后在服务器上调用
    [ClientRpc]
    方法来设置此客户端的
    currentTrail
    对象

  • (我在这里假设,您发布的脚本直接附加到玩家对象。如果不是这样,那么您必须以另一种方式获取玩家的
    gameObject
    ,而不是带有
    this.gameObject
    的行。)

    void FixedUpdate(){
    如果(!isLocalPlayer)返回;
    if(Input.GetMouseButtonDown(0)){
    //在客户端上执行光线投射和计算
    Ray mRay=Camera.main.ScreenPointRoay(输入.鼠标位置);
    浮动射线距离;
    if(objPlane.Raycast(mRay,外光线距离)){
    startPos=mRay.GetPoint(光线距离);
    //传递调用玩家游戏对象和
    //定位为服务器的参数
    CmdSpawn(this.gameObject,startPos);
    }
    }else if(Input.GetMouseButton(0)){
    //在客户端上执行光线投射和计算
    Ray mRay=Camera.main.ScreenPointRoay(输入.鼠标位置);
    浮动射线距离;
    if(objPlane.Raycast(mRay,外光线距离)){
    //仅更新客户端上的本地对象
    //因为他们已经连接了NetworkTransform
    //无论如何,它都将在服务器(和其他客户端)上更新
    currentTrail.transform.position=mRay.GetPoint(光线距离);
    }
    }
    }
    [命令]
    私有void CmdSpawn(游戏对象调用客户端,向量3 spawnPosition){
    //请注意,这仅在服务器上设置currentTrail
    currentTrail=(游戏对象)实例化(trail、spawnPosition、Quaternion.identity);
    NetworkServer.Spawn(currentTrail);
    //在调用客户端中设置currentTrail
    RpcSetCurrentTrail(呼叫客户端,currentTrail);
    }
    //ClientRpc在某种程度上与命令相反
    //它从服务器调用,但仅在所有客户端上执行
    //因此,我们必须确保它只在客户机上执行
    //谁最初调用了CmdSpawn方法
    [客户端RPC]
    私有void RpcSetCurrentTrail(游戏对象客户端,游戏对象轨迹){
    //如果此客户机不是调用spawn方法的客户机,则不执行任何操作
    如果(this.gameObject!=客户端)返回;
    //如果调用客户机本身就是服务器,则也不执行任何操作
    //->他是主持人
    if(isServer)返回;
    //在客户端上设置currentTrail
    currentTrail=trail;
    }
    
    我想你的问题是: