Photon自定义加载Resource之外的资源
PhotonNetwork.cs 结尾添加如下代码:
#region >>> Photon自定义异步加载GameObject
public delegate void CustomLoader(string prefabName, Action<UnityEngine.Object> ac);
public static CustomLoader _loader;
public static void RegisterCustomLoaderToPhoton(CustomLoader loader)
{
_loader = loader;
}
public static bool InstantiateCustom(string prefabName, Vector3 position, Quaternion rotation, byte group, object[] data, Action<GameObject> callback)
{
if (!connected || (InstantiateInRoomOnly && !inRoom))
{
Debug.LogError("Failed to Instantiate prefab: " + prefabName + ". Client should be in a room. Current connectionStateDetailed: " + PhotonNetwork.connectionStateDetailed);
return false;
}
GameObject prefabGo;
if (!UsePrefabCache || !PrefabCache.TryGetValue(prefabName, out prefabGo))
{
_loader(prefabName, (ab) =>
{
prefabGo = (GameObject)(ab);
if (UsePrefabCache)
{
PrefabCache.Add(prefabName, prefabGo);
}
if (prefabGo == null)
{
Debug.LogError("Failed to Instantiate prefab: " + prefabName + ". Verify the Prefab is in a Resources folder (and not in a subfolder)");
callback.Invoke(null);
}
// a scene object instantiated with network visibility has to contain a PhotonView
if (prefabGo.GetComponent<PhotonView>() == null)
{
Debug.LogError("Failed to Instantiate prefab:" + prefabName + ". Prefab must have a PhotonView component.");
callback.Invoke(null);
}
Component[] views = (Component[])prefabGo.GetPhotonViewsInChildren();
int[] viewIDs = new int[views.Length];
for (int i = 0; i < viewIDs.Length; i++)
{
//Debug.Log("Instantiate prefabName: " + prefabName + " player.ID: " + player.ID);
viewIDs[i] = AllocateViewID(player.ID);
}
// Send to others, create info
Hashtable instantiateEvent = networkingPeer.SendInstantiate(prefabName, position, rotation, group, viewIDs, data, false);
// Instantiate the GO locally (but the same way as if it was done via event). This will also cache the instantiationId
callback.Invoke(networkingPeer.DoInstantiate(instantiateEvent, networkingPeer.LocalPlayer, prefabGo));
});
return true;
}
if (prefabGo != null)
{
// a scene object instantiated with network visibility has to contain a PhotonView
if (prefabGo.GetComponent<PhotonView>() == null)
{
Debug.LogError("Failed to Instantiate prefab:" + prefabName + ". Prefab must have a PhotonView component.");
callback.Invoke(null);
}
Component[] views = (Component[])prefabGo.GetPhotonViewsInChildren();
int[] viewIDs = new int[views.Length];
for (int i = 0; i < viewIDs.Length; i++)
{
//Debug.Log("Instantiate prefabName: " + prefabName + " player.ID: " + player.ID);
viewIDs[i] = AllocateViewID(player.ID);
}
// Send to others, create info
Hashtable instantiateEvent = networkingPeer.SendInstantiate(prefabName, position, rotation, group, viewIDs, data, false);
callback.Invoke(networkingPeer.DoInstantiate(instantiateEvent, networkingPeer.LocalPlayer, prefabGo));
return true;
}
return false;
}
#endregion
NetworkingPeer.cs 结尾添加如下代码:
#region >>> Photon自定义异步加载GameObject
public delegate void CustomInstantiatedHandler(PhotonPlayer photonPlayer, GameObject go);
public static event CustomInstantiatedHandler OnCustomInstantiated;
internal void DoInstantiateCustom(Hashtable evData, PhotonPlayer photonPlayer, GameObject resourceGameObject, Action<GameObject> callback)
{
// some values always present:
string prefabName = (string)evData[(byte)0];
int serverTime = (int)evData[(byte)6];
int instantiationId = (int)evData[(byte)7];
Vector3 position;
if (evData.ContainsKey((byte)1))
{
position = (Vector3)evData[(byte)1];
}
else
{
position = Vector3.zero;
}
Quaternion rotation = Quaternion.identity;
if (evData.ContainsKey((byte)2))
{
rotation = (Quaternion)evData[(byte)2];
}
byte group = 0;
if (evData.ContainsKey((byte)3))
{
group = (byte)evData[(byte)3];
}
short objLevelPrefix = 0;
if (evData.ContainsKey((byte)8))
{
objLevelPrefix = (short)evData[(byte)8];
}
int[] viewsIDs;
if (evData.ContainsKey((byte)4))
{
viewsIDs = (int[])evData[(byte)4];
}
else
{
viewsIDs = new int[1] { instantiationId };
}
object[] incomingInstantiationData;
if (evData.ContainsKey((byte)5))
{
incomingInstantiationData = (object[])evData[(byte)5];
}
else
{
incomingInstantiationData = null;
}
// SetReceiving filtering
if (group != 0 && !this.allowedReceivingGroups.Contains(group))
{
if (callback != null)
{
callback.Invoke(null);
}
return; // Ignore group
}
if (ObjectPool != null) // 使用对象池的情况
{
GameObject go = ObjectPool.Instantiate(prefabName, position, rotation);
PhotonView[] photonViews = go.GetPhotonViewsInChildren();
if (photonViews.Length != viewsIDs.Length)
{
throw new Exception("Error in Instantiation! The resource's PhotonView count is not the same as in incoming data.");
}
for (int i = 0; i < photonViews.Length; i++)
{
photonViews[i].didAwake = false;
photonViews[i].viewID = 0;
photonViews[i].prefix = objLevelPrefix;
photonViews[i].instantiationId = instantiationId;
photonViews[i].isRuntimeInstantiated = true;
photonViews[i].instantiationDataField = incomingInstantiationData;
photonViews[i].didAwake = true;
photonViews[i].viewID = viewsIDs[i]; // with didAwake true and viewID == 0, this will also register the view
}
// Send OnPhotonInstantiate callback to newly created GO.
// GO will be enabled when instantiated from Prefab and it does not matter if the script is enabled or disabled.
go.SendMessage(OnPhotonInstantiateString, new PhotonMessageInfo(photonPlayer, serverTime, null), SendMessageOptions.DontRequireReceiver);
if (callback != null)
{
callback.Invoke(go);
if (OnCustomInstantiated != null)
{
OnCustomInstantiated.Invoke(photonPlayer, go);
}
}
return;
}
else
{
// load prefab, if it wasn't loaded before (calling methods might do this)
if (resourceGameObject == null)
{
if (!NetworkingPeer.UsePrefabCache || !NetworkingPeer.PrefabCache.TryGetValue(prefabName, out resourceGameObject))
{
//resourceGameObject = (GameObject)Resources.Load(prefabName, typeof(GameObject));
PhotonNetwork._loader(prefabName, (ab) =>
{
resourceGameObject = (GameObject)ab;
if (NetworkingPeer.UsePrefabCache)
{
NetworkingPeer.PrefabCache.Add(prefabName, resourceGameObject);
}
if (resourceGameObject == null)
{
Debug.LogError("PhotonNetwork error: Could not find the bundle [" + prefabName + "]. Please verify you have this gameobject in a StreamingAssets/Res folder.");
if (callback != null)
{
callback.Invoke(null);
}
return;
}
// now modify the loaded "blueprint" object before it becomes a part of the scene (by instantiating it)
PhotonView[] resourcePVs = resourceGameObject.GetPhotonViewsInChildren();
if (resourcePVs.Length != viewsIDs.Length)
{
throw new Exception("Error in Instantiation! The resource's PhotonView count is not the same as in incoming data.");
}
for (int i = 0; i < viewsIDs.Length; i++)
{
// NOTE instantiating the loaded resource will keep the viewID but would not copy instantiation data, so it's set below
// so we only set the viewID and instantiationId now. the instantiationData can be fetched
resourcePVs[i].viewID = viewsIDs[i];
resourcePVs[i].prefix = objLevelPrefix;
resourcePVs[i].instantiationId = instantiationId;
resourcePVs[i].isRuntimeInstantiated = true;
}
this.StoreInstantiationData(instantiationId, incomingInstantiationData);
// load the resource and set it's values before instantiating it:
GameObject go = (GameObject)GameObject.Instantiate(resourceGameObject, position, rotation);
for (int i = 0; i < viewsIDs.Length; i++)
{
// NOTE instantiating the loaded resource will keep the viewID but would not copy instantiation data, so it's set below
// so we only set the viewID and instantiationId now. the instantiationData can be fetched
resourcePVs[i].viewID = 0;
resourcePVs[i].prefix = -1;
resourcePVs[i].prefixBackup = -1;
resourcePVs[i].instantiationId = -1;
resourcePVs[i].isRuntimeInstantiated = false;
}
this.RemoveInstantiationData(instantiationId);
// Send OnPhotonInstantiate callback to newly created GO.
// GO will be enabled when instantiated from Prefab and it does not matter if the script is enabled or disabled.
go.SendMessage(OnPhotonInstantiateString, new PhotonMessageInfo(photonPlayer, serverTime, null), SendMessageOptions.DontRequireReceiver);
if (callback != null)
{
callback.Invoke(go);
if (OnCustomInstantiated != null)
{
OnCustomInstantiated.Invoke(photonPlayer, go);
}
}
return;
});
}
else
{
// now modify the loaded "blueprint" object before it becomes a part of the scene (by instantiating it)
PhotonView[] resourcePVs = resourceGameObject.GetPhotonViewsInChildren();
if (resourcePVs.Length != viewsIDs.Length)
{
throw new Exception("Error in Instantiation! The resource's PhotonView count is not the same as in incoming data.");
}
for (int i = 0; i < viewsIDs.Length; i++)
{
// NOTE instantiating the loaded resource will keep the viewID but would not copy instantiation data, so it's set below
// so we only set the viewID and instantiationId now. the instantiationData can be fetched
resourcePVs[i].viewID = viewsIDs[i];
resourcePVs[i].prefix = objLevelPrefix;
resourcePVs[i].instantiationId = instantiationId;
resourcePVs[i].isRuntimeInstantiated = true;
}
this.StoreInstantiationData(instantiationId, incomingInstantiationData);
// load the resource and set it's values before instantiating it:
GameObject go = (GameObject)GameObject.Instantiate(resourceGameObject, position, rotation);
for (int i = 0; i < viewsIDs.Length; i++)
{
// NOTE instantiating the loaded resource will keep the viewID but would not copy instantiation data, so it's set below
// so we only set the viewID and instantiationId now. the instantiationData can be fetched
resourcePVs[i].viewID = 0;
resourcePVs[i].prefix = -1;
resourcePVs[i].prefixBackup = -1;
resourcePVs[i].instantiationId = -1;
resourcePVs[i].isRuntimeInstantiated = false;
}
this.RemoveInstantiationData(instantiationId);
// Send OnPhotonInstantiate callback to newly created GO.
// GO will be enabled when instantiated from Prefab and it does not matter if the script is enabled or disabled.
go.SendMessage(OnPhotonInstantiateString, new PhotonMessageInfo(photonPlayer, serverTime, null), SendMessageOptions.DontRequireReceiver);
if (callback != null)
{
callback.Invoke(go);
if (OnCustomInstantiated != null)
{
OnCustomInstantiated.Invoke(photonPlayer, go);
}
}
return;
}
}
}
}
#endregion
NetworkingPeer.cs 第2598行:
屏蔽掉原有的 DoInstantiate 调用,改为 DoInstantiateCustom 调用
//this.DoInstantiate((Hashtable)photonEvent[ParameterCode.Data], originatingPlayer, null);
this.DoInstantiateCustom((Hashtable)photonEvent[ParameterCode.Data], originatingPlayer, null, (go) => {
SendMonoMessage(PhotonNetworkingMessage.OnPhotonInstantiate, new PhotonMessageInfo(originatingPlayer, 0, go.GetComponent<PhotonView>()));
});
回调的意义在于你可以在初始Photon.MonoBehaviour中捕获全局的OnPhotonInstantiate网络物体初始回调,同样的你也可以通过OnCustomInstantiated事件来自定义回调事件行为
之后记得调用 PhotonNetwork.RegisterCustomLoaderToPhoton 注册一个自定义的默认异步资源加载方法给 Photon 即可
Photon自定义加载Resource之外的资源的更多相关文章
- 05.Spring 资源加载 - Resource
基本概念 Spring 把所有能记录信息的载体,如各种类型的文件.二进制流等都称为资源. 对 Spring 开发者来说,最常用的资源就是 Spring 配置文件(通常是一份 XML 格式的文件). S ...
- Java类加载机制及自定义加载器
转载:https://www.cnblogs.com/gdpuzxs/p/7044963.html Java类加载机制及自定义加载器 一:ClassLoader类加载器,主要的作用是将class文件加 ...
- spring3: 4.4 使用路径通配符加载Resource
4.4.1 使用路径通配符加载Resource 前面介绍的资源路径都是非常简单的一个路径匹配一个资源,Spring还提供了一种更强大的Ant模式通配符匹配,从能一个路径匹配一批资源. Ant路径通配 ...
- Android 自定义View修炼-自定义加载进度动画XCLoadingImageView
一.概述 本自定义View,是加载进度动画的自定义View,继承于ImageView来实现,主要实现蒙层加载进度的加载进度效果. 支持水平左右加载和垂直上下加载四个方向,同时也支持自定义蒙层进度颜色. ...
- Android:webView加载h5网页视频,播放不了,以及横屏全屏的问题和实现自定义加载进度条的效果
1.webView加载h5网页视频,播放不了,android3.0之后要在menifest添加硬件加速的属性 android:hardwareAccelerated="true". ...
- Entity Framework 无法加载指定的元数据资源。
ADO.NET Entity Framework发布以来,本人也一直在用,深感好用,忍不住地要感谢微软啊!由于项目结构创建完成后,没怎么改动过,所以一直没出题过问题,可最近由于改动了下命名空间,问题来 ...
- [转] Entity Framework 无法加载指定的元数据资源。
Entity Framework 发布以来,本人也一直在用,深感好用,忍不住地要感谢微软啊!由于项目结构创建完成后,没怎么改动过,所以一直没出题过问题,可最近由于改动了下命名空间,问题来了,正是标题中 ...
- asp.net读取用户控件,自定义加载用户控件
1.自定义加载用户控件 ceshi.aspx页面 <html> <body> <div id="divControls" runat="se ...
- 关于document.write()加载JS等静态资源 和 异步async加载JS
现流行浏览器对于静态资源的预加载 传统的浏览器,对于静态资源加载,会阻塞 HTML 解析器的线程进行,无论内联还是外链. 例如: <script src="test1.js" ...
随机推荐
- java 基础 ----- Arrays 工具类
----- Arrays 工具类是一个比较方便的类 常用的方法 也可以通过jdk文档进行查看 右侧有偶 对一些比较常用的方法进行演示 直接放在main方法中进行测试 ---- equ ...
- Solidity知识点集 — 溢出和下溢
合约安全增强: 溢出和下溢 什么是 溢出 (overflow)? 假设我们有一个 uint8, 只能存储8 bit数据.这意味着我们能存储的最大数字就是二进制 11111111 (或者说十进制的 2^ ...
- 关于接口测试工具postman与DHC介绍
一.Postman背景介绍 用户在开发或者调试网络程序或者是网页B/S模式的程序的时候是需要一些方法来跟踪网页请求的,用户可以使用一些网络的监视工具比如著名的Firebug等网页调试工具.今天给大家介 ...
- Security.ssl-pinning
SSL Pinning 1. What's SSL Pinning? "SSL Pinning is making sure the client checks the server’s c ...
- Debian9安装后的一些配置
第一步 修改源 su root vi /etc/apt/sources.list #建议先备份,不过系统好像有已经备份好的 加入国内源,保存 apt-get update #更新源 ...
- go的包下载失败解决方案
包被墙的方案 1 翻啊的墙 2 gopm 3 https://github.com/golang/net 4 使用国内网站打包 5 export GOPROXY=https://goproxy.io
- [精华][推荐]CAS SSO单点登录服务端客户端实例
1.修改server.xml文件,如下: 注意: 这里使用的是https的认证方式,需要将这个配置放开,并做如下修改: <Connector port="8443" prot ...
- OO第二次作业总结
OO~第二次作业总结 连续三周的电梯作业结束了,总的来说这三次作业做的还算平稳,既没有被刀,也没有刀中别人.那么接下来开始谈谈我对这三次作业的认识. 一.设计策略 我三次作业的设计思路基本上是相同的, ...
- list对象中根据两个参数过滤数据
list对象中根据两个参数过滤数据 List<demo> list = new List<demo>() { ,b=,c=,d= }, ,b=,c=,d= }, ,b=,c=, ...
- 【Selenium】【BugList5】chrom窗口未关闭,又新开窗口,报错:[8564:8632:0522/111825.341:ERROR:persistent_memory_allocator.cc(845)] Corruption detected in shared-memory segment.
环境信息:Windows7 64位 + python 3.6.5 + selenium 3.11.0 +pyCharm 解决方法: 执行 driver = webdriver.Chrome()前必须把 ...