Category - Unity3d

2022-10-14 17:52:46    118    0    0
  1. public class ctrl : MonoBehaviour
  2. {
  3. [SerializeField]
  4. PostProcessVolume m_postpVol;
  5. [SerializeField]
  6. Camera m_Cam;
  7. DepthOfField m_Df;
  8. void Awake()
  9. {
  10. m_postpVol.profile.TryGetSettings(out m_Df);
  11. }
  12. //焦距设置为摄像机和玩家的位置
  13. void Update()
  14. {
  15. m_Df.focusDistance.value = Vector3.Distance(Player.position, m_Cam.transform.position);
  16. }
  17. }
2022-05-26 10:36:31    236    0    0

将unity缓存三个文件夹

C:\Users\你用户名\AppData\Local\Unity
C:\Users\你用户名\AppData\LocalLow\Unity
C:\Users\你用户名\AppData\Roaming\Unity

分别拷贝到 别的盘符,如

F:\UnityCache\LocalUnity
F:\UnityCache\LocalLowUnity
F:\UnityCache\RoaMingUnity

 

删除源文件夹,添加软链接

mklink /j C:\Users\你用户名\AppData\Local\Unity F:\UnityCache\LocalUnity
mklink /j C:\Users\你用户名\AppData\LocalLow\Unity F:\UnityCache\LocalLowUnity
mklink /j C:\Users\你用户名\AppData\Roaming\Unity F:\UnityCache\RoaMingUnity

 

管理员身份运行CMD,并执行, 结果:

Microsoft Windows [版本 10.0.19044.1706]
(c) Microsoft Corporation。保留所有权利。

C:\Users\Admin>mklink /j C:\Users\Admin\AppData\Local\Unity F:\UnityCache\LocalUnity
为 C:\Users\Admin\AppData\Local\Unity <<===>> F:\UnityCache\LocalUnity 创建的联接

C:\Users\Admin>mklink /j C:\Users\Admin\AppData\LocalLow\Unity F:\UnityCache\LocalLowUnity
为 C:\Users\Admin\AppData\LocalLow\Unity <<===>> F:\UnityCache\LocalLowUnity 创建的联接

C:\Users\Admin>mklink /j C:\Users\Admin\AppData\Roaming\Unity F:\UnityCache\RoaMingUnity
为 C:\Users\Admin\AppData\Roaming\Unity <<===>> F:\UnityCac

2022-05-19 11:32:19    624    0    0

我写一个简单明了的范例
比如我们要同步一个V3类型的数据,
数据来源:客户端操作
目标:同步所有客户端的 Vector3 V3FromNetwork 变量值

流程为

本地客户端客户端(isLocalPlayer为true)进行操作
↓↓↓
调用[Command]修饰的方法SetTestV3,(SetTestV3就具备了往服务器上报的特性)
↓↓↓
服务器执行SetTestV3函数内容
↓↓↓
服务器修改TestV3值时,由于具备标识[SyncVar(hook = nameof(ChangeTestV3))],通知所有客户端的该对象脚本中调用ChangeTestV3
↓↓↓
客户端调用ChangeTestV3,最终成功修改到值。

