IDS









How do I use I D S
Below are practical examples compiled from projects for learning and reference purposes

Featured Snippets


File name: PhotonViewHandler.cs Copy
25     internal static void HierarchyChange()
26     {
27         if (Application.isPlaying)
28         {
29             //Debug.Log("HierarchyChange ignored, while running.");
30             CheckSceneForStuckHandlers = true; // done once AFTER play mode.
31             return;
32         }
33
34         if (CheckSceneForStuckHandlers)
35         {
36             CheckSceneForStuckHandlers = false;
37             PhotonNetwork.InternalCleanPhotonMonoFromSceneIfStuck();
38         }
39
40         HashSet pvInstances = new HashSet();
41         HashSet usedInstanceViewNumbers = new HashSet();
42         bool fixedSomeId = false;
43
44         //// the following code would be an option if we only checked scene objects (but we can check all PVs)
45         //PhotonView[] pvObjects = GameObject.FindSceneObjectsOfType(typeof(PhotonView)) as PhotonView[];
46         //Debug.Log("HierarchyChange. PV Count: " + pvObjects.Length);
47
48         string levelName = Application.loadedLevelName;
49         #if UNITY_EDITOR
50         levelName = System.IO.Path.GetFileNameWithoutExtension(EditorApplication.currentScene);
51         #endif
52         int minViewIdInThisScene = PunSceneSettings.MinViewIdForScene(levelName);
53         //Debug.Log("Level '" + Application.loadedLevelName + "' has a minimum ViewId of: " + minViewIdInThisScene);
54
55         PhotonView[] pvObjects = Resources.FindObjectsOfTypeAll(typeof(PhotonView)) as PhotonView[];
56
57         foreach (PhotonView view in pvObjects)
58         {
59             // first pass: fix prefabs to viewID 0 if they got a view number assigned (cause they should not have one!)
60             if (EditorUtility.IsPersistent(view.gameObject))
61             {
62                 if (view.viewID != 0 || view.prefixBackup != -1 || view.instantiationId != -1)
63                 {
64                     Debug.LogWarning("PhotonView on persistent object being fixed (id and prefix must be 0). Was: " + view);
65                     view.viewID = 0;
66                     view.prefixBackup = -1;
67                     view.instantiationId = -1;
68                     EditorUtility.SetDirty(view);
69                     fixedSomeId = true;
70                 }
71             }
72             else
73             {
74                 // keep all scene-instanced PVs for later re-check
75                 pvInstances.Add(view);
76             }
77         }
78
79         Dictionary idPerObject = new Dictionary();
80
81         // second pass: check all used-in-scene viewIDs for duplicate viewIDs (only checking anything non-prefab)
82         // scene-PVs must have user == 0 (scene/room) and a subId != 0
83         foreach (PhotonView view in pvInstances)
84         {
85             if (view.ownerId > 0)
86             {
87                 Debug.Log("Re-Setting Owner ID of: " + view);
88             }
89             view.ownerId = 0; // simply make sure no owner is set (cause room always uses 0)
90             view.prefix = -1; // TODO: prefix could be settable via inspector per scene?!
91
92             if (view.viewID != 0)
93             {
94                 if (view.viewID < minViewIdInThisScene || usedInstanceViewNumbers.Contains(view.viewID))
95                 {
96                     view.viewID = 0; // avoid duplicates and negative values by assigning 0 as (temporary) number to be fixed in next pass
97                 }
98                 else
99                 {
100                     usedInstanceViewNumbers.Add(view.viewID); // builds a list of currently used viewIDs
101
102                     int instId = 0;
103                     if (idPerObject.TryGetValue(view.gameObject, out instId))
104                     {
105                         view.instantiationId = instId;
106                     }
107                     else
108                     {
109                         view.instantiationId = view.viewID;
110                         idPerObject[view.gameObject] = view.instantiationId;
111                     }
112                 }
113             }
114
115         }
116
117         // third pass: anything that's now 0 must get a new (not yet used) ID (starting at 0)
118         int lastUsedId = (minViewIdInThisScene > 0) ? minViewIdInThisScene - 1 : 0;
119
120         foreach (PhotonView view in pvInstances)
121         {
122             if (view.viewID == 0)
123             {
124                 // Debug.LogWarning("setting scene ID: " + view.gameObject.name + " ID: " + view.subId.ID + " scene ID: " + view.GetSceneID() + " IsPersistent: " + EditorUtility.IsPersistent(view.gameObject) + " IsSceneViewIDFree: " + IsSceneViewIDFree(view.subId.ID, view));
125                 int nextViewId = PhotonViewHandler.GetID(lastUsedId, usedInstanceViewNumbers);
126
127                 view.viewID = nextViewId;
128
129                 int instId = 0;
130                 if (idPerObject.TryGetValue(view.gameObject, out instId))
131                 {
132                     Debug.Log("Set inst ID");
133                     view.instantiationId = instId;
134                 }
135                 else
136                 {
137                     view.instantiationId = view.viewID;
138                     idPerObject[view.gameObject] = nextViewId;
139                 }
140
141                 //// when using the Editor's serialization (view.subId in this case), this is not needed, it seems
142                 //PrefabUtility.RecordPrefabInstancePropertyModifications(view);
143
144                 lastUsedId = nextViewId;
145                 EditorUtility.SetDirty(view);
146                 fixedSomeId = true;
147             }
148         }
149
150
151         if (fixedSomeId)
152         {
153             //Debug.LogWarning("Some subId was adjusted."); // this log is only interesting for Exit Games
154         }
155     }
File name: PhotonViewHandler.cs Copy
159     public static int GetID(int idOffset, HashSet usedInstanceViewNumbers)
160     {
161         while (idOffset < PhotonNetwork.MAX_VIEW_IDS)
162         {
163             idOffset++;
164             if (!usedInstanceViewNumbers.Contains(idOffset))
165             {
166                 break;
167             }
168         }
169
170         return idOffset;
171     }
File name: PhotonViewInspector.cs Copy
21     public override void OnInspectorGUI()
22     {
23         #if UNITY_3_5
24         EditorGUIUtility.LookLikeInspector();
25         #endif
26         //EditorGUI.indentLevel = 1;
27
28         m_Target = (PhotonView)this.target;
29         bool isProjectPrefab = EditorUtility.IsPersistent(m_Target.gameObject);
30
31         if( m_Target.ObservedComponents == null )
32         {
33             m_Target.ObservedComponents = new System.Collections.Generic.List();
34         }
35
36         if( m_Target.ObservedComponents.Count == 0 )
37         {
38             m_Target.ObservedComponents.Add( null );
39         }
40
41         EditorGUILayout.BeginHorizontal();
42         // Owner
43         if (isProjectPrefab)
44         {
45             EditorGUILayout.LabelField("Owner:", "Set at runtime");
46         }
47         else if (m_Target.isSceneView)
48         {
49             EditorGUILayout.LabelField("Owner", "Scene");
50         }
51         else
52         {
53             PhotonPlayer owner = m_Target.owner;
54             string ownerInfo = (owner != null) ? owner.name : "";
55
56             if (string.IsNullOrEmpty(ownerInfo))
57             {
58                 ownerInfo = "";
59             }
60
61             EditorGUILayout.LabelField("Owner", "[" + m_Target.ownerId + "] " + ownerInfo);
62         }
63
64         // ownership requests
65         EditorGUI.BeginDisabledGroup(Application.isPlaying);
66         m_Target.ownershipTransfer = (OwnershipOption)EditorGUILayout.EnumPopup(m_Target.ownershipTransfer, GUILayout.Width(100));
67         EditorGUI.EndDisabledGroup();
68
69         EditorGUILayout.EndHorizontal();
70
71
72         // View ID
73         if (isProjectPrefab)
74         {
75             EditorGUILayout.LabelField("View ID", "Set at runtime");
76         }
77         else if (EditorApplication.isPlaying)
78         {
79             EditorGUILayout.LabelField("View ID", m_Target.viewID.ToString());
80         }
81         else
82         {
83             int idValue = EditorGUILayout.IntField("View ID [1.."+(PhotonNetwork.MAX_VIEW_IDS-1)+"]", m_Target.viewID);
84             m_Target.viewID = idValue;
85         }
86
87
88
89         // Locally Controlled
90         if (EditorApplication.isPlaying)
91         {
92             string masterClientHint = PhotonNetwork.isMasterClient ? "(master)" : "";
93             EditorGUILayout.Toggle("Controlled locally: " + masterClientHint, m_Target.isMine);
94         }
95
96
97
98         //DrawOldObservedItem();
99         ConvertOldObservedItemToObservedList();
100
101
102         // ViewSynchronization (reliability)
103         if (m_Target.synchronization == ViewSynchronization.Off)
104         {
105             GUI.color = Color.grey;
106         }
107
108         EditorGUILayout.PropertyField( serializedObject.FindProperty( "synchronization" ), new GUIContent( "Observe option:" ) );
109
110         if( m_Target.synchronization != ViewSynchronization.Off &&
111             m_Target.ObservedComponents.FindAll( item => item != null ).Count == 0 )
112         {
113             GUILayout.BeginVertical( GUI.skin.box );
114             GUILayout.Label( "Warning", EditorStyles.boldLabel );
115             GUILayout.Label( "Setting the synchronization option only makes sense if you observe something." );
116             GUILayout.EndVertical();
117         }
118
119         /*ViewSynchronization vsValue = (ViewSynchronization)EditorGUILayout.EnumPopup("Observe option:", m_Target.synchronization);
120         if (vsValue != m_Target.synchronization)
121         {
122             m_Target.synchronization = vsValue;
123             if (m_Target.synchronization != ViewSynchronization.Off && m_Target.observed == null)
124             {
125                 EditorUtility.DisplayDialog("Warning", "Setting the synchronization option only makes sense if you observe something.", "OK, I will fix it.");
126             }
127         }*/
128
129         DrawSpecificTypeSerializationOptions();
130
131         GUI.color = Color.white;
132         DrawObservedComponentsList();
133
134         // Cleanup: save and fix look
135         if (GUI.changed)
136         {
137             EditorUtility.SetDirty(m_Target);
138             PhotonViewHandler.HierarchyChange(); // TODO: check if needed
139         }
140
141         GUI.color = Color.white;
142         EditorGUIUtility.LookLikeControls();
143     }
File name: LoadbalancingPeer.cs Copy
29         private readonly Dictionary opParameters = new Dictionary(); // used in OpRaiseEvent() (avoids lots of new Dictionary() calls)
31         public LoadbalancingPeer(IPhotonPeerListener listener, ConnectionProtocol protocolType) : base(listener, protocolType)
32         {
33         }
File name: NetworkingPeer.cs Copy
459     private void LeftRoomCleanup()
460     {
461         bool wasInRoom = mRoomToGetInto != null;
462         // when leaving a room, we clean up depending on that room's settings.
463         bool autoCleanupSettingOfRoom = (this.mRoomToGetInto != null) ? this.mRoomToGetInto.autoCleanUp : PhotonNetwork.autoCleanUpPlayerObjects;
464
465         this.hasSwitchedMC = false;
466         this.mRoomToGetInto = null;
467         this.mActors = new Dictionary();
468         this.mPlayerListCopy = new PhotonPlayer[0];
469         this.mOtherPlayerListCopy = new PhotonPlayer[0];
470         this.mMasterClient = null;
471         this.allowedReceivingGroups = new HashSet();
472         this.blockSendingGroups = new HashSet();
473         this.mGameList = new Dictionary();
474         this.mGameListCopy = new RoomInfo[0];
475         this.isFetchingFriends = false;
476
477         this.ChangeLocalID(-1);
478
479         // Cleanup all network objects (all spawned PhotonViews, local and remote)
480         if (autoCleanupSettingOfRoom)
481         {
482             this.LocalCleanupAnythingInstantiated(true);
483             PhotonNetwork.manuallyAllocatedViewIds = new List(); // filled and easier to replace completely
484         }
485
486         if (wasInRoom)
487         {
488             SendMonoMessage(PhotonNetworkingMessage.OnLeftRoom);
489         }
490     }
File name: NetworkingPeer.cs Copy
495     protected internal void LocalCleanupAnythingInstantiated(bool destroyInstantiatedGameObjects)
496     {
497         if (tempInstantiationData.Count > 0)
498         {
499             Debug.LogWarning("It seems some instantiation is not completed, as instantiation data is used. You should make sure instantiations are paused when calling this method. Cleaning now, despite this.");
500         }
501
502         // Destroy GO's (if we should)
503         if (destroyInstantiatedGameObjects)
504         {
505             // Fill list with Instantiated objects
506             HashSet instantiatedGos = new HashSet();
507             foreach (PhotonView view in this.photonViewList.Values)
508             {
509                 if (view.isRuntimeInstantiated)
510                 {
511                     instantiatedGos.Add(view.gameObject); // HashSet keeps each object only once
512                 }
513             }
514
515             foreach (GameObject go in instantiatedGos)
516             {
517                 this.RemoveInstantiatedGO(go, true);
518             }
519         }
520
521         // photonViewList is cleared of anything instantiated (so scene items are left inside)
522         // any other lists can be
523         this.tempInstantiationData.Clear(); // should be empty but to be safe we clear (no new list needed)
524         PhotonNetwork.lastUsedViewSubId = 0;
525         PhotonNetwork.lastUsedViewSubIdStatic = 0;
526     }
File name: NetworkingPeer.cs Copy
1918     private void SendVacantViewIds()
1919     {
1920         Debug.Log("SendVacantViewIds()");
1921         List vacantViews = new List();
1922         foreach (PhotonView view in this.photonViewList.Values)
1923         {
1924             if (!view.isOwnerActive)
1925             {
1926                 vacantViews.Add(view.viewID);
1927             }
1928         }
1929
1930         Debug.Log("Sending vacant view IDs. Length: " + vacantViews.Count);
1931         //this.OpRaiseEvent(PunEvent.VacantViewIds, true, vacantViews.ToArray());
1932         this.OpRaiseEvent(PunEvent.VacantViewIds, vacantViews.ToArray(), true, null);
1933     }
File name: NetworkingPeer.cs Copy
1962     public void ExecuteRPC(Hashtable rpcData, PhotonPlayer sender)
1963     {
1964         if (rpcData == null || !rpcData.ContainsKey((byte)0))
1965         {
1966             Debug.LogError("Malformed RPC; this should never occur. Content: " + SupportClass.DictionaryToString(rpcData));
1967             return;
1968         }
1969
1970         // ts: updated with "flat" event data
1971         int netViewID = (int)rpcData[(byte)0]; // LIMITS PHOTONVIEWS&PLAYERS
1972         int otherSidePrefix = 0; // by default, the prefix is 0 (and this is not being sent)
1973         if (rpcData.ContainsKey((byte)1))
1974         {
1975             otherSidePrefix = (short)rpcData[(byte)1];
1976         }
1977
1978         string inMethodName;
1979         if (rpcData.ContainsKey((byte)5))
1980         {
1981             int rpcIndex = (byte)rpcData[(byte)5]; // LIMITS RPC COUNT
1982             if (rpcIndex > PhotonNetwork.PhotonServerSettings.RpcList.Count - 1)
1983             {
1984                 Debug.LogError("Could not find RPC with index: " + rpcIndex + ". Going to ignore! Check PhotonServerSettings.RpcList");
1985                 return;
1986             }
1987             else
1988             {
1989                 inMethodName = PhotonNetwork.PhotonServerSettings.RpcList[rpcIndex];
1990             }
1991         }
1992         else
1993         {
1994             inMethodName = (string)rpcData[(byte)3];
1995         }
1996
1997         object[] inMethodParameters = null;
1998         if (rpcData.ContainsKey((byte)4))
1999         {
2000             inMethodParameters = (object[])rpcData[(byte)4];
2001         }
2002
2003         if (inMethodParameters == null)
2004         {
2005             inMethodParameters = new object[0];
2006         }
2007
2008         PhotonView photonNetview = this.GetPhotonView(netViewID);
2009         if (photonNetview == null)
2010         {
2011             int viewOwnerId = netViewID/PhotonNetwork.MAX_VIEW_IDS;
2012             bool owningPv = (viewOwnerId == this.mLocalActor.ID);
2013             bool ownerSent = (viewOwnerId == sender.ID);
2014
2015             if (owningPv)
2016             {
2017                 Debug.LogWarning("Received RPC \"" + inMethodName + "\" for viewID " + netViewID + " but this PhotonView does not exist! View was/is ours." + (ownerSent ? " Owner called." : " Remote called.") + " By: " + sender.ID);
2018             }
2019             else
2020             {
2021                 Debug.LogWarning("Received RPC \"" + inMethodName + "\" for viewID " + netViewID + " but this PhotonView does not exist! Was remote PV." + (ownerSent ? " Owner called." : " Remote called.") + " By: " + sender.ID + " Maybe GO was destroyed but RPC not cleaned up.");
2022             }
2023             return;
2024         }
2025
2026         if (photonNetview.prefix != otherSidePrefix)
2027         {
2028             Debug.LogError(
2029                 "Received RPC \"" + inMethodName + "\" on viewID " + netViewID + " with a prefix of " + otherSidePrefix
2030                 + ", our prefix is " + photonNetview.prefix + ". The RPC has been ignored.");
2031             return;
2032         }
2033
2034         // Get method name
2035         if (inMethodName == string.Empty)
2036         {
2037             Debug.LogError("Malformed RPC; this should never occur. Content: " + SupportClass.DictionaryToString(rpcData));
2038             return;
2039         }
2040
2041         if (PhotonNetwork.logLevel >= PhotonLogLevel.Full)
2042             Debug.Log("Received RPC: " + inMethodName);
2043
2044
2045         // SetReceiving filtering
2046         if (photonNetview.group != 0 && !allowedReceivingGroups.Contains(photonNetview.group))
2047         {
2048             return; // Ignore group
2049         }
2050
2051         Type[] argTypes = new Type[0];
2052         if (inMethodParameters.Length > 0)
2053         {
2054             argTypes = new Type[inMethodParameters.Length];
2055             int i = 0;
2056             for (int index = 0; index < inMethodParameters.Length; index++)
2057             {
2058                 object objX = inMethodParameters[index];
2059                 if (objX == null)
2060                 {
2061                     argTypes[i] = null;
2062                 }
2063                 else
2064                 {
2065                     argTypes[i] = objX.GetType();
2066                 }
2067
2068                 i++;
2069             }
2070         }
2071
2072         int receivers = 0;
2073         int foundMethods = 0;
2074         MonoBehaviour[] mbComponents = photonNetview.GetComponents(); // NOTE: we could possibly also cache MonoBehaviours per view?!
2075         for (int componentsIndex = 0; componentsIndex < mbComponents.Length; componentsIndex++)
2076         {
2077             MonoBehaviour monob = mbComponents[componentsIndex];
2078             if (monob == null)
2079             {
2080                 Debug.LogError("ERROR You have missing MonoBehaviours on your gameobjects!");
2081                 continue;
2082             }
2083
2084             Type type = monob.GetType();
2085
2086             // Get [RPC] methods from cache
2087             List cachedRPCMethods = null;
2088             if (this.monoRPCMethodsCache.ContainsKey(type))
2089             {
2090                 cachedRPCMethods = this.monoRPCMethodsCache[type];
2091             }
2092
2093             if (cachedRPCMethods == null)
2094             {
2095                 List entries = SupportClass.GetMethods(type, typeof(RPC));
2096
2097                 this.monoRPCMethodsCache[type] = entries;
2098                 cachedRPCMethods = entries;
2099             }
2100
2101             if (cachedRPCMethods == null)
2102             {
2103                 continue;
2104             }
2105
2106             // Check cache for valid methodname+arguments
2107             for (int index = 0; index < cachedRPCMethods.Count; index++)
2108             {
2109                 MethodInfo mInfo = cachedRPCMethods[index];
2110                 if (mInfo.Name == inMethodName)
2111                 {
2112                     foundMethods++;
2113                     ParameterInfo[] pArray = mInfo.GetParameters();
2114                     if (pArray.Length == argTypes.Length)
2115                     {
2116                         // Normal, PhotonNetworkMessage left out
2117                         if (this.CheckTypeMatch(pArray, argTypes))
2118                         {
2119                             receivers++;
2120                             object result = mInfo.Invoke((object)monob, inMethodParameters);
2121                             if (mInfo.ReturnType == typeof(IEnumerator))
2122                             {
2123                                 monob.StartCoroutine((IEnumerator)result);
2124                             }
2125                         }
2126                     }
2127                     else if ((pArray.Length - 1) == argTypes.Length)
2128                     {
2129                         // Check for PhotonNetworkMessage being the last
2130                         if (this.CheckTypeMatch(pArray, argTypes))
2131                         {
2132                             if (pArray[pArray.Length - 1].ParameterType == typeof(PhotonMessageInfo))
2133                             {
2134                                 receivers++;
2135
2136                                 int sendTime = (int)rpcData[(byte)2];
2137                                 object[] deParamsWithInfo = new object[inMethodParameters.Length + 1];
2138                                 inMethodParameters.CopyTo(deParamsWithInfo, 0);
2139                                 deParamsWithInfo[deParamsWithInfo.Length - 1] = new PhotonMessageInfo(sender, sendTime, photonNetview);
2140
2141                                 object result = mInfo.Invoke((object)monob, deParamsWithInfo);
2142                                 if (mInfo.ReturnType == typeof(IEnumerator))
2143                                 {
2144                                     monob.StartCoroutine((IEnumerator)result);
2145                                 }
2146                             }
2147                         }
2148                     }
2149                     else if (pArray.Length == 1 && pArray[0].ParameterType.IsArray)
2150                     {
2151                         receivers++;
2152                         object result = mInfo.Invoke((object)monob, new object[] { inMethodParameters });
2153                         if (mInfo.ReturnType == typeof(IEnumerator))
2154                         {
2155                             monob.StartCoroutine((IEnumerator)result);
2156                         }
2157                     }
2158                 }
2159             }
2160         }
2161
2162         // Error handling
2163         if (receivers != 1)
2164         {
2165             string argsString = string.Empty;
2166             for (int index = 0; index < argTypes.Length; index++)
2167             {
2168                 Type ty = argTypes[index];
2169                 if (argsString != string.Empty)
2170                 {
2171                     argsString += ", ";
2172                 }
2173
2174                 if (ty == null)
2175                 {
2176                     argsString += "null";
2177                 }
2178                 else
2179                 {
2180                     argsString += ty.Name;
2181                 }
2182             }
2183
2184             if (receivers == 0)
2185             {
2186                 if (foundMethods == 0)
2187                 {
2188                     Debug.LogError("PhotonView with ID " + netViewID + " has no method \"" + inMethodName + "\" marked with the [RPC](C#) or @RPC(JS) property! Args: " + argsString);
2189                 }
2190                 else
2191                 {
2192                     Debug.LogError("PhotonView with ID " + netViewID + " has no method \"" + inMethodName + "\" that takes " + argTypes.Length + " argument(s): " + argsString);
2193                 }
2194             }
2195             else
2196             {
2197                 Debug.LogError("PhotonView with ID " + netViewID + " has " + receivers + " methods \"" + inMethodName + "\" that takes " + argTypes.Length + " argument(s): " + argsString + ". Should be just one?");
2198             }
2199         }
2200     }
File name: NetworkingPeer.cs Copy
2228     internal Hashtable SendInstantiate(string prefabName, Vector3 position, Quaternion rotation, int group, int[] viewIDs, object[] data, bool isGlobalObject)
2229     {
2230         // first viewID is now also the gameobject's instantiateId
2231         int instantiateId = viewIDs[0]; // LIMITS PHOTONVIEWS&PLAYERS
2232
2233         //TODO: reduce hashtable key usage by using a parameter array for the various values
2234         Hashtable instantiateEvent = new Hashtable(); // This players info is sent via ActorID
2235         instantiateEvent[(byte)0] = prefabName;
2236
2237         if (position != Vector3.zero)
2238         {
2239             instantiateEvent[(byte)1] = position;
2240         }
2241
2242         if (rotation != Quaternion.identity)
2243         {
2244             instantiateEvent[(byte)2] = rotation;
2245         }
2246
2247         if (group != 0)
2248         {
2249             instantiateEvent[(byte)3] = group;
2250         }
2251
2252         // send the list of viewIDs only if there are more than one. else the instantiateId is the viewID
2253         if (viewIDs.Length > 1)
2254         {
2255             instantiateEvent[(byte)4] = viewIDs; // LIMITS PHOTONVIEWS&PLAYERS
2256         }
2257
2258         if (data != null)
2259         {
2260             instantiateEvent[(byte)5] = data;
2261         }
2262
2263         if (this.currentLevelPrefix > 0)
2264         {
2265             instantiateEvent[(byte)8] = this.currentLevelPrefix; // photonview's / object's level prefix
2266         }
2267
2268         instantiateEvent[(byte)6] = this.ServerTimeInMilliSeconds;
2269         instantiateEvent[(byte)7] = instantiateId;
2270
2271
2272         RaiseEventOptions options = new RaiseEventOptions();
2273         options.CachingOption = (isGlobalObject) ? EventCaching.AddToRoomCacheGlobal : EventCaching.AddToRoomCache;
2274
2275         this.OpRaiseEvent(PunEvent.Instantiation, instantiateEvent, true, options);
2276         return instantiateEvent;
2277     }
File name: NetworkingPeer.cs Copy
2279     internal GameObject DoInstantiate(Hashtable evData, PhotonPlayer photonPlayer, GameObject resourceGameObject)
2280     {
2281         // some values always present:
2282         string prefabName = (string)evData[(byte)0];
2283         int serverTime = (int)evData[(byte)6];
2284         int instantiationId = (int)evData[(byte)7];
2285
2286         Vector3 position;
2287         if (evData.ContainsKey((byte)1))
2288         {
2289             position = (Vector3)evData[(byte)1];
2290         }
2291         else
2292         {
2293             position = Vector3.zero;
2294         }
2295
2296         Quaternion rotation = Quaternion.identity;
2297         if (evData.ContainsKey((byte)2))
2298         {
2299             rotation = (Quaternion)evData[(byte)2];
2300         }
2301
2302         int group = 0;
2303         if (evData.ContainsKey((byte)3))
2304         {
2305             group = (int)evData[(byte)3];
2306         }
2307
2308         short objLevelPrefix = 0;
2309         if (evData.ContainsKey((byte)8))
2310         {
2311             objLevelPrefix = (short)evData[(byte)8];
2312         }
2313
2314         int[] viewsIDs;
2315         if (evData.ContainsKey((byte)4))
2316         {
2317             viewsIDs = (int[])evData[(byte)4];
2318         }
2319         else
2320         {
2321             viewsIDs = new int[1] { instantiationId };
2322         }
2323
2324         object[] incomingInstantiationData;
2325         if (evData.ContainsKey((byte)5))
2326         {
2327             incomingInstantiationData = (object[])evData[(byte)5];
2328         }
2329         else
2330         {
2331             incomingInstantiationData = null;
2332         }
2333
2334         // SetReceiving filtering
2335         if (group != 0 && !this.allowedReceivingGroups.Contains(group))
2336         {
2337             return null; // Ignore group
2338         }
2339
2340         // load prefab, if it wasn't loaded before (calling methods might do this)
2341         if (resourceGameObject == null)
2342         {
2343             if (!NetworkingPeer.UsePrefabCache || !NetworkingPeer.PrefabCache.TryGetValue(prefabName, out resourceGameObject))
2344             {
2345                 resourceGameObject = (GameObject)Resources.Load(prefabName, typeof(GameObject));
2346                 if (NetworkingPeer.UsePrefabCache)
2347                 {
2348                     NetworkingPeer.PrefabCache.Add(prefabName, resourceGameObject);
2349                 }
2350             }
2351
2352             if (resourceGameObject == null)
2353             {
2354                 Debug.LogError("PhotonNetwork error: Could not Instantiate the prefab [" + prefabName + "]. Please verify you have this gameobject in a Resources folder.");
2355                 return null;
2356             }
2357         }
2358
2359         // now modify the loaded "blueprint" object before it becomes a part of the scene (by instantiating it)
2360         PhotonView[] resourcePVs = resourceGameObject.GetPhotonViewsInChildren();
2361         if (resourcePVs.Length != viewsIDs.Length)
2362         {
2363             throw new Exception("Error in Instantiation! The resource's PhotonView count is not the same as in incoming data.");
2364         }
2365
2366         for (int i = 0; i < viewsIDs.Length; i++)
2367         {
2368             // NOTE instantiating the loaded resource will keep the viewID but would not copy instantiation data, so it's set below
2369             // so we only set the viewID and instantiationId now. the instantiationData can be fetched
2370             resourcePVs[i].viewID = viewsIDs[i];
2371             resourcePVs[i].prefix = objLevelPrefix;
2372             resourcePVs[i].instantiationId = instantiationId;
2373             resourcePVs[i].isRuntimeInstantiated = true;
2374         }
2375
2376         this.StoreInstantiationData(instantiationId, incomingInstantiationData);
2377
2378         // load the resource and set it's values before instantiating it:
2379         GameObject go = (GameObject)GameObject.Instantiate(resourceGameObject, position, rotation);
2380
2381         for (int i = 0; i < viewsIDs.Length; i++)
2382         {
2383             // NOTE instantiating the loaded resource will keep the viewID but would not copy instantiation data, so it's set below
2384             // so we only set the viewID and instantiationId now. the instantiationData can be fetched
2385             resourcePVs[i].viewID = 0;
2386             resourcePVs[i].prefix = -1;
2387             resourcePVs[i].prefixBackup = -1;
2388             resourcePVs[i].instantiationId = -1;
2389             resourcePVs[i].isRuntimeInstantiated = false;
2390         }
2391
2392         this.RemoveInstantiationData(instantiationId);
2393
2394         // Send OnPhotonInstantiate callback to newly created GO.
2395         // GO will be enabled when instantiated from Prefab and it does not matter if the script is enabled or disabled.
2396         go.SendMessage(PhotonNetworkingMessage.OnPhotonInstantiate.ToString(), new PhotonMessageInfo(photonPlayer, serverTime, null), SendMessageOptions.DontRequireReceiver);
2397         return go;
2398     }

IDS 141 lượt xem

Gõ tìm kiếm nhanh...