FishNet和常规网络手游不太一样他是可以将客户端和服务器写成一套代码的也就是客户端也可以作为服务器C#特性[ServerRpc] 方法添加了这个特性后这个方法只会在服务端执行由客户端调用但是客户端不会执行这个方法[ObserversRpc] 添加了这个特性的方法只会在客户端运行并且由服务端调用服务端调用后所有客户端都会被执行[TargetRpc] 添加了这个特性后只会在客户端运行由服务器调用并且需要指定一个NetworkConnection只会给这个connection调用对于ObserverRpc的使用情况如下假如说现在客户端需要有一个playerId并且每个玩家都要有。如果我是基于TargetRpc如下[TargetRpc]//这是错误使用publicvoidSyncData(intplayerId,intteamId,stringplayerName,boolisRobot){DatanewPlayerData(){playerIdplayerId,teamIdteamId,playerNameplayerName,isRobotisRobot};Debug.Log(玩家数据同步完成 idplayerId);}那么当玩家生成后服务器调用SyncData时只有当前客户端的Owner能同步到数据其他玩家没有反应。比如现在有3个客户端一共3个玩家ABC那么当我玩家A登录的时候客户端A会收到服务器发来的SyncData A当玩家B登录的时候客户端A并不会收到任何消息也就是在客户端A中玩家BC完全是没有数据的他们的数据只在客户端B和客户端C中。这时就需要用ObserversRpc将SyncData改为ObserversRpc后玩家A登录时客户端A能正常收到消息当B登录时客户端A也可以收到SyncData并且playerId是B的playerId所以ObserversRpc的原理就是将这次数据发送给所有客户端并且找到他们对应的player对象的对应方法。并不是说我将这次数据发送给这个客户端的所有player对象那这样所有的player都拿到的是一个数据了我们平时开发有2种办法实现FishNet1.所有代码集成在一个项目中服务器和客户端逻辑写在一起2.服务器和客户端分成2个项目分别处理逻辑分成2个项目的时候需要注意踩坑点1.NetworkBehavior对象必须客户端和服务器同时有并且类名完全一样。比如一个Player上有PlayerHealth脚本那么客户端和服务器都得挂上这个脚本并且名字不能改否则会报错提示协议错误其他的踩坑点1.Player上有Camera那么客户端只有isOwner为true的情况才开启这个Camera并且其他玩家Camera必须默认隐藏不然会导致客户端的视角错乱因为会有很多相机存在场景里unity不知道是哪个2.NetworkTransform如果勾选了Client Authoritative那么只会由客户端控制Transform服务器自己拖动坐标是没有用的如果没有勾选那么就是由服务器控制Transform