代码如下

  1. using UnityEngine;
  2. using Mirror;
  3. public class Player : NetworkBehaviour
  4. {
  5. void Update()
  6. {
  7. if (!isLocalPlayer) return;//只操作本地客户端
  8. Vector3 V3SendData = new Vector3(Input.GetAxis("Vertical") * Time.deltaTime, 0, Input.GetAxis("Horizontal") * Time.deltaTime);
  9. SetTestV3(V3SendData);
  10. }
  11. [Command]//客户端上行标识
  12. public void SetTestV3(Vector3 v)
  13. {
  14. //服务端执行内容
  15. TestV3 = v;
  16. }
  17. [SyncVar(hook = nameof(ChangeTestV3))]//服务端修改触发客户端调用hook函数
  18. public Vector3 TestV3 = Vector3.zero;
  19. public void ChangeTestV3(Vector3 oldv, Vector3 newc)
  20. {
  21. //客户端执行内容
2022-05-17 17:13:05    1020    0    0

标签: Command 从客户端发送到服务器,服务器执行

  1. [Command]
  2. void ABC(){}

注意点
1,方法可以带参数,但需要序列化
2,客户端只能发送属于自己的对象的方法
如果都允许,则设置为不验证:

  1. [Command(requiresAuthority = false)]

标签: ClientRpc 从服务器发送到,客户端执行

  1. [ClientRpc]
  2. void ABC(){}

标签: TargetRpc 从服务器发送到,指定的客户端执行

  1. [TargetRpc]
  2. void TargetRemoteDamaged(NetworkConnection target, int damage){}

PS:第一个参数可忽略,默认发给自己,也就是调用此方法的客户端实体
PS:如果第一个参数有,则发给指定,目标

总结

[Command] 由客户端调用,内容服务器执行;
[ClientRpc]和[TargetRpc]由服务器调用,内容客户端执行;
但[TargetRpc]是指定目标发送,[ClientRpc]是都发送。

2022-05-17 16:05:14    431    0    0

一,用SyncVar进行同步

函数标签[SyncVar]
用标签来标记变量,被改变时时,同步给其他客户端;
可指定Hook指定回调函数,并返回旧值和新值

如:

  1. [SyncVar(hook = nameof(ChangeColor))]
  2. Color pcolor = Color.white;
  3. void ChangeColor(Color oldc, Color newc)
  4. {
  5. }

即pcolor发生变化时,客户端都调用ChangeColor

PS:使用此特性标注的变量,只应该在服务器上对此变量进行更改,而通过hook在客户端作用此更改
然后hook,仅会再客户端调用,如果服务器是OnlyServer模式则不会调用

使用脚本让服务器控制所有客户端颜色变化的代码

  1. using UnityEngine;
  2. using Mirror;
  3. public class PlayerController : NetworkBehaviour
  4. {
  5. [SyncVar(hook = nameof(ChangeColor))]
  6. Color pcolor = Color.white;
  7. Rigidbody rb;
  8. MaterialPropertyBlock prop;
  9. /// <summary>
  10. /// 客户端收到同步时调用
  11. /// </summary>
  12. /// <param name="oldc"></param>
  13. /// <param name="newc"></param>
  14. void ChangeColor(Color oldc, Color newc)
  15. {
  16. Debug.Log("更新为新颜色");
  17. prop.SetColor("_Color", newc);
  18. GetComponent<Renderer>().SetPropertyBlock(prop);
  19. }
  20. private void Awake()
  21. {
  22. rb = GetComponent<Rigidbody>();
  23. prop = new MaterialPropert
2022-05-17 14:39:49    89    0    0

个人理解的两种方式

方式一 房间模式:(自带一个需要准备等待功能的模式)

创建场景

Offline,Room,GamePlay
作用:区分Online和非Online模式

准备脚本

通过create->mirror 创建如下脚本

[NetworkRoomManager]
作用:房间管理,有房间创建,连接,等房间相关的回调
基于房间补充相关逻辑

[NetworkRoomPlayer]
作用:包含房间里的玩家状态和回调

[NetworkBehaviour]

创建多个NetworkBehaviour :
如,NetworkBehaviour 改为 myPlayer
NetworkBehaviour 改为 myItem
作用: 有了本脚本,才会标记告知服务器需要同步本对象
继承了MonoBehaviour的Network脚本,
可以衔接Update等函数书写自己的逻辑,
取到玩家网络状态,如

  1. isServer
  2. 如果是此对象是在服务器上运行的(包括服务器+客户端一体的主机),则返回true
  3. isServerOnly
  4. 如果是此对象仅在服务器运行的(而非包含客户端的主机),则返回true
  5. isClient
  6. 如果此对象已经存在,且处于客户端上(包括主机的客户端),则返回true
  7. 等等

准备预制体

创建空物体,命名为RoomPlayer,挂MyNetworkRoomPlayer
创建胶囊,命名为Player,挂MyPlayer
创建Cube, 命名为Item 挂myItem

客户端操作权限:
Player预制体上的挂NetworkTransform脚本的ClientAuthority 一定要勾选上,否则没有客户端操作其状态的权限。

在玩家或者我物体预制体上挂载,NetworkIdentity 脚本
(往往挂载其他Mirror脚本时,NetworkIdentity脚本会自动挂载)

创建管理组件

1.在Offline场景空物体,挂MyNetworkRoomManager脚本
挂载好在线和离线对应的场景,Player预制体,以及房间相关的预制体和场景
title

2.同时

2021-04-10 15:31:04    90    1    0

比起 Unity集成的Navigation中的OffMeshLink,扩展的NavMeshComponents中NavMeshLink,会强大好用许多,

2021-04-10 14:49:37    278    1    0

·比起 Unity集成的Navigation ,扩展的NavMeshComponents,扩展了不少方便的功能

比如同一个场景,更方便的创建不同的烘培网格

拷贝Github克隆的Asset中NavMeshComponents目录到你的项目Asset
title

title

创建一个场景,
然后在场景根节点下 挂载脚本提供的NavMeshSurface.cs

title

而且可以挂载多个

打开Agent 设置
title

设置不同体型的宽高配置
title

title

然后回到地形对象的Inspector面板,选择不同的配置
title
分别点击Bake,进行烘培得到两个不同的结果
title

此外还可以选择渲染的layer层级,
title
或者你也可以选择渲染范围:
title

然后就是移动了
创建两个玩家胶囊提
分别创建寻路导航代理组件
title

挂载移动脚本到两个player胶囊提上

  1. public class Player : MonoBehaviour
  2. {
  3. // Start is called before the first frame update
  4. void Start()
  5. {
  6. agent = GetComponent<NavMeshAgent>();
  7. }
  8. private NavMeshAgent agent;
  9. // Update is called once per frame
  10. void Update()
  11. {
  12. if (Input.GetMouseButtonDown(0))
  13. {
  14. Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
  15. RaycastHit hit;
  16. if (Physics.Raycast(ray, out hit))
  17. {
  18. agent.SetDestination(hit.point);
  19. }
  20. }
  21. }
  22. }

鼠标控制移动,两个角色则会走对应体型配置的烘培寻路

2021-04-10 14:49:10    68    0    0

unity各类压缩方式性能探究,陈皓2020-12-24
版本:2019.2.6
打包对象:角色“白民“预制体

相关记录:
打包时间:包含依赖资源自动查找时间,(性能差异应关注秒级以下时间!)
读取时间包含:AssetBundleCreateRequest,AssetBundle,AssetBundleRequest 流程的时间
Unity读取机制:不压缩或者LZMA格式,在unity加载后内存中会处理成LZ4

压缩方式 大小 打包处理时间(s) 读取时间(x)
————————————————————————————
不压缩 1622k 13.3640811 0.5399647
13.5700311 0.5609903
13.5495395 0.6687141

unity-LZ4 948k 13.7928144 0.5434550
13.6893117 0.5586369
13.7192026 0.5431827

unity-LZMA 689k 14.7435645 0.8226537
14.0434290 0.7473594
14.9094666 0.8506351

外部压缩方式,7zip,zip待测

抛开Unity本身流程,打包时间减去10秒左右,读取减去0.4秒左右,分析,
得:
1,一般场景:
直接使用LZ4比较合适,不明显影响加载速度的情况下,容量还是可以减少40%。
2,网络下载场景:
使用LZMA文件更小,减少传输量,提升下载速度。影响加载速度。
3,思考,同时兼顾传输量小和加载速度的方案:
AB包不使用Unity内部压缩,或者仅使用LZ4。保证加载速度。
AB包打包后使用外部类库(7zip),进行进行高压。传至文件服务器。文件传输显著减少。
由更新器下载后在缓存中解压高压文件,释放出压缩率底的文件到StreamA