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之外的资源的更多相关文章

  1. 05.Spring 资源加载 - Resource

    基本概念 Spring 把所有能记录信息的载体,如各种类型的文件.二进制流等都称为资源. 对 Spring 开发者来说,最常用的资源就是 Spring 配置文件(通常是一份 XML 格式的文件). S ...

  2. Java类加载机制及自定义加载器

    转载:https://www.cnblogs.com/gdpuzxs/p/7044963.html Java类加载机制及自定义加载器 一:ClassLoader类加载器,主要的作用是将class文件加 ...

  3. spring3: 4.4 使用路径通配符加载Resource

    4.4.1  使用路径通配符加载Resource 前面介绍的资源路径都是非常简单的一个路径匹配一个资源,Spring还提供了一种更强大的Ant模式通配符匹配,从能一个路径匹配一批资源. Ant路径通配 ...

  4. Android 自定义View修炼-自定义加载进度动画XCLoadingImageView

    一.概述 本自定义View,是加载进度动画的自定义View,继承于ImageView来实现,主要实现蒙层加载进度的加载进度效果. 支持水平左右加载和垂直上下加载四个方向,同时也支持自定义蒙层进度颜色. ...

  5. Android:webView加载h5网页视频,播放不了,以及横屏全屏的问题和实现自定义加载进度条的效果

    1.webView加载h5网页视频,播放不了,android3.0之后要在menifest添加硬件加速的属性 android:hardwareAccelerated="true". ...

  6. Entity Framework 无法加载指定的元数据资源。

    ADO.NET Entity Framework发布以来,本人也一直在用,深感好用,忍不住地要感谢微软啊!由于项目结构创建完成后,没怎么改动过,所以一直没出题过问题,可最近由于改动了下命名空间,问题来 ...

  7. [转] Entity Framework 无法加载指定的元数据资源。

    Entity Framework 发布以来,本人也一直在用,深感好用,忍不住地要感谢微软啊!由于项目结构创建完成后,没怎么改动过,所以一直没出题过问题,可最近由于改动了下命名空间,问题来了,正是标题中 ...

  8. asp.net读取用户控件,自定义加载用户控件

    1.自定义加载用户控件 ceshi.aspx页面 <html> <body> <div id="divControls" runat="se ...

  9. 关于document.write()加载JS等静态资源 和 异步async加载JS

    现流行浏览器对于静态资源的预加载 传统的浏览器,对于静态资源加载,会阻塞 HTML 解析器的线程进行,无论内联还是外链. 例如: <script src="test1.js" ...

随机推荐

  1. java 基础 ----- Arrays 工具类

    -----  Arrays  工具类是一个比较方便的类 常用的方法 也可以通过jdk文档进行查看    右侧有偶 对一些比较常用的方法进行演示   直接放在main方法中进行测试 ----   equ ...

  2. Solidity知识点集 — 溢出和下溢

    合约安全增强: 溢出和下溢 什么是 溢出 (overflow)? 假设我们有一个 uint8, 只能存储8 bit数据.这意味着我们能存储的最大数字就是二进制 11111111 (或者说十进制的 2^ ...

  3. 关于接口测试工具postman与DHC介绍

    一.Postman背景介绍 用户在开发或者调试网络程序或者是网页B/S模式的程序的时候是需要一些方法来跟踪网页请求的,用户可以使用一些网络的监视工具比如著名的Firebug等网页调试工具.今天给大家介 ...

  4. Security.ssl-pinning

    SSL Pinning 1. What's SSL Pinning? "SSL Pinning is making sure the client checks the server’s c ...

  5. Debian9安装后的一些配置

    第一步   修改源 su root vi /etc/apt/sources.list #建议先备份,不过系统好像有已经备份好的 加入国内源,保存 apt-get update   #更新源       ...

  6. go的包下载失败解决方案

    包被墙的方案 1 翻啊的墙 2 gopm 3 https://github.com/golang/net 4 使用国内网站打包 5 export GOPROXY=https://goproxy.io

  7. [精华][推荐]CAS SSO单点登录服务端客户端实例

    1.修改server.xml文件,如下: 注意: 这里使用的是https的认证方式,需要将这个配置放开,并做如下修改: <Connector port="8443" prot ...

  8. OO第二次作业总结

    OO~第二次作业总结 连续三周的电梯作业结束了,总的来说这三次作业做的还算平稳,既没有被刀,也没有刀中别人.那么接下来开始谈谈我对这三次作业的认识. 一.设计策略 我三次作业的设计思路基本上是相同的, ...

  9. list对象中根据两个参数过滤数据

    list对象中根据两个参数过滤数据 List<demo> list = new List<demo>() { ,b=,c=,d= }, ,b=,c=,d= }, ,b=,c=, ...

  10. 【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()前必须把 ...