├── .gitignore
├── Assets
├── DynamicResolution.meta
├── DynamicResolution
│ ├── Prefabs.meta
│ ├── Prefabs
│ │ ├── FpsResolutionCanvas.prefab
│ │ └── FpsResolutionCanvas.prefab.meta
│ ├── Scripts.meta
│ └── Scripts
│ │ ├── DynamicResolution.cs
│ │ └── DynamicResolution.cs.meta
├── test.unity
└── test.unity.meta
├── DynamicResolution.unitypackage
├── LICENSE
├── ProjectSettings
├── AudioManager.asset
├── ClusterInputManager.asset
├── DynamicsManager.asset
├── EditorBuildSettings.asset
├── EditorSettings.asset
├── GraphicsSettings.asset
├── InputManager.asset
├── NavMeshAreas.asset
├── NetworkManager.asset
├── Physics2DSettings.asset
├── ProjectSettings.asset
├── ProjectVersion.txt
├── QualitySettings.asset
├── TagManager.asset
├── TimeManager.asset
└── UnityConnectSettings.asset
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | /[Ll]ibrary/
2 | /[Tt]emp/
3 | /[Oo]bj/
4 | /[Bb]uild/
5 | /[Bb]uilds/
6 | /Assets/AssetStoreTools*
7 |
8 | # Autogenerated VS/MD solution and project files
9 | ExportedObj/
10 | *.csproj
11 | *.unityproj
12 | *.sln
13 | *.suo
14 | *.tmp
15 | *.user
16 | *.userprefs
17 | *.pidb
18 | *.booproj
19 | *.svd
20 |
21 |
22 | # Unity3D generated meta files
23 | *.pidb.meta
24 |
25 | # Unity3D Generated File On Crash Reports
26 | sysinfo.txt
27 |
28 | # Builds
29 | *.apk
30 | #*.unitypackage
31 |
--------------------------------------------------------------------------------
/Assets/DynamicResolution.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: b78d8bcab55b9c74a8cbd827cbc3ea29
3 | folderAsset: yes
4 | timeCreated: 1485306087
5 | licenseType: Free
6 | DefaultImporter:
7 | userData:
8 | assetBundleName:
9 | assetBundleVariant:
10 |
--------------------------------------------------------------------------------
/Assets/DynamicResolution/Prefabs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 65a1ffb3afe64cb4f99c4d9165207eb5
3 | folderAsset: yes
4 | timeCreated: 1485306067
5 | licenseType: Free
6 | DefaultImporter:
7 | userData:
8 | assetBundleName:
9 | assetBundleVariant:
10 |
--------------------------------------------------------------------------------
/Assets/DynamicResolution/Prefabs/FpsResolutionCanvas.prefab:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kidel/DynamicResolution-for-Unity3D/bc45c4652fd952d45873920df76e733658d938f3/Assets/DynamicResolution/Prefabs/FpsResolutionCanvas.prefab
--------------------------------------------------------------------------------
/Assets/DynamicResolution/Prefabs/FpsResolutionCanvas.prefab.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 00dddc66939c2a442b5ea6409518c98e
3 | timeCreated: 1479751928
4 | licenseType: Free
5 | NativeFormatImporter:
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Assets/DynamicResolution/Scripts.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 22eb00c6cb1af7a49899df8dea9af189
3 | folderAsset: yes
4 | timeCreated: 1485306067
5 | licenseType: Free
6 | DefaultImporter:
7 | userData:
8 | assetBundleName:
9 | assetBundleVariant:
10 |
--------------------------------------------------------------------------------
/Assets/DynamicResolution/Scripts/DynamicResolution.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 | using UnityEngine.UI;
3 |
4 | [RequireComponent(typeof(Text))]
5 | public class DynamicResolution : MonoBehaviour
6 | {
7 | ///
8 | /// Tells if the text has to be visible (true) or not (false).
9 | ///
10 | public bool EnableText = true;
11 | ///
12 | /// Disables everything when true.
13 | ///
14 | public bool DisableResolutionChangesAndEvaluation = false;
15 | ///
16 | /// Overrides the default resolution (1 means normal, 0.9f is 90%, and so on)
17 | ///
18 | public float StartingRatioOverride = 1;
19 | ///
20 | /// Setting to say that the current scene has static resolution (basically disables the script except for StartingRatioOverride)
21 | ///
22 | public bool StaticResolution = false;
23 | ///
24 | /// Setting to decide if the resolution has to be changed based on scene average fps or based on instant fps.
25 | ///
26 | public bool BasedOnSceneAvg = true;
27 | ///
28 | /// Setting to decide how many times a scene can chenge the resolution
29 | /// 0 = false; -1 = true (until minimum);
30 | /// 1 means 1 time, 2 means 2 times and so on.
31 | ///
32 | public int InvokeRecursively = 1; // 0 = false; -1 = true; 1 means 1 time, 2 means 2 times and so on.
33 | ///
34 | /// Setting to tell if the resolution has to be changed at screen change or as soon as possible.
35 | /// Enabled by default since resolution changes are visible.
36 | /// Still changing all the time (false) can be useful if you have a scene dedicate to hardware estimation.
37 | ///
38 | public bool OnlyOnSceneChange = true;
39 | ///
40 | /// Resolution will go lower if FPS (or average FPS ot the scene, depending on settings) drop below this value
41 | ///
42 | public int InferiorFpsLimit = 29;
43 | ///
44 | /// Resolution will go higher if FPS (or average FPS ot the scene, depending on settings) goes above this value
45 | ///
46 | public int SuperiorFpsLimit = 49;
47 | ///
48 | /// Sets the maximum FPS of the scene (60 is usually the maximum allowed on smartphones)
49 | ///
50 | public int TargetFps = 60;
51 |
52 | private const float startingPeriod = 0.5f;
53 | private const float regimePeriod = 2.0f;
54 | private const float avgFpsStartPeriod = 2.0f; // better be a multiple of regimePeriod
55 | private bool startAvg = false;
56 |
57 | private static float fpsMeasurePeriod;
58 | private int fpsAccumulator = 0;
59 | private float fpsNextPeriod = 0;
60 | private int currentFps = 0;
61 | private int avgFpsAccumulator = 0;
62 | private float totalPeriodSinceStart = 0;
63 | private int currentAvgFps = 0;
64 |
65 | private static int lastSceneAvgFps = 0;
66 |
67 | const string display = "{0} FPS - {8} Avg FPS\nResolution at next refresh: {1}x{2}\nOriginal resolution: {3}x{4}\nCurrent res and modifier: {5}x{6} * {7}";
68 | private Text text;
69 |
70 |
71 |
72 | private static int originalwidth;
73 | private static int originalheight;
74 | private static int currentwidth;
75 | private static int currentheight;
76 | private int minimalwidth;
77 | private int minimalheight;
78 |
79 | public static bool resized { get; private set; }
80 |
81 | void Start()
82 | {
83 | this.gameObject.SetActive(!DisableResolutionChangesAndEvaluation);
84 |
85 | // initialization
86 | resized = resized ? true : false;
87 | fpsMeasurePeriod = startingPeriod;
88 | originalwidth = (originalwidth == 0) ? Screen.width : originalwidth;
89 | originalheight = (originalheight == 0) ? Screen.height : originalheight;
90 |
91 | currentwidth = (currentwidth == 0) ? originalwidth : currentwidth;
92 | currentheight = (currentheight == 0) ? originalheight : currentheight;
93 |
94 | minimalwidth = (int)(originalwidth * 0.69f);
95 | minimalheight = (int)(originalheight * 0.69f);
96 |
97 | float ratioOverride = (!resized) ? StartingRatioOverride : 1;
98 |
99 | fpsNextPeriod = Time.realtimeSinceStartup + fpsMeasurePeriod;
100 |
101 | text = GetComponent();
102 |
103 | // decisions
104 | if (EnableText)
105 | updateOverlay();
106 | else
107 | text.text = "";
108 |
109 | if (ratioOverride != 1 && (!resized || StaticResolution)) resize((int)(currentwidth * ratioOverride), (int)(currentheight * ratioOverride));
110 | else if (resized && OnlyOnSceneChange)
111 | {
112 | resize(currentwidth, currentheight);
113 | lastSceneAvgFps = 0;
114 | }
115 | if (!StaticResolution)
116 | if (InvokeRecursively == -1 || InvokeRecursively > 0)
117 | {
118 | Invoke("refreshResolution", regimePeriod);
119 | }
120 | }
121 |
122 | void Update()
123 | {
124 | // measuring frames per second in the fpsMeasurePeriod
125 | fpsAccumulator++;
126 | avgFpsAccumulator++;
127 |
128 | if (Time.realtimeSinceStartup > fpsNextPeriod)
129 | {
130 | totalPeriodSinceStart += fpsNextPeriod;
131 | int appFps = currentFps;
132 | currentFps = (int)(fpsAccumulator / fpsMeasurePeriod);
133 | if (appFps > currentFps)
134 | startAvg = true;
135 | fpsAccumulator = 0;
136 | fpsNextPeriod += fpsMeasurePeriod;
137 |
138 | //Debug.Log("Time Since Level Load " + Time.timeSinceLevelLoad);
139 | if (BasedOnSceneAvg)
140 | {
141 | if (startAvg && Time.timeSinceLevelLoad > avgFpsStartPeriod)
142 | {
143 | currentAvgFps = (int)(avgFpsAccumulator / Time.timeSinceLevelLoad);
144 | lastSceneAvgFps = currentAvgFps;
145 | }
146 | else
147 | {
148 | //Debug.Log("Not yet started recording avg fps");
149 | currentAvgFps = currentFps;
150 | avgFpsAccumulator = (int)(currentAvgFps * Time.timeSinceLevelLoad);
151 | }
152 | }
153 | if (EnableText)
154 | updateOverlay();
155 | else
156 | text.text = "";
157 | }
158 | }
159 |
160 | private void resize(int width, int height)
161 | {
162 | UnityEngine.Debug.Log(string.Format("resizing to {0}x{1}", width, height));
163 | Screen.SetResolution(width, height, true, TargetFps);
164 | resized = true;
165 | }
166 |
167 | private void refreshResolution()
168 | {
169 | // bases resolution change on the selected option, so scene average or current fps
170 | float fpsToUse = (BasedOnSceneAvg) ? (lastSceneAvgFps > 0 ? lastSceneAvgFps : currentAvgFps) : currentFps;
171 | bool changed = false;
172 | if (fpsToUse < InferiorFpsLimit && fpsToUse > 0 && currentheight > minimalheight)
173 | {
174 | float ratio = (resized) ? 0.92f : 0.82f;
175 | currentheight = (int)(currentheight * ratio);
176 | if (currentheight < minimalheight) currentheight = minimalheight;
177 | currentwidth = (int)(currentwidth * ratio);
178 | if (currentwidth < minimalwidth) currentwidth = minimalwidth;
179 |
180 | // if it's realtime dynamic resolution applies the resize
181 | if (!OnlyOnSceneChange) resize(currentwidth, currentheight);
182 | changed = true;
183 | }
184 | else if (resized && fpsToUse >= SuperiorFpsLimit && currentheight < originalheight)
185 | {
186 | currentheight = (int)(currentheight * 1.1f);
187 | if (currentheight > originalheight) currentheight = originalheight;
188 | currentwidth = (int)(currentwidth * 1.1f);
189 | if (currentwidth > originalwidth) currentwidth = originalwidth;
190 |
191 | // if it's realtime dynamic resolution applies the resize
192 | if (!OnlyOnSceneChange) resize(currentwidth, currentheight);
193 | changed = true;
194 | }
195 |
196 | resized = true;
197 |
198 | if (InvokeRecursively > 0 && changed)
199 | {
200 | InvokeRecursively--;
201 | changed = false;
202 | }
203 | if (InvokeRecursively == -1 || InvokeRecursively > 0)
204 | {
205 | Invoke("refreshResolution", regimePeriod);
206 | }
207 | }
208 |
209 | private void updateOverlay()
210 | {
211 | string settingsString = "\nMode: " +
212 | (OnlyOnSceneChange ? "only at scene change" : "can change during scene") +
213 | " " +
214 | (InvokeRecursively == -1 ? "recursively" : (InvokeRecursively + " times") +
215 | "\n " +
216 | (BasedOnSceneAvg ? "based on scene average":""));
217 | text.text = string.Format(display + settingsString,
218 | currentFps, currentwidth, currentheight, originalwidth, originalheight, Screen.width, Screen.height,
219 | !resized ? StartingRatioOverride : 1, currentAvgFps);
220 | Debug.Log(text.text);
221 | }
222 | }
223 |
224 |
--------------------------------------------------------------------------------
/Assets/DynamicResolution/Scripts/DynamicResolution.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: d564e577a8647684fa6591bbe900b4cc
3 | timeCreated: 1479735293
4 | licenseType: Free
5 | MonoImporter:
6 | serializedVersion: 2
7 | defaultReferences: []
8 | executionOrder: 0
9 | icon: {instanceID: 0}
10 | userData:
11 | assetBundleName:
12 | assetBundleVariant:
13 |
--------------------------------------------------------------------------------
/Assets/test.unity:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kidel/DynamicResolution-for-Unity3D/bc45c4652fd952d45873920df76e733658d938f3/Assets/test.unity
--------------------------------------------------------------------------------
/Assets/test.unity.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 237079c7595e6cf42b799d92e34a92fc
3 | timeCreated: 1485307711
4 | licenseType: Free
5 | DefaultImporter:
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/DynamicResolution.unitypackage:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kidel/DynamicResolution-for-Unity3D/bc45c4652fd952d45873920df76e733658d938f3/DynamicResolution.unitypackage
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Gaetano Bonofiglio
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/ProjectSettings/AudioManager.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kidel/DynamicResolution-for-Unity3D/bc45c4652fd952d45873920df76e733658d938f3/ProjectSettings/AudioManager.asset
--------------------------------------------------------------------------------
/ProjectSettings/ClusterInputManager.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kidel/DynamicResolution-for-Unity3D/bc45c4652fd952d45873920df76e733658d938f3/ProjectSettings/ClusterInputManager.asset
--------------------------------------------------------------------------------
/ProjectSettings/DynamicsManager.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kidel/DynamicResolution-for-Unity3D/bc45c4652fd952d45873920df76e733658d938f3/ProjectSettings/DynamicsManager.asset
--------------------------------------------------------------------------------
/ProjectSettings/EditorBuildSettings.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kidel/DynamicResolution-for-Unity3D/bc45c4652fd952d45873920df76e733658d938f3/ProjectSettings/EditorBuildSettings.asset
--------------------------------------------------------------------------------
/ProjectSettings/EditorSettings.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kidel/DynamicResolution-for-Unity3D/bc45c4652fd952d45873920df76e733658d938f3/ProjectSettings/EditorSettings.asset
--------------------------------------------------------------------------------
/ProjectSettings/GraphicsSettings.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kidel/DynamicResolution-for-Unity3D/bc45c4652fd952d45873920df76e733658d938f3/ProjectSettings/GraphicsSettings.asset
--------------------------------------------------------------------------------
/ProjectSettings/InputManager.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kidel/DynamicResolution-for-Unity3D/bc45c4652fd952d45873920df76e733658d938f3/ProjectSettings/InputManager.asset
--------------------------------------------------------------------------------
/ProjectSettings/NavMeshAreas.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kidel/DynamicResolution-for-Unity3D/bc45c4652fd952d45873920df76e733658d938f3/ProjectSettings/NavMeshAreas.asset
--------------------------------------------------------------------------------
/ProjectSettings/NetworkManager.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kidel/DynamicResolution-for-Unity3D/bc45c4652fd952d45873920df76e733658d938f3/ProjectSettings/NetworkManager.asset
--------------------------------------------------------------------------------
/ProjectSettings/Physics2DSettings.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kidel/DynamicResolution-for-Unity3D/bc45c4652fd952d45873920df76e733658d938f3/ProjectSettings/Physics2DSettings.asset
--------------------------------------------------------------------------------
/ProjectSettings/ProjectSettings.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kidel/DynamicResolution-for-Unity3D/bc45c4652fd952d45873920df76e733658d938f3/ProjectSettings/ProjectSettings.asset
--------------------------------------------------------------------------------
/ProjectSettings/ProjectVersion.txt:
--------------------------------------------------------------------------------
1 | m_EditorVersion: 5.5.0f3
2 |
--------------------------------------------------------------------------------
/ProjectSettings/QualitySettings.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kidel/DynamicResolution-for-Unity3D/bc45c4652fd952d45873920df76e733658d938f3/ProjectSettings/QualitySettings.asset
--------------------------------------------------------------------------------
/ProjectSettings/TagManager.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kidel/DynamicResolution-for-Unity3D/bc45c4652fd952d45873920df76e733658d938f3/ProjectSettings/TagManager.asset
--------------------------------------------------------------------------------
/ProjectSettings/TimeManager.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kidel/DynamicResolution-for-Unity3D/bc45c4652fd952d45873920df76e733658d938f3/ProjectSettings/TimeManager.asset
--------------------------------------------------------------------------------
/ProjectSettings/UnityConnectSettings.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kidel/DynamicResolution-for-Unity3D/bc45c4652fd952d45873920df76e733658d938f3/ProjectSettings/UnityConnectSettings.asset
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Dynamic Resolution for Unity 3D
2 | Dynamic Screen Resolution script for constant framerates in Unity 3D games.
3 |
4 | This is the script we used for [Cubic Space](https://play.google.com/store/apps/details?id=com.cubicspace.mcpals) to keep 30+ fps on almost every Android phone.
5 |
6 | :copyright: 2016 Gaetano Bonofiglio, MIT License.
7 |
--------------------------------------------------------------------------------