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" ...
随机推荐
- WebSocket入门及示例
前言 一直在想要不要写下这篇,因为网上关于websocket的介绍和使用的好文实在太多太多,例如有这篇和这篇. 但我不管了,写下来,这样我就不用在想使用的时候总是去翻写过的源码了. 先回答几个简单的问 ...
- 从本地上传项目到 github 以及从github 下载项目到本地环境
前置条件:成功安装github,安装成功后,要配置密钥,不然上传不成功,要报错 具体上传步骤: git init //初始化 git add 文件名 //更新文件 git commit -m ...
- “天龙八步”细说浏览器输入URL后发生了什么
本文摘要: 1.DNS域名解析: 2.建立TCP连接: 3.发送HTTP请求: 4.服务器处理请求: 5.返回响应结果: 6.关闭TCP连接: 7.浏览器解析HTML: 8.浏览器布局渲染: 总结 输 ...
- 计数排序之python
话说,一口气不能吃个胖子, 一次性 学习 计数排序, 也确实容易消化不良. 下面,我们逐步学习下计数排序. 1. 已知一个简单列表 l1 = [5, 4, 3], 分析下这个列表的情况 5 > ...
- GUI学习之十——QFrame和的QAbstractScrollArea学习总结
上一章我们学习了单行的文本框QLineEdit类,下面我们要为多行的文本框的学习坐下准备,总结一下QFrame类和QAbstractScrollArea类 一.QFrame类 1.描述 QFrame的 ...
- RF自动化测试
1.自动化分层:UI层实现界面自动化,Service层实现接口自动化,Unit层实现单元测试. 2.UI自动化测试常见的工具有:QTP,AutoIt,Selenium.Selenium是做Web测试最 ...
- node vue 项目部署问题汇总
场景:vue-router为history模式,不带项目名访问的部署,如果资源是用相对路径加载,则资源匹配路径不对 一.带项目名称访问,如部署到tomcat服务上 webpack: build/ut ...
- mysql数据库保存sesison会话
<?php header('Content-type:text/html;charset=gbk;'); date_default_timezone_set('PRC'); class db{ ...
- 【转】TCP/UDP简易通信框架源码,支持轻松管理多个TCP服务端(客户端)、UDP客户端
[转]TCP/UDP简易通信框架源码,支持轻松管理多个TCP服务端(客户端).UDP客户端 目录 说明 TCP/UDP通信主要结构 管理多个Socket的解决方案 框架中TCP部分的使用 框架中UDP ...
- 距离不是一个连续的物理量(Distance is not a continuous physical quantity)
量子距:不同于现有物理学的长度计量.量子距,空间中的两个粒子之间的距离并不是连续的,而是某个单位距(量子单位距)的整数倍,而这个距离被称为量子距. Quantum distance: Length m ...