ViewIDs
How do I use View I Ds
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
41 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
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: 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
484 }
485
486 if (wasInRoom)
487 {
488 SendMonoMessage(PhotonNetworkingMessage.OnLeftRoom);
489 }
490 }
File name: NetworkingPeer.cs
Copy
1918 private void SendVacantViewIds()
1919 {
1920 Debug.Log("SendVacantViewIds()");
1921 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
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: PhotonNetwork.cs
Copy
1959 public static int AllocateViewID()
1960 {
1961 int manualId = AllocateViewID(player.ID);
1962 manuallyAllocatedViewIds.Add(manualId);
1963 return manualId;
1964 }
File name: PhotonNetwork.cs
Copy
1971 public static int AllocateSceneViewID()
1972 {
1973 if (!PhotonNetwork.isMasterClient)
1974 {
1975 Debug.LogError("Only the Master Client can AllocateSceneViewID(). Check PhotonNetwork.isMasterClient!");
1976 return -1;
1977 }
1978
1979 int manualId = AllocateViewID(0);
1980 manuallyAllocatedViewIds.Add(manualId);
1981 return manualId;
1982 }
File name: PhotonNetwork.cs
Copy
1988 public static void UnAllocateViewID(int viewID)
1989 {
1990 manuallyAllocatedViewIds.Remove(viewID);
1991
1992 if (networkingPeer.photonViewList.ContainsKey(viewID))
1993 {
1994 Debug.LogWarning(string.Format("UnAllocateViewID() should be called after the PhotonView was destroyed (GameObject.Destroy()). ViewID: {0} still found in: {1}", viewID, networkingPeer.photonViewList[viewID]));
1995 }
1996 }
File name: PhotonNetwork.cs
Copy
1999 // returns viewID (combined owner and sub id)
2000 private static int AllocateViewID(int ownerId)
2001 {
2002 if (ownerId == 0)
2003 {
2004 // we look up a fresh subId for the owner "room" (mind the "sub" in subId)
2005 int newSubId = lastUsedViewSubIdStatic;
2006 int newViewId;
2007 int ownerIdOffset = ownerId * MAX_VIEW_IDS;
2008 for (int i = 1; i < MAX_VIEW_IDS; i++)
2009 {
2010 newSubId = (newSubId + 1) % MAX_VIEW_IDS;
2011 if (newSubId == 0)
2012 {
2013 continue; // avoid using subID 0
2014 }
2015
2016 newViewId = newSubId + ownerIdOffset;
2017 if (!networkingPeer.photonViewList.ContainsKey(newViewId))
2018 {
2019 lastUsedViewSubIdStatic = newSubId;
2020 return newViewId;
2021 }
2022 }
2023
2024 // this is the error case: we didn't find any (!) free subId for this user
2025 throw new Exception(string.Format("AllocateViewID() failed. Room (user {0}) is out of 'scene' viewIDs. It seems all available are in use.", ownerId));
2026 }
2027 else
2028 {
2029 // we look up a fresh SUBid for the owner
2030 int newSubId = lastUsedViewSubId;
2031 int newViewId;
2032 int ownerIdOffset = ownerId * MAX_VIEW_IDS;
2033 for (int i = 1; i < MAX_VIEW_IDS; i++)
2034 {
2035 newSubId = (newSubId + 1) % MAX_VIEW_IDS;
2036 if (newSubId == 0)
2037 {
2038 continue; // avoid using subID 0
2039 }
2040
2041 newViewId = newSubId + ownerIdOffset;
2042 if (!networkingPeer.photonViewList.ContainsKey(newViewId) && !manuallyAllocatedViewIds.Contains(newViewId))
2043 {
2044 lastUsedViewSubId = newSubId;
2045 return newViewId;
2046 }
2047 }
2048
2049 throw new Exception(string.Format("AllocateViewID() failed. User {0} is out of subIds, as all viewIDs are used.", ownerId));
2050 }
2051 }
File name: PhotonNetwork.cs
Copy
2053 private static int[] AllocateSceneViewIDs(int countOfNewViews)
2054 {
2055 int[] viewIDs = new int[countOfNewViews];
2056 for (int view = 0; view < countOfNewViews; view++)
2057 {
2058 viewIDs[view] = AllocateViewID(0);
2059 }
2060
2061 return viewIDs;
2062 }
File name: PhotonNetwork.cs
Copy
2090 public static GameObject Instantiate(string prefabName, Vector3 position, Quaternion rotation, int group, object[] data)
2091 {
2092 if (!connected || (InstantiateInRoomOnly && !inRoom))
2093 {
2094 Debug.LogError("Failed to Instantiate prefab: " + prefabName + ". Client should be in a room. Current connectionStateDetailed: " + PhotonNetwork.connectionStateDetailed);
2095 return null;
2096 }
2097
2098 GameObject prefabGo;
2099 if (!UsePrefabCache || !PrefabCache.TryGetValue(prefabName, out prefabGo))
2100 {
2101 prefabGo = (GameObject)Resources.Load(prefabName, typeof(GameObject));
2102 if (UsePrefabCache)
2103 {
2104 PrefabCache.Add(prefabName, prefabGo);
2105 }
2106 }
2107
2108 if (prefabGo == null)
2109 {
2110 Debug.LogError("Failed to Instantiate prefab: " + prefabName + ". Verify the Prefab is in a Resources folder (and not in a subfolder)");
2111 return null;
2112 }
2113
2114 // a scene object instantiated with network visibility has to contain a PhotonView
2115 if (prefabGo.GetComponent
2116 {
2117 Debug.LogError("Failed to Instantiate prefab:" + prefabName + ". Prefab must have a PhotonView component.");
2118 return null;
2119 }
2120
2121 Component[] views = (Component[])prefabGo.GetPhotonViewsInChildren();
2122 int[] viewIDs = new int[views.Length];
2123 for (int i = 0; i < viewIDs.Length; i++)
2124 {
2125 //Debug.Log("Instantiate prefabName: " + prefabName + " player.ID: " + player.ID);
2126 viewIDs[i] = AllocateViewID(player.ID);
2127 }
2128
2129 // Send to others, create info
2130 Hashtable instantiateEvent = networkingPeer.SendInstantiate(prefabName, position, rotation, group, viewIDs, data, false);
2131
2132 // Instantiate the GO locally (but the same way as if it was done via event). This will also cache the instantiationId
2133 return networkingPeer.DoInstantiate(instantiateEvent, networkingPeer.mLocalActor, prefabGo);
2134 }
ViewIDs 163 lượt xem
Gõ tìm kiếm nhanh...