Also









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

Featured Snippets


File name: HubGui.cs Copy
28     void OnGUI()
29     {
30         GUI.skin = this.Skin;
31         GUILayout.Space(10);
32
33         GUILayout.BeginHorizontal();
34         GUILayout.Space(10);
35         scrollPos = GUILayout.BeginScrollView(scrollPos, GUILayout.Width(320));
36
37         GUILayout.Label("Basics", m_Headline);
38         if (GUILayout.Button("Demo Boxes", GUILayout.Width(280)))
39         {
40             demoDescription = "Demo Boxes\n\nUses ConnectAndJoinRandom script.\n(joins a random room or creates one)\n\nInstantiates simple prefab.\nSynchronizes positions without smoothing.";
41             demoBtn = new DemoBtn() { Text = "Start", Link = "DemoBoxes-Scene" };
42         }
43         if (GUILayout.Button("Demo Worker", GUILayout.Width(280)))
44         {
45             demoDescription = "Demo Worker\n\nJoins the default lobby and shows existing rooms.\nLets you create or join a room.\nInstantiates an animated character.\nSynchronizes position and animation state of character with smoothing.\nImplements simple in-room Chat via RPC calls.";
46             demoBtn = new DemoBtn() { Text = "Start", Link = "DemoWorker-Scene" };
47         }
48         if (GUILayout.Button("Movement Smoothing", GUILayout.Width(280)))
49         {
50             demoDescription = "Movement Smoothing\n\nUses ConnectAndJoinRandom script.\nShows several basic ways to update positions of remote objects.";
51             demoBtn = new DemoBtn() { Text = "Start", Link = "DemoSynchronization-Scene" };
52         }
53
54         GUILayout.Label("Advanced", m_Headline);
55         if (GUILayout.Button("Ownership Transfer", GUILayout.Width(280)))
56         {
57             demoDescription = "Ownership Transfer\n\nShows how to transfer the ownership of a PhotonView.\nThe owner will send position updates of the GameObject.\nTransfer can be edited per PhotonView and set to Fixed (no transfer), Request (owner has to agree) or Takeover (owner can't object).";
58             this.demoBtn = new DemoBtn() { Text = "Start", Link = "DemoChangeOwner-Scene" };
59             this.webLink = new DemoBtn();
60         }
61         if (GUILayout.Button("Pickup, Teams, Scores", GUILayout.Width(280)))
62         {
63             demoDescription = "Pickup, Teams, Scores\n\nUses ConnectAndJoinRandom script.\nImplements item pickup with RPCs.\nUses Custom Properties for Teams.\nCounts score per player and team.\nUses PhotonPlayer extension methods for easy Custom Property access.";
64             this.demoBtn = new DemoBtn() { Text = "Start", Link = "DemoPickup-Scene" };
65             this.webLink = new DemoBtn();
66         }
67
68         GUILayout.Label("Feature Demos", m_Headline);
69         if (GUILayout.Button("Chat", GUILayout.Width(280)))
70         {
71             demoDescription = "Chat\n\nUses the Chat API (now part of PUN).\nSimple UI.\nYou can enter any User ID.\nAutomatically subscribes some channels.\nAllows simple commands via text.\n\nRequires configuration of Chat App ID in scene.";
72             this.demoBtn = new DemoBtn() { Text = "Start", Link = "DemoChat-Scene" };
73             this.webLink = new DemoBtn();
74         }
75         if (GUILayout.Button("RPG Movement", GUILayout.Width(280)))
76         {
77             demoDescription = "RPG Movement\n\nDemonstrates how to use the PhotonTransformView component to synchronize position updates smoothly using inter- and extrapolation.\n\nThis demo also shows how to setup a Mecanim Animator to update animations automatically based on received position updates (without sending explicit animation updates).";
78             this.demoBtn = new DemoBtn() { Text = "Start", Link = "DemoRPGMovement-Scene" };
79             this.webLink = new DemoBtn();
80         }
81         if (GUILayout.Button("Mecanim Animations", GUILayout.Width(280)))
82         {
83             demoDescription = "Mecanim Animations\n\nThis demo shows how to use the PhotonAnimatorView component to easily synchronize Mecanim animations.\n\nIt also demonstrates another feature of the PhotonTransformView component which gives you more control how position updates are inter-/extrapolated by telling the component how fast the object moves and turns using SetSynchronizedValues().";
84             this.demoBtn = new DemoBtn() { Text = "Start", Link = "DemoMecanim-Scene" };
85             this.webLink = new DemoBtn();
86         }
87         if (GUILayout.Button("2D Game", GUILayout.Width(280)))
88         {
89             demoDescription = "2D Game Demo\n\nSynchronizes animations, positions and physics in a 2D scene.";
90             this.demoBtn = new DemoBtn() { Text = "Start", Link = "Demo2DJumpAndRunWithPhysics-Scene" };
91             this.webLink = new DemoBtn();
92         }
93         if (GUILayout.Button("Friends & Authentication", GUILayout.Width(280)))
94         {
95             demoDescription = "Friends & Authentication\n\nShows connect with or without (server-side) authentication.\n\nAuthentication requires minor server-side setup (in Dashboard).\n\nOnce connected, you can find (made up) friends.\nJoin a room just to see how that gets visible in friends list.";
96             this.demoBtn = new DemoBtn() { Text = "Start", Link = "DemoFriends-Scene" };
97             this.webLink = new DemoBtn();
98         }
99
100         GUILayout.Label("Tutorial", m_Headline);
101         if (GUILayout.Button("Marco Polo Tutorial", GUILayout.Width(280)))
102         {
103             demoDescription = "Marco Polo Tutorial\n\nFinal result you could get when you do the Marco Polo Tutorial.\nSlightly modified to be more compatible with this package.";
104             this.demoBtn = new DemoBtn() { Text = "Start", Link = "MarcoPolo-Scene" };
105             this.webLink = new DemoBtn() { Text = "Open Tutorial (www)", Link = "http://tinyurl.com/nmylf44" };
106         }
107         GUILayout.EndScrollView();
108
109         GUILayout.BeginVertical(GUILayout.Width(Screen.width - 345));
110         GUILayout.Label(demoDescription);
111         GUILayout.Space(10);
112         if (!string.IsNullOrEmpty(this.demoBtn.Text))
113         {
114             if (GUILayout.Button(this.demoBtn.Text))
115             {
116                 Application.LoadLevel(this.demoBtn.Link);
117             }
118         }
119         if (!string.IsNullOrEmpty(this.webLink.Text))
120         {
121             if (GUILayout.Button(this.webLink.Text))
122             {
123                 Application.OpenURL(this.webLink.Link);
124             }
125         }
126         GUILayout.EndVertical();
127
128
129         GUILayout.EndHorizontal();
130     }
File name: PhotonViewHandler.cs Copy
173     //TODO: check if this can be internal protected (as source in editor AND as dll)
174     public static void LoadAllScenesToFix()
175     {
176         string[] scenes = System.IO.Directory.GetFiles(".", "*.unity", SearchOption.AllDirectories);
177
178         foreach (string scene in scenes)
179         {
180             EditorApplication.OpenScene(scene);
181
182             PhotonViewHandler.HierarchyChange();//TODO: most likely on load also triggers a hierarchy change
183
184             EditorApplication.SaveScene();
185         }
186
187         Debug.Log("Corrected scene views where needed.");
188     }
File name: LoadbalancingPeer.cs Copy
86         public virtual bool OpCreateRoom(string roomName, RoomOptions roomOptions, TypedLobby lobby, Hashtable playerProperties, bool onGameServer)
87         {
88             if (this.DebugOut >= DebugLevel.INFO)
89             {
90                 this.Listener.DebugReturn(DebugLevel.INFO, "OpCreateRoom()");
91             }
92
93             Dictionary op = new Dictionary();
94
95             if (!string.IsNullOrEmpty(roomName))
96             {
97                 op[ParameterCode.RoomName] = roomName;
98             }
99             if (lobby != null)
100             {
101                 op[ParameterCode.LobbyName] = lobby.Name;
102                 op[ParameterCode.LobbyType] = (byte)lobby.Type;
103             }
104
105             if (onGameServer)
106             {
107                 if (playerProperties != null && playerProperties.Count > 0)
108                 {
109                     op[ParameterCode.PlayerProperties] = playerProperties;
110                     op[ParameterCode.Broadcast] = true; // TODO: check if this also makes sense when creating a room?! // broadcast actor properties
111                 }
112
113
114                 if (roomOptions == null)
115                 {
116                     roomOptions = new RoomOptions();
117                 }
118
119                 Hashtable gameProperties = new Hashtable();
120                 op[ParameterCode.GameProperties] = gameProperties;
121                 gameProperties.MergeStringKeys(roomOptions.customRoomProperties);
122
123                 gameProperties[GameProperties.IsOpen] = roomOptions.isOpen; // TODO: check default value. dont send this then
124                 gameProperties[GameProperties.IsVisible] = roomOptions.isVisible; // TODO: check default value. dont send this then
125                 gameProperties[GameProperties.PropsListedInLobby] = roomOptions.customRoomPropertiesForLobby;
126                 if (roomOptions.maxPlayers > 0)
127                 {
128                     gameProperties[GameProperties.MaxPlayers] = roomOptions.maxPlayers;
129                 }
130                 if (roomOptions.cleanupCacheOnLeave)
131                 {
132                     op[ParameterCode.CleanupCacheOnLeave] = true; // this is actually setting the room's config
133                     gameProperties[GameProperties.CleanupCacheOnLeave] = true; // this is only informational for the clients which join
134                 }
135             }
136
137             // UnityEngine.Debug.Log("CreateGame: " + SupportClass.DictionaryToString(op));
138             return this.OpCustom(OperationCode.CreateGame, op, true);
139         }
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
3034     public void SetReceivingEnabled(int[] enableGroups, int[] disableGroups)
3035     {
3036         List enableList = new List();
3037         List disableList = new List();
3038
3039         if (enableGroups != null)
3040         {
3041             for (int index = 0; index < enableGroups.Length; index++)
3042             {
3043                 int i = enableGroups[index];
3044                 if (i <= 0)
3045                 {
3046                     Debug.LogError("Error: PhotonNetwork.SetReceivingEnabled was called with an illegal group number: " + i + ". The group number should be at least 1.");
3047                     continue;
3048                 }
3049                 if (!this.allowedReceivingGroups.Contains(i))
3050                 {
3051                     this.allowedReceivingGroups.Add(i);
3052                     enableList.Add((byte)i);
3053                 }
3054             }
3055         }
3056         if (disableGroups != null)
3057         {
3058             for (int index = 0; index < disableGroups.Length; index++)
3059             {
3060                 int i = disableGroups[index];
3061                 if (i <= 0)
3062                 {
3063                     Debug.LogError("Error: PhotonNetwork.SetReceivingEnabled was called with an illegal group number: " + i + ". The group number should be at least 1.");
3064                     continue;
3065                 }
3066                 if (enableList.Contains((byte)i))
3067                 {
3068                     Debug.LogError("Error: PhotonNetwork.SetReceivingEnabled disableGroups contains a group that is also in the enableGroups: " + i + ".");
3069                     continue;
3070                 }
3071                 if (this.allowedReceivingGroups.Contains(i))
3072                 {
3073                     this.allowedReceivingGroups.Remove(i);
3074                     disableList.Add((byte)i);
3075                 }
3076             }
3077         }
3078
3079         this.OpChangeGroups(disableList.Count > 0 ? disableList.ToArray() : null, enableList.Count > 0 ? enableList.ToArray() : null); //Passing a 0 sized array != passing null
3080     }
File name: PhotonNetwork.cs Copy
402     {
403         get
404         {
405             return isOfflineMode;
406         }
407
408         set
409         {
410             if (value == isOfflineMode)
411             {
412                 return;
413             }
414
415             if (value && connected)
416             {
417                 Debug.LogError("Can't start OFFLINE mode while connected!");
418             }
419             else
420             {
421                 if (networkingPeer.PeerState != PeerStateValue.Disconnected)
422                 {
423                     networkingPeer.Disconnect(); // Cleanup (also calls OnLeftRoom to reset stuff)
424                 }
425                 isOfflineMode = value;
426                 if (isOfflineMode)
427                 {
428                     NetworkingPeer.SendMonoMessage(PhotonNetworkingMessage.OnConnectedToMaster);
429                     networkingPeer.ChangeLocalID(1);
430                     networkingPeer.mMasterClient = player;
431                 }
432                 else
433                 {
434                     offlineModeRoom = null;
435                     networkingPeer.ChangeLocalID(-1);
436                     networkingPeer.mMasterClient = null;
437                 }
438             }
439         }
440     }
File name: InstructionsScript.cs Copy
27  void OnGUI() {
28   if (this.gameScript.gameView == "instructions") {
29    GUI.skin = currentGUISkin;
30
31    this.gameScript.mainCamera.transform.eulerAngles = new Vector3 (120, 23, 0);
32
33    GUIStyle labelStyle = new GUIStyle(currentGUISkin.label);
34    labelStyle.alignment = TextAnchor.UpperLeft;
35    GUILayout.Label ("Instructions", "BigLabel");
36
37
38    scrollPosition = GUILayout.BeginScrollView(scrollPosition, GUILayout.Width(Screen.width), GUILayout.Height(Mathf.Ceil(Screen.height * .80f)));
39
40    GUILayout.Label ("Object", "Subheader");
41
42    GUILayout.Label (@"The object of 2048-3D is to"
43                  + " slide numbered blocks in such a way"
44                  + " so that blocks with the same numbers collide"
45                  + " and combine into a new block that is twice"
46                  + " as much as the originals until"
47                  + " the number 2048 is reached.", labelStyle);
48
49    GUILayout.Label ("Moving the Blocks", "Subheader");
50
51    GUILayout.Label (@"You cannot move blocks individually, but must"
52                 + " move all blocks simultaneously in the same direction."
53                 + " Blocks can move forward, backward, up, down, left"
54     + " and right along the green connectors."
55           + " Simply swipe any part of the screen to move up,"
56     + " down, left or right (keyboard: arrow keys). To move the"
57     + " blocks forward and backward use the"
58     + " big red arrow keys at the bottom of the screen (keyboard: a and z keys)."
59     + " When moving, all blocks that can slide in the chosen direction will move."
60     + " Any block moving toward another block with the same number will collide "
61        + " and form a single block with twice the number as the originals", labelStyle);
62
63
64    GUILayout.Label ("New Blocks", "Subheader");
65
66    GUILayout.Label (@"After each move is"
67                 + " made a new block will appear randomly in an empty position."
68                 + " This block will have a number of either 2 or 4."
69        + " For an extra challenge, there is a game option you can"
70        + " set so that zeros can also be assinged to a new block."
71        + " Zeros act like any other number in that they can"
72        + " collide with other zeros to make a block twice as much "
73        + " (which is still zero).", labelStyle);
74
75
76
77    GUILayout.Label ("Scoring and Finishing", "Subheader");
78
79    GUILayout.Label(@"For every block collision that occurs you receive"
80                 + " the number of points of the newly"
81                 + " created block. If after making a move"
82                 + " all positions are filled and no new"
83                 + " moves are possible, the game ends."
84        + " A separate high score / highest block is kept for each"
85        + " distinct combination of game options", labelStyle);
86
87
88    GUILayout.Label ("Game Layout Options", "Subheader");
89
90    GUILayout.Label (@"When I first made this game there"
91            + " was only one game layout, a 3x3x3 cube."
92            + " After testing it a bit, it was way to easy"
93            + " so the zero option was added."
94            + " It was still way to easy "
95            + " (e.g. you could swipe without even looking and get pretty far)."
96            + " Therefore there are now several diffent game layouts that"
97            + " make the game more challenging and fun.", labelStyle);
98
99    GUILayout.Label ("Game Timer Option", "Subheader");
100
101    GUILayout.Label (@"To give yourself even more of a challenge"
102                     + " you can set game options to include a timer."
103                     + " If a timer is chosen you have a specific"
104                     + " amount of time to combined blocks to make the 64 block."
105                     + " If you run out of time the game is over."
106                     + " If you reach your target before the timer runs down you will"
107                     + " receive additional time to reach the next target."
108                     + " The time you received is as follows: \n"
109                     + " 64: option time + 5 seconds (because the first one is the hardest!)\n"
110                     + " 128: option time\n"
111                     + " 256: 2X option time\n"
112                     + " 512: 4X option time \n"
113                     + " 1024: 8X option time \n"
114                     + " you get the idea.", labelStyle);
115
116
117    GUILayout.Label ("Acknowledgements \nand Confessions", "Subheader");
118
119    GUILayout.Label (@"2048-3D is based upon the original" +
120                     " 2048 game designed by Gabriele Cirulli " +
121                     " \n\n" +
122                     " Sound effects by freeSFX http://www.freesfx.co.uk.\n\n" +
123                     " This game was designed using the Unity3D game engine.\n\n" +
124                     " FOR MORE PROJECTS VISIT:" +
125                     " https://code-projects.org/", labelStyle);
126
127
128    foreach (Touch touch in Input.touches) {
129     if (touch.phase == TouchPhase.Moved)
130     {
131      // dragging
132      this.scrollPosition.y += touch.deltaPosition.y;
133     }
134    }
135    GUILayout.EndScrollView();
136
137    if (GUILayout.Button ("Return to Menu")) {
138     this.gameScript.gameView = "menu";
139    }
140   }
141  }

Also 138 lượt xem

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