update
This commit is contained in:
2
Assets/Third Parties/BuildReport/Scripts/Editor.meta
Normal file
2
Assets/Third Parties/BuildReport/Scripts/Editor.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 39eb7498cc81e4d4dbedb83cbc8000de
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace BuildReportTool
|
||||
{
|
||||
public static class Info
|
||||
{
|
||||
public const string ReadableVersion = "Build Report Tool v3.11.9";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 70fb2953aa9990f4e81dfe9ff2142917
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"name": "BuildReportTool",
|
||||
"references": [],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 050ecfeccd482f24a8fcc4e107befa75
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6b0f5b37c5f879a498fece214132bbda
|
||||
folderAsset: yes
|
||||
timeCreated: 1480240136
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,155 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace FuzzyString
|
||||
{
|
||||
public static partial class ComparisonMetrics
|
||||
{
|
||||
public static double GetFuzzyEqualityScore(this string source, string target, params FuzzyStringComparisonOptions[] options)
|
||||
{
|
||||
List<double> comparisonResults = new List<double>();
|
||||
|
||||
if (!options.Contains(FuzzyStringComparisonOptions.CaseSensitive))
|
||||
{
|
||||
source = source.Capitalize();
|
||||
target = target.Capitalize();
|
||||
}
|
||||
|
||||
// Min: 0 Max: source.Length = target.Length
|
||||
if (options.Contains(FuzzyStringComparisonOptions.UseHammingDistance))
|
||||
{
|
||||
if (source.Length == target.Length)
|
||||
{
|
||||
comparisonResults.Add(source.HammingDistance(target)/target.Length);
|
||||
}
|
||||
}
|
||||
|
||||
// Min: 0 Max: 1
|
||||
if (options.Contains(FuzzyStringComparisonOptions.UseJaccardDistance))
|
||||
{
|
||||
comparisonResults.Add(source.JaccardDistance(target));
|
||||
}
|
||||
|
||||
// Min: 0 Max: 1
|
||||
if (options.Contains(FuzzyStringComparisonOptions.UseJaroDistance))
|
||||
{
|
||||
comparisonResults.Add(source.JaroDistance(target));
|
||||
}
|
||||
|
||||
// Min: 0 Max: 1
|
||||
if (options.Contains(FuzzyStringComparisonOptions.UseJaroWinklerDistance))
|
||||
{
|
||||
comparisonResults.Add(source.JaroWinklerDistance(target));
|
||||
}
|
||||
|
||||
// Min: 0 Max: LevenshteinDistanceUpperBounds - LevenshteinDistanceLowerBounds
|
||||
// Min: LevenshteinDistanceLowerBounds Max: LevenshteinDistanceUpperBounds
|
||||
if (options.Contains(FuzzyStringComparisonOptions.UseNormalizedLevenshteinDistance))
|
||||
{
|
||||
comparisonResults.Add(Convert.ToDouble(source.NormalizedLevenshteinDistance(target))/
|
||||
Convert.ToDouble((Math.Max(source.Length, target.Length) - source.LevenshteinDistanceLowerBounds(target))));
|
||||
}
|
||||
else if (options.Contains(FuzzyStringComparisonOptions.UseLevenshteinDistance))
|
||||
{
|
||||
comparisonResults.Add(Convert.ToDouble(source.LevenshteinDistance(target))/
|
||||
Convert.ToDouble(source.LevenshteinDistanceUpperBounds(target)));
|
||||
}
|
||||
|
||||
if (options.Contains(FuzzyStringComparisonOptions.UseLongestCommonSubsequence))
|
||||
{
|
||||
comparisonResults.Add(1 -
|
||||
Convert.ToDouble((source.LongestCommonSubsequence(target).Length)/
|
||||
Convert.ToDouble(Math.Min(source.Length, target.Length))));
|
||||
}
|
||||
|
||||
if (options.Contains(FuzzyStringComparisonOptions.UseLongestCommonSubstring))
|
||||
{
|
||||
comparisonResults.Add(1 -
|
||||
Convert.ToDouble((source.LongestCommonSubstring(target).Length)/
|
||||
Convert.ToDouble(Math.Min(source.Length, target.Length))));
|
||||
}
|
||||
|
||||
// Min: 0 Max: 1
|
||||
if (options.Contains(FuzzyStringComparisonOptions.UseSorensenDiceDistance))
|
||||
{
|
||||
comparisonResults.Add(source.SorensenDiceDistance(target));
|
||||
}
|
||||
|
||||
// Min: 0 Max: 1
|
||||
if (options.Contains(FuzzyStringComparisonOptions.UseOverlapCoefficient))
|
||||
{
|
||||
comparisonResults.Add(1 - source.OverlapCoefficient(target));
|
||||
}
|
||||
|
||||
// Min: 0 Max: 1
|
||||
if (options.Contains(FuzzyStringComparisonOptions.UseRatcliffObershelpSimilarity))
|
||||
{
|
||||
comparisonResults.Add(1 - source.RatcliffObershelpSimilarity(target));
|
||||
}
|
||||
|
||||
return comparisonResults.Average();
|
||||
}
|
||||
|
||||
|
||||
public static bool ApproximatelyEquals(this string source, string target, FuzzyStringComparisonTolerance tolerance, params FuzzyStringComparisonOptions[] options)
|
||||
{
|
||||
if (options.Length == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var score = source.GetFuzzyEqualityScore(target, options);
|
||||
|
||||
if (tolerance == FuzzyStringComparisonTolerance.Strong)
|
||||
{
|
||||
if (score < 0.25)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (tolerance == FuzzyStringComparisonTolerance.Normal)
|
||||
{
|
||||
if (score < 0.5)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (tolerance == FuzzyStringComparisonTolerance.Weak)
|
||||
{
|
||||
if (score < 0.75)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (tolerance == FuzzyStringComparisonTolerance.Manual)
|
||||
{
|
||||
if (score > 0.6)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 52c9e315ce408da44a5051f07f4d77c2
|
||||
timeCreated: 1480240216
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace FuzzyString
|
||||
{
|
||||
public enum FuzzyStringComparisonOptions
|
||||
{
|
||||
UseHammingDistance,
|
||||
|
||||
UseJaccardDistance,
|
||||
|
||||
UseJaroDistance,
|
||||
|
||||
UseJaroWinklerDistance,
|
||||
|
||||
UseLevenshteinDistance,
|
||||
|
||||
UseLongestCommonSubsequence,
|
||||
|
||||
UseLongestCommonSubstring,
|
||||
|
||||
UseNormalizedLevenshteinDistance,
|
||||
|
||||
UseOverlapCoefficient,
|
||||
|
||||
UseRatcliffObershelpSimilarity,
|
||||
|
||||
UseSorensenDiceDistance,
|
||||
|
||||
UseTanimotoCoefficient,
|
||||
|
||||
CaseSensitive
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8418a062dc45ffa41b5edf5f6c1ace75
|
||||
timeCreated: 1480240216
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace FuzzyString
|
||||
{
|
||||
public enum FuzzyStringComparisonTolerance
|
||||
{
|
||||
Strong,
|
||||
|
||||
Normal,
|
||||
|
||||
Weak,
|
||||
|
||||
Manual
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 142b46597f1b8c649a575d39d52f0e60
|
||||
timeCreated: 1480240216
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,87 @@
|
||||
Eclipse Public License -v 1.0
|
||||
|
||||
THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
|
||||
|
||||
1. DEFINITIONS
|
||||
|
||||
"Contribution" means:
|
||||
|
||||
a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and
|
||||
|
||||
b) in the case of each subsequent Contributor:
|
||||
|
||||
i) changes to the Program, and
|
||||
|
||||
ii) additions to the Program;
|
||||
|
||||
where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program.
|
||||
|
||||
"Contributor" means any person or entity that distributes the Program.
|
||||
|
||||
"Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program.
|
||||
|
||||
"Program" means the Contributions distributed in accordance with this Agreement.
|
||||
|
||||
"Recipient" means anyone who receives the Program under this Agreement, including all Contributors.
|
||||
|
||||
2. GRANT OF RIGHTS
|
||||
|
||||
a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form.
|
||||
|
||||
b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder.
|
||||
|
||||
c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program.
|
||||
|
||||
d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement.
|
||||
|
||||
3. REQUIREMENTS
|
||||
|
||||
A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that:
|
||||
|
||||
a) it complies with the terms and conditions of this Agreement; and
|
||||
|
||||
b) its license agreement:
|
||||
|
||||
i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose;
|
||||
|
||||
ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits;
|
||||
|
||||
iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and
|
||||
|
||||
iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange.
|
||||
|
||||
When the Program is made available in source code form:
|
||||
|
||||
a) it must be made available under this Agreement; and
|
||||
|
||||
b) a copy of this Agreement must be included with each copy of the Program.
|
||||
|
||||
Contributors may not remove or alter any copyright notices contained within the Program.
|
||||
|
||||
Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution.
|
||||
|
||||
4. COMMERCIAL DISTRIBUTION
|
||||
|
||||
Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense.
|
||||
|
||||
For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages.
|
||||
|
||||
5. NO WARRANTY
|
||||
|
||||
EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement , including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations.
|
||||
|
||||
6. DISCLAIMER OF LIABILITY
|
||||
|
||||
EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
7. GENERAL
|
||||
|
||||
If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable.
|
||||
|
||||
If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed.
|
||||
|
||||
All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive.
|
||||
|
||||
Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. The Eclipse Foundation is the initial Agreement Steward. The Eclipse Foundation may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved.
|
||||
|
||||
This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation.
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 231bc3d9a68d6444b82e673f1aa4aeee
|
||||
timeCreated: 1480240220
|
||||
licenseType: Store
|
||||
TextScriptImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace FuzzyString
|
||||
{
|
||||
public static partial class ComparisonMetrics
|
||||
{
|
||||
public static int HammingDistance(this string source, string target)
|
||||
{
|
||||
int distance = 0;
|
||||
|
||||
if (source.Length == target.Length)
|
||||
{
|
||||
for (int i = 0; i < source.Length; i++)
|
||||
{
|
||||
if (!source[i].Equals(target[i]))
|
||||
{
|
||||
distance++;
|
||||
}
|
||||
}
|
||||
return distance;
|
||||
}
|
||||
else { return 99999; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 442805575a155b34eb98cbef87ee3955
|
||||
timeCreated: 1480240216
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace FuzzyString
|
||||
{
|
||||
public static partial class ComparisonMetrics
|
||||
{
|
||||
public static double JaccardDistance(this string source, string target)
|
||||
{
|
||||
return 1 - source.JaccardIndex(target);
|
||||
}
|
||||
|
||||
public static double JaccardIndex(this string source, string target)
|
||||
{
|
||||
return (Convert.ToDouble(source.Intersect(target).Count())) / (Convert.ToDouble(source.Union(target).Count()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6d1e6db0392d10341a8c25c2154ddcee
|
||||
timeCreated: 1480240216
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace FuzzyString
|
||||
{
|
||||
public static partial class ComparisonMetrics
|
||||
{
|
||||
public static double JaroDistance(this string source, string target)
|
||||
{
|
||||
int m = source.Intersect(target).Count();
|
||||
|
||||
if (m == 0) { return 0; }
|
||||
else
|
||||
{
|
||||
string sourceTargetIntersetAsString = "";
|
||||
string targetSourceIntersetAsString = "";
|
||||
IEnumerable<char> sourceIntersectTarget = source.Intersect(target);
|
||||
IEnumerable<char> targetIntersectSource = target.Intersect(source);
|
||||
foreach (char character in sourceIntersectTarget) { sourceTargetIntersetAsString += character; }
|
||||
foreach (char character in targetIntersectSource) { targetSourceIntersetAsString += character; }
|
||||
double t = sourceTargetIntersetAsString.LevenshteinDistance(targetSourceIntersetAsString) / 2;
|
||||
return ((m / source.Length) + (m / target.Length) + ((m - t) / m)) / 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 91f3890fdf8883346ad1f5871d897baf
|
||||
timeCreated: 1480240216
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,47 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace FuzzyString
|
||||
{
|
||||
public static partial class ComparisonMetrics
|
||||
{
|
||||
public static double JaroWinklerDistance(this string source, string target)
|
||||
{
|
||||
double jaroDistance = source.JaroDistance(target);
|
||||
double commonPrefixLength = CommonPrefixLength(source, target);
|
||||
|
||||
return jaroDistance + (commonPrefixLength * 0.1 * (1 - jaroDistance));
|
||||
}
|
||||
|
||||
public static double JaroWinklerDistanceWithPrefixScale(string source, string target, double p)
|
||||
{
|
||||
double prefixScale = 0.1;
|
||||
|
||||
if (p > 0.25) { prefixScale = 0.25; } // The maximu value for distance to not exceed 1
|
||||
else if (p < 0) { prefixScale = 0; } // The Jaro Distance
|
||||
else { prefixScale = p; }
|
||||
|
||||
double jaroDistance = source.JaroDistance(target);
|
||||
double commonPrefixLength = CommonPrefixLength(source, target);
|
||||
|
||||
return jaroDistance + (commonPrefixLength * prefixScale * (1 - jaroDistance));
|
||||
}
|
||||
|
||||
private static double CommonPrefixLength(string source, string target)
|
||||
{
|
||||
int maximumPrefixLength = 4;
|
||||
int commonPrefixLength = 0;
|
||||
if (source.Length <= 4 || target.Length <= 4) { maximumPrefixLength = Math.Min(source.Length, target.Length); }
|
||||
|
||||
for (int i = 0; i < maximumPrefixLength; i++)
|
||||
{
|
||||
if (source[i].Equals(target[i])) { commonPrefixLength++; }
|
||||
else { return commonPrefixLength; }
|
||||
}
|
||||
|
||||
return commonPrefixLength;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b91a749102d81ad4daf9827850ead7dc
|
||||
timeCreated: 1480240217
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,54 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace FuzzyString
|
||||
{
|
||||
public static partial class ComparisonMetrics
|
||||
{
|
||||
public static int LevenshteinDistance(this string source, string target)
|
||||
{
|
||||
if (source.Length == 0) { return target.Length; }
|
||||
if (target.Length == 0) { return source.Length; }
|
||||
|
||||
int distance = 0;
|
||||
|
||||
if (source[source.Length - 1] == target[target.Length - 1]) { distance = 0; }
|
||||
else { distance = 1; }
|
||||
|
||||
return Math.Min(Math.Min(LevenshteinDistance(source.Substring(0, source.Length - 1), target) + 1,
|
||||
LevenshteinDistance(source, target.Substring(0, target.Length - 1))) + 1,
|
||||
LevenshteinDistance(source.Substring(0, source.Length - 1), target.Substring(0, target.Length - 1)) + distance);
|
||||
}
|
||||
|
||||
public static double NormalizedLevenshteinDistance(this string source, string target)
|
||||
{
|
||||
int unnormalizedLevenshteinDistance = source.LevenshteinDistance(target);
|
||||
|
||||
return unnormalizedLevenshteinDistance - source.LevenshteinDistanceLowerBounds(target);
|
||||
}
|
||||
|
||||
public static int LevenshteinDistanceUpperBounds(this string source, string target)
|
||||
{
|
||||
// If the two strings are the same length then the Hamming Distance is the upper bounds of the Levenshtien Distance.
|
||||
if (source.Length == target.Length) { return source.HammingDistance(target); }
|
||||
|
||||
// Otherwise, the upper bound is the length of the longer string.
|
||||
else if (source.Length > target.Length) { return source.Length; }
|
||||
else if (target.Length > source.Length) { return target.Length; }
|
||||
|
||||
return 9999;
|
||||
}
|
||||
|
||||
public static int LevenshteinDistanceLowerBounds(this string source, string target)
|
||||
{
|
||||
// If the two strings are the same length then the lower bound is zero.
|
||||
if (source.Length == target.Length) { return 0; }
|
||||
|
||||
// If the two strings are different lengths then the lower bounds is the difference in length.
|
||||
else { return Math.Abs(source.Length - target.Length); }
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d2eb81c9a38774d48ae2e2788e109092
|
||||
timeCreated: 1480240217
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,65 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace FuzzyString
|
||||
{
|
||||
public static partial class ComparisonMetrics
|
||||
{
|
||||
public static string LongestCommonSubsequence(this string source, string target)
|
||||
{
|
||||
int[,] C = LongestCommonSubsequenceLengthTable(source, target);
|
||||
|
||||
return Backtrack(C, source, target, source.Length, target.Length);
|
||||
}
|
||||
|
||||
private static int[,] LongestCommonSubsequenceLengthTable(string source, string target)
|
||||
{
|
||||
int[,] C = new int[source.Length + 1, target.Length + 1];
|
||||
|
||||
for (int i = 0; i < source.Length + 1; i++) { C[i, 0] = 0; }
|
||||
for (int j = 0; j < target.Length + 1; j++) { C[0, j] = 0; }
|
||||
|
||||
for (int i = 1; i < source.Length + 1; i++)
|
||||
{
|
||||
for (int j = 1; j < target.Length + 1; j++)
|
||||
{
|
||||
if (source[i - 1].Equals(target[j - 1]))
|
||||
{
|
||||
C[i, j] = C[i - 1, j - 1] + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
C[i, j] = Math.Max(C[i, j - 1], C[i - 1, j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return C;
|
||||
}
|
||||
|
||||
private static string Backtrack(int[,] C, string source, string target, int i, int j)
|
||||
{
|
||||
if (i == 0 || j == 0)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
else if (source[i - 1].Equals(target[j - 1]))
|
||||
{
|
||||
return Backtrack(C, source, target, i - 1, j - 1) + source[i - 1];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (C[i, j - 1] > C[i - 1, j])
|
||||
{
|
||||
return Backtrack(C, source, target, i, j - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
return Backtrack(C, source, target, i - 1, j);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e92ef006685958347b7bac1e79a34956
|
||||
timeCreated: 1480240217
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,57 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace FuzzyString
|
||||
{
|
||||
public static partial class ComparisonMetrics
|
||||
{
|
||||
public static string LongestCommonSubstring(this string source, string target)
|
||||
{
|
||||
if (String.IsNullOrEmpty(source) || String.IsNullOrEmpty(target)) { return null; }
|
||||
|
||||
int[,] L = new int[source.Length, target.Length];
|
||||
int maximumLength = 0;
|
||||
int lastSubsBegin = 0;
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
|
||||
for (int i = 0; i < source.Length; i++)
|
||||
{
|
||||
for (int j = 0; j < target.Length; j++)
|
||||
{
|
||||
if (source[i] != target[j])
|
||||
{
|
||||
L[i, j] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((i == 0) || (j == 0))
|
||||
L[i, j] = 1;
|
||||
else
|
||||
L[i, j] = 1 + L[i - 1, j - 1];
|
||||
|
||||
if (L[i, j] > maximumLength)
|
||||
{
|
||||
maximumLength = L[i, j];
|
||||
int thisSubsBegin = i - L[i, j] + 1;
|
||||
if (lastSubsBegin == thisSubsBegin)
|
||||
{//if the current LCS is the same as the last time this block ran
|
||||
stringBuilder.Append(source[i]);
|
||||
}
|
||||
else //this block resets the string builder if a different LCS is found
|
||||
{
|
||||
lastSubsBegin = thisSubsBegin;
|
||||
stringBuilder.Length = 0; //clear it
|
||||
stringBuilder.Append(source.Substring(lastSubsBegin, (i + 1) - lastSubsBegin));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return stringBuilder.ToString();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6c12917da8d444f4ead18cda49cb1b0a
|
||||
timeCreated: 1480240216
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,84 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace FuzzyString
|
||||
{
|
||||
public static partial class Operations
|
||||
{
|
||||
public static string Capitalize(this string source)
|
||||
{
|
||||
return source.ToUpper();
|
||||
}
|
||||
|
||||
public static string[] SplitIntoIndividualElements(string source)
|
||||
{
|
||||
string[] stringCollection = new string[source.Length];
|
||||
|
||||
for (int i = 0; i < stringCollection.Length; i++)
|
||||
{
|
||||
stringCollection[i] = source[i].ToString();
|
||||
}
|
||||
|
||||
return stringCollection;
|
||||
}
|
||||
|
||||
public static string MergeIndividualElementsIntoString(IEnumerable<string> source)
|
||||
{
|
||||
string returnString = "";
|
||||
|
||||
for (int i = 0; i < source.Count(); i++)
|
||||
{
|
||||
returnString += source.ElementAt<string>(i);
|
||||
}
|
||||
return returnString;
|
||||
}
|
||||
|
||||
public static List<string> ListPrefixes(this string source)
|
||||
{
|
||||
List<string> prefixes = new List<string>();
|
||||
|
||||
for (int i = 0; i < source.Length; i++)
|
||||
{
|
||||
prefixes.Add(source.Substring(0, i));
|
||||
}
|
||||
|
||||
return prefixes;
|
||||
}
|
||||
|
||||
public static List<string> ListBiGrams(this string source)
|
||||
{
|
||||
return ListNGrams(source, 2);
|
||||
}
|
||||
|
||||
public static List<string> ListTriGrams(this string source)
|
||||
{
|
||||
return ListNGrams(source, 3);
|
||||
}
|
||||
|
||||
public static List<string> ListNGrams(this string source, int n)
|
||||
{
|
||||
List<string> nGrams = new List<string>();
|
||||
|
||||
if (n > source.Length)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else if (n == source.Length)
|
||||
{
|
||||
nGrams.Add(source);
|
||||
return nGrams;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < source.Length - n; i++)
|
||||
{
|
||||
nGrams.Add(source.Substring(i, n));
|
||||
}
|
||||
|
||||
return nGrams;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1099ad1dfff8e364bbfd13fa796b6ad3
|
||||
timeCreated: 1480240216
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace FuzzyString
|
||||
{
|
||||
public static partial class ComparisonMetrics
|
||||
{
|
||||
public static double OverlapCoefficient(this string source, string target)
|
||||
{
|
||||
return (Convert.ToDouble(source.Intersect(target).Count())) / Convert.ToDouble(Math.Min(source.Length, target.Length));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9d9e58b928ef76c45b076d10be498295
|
||||
timeCreated: 1480240216
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace FuzzyString
|
||||
{
|
||||
public static partial class ComparisonMetrics
|
||||
{
|
||||
public static double RatcliffObershelpSimilarity(this string source, string target)
|
||||
{
|
||||
return (2 * Convert.ToDouble(source.Intersect(target).Count())) / (Convert.ToDouble(source.Length + target.Length));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 91761eda3a4ce614d8e6155b58573f9e
|
||||
timeCreated: 1480240216
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace FuzzyString
|
||||
{
|
||||
public static partial class ComparisonMetrics
|
||||
{
|
||||
public static double SorensenDiceDistance(this string source, string target)
|
||||
{
|
||||
return 1 - source.SorensenDiceIndex(target);
|
||||
}
|
||||
|
||||
public static double SorensenDiceIndex(this string source, string target)
|
||||
{
|
||||
return (2 * Convert.ToDouble(source.Intersect(target).Count())) / (Convert.ToDouble(source.Length + target.Length));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a4f986a8582fa1746b9341fb8600e0b5
|
||||
timeCreated: 1480240216
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,19 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace FuzzyString
|
||||
{
|
||||
public static partial class ComparisonMetrics
|
||||
{
|
||||
public static double TanimotoCoefficient(this string source, string target)
|
||||
{
|
||||
double Na = source.Length;
|
||||
double Nb = target.Length;
|
||||
double Nc = source.Intersect(target).Count();
|
||||
|
||||
return Nc / (Na + Nb - Nc);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 81089ababf44160429ce96d78cef55a6
|
||||
timeCreated: 1480240216
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 13a482ba4833cff4aaccee9b9e1c3fe6
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,588 @@
|
||||
/*
|
||||
* Copyright (c) 2013 Calvin Rien
|
||||
*
|
||||
* Based on the JSON parser by Patrick van Bergen
|
||||
* http://techblog.procurios.nl/k/618/news/view/14605/14863/How-do-I-write-my-own-parser-for-JSON.html
|
||||
*
|
||||
* Simplified it so that it doesn't throw exceptions
|
||||
* and can be used in Unity iPhone with maximum code stripping.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace MiniJSON {
|
||||
// Example usage:
|
||||
//
|
||||
// using UnityEngine;
|
||||
// using System.Collections;
|
||||
// using System.Collections.Generic;
|
||||
// using MiniJSON;
|
||||
//
|
||||
// public class MiniJSONTest : MonoBehaviour {
|
||||
// void Start () {
|
||||
// var jsonString = "{ \"array\": [1.44,2,3], " +
|
||||
// "\"object\": {\"key1\":\"value1\", \"key2\":256}, " +
|
||||
// "\"string\": \"The quick brown fox \\\"jumps\\\" over the lazy dog \", " +
|
||||
// "\"unicode\": \"\\u3041 Men\u00fa sesi\u00f3n\", " +
|
||||
// "\"int\": 65536, " +
|
||||
// "\"float\": 3.1415926, " +
|
||||
// "\"bool\": true, " +
|
||||
// "\"null\": null }";
|
||||
//
|
||||
// var dict = Json.Deserialize(jsonString) as Dictionary<string,object>;
|
||||
//
|
||||
// Debug.Log("deserialized: " + dict.GetType());
|
||||
// Debug.Log("dict['array'][0]: " + ((List<object>) dict["array"])[0]);
|
||||
// Debug.Log("dict['string']: " + (string) dict["string"]);
|
||||
// Debug.Log("dict['float']: " + (double) dict["float"]); // floats come out as doubles
|
||||
// Debug.Log("dict['int']: " + (long) dict["int"]); // ints come out as longs
|
||||
// Debug.Log("dict['unicode']: " + (string) dict["unicode"]);
|
||||
//
|
||||
// var str = Json.Serialize(dict);
|
||||
//
|
||||
// Debug.Log("serialized: " + str);
|
||||
// }
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// This class encodes and decodes JSON strings.
|
||||
/// Spec. details, see http://www.json.org/
|
||||
///
|
||||
/// JSON uses Arrays and Objects. These correspond here to the datatypes IList and IDictionary.
|
||||
/// All numbers are parsed to doubles.
|
||||
/// </summary>
|
||||
public static class Json {
|
||||
/// <summary>
|
||||
/// Parses the string json into a value
|
||||
/// </summary>
|
||||
/// <param name="json">A JSON string.</param>
|
||||
/// <returns>An List<object>, a Dictionary<string, object>, a double, an integer,a string, null, true, or false</returns>
|
||||
public static object Deserialize(string json) {
|
||||
// save the string for debug information
|
||||
if (string.IsNullOrEmpty(json)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return Parser.Parse(json);
|
||||
}
|
||||
|
||||
sealed class Parser : IDisposable {
|
||||
const string WORD_BREAK = "{}[],:\"";
|
||||
|
||||
public static bool IsWordBreak(char c) {
|
||||
return Char.IsWhiteSpace(c) || WORD_BREAK.IndexOf(c) != -1;
|
||||
}
|
||||
|
||||
const string HEX_DIGIT = "0123456789ABCDEFabcdef";
|
||||
|
||||
public static bool IsHexDigit(char c) {
|
||||
return HEX_DIGIT.IndexOf(c) != -1;
|
||||
}
|
||||
|
||||
enum TOKEN {
|
||||
NONE,
|
||||
CURLY_OPEN,
|
||||
CURLY_CLOSE,
|
||||
SQUARED_OPEN,
|
||||
SQUARED_CLOSE,
|
||||
COLON,
|
||||
COMMA,
|
||||
STRING,
|
||||
NUMBER,
|
||||
TRUE,
|
||||
FALSE,
|
||||
NULL
|
||||
};
|
||||
|
||||
StringReader json;
|
||||
|
||||
Parser(string jsonString) {
|
||||
json = new StringReader(jsonString);
|
||||
}
|
||||
|
||||
public static object Parse(string jsonString) {
|
||||
using (var instance = new Parser(jsonString)) {
|
||||
return instance.ParseValue();
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose() {
|
||||
json.Dispose();
|
||||
json = null;
|
||||
}
|
||||
|
||||
Dictionary<string, object> ParseObject() {
|
||||
Dictionary<string, object> table = new Dictionary<string, object>();
|
||||
|
||||
// ditch opening brace
|
||||
json.Read();
|
||||
|
||||
// {
|
||||
while (true) {
|
||||
switch (NextToken) {
|
||||
case TOKEN.NONE:
|
||||
return null;
|
||||
case TOKEN.COMMA:
|
||||
continue;
|
||||
case TOKEN.CURLY_CLOSE:
|
||||
return table;
|
||||
case TOKEN.STRING:
|
||||
// name
|
||||
string name = ParseString();
|
||||
if (name == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// :
|
||||
if (NextToken != TOKEN.COLON) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// ditch the colon
|
||||
json.Read();
|
||||
|
||||
// value
|
||||
TOKEN valueToken = NextToken;
|
||||
object value = ParseByToken(valueToken);
|
||||
if(value==null && valueToken!=TOKEN.NULL)
|
||||
return null;
|
||||
table[name] = value;
|
||||
break;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<object> ParseArray() {
|
||||
List<object> array = null;
|
||||
|
||||
// ditch opening bracket
|
||||
json.Read();
|
||||
|
||||
// [
|
||||
var parsing = true;
|
||||
while (parsing) {
|
||||
TOKEN nextToken = NextToken;
|
||||
|
||||
switch (nextToken) {
|
||||
case TOKEN.NONE:
|
||||
return null;
|
||||
case TOKEN.COMMA:
|
||||
continue;
|
||||
case TOKEN.SQUARED_CLOSE:
|
||||
parsing = false;
|
||||
break;
|
||||
default:
|
||||
object value = ParseByToken(nextToken);
|
||||
if(value==null && nextToken!=TOKEN.NULL)
|
||||
return null;
|
||||
if (array == null) {
|
||||
array = new List<object>();
|
||||
}
|
||||
array.Add(value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (array == null) {
|
||||
array = new List<object>();
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
object ParseValue() {
|
||||
TOKEN nextToken = NextToken;
|
||||
return ParseByToken(nextToken);
|
||||
}
|
||||
|
||||
object ParseByToken(TOKEN token) {
|
||||
switch (token) {
|
||||
case TOKEN.STRING:
|
||||
return ParseString();
|
||||
case TOKEN.NUMBER:
|
||||
return ParseNumber();
|
||||
case TOKEN.CURLY_OPEN:
|
||||
return ParseObject();
|
||||
case TOKEN.SQUARED_OPEN:
|
||||
return ParseArray();
|
||||
case TOKEN.TRUE:
|
||||
return true;
|
||||
case TOKEN.FALSE:
|
||||
return false;
|
||||
case TOKEN.NULL:
|
||||
return null;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
string ParseString() {
|
||||
StringBuilder s = new StringBuilder();
|
||||
char c;
|
||||
|
||||
// ditch opening quote
|
||||
json.Read();
|
||||
|
||||
bool parsing = true;
|
||||
while (parsing) {
|
||||
|
||||
if (json.Peek() == -1) {
|
||||
parsing = false;
|
||||
break;
|
||||
}
|
||||
|
||||
c = NextChar;
|
||||
switch (c) {
|
||||
case '"':
|
||||
parsing = false;
|
||||
break;
|
||||
case '\\':
|
||||
if (json.Peek() == -1) {
|
||||
parsing = false;
|
||||
break;
|
||||
}
|
||||
|
||||
c = NextChar;
|
||||
switch (c) {
|
||||
case '"':
|
||||
case '\\':
|
||||
case '/':
|
||||
s.Append(c);
|
||||
break;
|
||||
case 'b':
|
||||
s.Append('\b');
|
||||
break;
|
||||
case 'f':
|
||||
s.Append('\f');
|
||||
break;
|
||||
case 'n':
|
||||
s.Append('\n');
|
||||
break;
|
||||
case 'r':
|
||||
s.Append('\r');
|
||||
break;
|
||||
case 't':
|
||||
s.Append('\t');
|
||||
break;
|
||||
case 'u':
|
||||
var hex = new char[4];
|
||||
|
||||
for (int i=0; i< 4; i++) {
|
||||
hex[i] = NextChar;
|
||||
if (!IsHexDigit(hex[i]))
|
||||
return null;
|
||||
}
|
||||
|
||||
s.Append((char) Convert.ToInt32(new string(hex), 16));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
s.Append(c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return s.ToString();
|
||||
}
|
||||
|
||||
object ParseNumber() {
|
||||
string number = NextWord;
|
||||
|
||||
if (number.IndexOf('.') == -1 && number.IndexOf('E') == -1 && number.IndexOf('e') == -1) {
|
||||
long parsedInt;
|
||||
Int64.TryParse(number, System.Globalization.NumberStyles.Any, System.Globalization.CultureInfo.InvariantCulture, out parsedInt);
|
||||
if (parsedInt == 0) {
|
||||
ulong parsedUInt;
|
||||
UInt64.TryParse(number, System.Globalization.NumberStyles.Any, System.Globalization.CultureInfo.InvariantCulture, out parsedUInt);
|
||||
return parsedUInt;
|
||||
}
|
||||
return parsedInt;
|
||||
}
|
||||
|
||||
double parsedDouble;
|
||||
Double.TryParse(number, System.Globalization.NumberStyles.Any, System.Globalization.CultureInfo.InvariantCulture, out parsedDouble);
|
||||
return parsedDouble;
|
||||
}
|
||||
|
||||
void EatWhitespace() {
|
||||
while (Char.IsWhiteSpace(PeekChar)) {
|
||||
json.Read();
|
||||
|
||||
if (json.Peek() == -1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char PeekChar {
|
||||
get {
|
||||
return Convert.ToChar(json.Peek());
|
||||
}
|
||||
}
|
||||
|
||||
char NextChar {
|
||||
get {
|
||||
return Convert.ToChar(json.Read());
|
||||
}
|
||||
}
|
||||
|
||||
string NextWord {
|
||||
get {
|
||||
StringBuilder word = new StringBuilder();
|
||||
|
||||
while (!IsWordBreak(PeekChar)) {
|
||||
word.Append(NextChar);
|
||||
|
||||
if (json.Peek() == -1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return word.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
TOKEN NextToken {
|
||||
get {
|
||||
EatWhitespace();
|
||||
|
||||
if (json.Peek() == -1) {
|
||||
return TOKEN.NONE;
|
||||
}
|
||||
|
||||
switch (PeekChar) {
|
||||
case '{':
|
||||
return TOKEN.CURLY_OPEN;
|
||||
case '}':
|
||||
json.Read();
|
||||
return TOKEN.CURLY_CLOSE;
|
||||
case '[':
|
||||
return TOKEN.SQUARED_OPEN;
|
||||
case ']':
|
||||
json.Read();
|
||||
return TOKEN.SQUARED_CLOSE;
|
||||
case ',':
|
||||
json.Read();
|
||||
return TOKEN.COMMA;
|
||||
case '"':
|
||||
return TOKEN.STRING;
|
||||
case ':':
|
||||
return TOKEN.COLON;
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
case '-':
|
||||
return TOKEN.NUMBER;
|
||||
}
|
||||
|
||||
switch (NextWord) {
|
||||
case "false":
|
||||
return TOKEN.FALSE;
|
||||
case "true":
|
||||
return TOKEN.TRUE;
|
||||
case "null":
|
||||
return TOKEN.NULL;
|
||||
}
|
||||
|
||||
return TOKEN.NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a IDictionary / IList object or a simple type (string, int, etc.) into a JSON string
|
||||
/// </summary>
|
||||
/// <param name="obj">A Dictionary<string, object> / List<object></param>
|
||||
/// <returns>A JSON encoded string, or null if object 'json' is not serializable</returns>
|
||||
public static string Serialize(object obj) {
|
||||
return Serializer.Serialize(obj);
|
||||
}
|
||||
|
||||
sealed class Serializer {
|
||||
StringBuilder builder;
|
||||
|
||||
Serializer() {
|
||||
builder = new StringBuilder();
|
||||
}
|
||||
|
||||
public static string Serialize(object obj) {
|
||||
var instance = new Serializer();
|
||||
|
||||
instance.SerializeValue(obj);
|
||||
|
||||
return instance.builder.ToString();
|
||||
}
|
||||
|
||||
void SerializeValue(object value) {
|
||||
IList asList;
|
||||
IDictionary asDict;
|
||||
string asStr;
|
||||
|
||||
if (value == null) {
|
||||
builder.Append("null");
|
||||
} else if ((asStr = value as string) != null) {
|
||||
SerializeString(asStr);
|
||||
} else if (value is bool) {
|
||||
builder.Append((bool) value ? "true" : "false");
|
||||
} else if ((asList = value as IList) != null) {
|
||||
SerializeArray(asList);
|
||||
} else if ((asDict = value as IDictionary) != null) {
|
||||
SerializeObject(asDict);
|
||||
} else if (value is char) {
|
||||
SerializeString(new string((char) value, 1));
|
||||
} else {
|
||||
SerializeOther(value);
|
||||
}
|
||||
}
|
||||
|
||||
void SerializeObject(IDictionary obj) {
|
||||
bool first = true;
|
||||
|
||||
builder.Append('{');
|
||||
|
||||
foreach (object e in obj.Keys) {
|
||||
if (!first) {
|
||||
builder.Append(',');
|
||||
}
|
||||
|
||||
SerializeString(e.ToString());
|
||||
builder.Append(':');
|
||||
|
||||
SerializeValue(obj[e]);
|
||||
|
||||
first = false;
|
||||
}
|
||||
|
||||
builder.Append('}');
|
||||
}
|
||||
|
||||
void SerializeArray(IList anArray) {
|
||||
builder.Append('[');
|
||||
|
||||
bool first = true;
|
||||
|
||||
for (int i=0; i<anArray.Count; i++) {
|
||||
object obj = anArray[i];
|
||||
if (!first) {
|
||||
builder.Append(',');
|
||||
}
|
||||
|
||||
SerializeValue(obj);
|
||||
|
||||
first = false;
|
||||
}
|
||||
|
||||
builder.Append(']');
|
||||
}
|
||||
|
||||
void SerializeString(string str) {
|
||||
builder.Append('\"');
|
||||
|
||||
char[] charArray = str.ToCharArray();
|
||||
for (int i=0; i<charArray.Length; i++) {
|
||||
char c = charArray[i];
|
||||
switch (c) {
|
||||
case '"':
|
||||
builder.Append("\\\"");
|
||||
break;
|
||||
case '\\':
|
||||
builder.Append("\\\\");
|
||||
break;
|
||||
case '\b':
|
||||
builder.Append("\\b");
|
||||
break;
|
||||
case '\f':
|
||||
builder.Append("\\f");
|
||||
break;
|
||||
case '\n':
|
||||
builder.Append("\\n");
|
||||
break;
|
||||
case '\r':
|
||||
builder.Append("\\r");
|
||||
break;
|
||||
case '\t':
|
||||
builder.Append("\\t");
|
||||
break;
|
||||
default:
|
||||
int codepoint = Convert.ToInt32(c);
|
||||
if ((codepoint >= 32) && (codepoint <= 126)) {
|
||||
builder.Append(c);
|
||||
} else {
|
||||
builder.Append("\\u");
|
||||
builder.Append(codepoint.ToString("x4"));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
builder.Append('\"');
|
||||
}
|
||||
|
||||
void SerializeOther(object value) {
|
||||
// NOTE: decimals lose precision during serialization.
|
||||
// They always have, I'm just letting you know.
|
||||
// Previously floats and doubles lost precision too.
|
||||
if (value is float) {
|
||||
var numberToString = ((float)value).ToString("R", System.Globalization.CultureInfo.InvariantCulture);
|
||||
if (numberToString.IndexOf('.') < 0 && numberToString.IndexOf("E", StringComparison.OrdinalIgnoreCase) < 0) {
|
||||
// if whole number, add a ".0" at the end
|
||||
numberToString = string.Format("{0}.0", numberToString);
|
||||
}
|
||||
builder.Append(numberToString);
|
||||
} else if (value is int
|
||||
|| value is uint
|
||||
|| value is long
|
||||
|| value is sbyte
|
||||
|| value is byte
|
||||
|| value is short
|
||||
|| value is ushort
|
||||
|| value is ulong) {
|
||||
builder.Append(value);
|
||||
} else if (value is double
|
||||
|| value is decimal) {
|
||||
var numberToString = Convert.ToDouble(value).ToString("R", System.Globalization.CultureInfo.InvariantCulture);
|
||||
if (numberToString.IndexOf('.') < 0 && numberToString.IndexOf("E", StringComparison.OrdinalIgnoreCase) < 0) {
|
||||
// if whole number, add a ".0" at the end
|
||||
numberToString = string.Format("{0}.0", numberToString);
|
||||
}
|
||||
builder.Append(numberToString);
|
||||
} else {
|
||||
#if UNITY_5_3_OR_NEWER
|
||||
builder.Append(UnityEngine.JsonUtility.ToJson(value));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5b3621adf6fd24d4f9cc9b73338492c2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 01b9a87b36472424cac8f71d5f683dcc
|
||||
@@ -0,0 +1,476 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace BuildReportTool
|
||||
{
|
||||
[System.Serializable]
|
||||
public class FileFilters
|
||||
{
|
||||
public FileFilters(string label, string[] filters)
|
||||
{
|
||||
_label = label;
|
||||
|
||||
for (int n = 0, len = filters.Length; n < len; ++n)
|
||||
{
|
||||
_filtersDict.Add(filters[n], false);
|
||||
var shouldBeAllLowerCase = true;
|
||||
|
||||
if ((filters[n].StartsWith("/") || filters[n].StartsWith("Assets/", StringComparison.OrdinalIgnoreCase)) &&
|
||||
filters[n].EndsWith("/"))
|
||||
{
|
||||
_usesFolderFilter = true;
|
||||
}
|
||||
else if (filters[n].StartsWith(BUILT_IN_ASSET_KEYWORD, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
_usesFolderFilter = true;
|
||||
|
||||
// note: filters for built-in types are case-sensitive
|
||||
shouldBeAllLowerCase = false;
|
||||
|
||||
//Debug.Log("uses built-in: " + label + ", " + filters[n]);
|
||||
}
|
||||
else if (filters[n].StartsWith("\"") && filters[n].EndsWith("\""))
|
||||
{
|
||||
_usesExactFileMatching = true;
|
||||
}
|
||||
|
||||
if (shouldBeAllLowerCase)
|
||||
{
|
||||
filters[n] = filters[n].ToLower();
|
||||
}
|
||||
}
|
||||
|
||||
_filtersList = filters;
|
||||
}
|
||||
|
||||
public FileFilters()
|
||||
{
|
||||
_label = "";
|
||||
}
|
||||
|
||||
const string BUILT_IN_ASSET_KEYWORD = "Built-in";
|
||||
|
||||
|
||||
[SerializeField]
|
||||
string _label;
|
||||
|
||||
readonly Dictionary<string, bool> _filtersDict = new Dictionary<string, bool>();
|
||||
|
||||
[SerializeField]
|
||||
string[] _filtersList;
|
||||
|
||||
[SerializeField]
|
||||
bool _usesFolderFilter;
|
||||
|
||||
[SerializeField]
|
||||
bool _usesExactFileMatching;
|
||||
|
||||
public string Label
|
||||
{
|
||||
get { return _label; }
|
||||
set { _label = value; }
|
||||
}
|
||||
|
||||
public string[] FiltersList
|
||||
{
|
||||
get { return _filtersList; }
|
||||
set
|
||||
{
|
||||
_filtersList = value;
|
||||
|
||||
for (int n = 0, len = _filtersList.Length; n < len; ++n)
|
||||
{
|
||||
_filtersDict.Add(_filtersList[n], false);
|
||||
var shouldBeAllLowerCase = true;
|
||||
|
||||
if ((_filtersList[n].StartsWith("/") ||
|
||||
_filtersList[n].StartsWith("Assets/", StringComparison.OrdinalIgnoreCase)) &&
|
||||
_filtersList[n].EndsWith("/"))
|
||||
{
|
||||
_usesFolderFilter = true;
|
||||
}
|
||||
else if (_filtersList[n].StartsWith(BUILT_IN_ASSET_KEYWORD, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
_usesFolderFilter = true;
|
||||
shouldBeAllLowerCase = false;
|
||||
//Debug.Log("uses built-in: " + _label + ", " + _filtersList[n]);
|
||||
}
|
||||
else if (_filtersList[n].StartsWith("\"") && _filtersList[n].EndsWith("\""))
|
||||
{
|
||||
_usesExactFileMatching = true;
|
||||
}
|
||||
|
||||
if (shouldBeAllLowerCase)
|
||||
{
|
||||
_filtersList[n] = _filtersList[n].ToLower();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public string GetFileExt(string file)
|
||||
{
|
||||
int lastDotIdx = file.LastIndexOf(".", StringComparison.OrdinalIgnoreCase);
|
||||
if (lastDotIdx == -1) return "";
|
||||
return file.Substring(lastDotIdx, file.Length - lastDotIdx);
|
||||
}
|
||||
|
||||
public bool IsFileInFilter(string file)
|
||||
{
|
||||
// -------------------------------------------------
|
||||
// try using folder filter method:
|
||||
|
||||
if (_usesFolderFilter)
|
||||
{
|
||||
//Debug.Log(_label + " uses folder filter");
|
||||
for (int n = 0, len = _filtersList.Length; n < len; ++n)
|
||||
{
|
||||
// built-in asset compare is case-sensitive
|
||||
if (_filtersList[n].StartsWith(BUILT_IN_ASSET_KEYWORD, StringComparison.OrdinalIgnoreCase) &&
|
||||
file.StartsWith(BUILT_IN_ASSET_KEYWORD, StringComparison.OrdinalIgnoreCase) &&
|
||||
file.IndexOf(_filtersList[n], StringComparison.OrdinalIgnoreCase) != -1)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
//Debug.Log(file + " ---- " + _filtersList[n]);
|
||||
if ((_filtersList[n].StartsWith("/") || _filtersList[n].StartsWith("Assets/", StringComparison.OrdinalIgnoreCase)) &&
|
||||
_filtersList[n].EndsWith("/") &&
|
||||
file.IndexOf(_filtersList[n], StringComparison.OrdinalIgnoreCase) != -1)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------
|
||||
// if not found using folder filter method, try exact file matching next:
|
||||
|
||||
if (_usesExactFileMatching)
|
||||
{
|
||||
//Debug.Log("_usesExactFileMatching");
|
||||
|
||||
string fileNameOnly = file.GetFileNameOnly();
|
||||
|
||||
for (int n = 0, len = _filtersList.Length; n < len; ++n)
|
||||
{
|
||||
//Debug.Log("in quotes: " + _filtersList[n] + " " + (_filtersList[n].StartsWith("\"") && _filtersList[n].EndsWith("\"")));
|
||||
|
||||
|
||||
if (_filtersList[n].StartsWith("\"") && _filtersList[n].EndsWith("\""))
|
||||
{
|
||||
string fileWithQuotes = string.Format("\"{0}\"", fileNameOnly);
|
||||
|
||||
//Debug.Log("match? " + _filtersList[n] + " == " + fileWithQuotes);
|
||||
|
||||
if (_filtersList[n].Equals(fileWithQuotes))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------
|
||||
// if not found using exact file matching, try checking in dictionary next:
|
||||
|
||||
var fileExtension = GetFileExt(file);
|
||||
|
||||
if (_filtersDict.ContainsKey(fileExtension))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
for (int n = 0, len = _filtersList.Length; n < len; ++n)
|
||||
{
|
||||
//Debug.Log("in quotes: " + _filtersList[n] + " " + (_filtersList[n].StartsWith("\"") && _filtersList[n].EndsWith("\"")));
|
||||
|
||||
if (fileExtension.Equals(_filtersList[n], StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[System.Serializable, XmlRoot("FileFilterGroup")]
|
||||
public class FileFilterGroup
|
||||
{
|
||||
[SerializeField]
|
||||
FileFilters[] _fileFilters;
|
||||
|
||||
public FileFilters[] FileFilters
|
||||
{
|
||||
get { return _fileFilters; }
|
||||
set
|
||||
{
|
||||
_fileFilters = value;
|
||||
InitNames();
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
string[] _names;
|
||||
|
||||
public FileFilterGroup()
|
||||
{
|
||||
_fileFilters = null;
|
||||
_names = null;
|
||||
}
|
||||
|
||||
public FileFilterGroup(FileFilters[] filters)
|
||||
{
|
||||
_fileFilters = filters;
|
||||
InitNames();
|
||||
}
|
||||
|
||||
void InitNames()
|
||||
{
|
||||
_names = new string[_fileFilters.Length + 2];
|
||||
|
||||
_names[0] = "All";
|
||||
|
||||
for (int n = 0, len = _fileFilters.Length; n < len; ++n)
|
||||
{
|
||||
_names[n + 1] = _fileFilters[n].Label;
|
||||
}
|
||||
|
||||
_names[_names.Length - 1] = "Unknown";
|
||||
}
|
||||
|
||||
int _selectedFilterIdx;
|
||||
|
||||
/// <summary>
|
||||
/// -1 means "All" list.
|
||||
/// </summary>
|
||||
public int SelectedFilterIdx
|
||||
{
|
||||
get { return _selectedFilterIdx - 1; }
|
||||
}
|
||||
|
||||
public int GetSelectedFilterIdx()
|
||||
{
|
||||
return _selectedFilterIdx;
|
||||
}
|
||||
|
||||
public string GetSelectedFilterLabel()
|
||||
{
|
||||
return _selectedFilterIdx >= 1 && _selectedFilterIdx <= _fileFilters.Length ? _fileFilters[_selectedFilterIdx-1].Label : null;
|
||||
}
|
||||
|
||||
public int GetFilterIdx(string label)
|
||||
{
|
||||
for (int n = 0; n < _fileFilters.Length; ++n)
|
||||
{
|
||||
if (_fileFilters[n].Label == label)
|
||||
{
|
||||
return n;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public void ForceSetSelectedFilterIdx(int idx)
|
||||
{
|
||||
if ((idx < _fileFilters.Length + 2) && idx >= 0)
|
||||
{
|
||||
_selectedFilterIdx = idx;
|
||||
}
|
||||
}
|
||||
|
||||
const string UNPRESSED_STYLE_NAME = "ButtonNoContents";
|
||||
const string ALREADY_PRESSED_STYLE_NAME = "ButtonAlreadyPressed";
|
||||
|
||||
const string HAS_CONTENTS_UNPRESSED_STYLE_NAME = "ButtonHasContents";
|
||||
const string HAS_CONTENTS_ALREADY_PRESSED_STYLE_NAME = "ButtonAlreadyPressed";
|
||||
|
||||
GUIStyle GetStyleToUse(int assetNum, int selectedIdx, int idxOfThisGroup)
|
||||
{
|
||||
string styleToUse;
|
||||
|
||||
if (assetNum > 0)
|
||||
{
|
||||
styleToUse = HAS_CONTENTS_UNPRESSED_STYLE_NAME;
|
||||
if (selectedIdx == idxOfThisGroup)
|
||||
{
|
||||
styleToUse = HAS_CONTENTS_ALREADY_PRESSED_STYLE_NAME;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
styleToUse = UNPRESSED_STYLE_NAME;
|
||||
if (selectedIdx == idxOfThisGroup)
|
||||
{
|
||||
styleToUse = ALREADY_PRESSED_STYLE_NAME;
|
||||
}
|
||||
}
|
||||
|
||||
var style = GUI.skin.FindStyle(styleToUse);
|
||||
if (style == null)
|
||||
{
|
||||
return GUI.skin.button;
|
||||
}
|
||||
return style;
|
||||
}
|
||||
|
||||
public bool Draw(AssetList assetList, float width)
|
||||
{
|
||||
BuildReportTool.Options.FileFilterDisplay displayType = BuildReportTool.Options.GetOptionFileFilterDisplay();
|
||||
switch (displayType)
|
||||
{
|
||||
case BuildReportTool.Options.FileFilterDisplay.DropDown:
|
||||
return DrawFiltersAsDropDown(assetList, width);
|
||||
case BuildReportTool.Options.FileFilterDisplay.Buttons:
|
||||
return DrawFiltersAsButtons(assetList, width);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DrawFiltersAsDropDown(AssetList assetList, float width)
|
||||
{
|
||||
var topBarLabelStyle = GUI.skin.FindStyle(BuildReportTool.Window.Settings.TOP_BAR_LABEL_STYLE_NAME);
|
||||
if (topBarLabelStyle == null)
|
||||
{
|
||||
topBarLabelStyle = GUI.skin.label;
|
||||
}
|
||||
|
||||
var topBarPopupStyle = GUI.skin.FindStyle(BuildReportTool.Window.Settings.FILE_FILTER_POPUP_STYLE_NAME);
|
||||
if (topBarPopupStyle == null)
|
||||
{
|
||||
topBarPopupStyle = GUI.skin.label;
|
||||
}
|
||||
|
||||
var changed = false;
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.Space(3);
|
||||
GUILayout.Label("Filter: ", topBarLabelStyle);
|
||||
if (assetList != null && assetList.Labels != null && assetList.Labels.Length > 0)
|
||||
{
|
||||
var newSelectedFilterIdx = EditorGUILayout.Popup(_selectedFilterIdx, assetList.Labels,
|
||||
topBarPopupStyle);
|
||||
|
||||
if (newSelectedFilterIdx != _selectedFilterIdx)
|
||||
{
|
||||
_selectedFilterIdx = newSelectedFilterIdx;
|
||||
assetList.SortIfNeeded(this);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
bool DrawFiltersAsButtons(AssetList assetList, float width)
|
||||
{
|
||||
var changed = false;
|
||||
GUILayout.BeginHorizontal();
|
||||
|
||||
float overallWidth = 0;
|
||||
|
||||
|
||||
var styleToUse = GetStyleToUse(assetList.All.Length, _selectedFilterIdx, 0);
|
||||
var label = string.Format("All ({0})", assetList.All.Length.ToString());
|
||||
|
||||
var widthToAdd = styleToUse.CalcSize(new GUIContent(label)).x;
|
||||
|
||||
overallWidth += widthToAdd;
|
||||
|
||||
if (GUILayout.Button(label, styleToUse))
|
||||
{
|
||||
_selectedFilterIdx = 0;
|
||||
assetList.SortIfNeeded(this);
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (overallWidth >= width)
|
||||
{
|
||||
overallWidth = 0;
|
||||
GUILayout.EndHorizontal();
|
||||
GUILayout.BeginHorizontal();
|
||||
}
|
||||
|
||||
if (assetList.PerCategory != null && assetList.PerCategory.Length >= _fileFilters.Length)
|
||||
{
|
||||
for (int n = 0, len = _fileFilters.Length; n < len; ++n)
|
||||
{
|
||||
styleToUse = GetStyleToUse(assetList.PerCategory[n].Length, _selectedFilterIdx, n + 1);
|
||||
label = string.Format("{0} ({1})", _fileFilters[n].Label, assetList.PerCategory[n].Length.ToString());
|
||||
|
||||
widthToAdd = styleToUse.CalcSize(new GUIContent(label)).x;
|
||||
|
||||
if (overallWidth + widthToAdd >= width)
|
||||
{
|
||||
overallWidth = 0;
|
||||
GUILayout.EndHorizontal();
|
||||
GUILayout.BeginHorizontal();
|
||||
}
|
||||
|
||||
overallWidth += widthToAdd;
|
||||
|
||||
if (GUILayout.Button(label, styleToUse))
|
||||
{
|
||||
_selectedFilterIdx = n + 1;
|
||||
assetList.SortIfNeeded(this);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
styleToUse = GetStyleToUse(assetList.PerCategory[assetList.PerCategory.Length - 1].Length,
|
||||
_selectedFilterIdx, assetList.PerCategory.Length);
|
||||
|
||||
label = string.Format("Unknown ({0})",
|
||||
assetList.PerCategory[assetList.PerCategory.Length - 1].Length.ToString());
|
||||
widthToAdd = styleToUse.CalcSize(new GUIContent(label)).x;
|
||||
if (overallWidth + widthToAdd >= width)
|
||||
{
|
||||
//overallWidth = 0;
|
||||
GUILayout.EndHorizontal();
|
||||
GUILayout.BeginHorizontal();
|
||||
}
|
||||
|
||||
if (GUILayout.Button(label, styleToUse))
|
||||
{
|
||||
_selectedFilterIdx = assetList.PerCategory.Length;
|
||||
assetList.SortIfNeeded(this);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
return changed;
|
||||
}
|
||||
|
||||
public FileFilters this[int idx]
|
||||
{
|
||||
get { return _fileFilters[idx]; }
|
||||
}
|
||||
|
||||
public int Count
|
||||
{
|
||||
get { return _fileFilters.Length; }
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string ret = "(" + _names.Length.ToString() + ") ";
|
||||
|
||||
for (int n = 0, len = _names.Length; n < len; ++n)
|
||||
{
|
||||
ret += _names[n] + ", ";
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
} // namespace BuildReportTool
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a0843a406dad03c43890250da06070e6
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
@@ -0,0 +1,322 @@
|
||||
#if UNITY_EDITOR
|
||||
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using System.Xml.Serialization;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BuildReportTool
|
||||
{
|
||||
public class FiltersUsed
|
||||
{
|
||||
static readonly FileFilterGroup DefaultFileFilters = new FileFilterGroup(CreateDefaultFileFilters());
|
||||
|
||||
static FileFilterGroup GetDefaultFileFilterGroup()
|
||||
{
|
||||
return DefaultFileFilters;
|
||||
}
|
||||
|
||||
static FileFilters[] CreateDefaultFileFilters()
|
||||
{
|
||||
return new[]
|
||||
{
|
||||
new FileFilters("Textures",
|
||||
new[]
|
||||
{
|
||||
".psd",
|
||||
".jpg",
|
||||
".jpeg",
|
||||
".gif",
|
||||
".png",
|
||||
".tiff",
|
||||
".tif",
|
||||
".tga",
|
||||
".bmp",
|
||||
".dds",
|
||||
".exr",
|
||||
".iff",
|
||||
".pict",
|
||||
"Built-in Texture2D:", // Unity-generated sprite atlases
|
||||
".spriteatlasv2", // Sprite Atlas V2
|
||||
}),
|
||||
new FileFilters("Models",
|
||||
new[]
|
||||
{
|
||||
".fbx",
|
||||
".dae",
|
||||
".mb",
|
||||
".ma",
|
||||
".max",
|
||||
".blend",
|
||||
".obj",
|
||||
".3ds",
|
||||
".dxf",
|
||||
"Built-in Mesh:"
|
||||
}),
|
||||
new FileFilters("Prefabs",
|
||||
new[]
|
||||
{
|
||||
".prefab"
|
||||
}),
|
||||
new FileFilters("Animation",
|
||||
new[]
|
||||
{
|
||||
".anim",
|
||||
".controller",
|
||||
".mask"
|
||||
}),
|
||||
new FileFilters("Movies",
|
||||
new[]
|
||||
{
|
||||
".mov",
|
||||
".mpg",
|
||||
".mpeg",
|
||||
".mp4",
|
||||
".avi",
|
||||
".asf"
|
||||
}),
|
||||
new FileFilters("Materials",
|
||||
new[]
|
||||
{
|
||||
".mat",
|
||||
".sbsar",
|
||||
".cubemap",
|
||||
".flare",
|
||||
".terrainlayer",
|
||||
"Built-in Material:"
|
||||
}),
|
||||
new FileFilters("Shaders",
|
||||
new[]
|
||||
{
|
||||
".shader",
|
||||
".compute",
|
||||
".cginc",
|
||||
"Built-in Shader:"
|
||||
}),
|
||||
new FileFilters("GUI",
|
||||
new[]
|
||||
{
|
||||
".guiskin",
|
||||
".fontsettings",
|
||||
".ttf",
|
||||
".dfont",
|
||||
".otf"
|
||||
}),
|
||||
new FileFilters("Sounds",
|
||||
new[]
|
||||
{
|
||||
".mixer",
|
||||
".wav",
|
||||
".mp3",
|
||||
".ogg",
|
||||
".aif",
|
||||
".xm",
|
||||
".mod",
|
||||
".it",
|
||||
".s3m"
|
||||
}),
|
||||
new FileFilters("Scripts",
|
||||
new[]
|
||||
{
|
||||
".cs",
|
||||
".js",
|
||||
".boo",
|
||||
"Built-in MonoScript:"
|
||||
}),
|
||||
new FileFilters("Plugins",
|
||||
new[]
|
||||
{
|
||||
".dll", // Windows
|
||||
".bundle", // Mac
|
||||
".so", // Android (C++) or Linux
|
||||
".jar", // Android (Java)
|
||||
".a", // iOS
|
||||
".m", // iOS
|
||||
".mm", // iOS
|
||||
".c", // iOS
|
||||
".cpp" // iOS
|
||||
}),
|
||||
new FileFilters("Text",
|
||||
new[]
|
||||
{
|
||||
".txt",
|
||||
".bytes",
|
||||
".html",
|
||||
".htm",
|
||||
".xml",
|
||||
".yaml",
|
||||
".json",
|
||||
".log"
|
||||
}),
|
||||
new FileFilters("Misc",
|
||||
new[]
|
||||
{
|
||||
".asset",
|
||||
".physicmaterial",
|
||||
".lighting",
|
||||
".unity"
|
||||
}),
|
||||
new FileFilters("Standard Assets",
|
||||
new[]
|
||||
{
|
||||
"/Standard Assets/"
|
||||
}),
|
||||
new FileFilters("\"Resources\" Assets",
|
||||
new[]
|
||||
{
|
||||
"/Resources/"
|
||||
}),
|
||||
new FileFilters("Streaming Assets",
|
||||
new[]
|
||||
{
|
||||
"Assets/StreamingAssets/"
|
||||
}),
|
||||
new FileFilters("Editor",
|
||||
new[]
|
||||
{
|
||||
"/Editor/"
|
||||
}),
|
||||
new FileFilters("Version Control",
|
||||
new[]
|
||||
{
|
||||
"/.svn/",
|
||||
"/.git/",
|
||||
"/.cvs/"
|
||||
}),
|
||||
new FileFilters("Built-in Assets",
|
||||
new[]
|
||||
{
|
||||
"Built-in",
|
||||
"\"unity_builtin_extra\""
|
||||
}),
|
||||
new FileFilters("Useless Files",
|
||||
new[]
|
||||
{
|
||||
"\"Thumbs.db\"",
|
||||
"\".DS_Store\"",
|
||||
"\"._.DS_Store\""
|
||||
})
|
||||
};
|
||||
}
|
||||
|
||||
static void SaveFileFilterGroupToFile(string saveFilePath, FileFilterGroup filterGroup)
|
||||
{
|
||||
System.Xml.Serialization.XmlSerializer x = new System.Xml.Serialization.XmlSerializer(typeof(FileFilterGroup));
|
||||
|
||||
saveFilePath = saveFilePath.Replace("\\", "/");
|
||||
|
||||
System.IO.TextWriter writer = new System.IO.StreamWriter(saveFilePath);
|
||||
x.Serialize(writer, filterGroup);
|
||||
writer.Close();
|
||||
|
||||
Debug.Log("Build Report Tool: Saved File Filter Group at \"" + saveFilePath + "\"");
|
||||
}
|
||||
|
||||
static FileFilterGroup AttemptLoadFileFiltersFromFile(string filePath)
|
||||
{
|
||||
FileFilterGroup ret;
|
||||
|
||||
XmlSerializer x = new XmlSerializer(typeof(FileFilterGroup));
|
||||
|
||||
using (FileStream fs = new FileStream(filePath, FileMode.Open))
|
||||
{
|
||||
XmlReader reader = new XmlTextReader(fs);
|
||||
ret = (FileFilterGroup) x.Deserialize(reader);
|
||||
fs.Close();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
const string FILE_FILTERS_USED_FILENAME = "FileFiltersUsed.xml";
|
||||
|
||||
public static string GetProperFileFilterGroupToUseFilePath()
|
||||
{
|
||||
return GetProperFileFilterGroupToUseFilePath(BuildReportTool.Options.BuildReportSavePath);
|
||||
}
|
||||
|
||||
public static string GetProperFileFilterGroupToUseFilePath(string userFileFilterSavePath)
|
||||
{
|
||||
// attempt to get from Assets/BuildReport/Config/FileFiltersUsed.xml
|
||||
// if none, attempt to get from ~/UnityBuildReports/FileFiltersUsed.xml
|
||||
// if no dice, create a new FileFiltersUsed.xml in ~/UnityBuildReports/ and use that
|
||||
|
||||
// attempt to get from default Build Report Tool folder: Assets/BuildReport/Config/FileFiltersUsed.xml
|
||||
|
||||
string fileFilterGroupAtDefaultAssetsPath =
|
||||
BuildReportTool.Options.BUILD_REPORT_TOOL_DEFAULT_PATH + "/" + FILE_FILTERS_USED_FILENAME;
|
||||
|
||||
if (File.Exists(fileFilterGroupAtDefaultAssetsPath))
|
||||
{
|
||||
return fileFilterGroupAtDefaultAssetsPath;
|
||||
}
|
||||
|
||||
|
||||
// search for Build Report Tool folder in all subfolders of Assets folder and look for file there
|
||||
// maybe shouldn't do this? it's recursive and could be slow on project with hundreds of folders...
|
||||
/*
|
||||
string assetFolderPath = BuildReportTool.Util.FindAssetFolder(Application.dataPath, BuildReportTool.Config.BUILD_REPORT_TOOL_DEFAULT_FOLDER_NAME);
|
||||
if (!string.IsNullOrEmpty(assetFolderPath))
|
||||
{
|
||||
string fileFilterGroupAtFoundAssetsPath = assetFolderPath + "/" + FILE_FILTERS_USED_FILENAME;
|
||||
|
||||
if (File.Exists(fileFilterGroupAtFoundAssetsPath))
|
||||
{
|
||||
return fileFilterGroupAtFoundAssetsPath;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
string fileFilterGroupAtUserPersonalFolder = userFileFilterSavePath + "/" + FILE_FILTERS_USED_FILENAME;
|
||||
if (File.Exists(fileFilterGroupAtUserPersonalFolder))
|
||||
{
|
||||
//Debug.Log("will use file filter from user folder: " + fileFilterGroupAtUserPersonalFolder);
|
||||
return fileFilterGroupAtUserPersonalFolder;
|
||||
}
|
||||
|
||||
string fileFilterGroupAtUserPersonalFolderDefaultName =
|
||||
BuildReportTool.Util.GetUserHomeFolder() + "/" + BuildReportTool.Options.BUILD_REPORTS_DEFAULT_FOLDER_NAME +
|
||||
"/" + FILE_FILTERS_USED_FILENAME;
|
||||
if (File.Exists(fileFilterGroupAtUserPersonalFolderDefaultName))
|
||||
{
|
||||
//Debug.Log("will use file filter from default user folder: " + fileFilterGroupAtUserPersonalFolderDefaultName);
|
||||
return fileFilterGroupAtUserPersonalFolderDefaultName;
|
||||
}
|
||||
|
||||
// no dice. create a file filter group xml file at user personal folder
|
||||
if (!Directory.Exists(userFileFilterSavePath))
|
||||
{
|
||||
Debug.Log("Created a new Build Report File Filter Config XML File at " + userFileFilterSavePath);
|
||||
Directory.CreateDirectory(userFileFilterSavePath);
|
||||
}
|
||||
|
||||
SaveFileFilterGroupToFile(fileFilterGroupAtUserPersonalFolder, DefaultFileFilters);
|
||||
return fileFilterGroupAtUserPersonalFolder;
|
||||
}
|
||||
|
||||
|
||||
public static FileFilterGroup GetProperFileFilterGroupToUse()
|
||||
{
|
||||
return GetProperFileFilterGroupToUse(BuildReportTool.Options.BuildReportSavePath);
|
||||
}
|
||||
|
||||
public static FileFilterGroup GetProperFileFilterGroupToUse(string userFileFilterSavePath)
|
||||
{
|
||||
string fileFilterGroupPath = GetProperFileFilterGroupToUseFilePath(userFileFilterSavePath);
|
||||
|
||||
//Debug.Log("fileFilterGroupPath: " + fileFilterGroupPath);
|
||||
|
||||
FileFilterGroup ret = AttemptLoadFileFiltersFromFile(fileFilterGroupPath);
|
||||
|
||||
if (ret != null)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
Debug.LogError("Build Report Tool: Could not find proper File Filter Group to use.");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
} // namespace BuildReportTool
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a04b2835e79127b44a25b5b4b6a9e937
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d54b85804521d9e418a8b7a7807a454b
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f09b35d8cd4d59f4ba3898a19f0dafe0
|
||||
@@ -0,0 +1,364 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
namespace BuildReportTool
|
||||
{
|
||||
/// <summary>
|
||||
/// Class for holding which asset uses which.
|
||||
/// This is the class that is serialized when saving an Asset Dependency Report to a file.
|
||||
/// </summary>
|
||||
[System.Serializable, System.Xml.Serialization.XmlRoot("AssetDependencies")]
|
||||
public class AssetDependencies : BuildReportTool.IDataFile
|
||||
{
|
||||
/// <summary>
|
||||
/// Name of project folder.
|
||||
/// Included as part of the filename when saved.
|
||||
/// </summary>
|
||||
public string ProjectName;
|
||||
|
||||
/// <summary>
|
||||
/// Type of build that the project was configured to, at the time that asset dependencies were calculated.
|
||||
/// Included as part of the filename when saved.
|
||||
/// </summary>
|
||||
public string BuildType;
|
||||
|
||||
/// <summary>
|
||||
/// When asset dependencies were calculated.
|
||||
/// Included as part of the filename when saved.
|
||||
/// </summary>
|
||||
public System.DateTime TimeGot;
|
||||
|
||||
public string GetDefaultFilename()
|
||||
{
|
||||
return BuildReportTool.Util.GetAssetDependenciesDefaultFilename(ProjectName, BuildType, TimeGot);
|
||||
}
|
||||
|
||||
public string GetAccompanyingBuildReportFilename()
|
||||
{
|
||||
return BuildReportTool.Util.GetBuildInfoDefaultFilename(ProjectName, BuildType, TimeGot);
|
||||
}
|
||||
|
||||
// ==================================================================================
|
||||
|
||||
/// <summary>
|
||||
/// Full path where this Asset Dependencies is saved in the local storage.
|
||||
/// </summary>
|
||||
string _savedPath;
|
||||
|
||||
/// <inheritdoc cref="_savedPath"/>
|
||||
public string SavedPath
|
||||
{
|
||||
get { return _savedPath; }
|
||||
}
|
||||
|
||||
public void SetSavedPath(string val)
|
||||
{
|
||||
_savedPath = val.Replace("\\", "/");
|
||||
}
|
||||
|
||||
|
||||
public bool HasContents
|
||||
{
|
||||
get { return _assetDependencies.Count > 0; }
|
||||
}
|
||||
|
||||
// ==================================================================================
|
||||
|
||||
Dictionary<string, DependencyEntry> _assetDependencies = new Dictionary<string, DependencyEntry>();
|
||||
|
||||
public List<string> Assets;
|
||||
public List<DependencyEntry> Dependencies;
|
||||
|
||||
public Dictionary<string, DependencyEntry> GetAssetDependencies()
|
||||
{
|
||||
return _assetDependencies;
|
||||
}
|
||||
|
||||
// ==================================================================================
|
||||
|
||||
public void OnBeforeSave()
|
||||
{
|
||||
if (Assets != null)
|
||||
{
|
||||
Assets.Clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
Assets = new List<string>();
|
||||
}
|
||||
|
||||
Assets.AddRange(_assetDependencies.Keys);
|
||||
|
||||
if (Dependencies != null)
|
||||
{
|
||||
Dependencies.Clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
Dependencies = new List<DependencyEntry>();
|
||||
}
|
||||
|
||||
Dependencies.AddRange(_assetDependencies.Values);
|
||||
}
|
||||
|
||||
public void OnAfterLoad()
|
||||
{
|
||||
_assetDependencies.Clear();
|
||||
|
||||
var len = Mathf.Min(Assets.Count, Dependencies.Count);
|
||||
for (int n = 0; n < len; ++n)
|
||||
{
|
||||
_assetDependencies.Add(Assets[n], Dependencies[n]);
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------
|
||||
|
||||
public static void PopulateAssetEndUsers(string rootAsset, AssetDependencies assetDependencies)
|
||||
{
|
||||
if (assetDependencies == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var dependencies = assetDependencies.GetAssetDependencies();
|
||||
|
||||
if (!dependencies.ContainsKey(rootAsset))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var selectedAssetDependencies = dependencies[rootAsset];
|
||||
|
||||
if (selectedAssetDependencies.Users.Count <= 0)
|
||||
{
|
||||
// asset isn't used by any other asset
|
||||
return;
|
||||
}
|
||||
|
||||
var destination = selectedAssetDependencies.GetEndUserLabels();
|
||||
|
||||
if (destination.Count > 0)
|
||||
{
|
||||
// already assigned
|
||||
return;
|
||||
}
|
||||
|
||||
PopulateAssetEndUsers(rootAsset, destination, assetDependencies);
|
||||
}
|
||||
|
||||
public static void PopulateAssetEndUsers(string rootAsset, List<GUIContent> destination,
|
||||
AssetDependencies assetDependencies)
|
||||
{
|
||||
if (assetDependencies == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var dependencies = assetDependencies.GetAssetDependencies();
|
||||
|
||||
if (!dependencies.ContainsKey(rootAsset))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var selectedAssetDependencies = dependencies[rootAsset];
|
||||
|
||||
if (destination.Count > 0)
|
||||
{
|
||||
// already assigned
|
||||
return;
|
||||
}
|
||||
|
||||
var usersFlattened = selectedAssetDependencies.UsersFlattened;
|
||||
|
||||
if (usersFlattened.Count <= 0)
|
||||
{
|
||||
// asset has no flattened users list
|
||||
destination.Clear();
|
||||
return;
|
||||
}
|
||||
|
||||
// count: 2
|
||||
// availableExistingIdx: 0
|
||||
//
|
||||
// 1st primary user found:
|
||||
// count <= availableExistingIdx
|
||||
// 2 <= 0 ? false: 1st primary user put to idx 0
|
||||
// availableExistingIdx: 1
|
||||
//
|
||||
// 2nd primary user found:
|
||||
// 2 <= 1 ? false: 2nd primary user put to idx 1
|
||||
// availableExistingIdx: 2
|
||||
//
|
||||
// 3rd primary user found:
|
||||
// 2 <= 2 ? true: 3rd primary user added as new entry to list (at idx 2)
|
||||
// count: 3
|
||||
// availableExistingIdx: 3
|
||||
//
|
||||
// while (count > availableExistingIdx)
|
||||
// 3 > 3 ? false: stop while loop
|
||||
|
||||
// count : 0
|
||||
// availableExistingIdx: 0
|
||||
//
|
||||
// 1st primary user found:
|
||||
// count <= availableExistingIdx
|
||||
// 0 <= 0 ? true: 1st primary user added as new entry to list (at idx 0)
|
||||
// count: 1
|
||||
// availableExistingIdx: 1
|
||||
//
|
||||
// while (count > availableExistingIdx)
|
||||
// 1 > 1 ? false: stop while loop
|
||||
|
||||
// count: 2
|
||||
// availableExistingIdx: 0
|
||||
//
|
||||
// 1st primary user found:
|
||||
// count <= availableExistingIdx
|
||||
// 2 <= 0 ? false: 1st primary user put to idx 0
|
||||
// availableExistingIdx: 1
|
||||
//
|
||||
// while (count > availableExistingIdx)
|
||||
// 2 > 1 ? true: removed idx 1 of list
|
||||
// 1 > 1 ? false: stop while loop
|
||||
|
||||
// count: 2
|
||||
// availableExistingIdx: 0
|
||||
//
|
||||
// while (count > availableExistingIdx)
|
||||
// 2 > 0 ? true: removed idx 1 of list
|
||||
// 1 > 0 ? true: removed idx 0 of list
|
||||
// 0 > 0 ? false: stop while loop
|
||||
|
||||
int availableExistingIdx = 0;
|
||||
|
||||
for (int n = 0, len = usersFlattened.Count; n < len; ++n)
|
||||
{
|
||||
bool isAssembly = usersFlattened[n].AssetPath.IsAnAssembly();
|
||||
if (usersFlattened[n].AssetPath.IsSceneFile() ||
|
||||
usersFlattened[n].AssetPath.IsInResourcesFolder() ||
|
||||
usersFlattened[n].AssetPath.IsSpriteAtlasFile() ||
|
||||
isAssembly)
|
||||
{
|
||||
string assetFilename =
|
||||
isAssembly ? usersFlattened[n].AssetPath : usersFlattened[n].AssetPath.GetFileNameOnly();
|
||||
|
||||
var alreadyInList = false;
|
||||
for (int alreadyN = 0, alreadyLen = availableExistingIdx; alreadyN < alreadyLen; ++alreadyN)
|
||||
{
|
||||
if (destination[alreadyN].text.Equals(assetFilename, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
alreadyInList = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (alreadyInList)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Texture icon = isAssembly
|
||||
? BuildReportTool.Window.Utility.AssemblyIcon
|
||||
: AssetDatabase.GetCachedIcon(usersFlattened[n].AssetPath);
|
||||
|
||||
if (destination.Count <= availableExistingIdx)
|
||||
{
|
||||
destination.Add(new GUIContent(
|
||||
assetFilename,
|
||||
icon,
|
||||
usersFlattened[n].AssetPath));
|
||||
}
|
||||
else
|
||||
{
|
||||
destination[availableExistingIdx].text = assetFilename;
|
||||
destination[availableExistingIdx].image = icon;
|
||||
destination[availableExistingIdx].tooltip = usersFlattened[n].AssetPath;
|
||||
}
|
||||
|
||||
++availableExistingIdx;
|
||||
}
|
||||
}
|
||||
|
||||
while (destination.Count > availableExistingIdx)
|
||||
{
|
||||
destination.RemoveAt(destination.Count - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ==================================================================================
|
||||
|
||||
public class DependencyEntry
|
||||
{
|
||||
/// <summary>
|
||||
/// Assets that this one directly uses.
|
||||
/// </summary>
|
||||
public List<string> Uses = new List<string>();
|
||||
|
||||
/// <summary>
|
||||
/// Assets that directly use this one.
|
||||
/// </summary>
|
||||
public List<string> Users = new List<string>();
|
||||
|
||||
/// <summary>
|
||||
/// Assets that use this one, and the assets that use those, et al.
|
||||
/// </summary>
|
||||
public List<AssetUserFlattened> UsersFlattened = new List<AssetUserFlattened>();
|
||||
|
||||
List<GUIContent> _endUserLabels;
|
||||
|
||||
public List<GUIContent> GetEndUserLabels()
|
||||
{
|
||||
if (_endUserLabels == null)
|
||||
{
|
||||
_endUserLabels = new List<GUIContent>();
|
||||
}
|
||||
|
||||
return _endUserLabels;
|
||||
}
|
||||
}
|
||||
|
||||
public struct AssetUserFlattened
|
||||
{
|
||||
public string AssetPath;
|
||||
|
||||
/// <summary>
|
||||
/// Always starts at 1.
|
||||
/// </summary>
|
||||
public int IndentLevel;
|
||||
|
||||
public bool CyclicDependency;
|
||||
|
||||
#if BRT_ASSET_DEPENDENCY_DEBUG
|
||||
public string DebugInfo;
|
||||
#endif
|
||||
|
||||
public AssetUserFlattened(string assetPath, int indentLevel)
|
||||
{
|
||||
AssetPath = assetPath;
|
||||
IndentLevel = indentLevel;
|
||||
CyclicDependency = false;
|
||||
|
||||
#if BRT_ASSET_DEPENDENCY_DEBUG
|
||||
DebugInfo = null;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if BRT_ASSET_DEPENDENCY_DEBUG
|
||||
public AssetUserFlattened(string assetPath, int indentLevel, string debugInfo)
|
||||
{
|
||||
AssetPath = assetPath;
|
||||
IndentLevel = indentLevel;
|
||||
CyclicDependency = false;
|
||||
|
||||
DebugInfo = debugInfo;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// ==================================================================================
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8344c853aaa50c348aec96fdbdb839c7
|
||||
timeCreated: 1558252652
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,689 @@
|
||||
using UnityEngine;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace BuildReportTool
|
||||
{
|
||||
/// <summary>
|
||||
/// A collection of file entries in a build report.
|
||||
/// Used to display the "Used Assets" and the "Unused Assets".
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
public class AssetList
|
||||
{
|
||||
// ==================================================================================
|
||||
|
||||
[SerializeField]
|
||||
BuildReportTool.SizePart[] _all;
|
||||
|
||||
int[] _viewOffsets;
|
||||
|
||||
[SerializeField]
|
||||
BuildReportTool.SizePart[][] _perCategory;
|
||||
|
||||
|
||||
[SerializeField]
|
||||
string[] _labels;
|
||||
|
||||
|
||||
public BuildReportTool.SizePart[] All
|
||||
{
|
||||
get { return _all; }
|
||||
set { _all = value; }
|
||||
}
|
||||
|
||||
public BuildReportTool.SizePart[][] PerCategory
|
||||
{
|
||||
get { return _perCategory; }
|
||||
}
|
||||
|
||||
public string[] Labels
|
||||
{
|
||||
get { return _labels; }
|
||||
set { _labels = value; }
|
||||
}
|
||||
|
||||
// ==================================================================================
|
||||
|
||||
BuildReportTool.SizePart[] _topLargest;
|
||||
|
||||
public BuildReportTool.SizePart[] TopLargest
|
||||
{
|
||||
get { return _topLargest; }
|
||||
}
|
||||
|
||||
public int NumberOfTopLargest
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_topLargest == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return _topLargest.Length;
|
||||
}
|
||||
}
|
||||
|
||||
void PostSetListAll(int numberOfTop)
|
||||
{
|
||||
List<BuildReportTool.SizePart> topLargestList = new List<BuildReportTool.SizePart>();
|
||||
|
||||
// temporarily sort "All" list by raw size so we can get the top largest
|
||||
AssetListUtility.SortAssetList(_all, SortType.RawSize, SortOrder.Descending);
|
||||
|
||||
// in case entries in "all" list is lesser than the numberOfTop value
|
||||
int len = Mathf.Min(numberOfTop, _all.Length);
|
||||
|
||||
for (int n = 0; n < len; ++n)
|
||||
{
|
||||
topLargestList.Add(_all[n]);
|
||||
}
|
||||
|
||||
_topLargest = topLargestList.ToArray();
|
||||
|
||||
// revert "All" list to original sort type
|
||||
Resort(_all);
|
||||
}
|
||||
|
||||
public void ResortDefault(int numberOfTop)
|
||||
{
|
||||
PostSetListAll(numberOfTop);
|
||||
}
|
||||
|
||||
// ==================================================================================
|
||||
// Sort Type
|
||||
|
||||
public enum SortType
|
||||
{
|
||||
None,
|
||||
AssetFullPath,
|
||||
AssetFilename,
|
||||
RawSize,
|
||||
ImportedSize,
|
||||
|
||||
/// <summary>
|
||||
/// Try imported size. If imported size is unavailable (N/A) use raw size.
|
||||
/// </summary>
|
||||
ImportedSizeOrRawSize,
|
||||
|
||||
SizeBeforeBuild,
|
||||
PercentSize,
|
||||
|
||||
TextureData,
|
||||
MeshData,
|
||||
PrefabData,
|
||||
}
|
||||
|
||||
public enum SortOrder
|
||||
{
|
||||
None,
|
||||
Ascending,
|
||||
Descending
|
||||
}
|
||||
|
||||
SortType _lastSortType = SortType.None;
|
||||
BuildReportTool.TextureData.DataId _lastTextureSortType = BuildReportTool.TextureData.DataId.None;
|
||||
BuildReportTool.MeshData.DataId _lastMeshSortType = BuildReportTool.MeshData.DataId.None;
|
||||
BuildReportTool.PrefabData.DataId _lastPrefabSortType = BuildReportTool.PrefabData.DataId.None;
|
||||
SortOrder _lastSortOrder = SortOrder.None;
|
||||
|
||||
public SortType LastSortType
|
||||
{
|
||||
get { return _lastSortType; }
|
||||
}
|
||||
|
||||
public SortOrder LastSortOrder
|
||||
{
|
||||
get { return _lastSortOrder; }
|
||||
}
|
||||
|
||||
readonly HashSet<int> _hasListBeenSorted = new HashSet<int>();
|
||||
|
||||
public void Resort(BuildReportTool.SizePart[] assetList)
|
||||
{
|
||||
if (_lastSortType != SortType.None &&
|
||||
_lastTextureSortType == BuildReportTool.TextureData.DataId.None &&
|
||||
_lastMeshSortType == BuildReportTool.MeshData.DataId.None &&
|
||||
_lastSortOrder != SortOrder.None)
|
||||
{
|
||||
AssetListUtility.SortAssetList(assetList, _lastSortType, _lastSortOrder);
|
||||
}
|
||||
}
|
||||
|
||||
public void Sort(BuildReportTool.TextureData textureData, BuildReportTool.TextureData.DataId sortType, SortOrder sortOrder, BuildReportTool.FileFilterGroup fileFilters)
|
||||
{
|
||||
_lastTextureSortType = sortType;
|
||||
_lastMeshSortType = BuildReportTool.MeshData.DataId.None;
|
||||
_lastSortType = SortType.TextureData;
|
||||
_lastSortOrder = sortOrder;
|
||||
|
||||
_hasListBeenSorted.Clear();
|
||||
|
||||
_hasListBeenSorted.Add(fileFilters.SelectedFilterIdx);
|
||||
|
||||
// sort only currently displayed list
|
||||
if (fileFilters.SelectedFilterIdx == -1)
|
||||
{
|
||||
AssetListUtility.SortAssetList(_all, textureData, sortType, sortOrder);
|
||||
}
|
||||
else
|
||||
{
|
||||
AssetListUtility.SortAssetList(_perCategory[fileFilters.SelectedFilterIdx], textureData, sortType, sortOrder);
|
||||
}
|
||||
}
|
||||
|
||||
public void Sort(BuildReportTool.MeshData meshData, BuildReportTool.MeshData.DataId sortType, SortOrder sortOrder, BuildReportTool.FileFilterGroup fileFilters)
|
||||
{
|
||||
_lastTextureSortType = BuildReportTool.TextureData.DataId.None;
|
||||
_lastMeshSortType = sortType;
|
||||
_lastSortType = SortType.MeshData;
|
||||
_lastSortOrder = sortOrder;
|
||||
|
||||
_hasListBeenSorted.Clear();
|
||||
|
||||
_hasListBeenSorted.Add(fileFilters.SelectedFilterIdx);
|
||||
|
||||
// sort only currently displayed list
|
||||
if (fileFilters.SelectedFilterIdx == -1)
|
||||
{
|
||||
AssetListUtility.SortAssetList(_all, meshData, sortType, sortOrder);
|
||||
}
|
||||
else
|
||||
{
|
||||
AssetListUtility.SortAssetList(_perCategory[fileFilters.SelectedFilterIdx], meshData, sortType, sortOrder);
|
||||
}
|
||||
}
|
||||
|
||||
public void Sort(BuildReportTool.PrefabData prefabData, BuildReportTool.PrefabData.DataId sortType, SortOrder sortOrder, BuildReportTool.FileFilterGroup fileFilters)
|
||||
{
|
||||
_lastTextureSortType = BuildReportTool.TextureData.DataId.None;
|
||||
_lastPrefabSortType = sortType;
|
||||
_lastSortType = SortType.PrefabData;
|
||||
_lastSortOrder = sortOrder;
|
||||
|
||||
_hasListBeenSorted.Clear();
|
||||
|
||||
_hasListBeenSorted.Add(fileFilters.SelectedFilterIdx);
|
||||
|
||||
// sort only currently displayed list
|
||||
if (fileFilters.SelectedFilterIdx == -1)
|
||||
{
|
||||
AssetListUtility.SortAssetList(_all, prefabData, sortType, sortOrder);
|
||||
}
|
||||
else
|
||||
{
|
||||
AssetListUtility.SortAssetList(_perCategory[fileFilters.SelectedFilterIdx], prefabData, sortType, sortOrder);
|
||||
}
|
||||
}
|
||||
|
||||
public void Sort(SortType sortType, SortOrder sortOrder, BuildReportTool.FileFilterGroup fileFilters)
|
||||
{
|
||||
_lastTextureSortType = BuildReportTool.TextureData.DataId.None;
|
||||
_lastMeshSortType = BuildReportTool.MeshData.DataId.None;
|
||||
_lastSortType = sortType;
|
||||
_lastSortOrder = sortOrder;
|
||||
|
||||
_hasListBeenSorted.Clear();
|
||||
|
||||
_hasListBeenSorted.Add(fileFilters.SelectedFilterIdx);
|
||||
|
||||
// sort only currently displayed list
|
||||
if (fileFilters.SelectedFilterIdx == -1)
|
||||
{
|
||||
AssetListUtility.SortAssetList(_all, sortType, sortOrder);
|
||||
}
|
||||
else
|
||||
{
|
||||
AssetListUtility.SortAssetList(_perCategory[fileFilters.SelectedFilterIdx], sortType, sortOrder);
|
||||
}
|
||||
|
||||
//SortAssetList(_all, sortType, sortOrder);
|
||||
//for (int n = 0, len = _perCategory.Length; n < len; ++n)
|
||||
//{
|
||||
// SortAssetList(_perCategory[n], sortType, sortOrder);
|
||||
//}
|
||||
}
|
||||
|
||||
public void SortIfNeeded(BuildReportTool.FileFilterGroup fileFilters)
|
||||
{
|
||||
if (_lastSortType != SortType.None &&
|
||||
_lastSortOrder != SortOrder.None &&
|
||||
!_hasListBeenSorted.Contains(fileFilters.SelectedFilterIdx))
|
||||
{
|
||||
if (fileFilters.SelectedFilterIdx == -1)
|
||||
{
|
||||
if (_lastSortType == SortType.TextureData)
|
||||
{
|
||||
|
||||
}
|
||||
else if (_lastSortType == SortType.MeshData)
|
||||
{
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
AssetListUtility.SortAssetList(_all, _lastSortType, _lastSortOrder);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_lastSortType == SortType.TextureData)
|
||||
{
|
||||
|
||||
}
|
||||
else if (_lastSortType == SortType.MeshData)
|
||||
{
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
AssetListUtility.SortAssetList(_perCategory[fileFilters.SelectedFilterIdx], _lastSortType, _lastSortOrder);
|
||||
}
|
||||
}
|
||||
|
||||
_hasListBeenSorted.Add(fileFilters.SelectedFilterIdx);
|
||||
}
|
||||
}
|
||||
|
||||
// Queries
|
||||
// ==================================================================================
|
||||
|
||||
public List<BuildReportTool.SizePart> GetAllAsList()
|
||||
{
|
||||
return _all.ToList();
|
||||
}
|
||||
|
||||
public int AllCount
|
||||
{
|
||||
get { return _all.Length; }
|
||||
}
|
||||
|
||||
public double GetTotalSizeInBytes()
|
||||
{
|
||||
double total = 0;
|
||||
|
||||
for (int n = 0, len = _all.Length; n < len; ++n)
|
||||
{
|
||||
if (_all[n].UsableSize > 0)
|
||||
{
|
||||
total += _all[n].UsableSize;
|
||||
}
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
public int GetViewOffsetForDisplayedList(FileFilterGroup fileFilters)
|
||||
{
|
||||
if (_viewOffsets == null || _viewOffsets.Length == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (fileFilters.SelectedFilterIdx == -1)
|
||||
{
|
||||
return _viewOffsets[0]; // _viewOffsets[0] is the "All" list
|
||||
}
|
||||
else if (PerCategory != null && PerCategory.Length >= fileFilters.SelectedFilterIdx + 1)
|
||||
{
|
||||
return _viewOffsets[fileFilters.SelectedFilterIdx + 1];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public BuildReportTool.SizePart[] GetListToDisplay(FileFilterGroup fileFilters)
|
||||
{
|
||||
BuildReportTool.SizePart[] ret = null;
|
||||
if (fileFilters.SelectedFilterIdx == -1)
|
||||
{
|
||||
ret = All;
|
||||
}
|
||||
else if (PerCategory != null && PerCategory.Length >= fileFilters.SelectedFilterIdx + 1)
|
||||
{
|
||||
ret = PerCategory[fileFilters.SelectedFilterIdx];
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
// Commands
|
||||
// ==================================================================================
|
||||
|
||||
public void UnescapeAssetNames()
|
||||
{
|
||||
for (int n = 0, len = _all.Length; n < len; ++n)
|
||||
{
|
||||
_all[n].Name = BuildReportTool.Util.MyHtmlDecode(_all[n].Name);
|
||||
}
|
||||
|
||||
|
||||
if (_perCategory != null)
|
||||
{
|
||||
for (int catIdx = 0, catLen = _perCategory.Length; catIdx < catLen; ++catIdx)
|
||||
{
|
||||
for (int n = 0, len = _perCategory[catIdx].Length; n < len; ++n)
|
||||
{
|
||||
_perCategory[catIdx][n].Name = BuildReportTool.Util.MyHtmlDecode(_perCategory[catIdx][n].Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SetViewOffsetForDisplayedList(FileFilterGroup fileFilters, int newVal)
|
||||
{
|
||||
if (fileFilters.SelectedFilterIdx == -1)
|
||||
{
|
||||
_viewOffsets[0] = newVal; // _viewOffsets[0] is the "All" list
|
||||
}
|
||||
else if (PerCategory != null && PerCategory.Length >= fileFilters.SelectedFilterIdx + 1)
|
||||
{
|
||||
_viewOffsets[fileFilters.SelectedFilterIdx + 1] = newVal;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void PopulateRawSizes()
|
||||
{
|
||||
/*long importedSize = -1;
|
||||
for (int n = 0, len = _all.Length; n < len; ++n)
|
||||
{
|
||||
importedSize = BRT_LibCacheUtil.GetImportedFileSize(_all[n].Name);
|
||||
|
||||
_all[n].SizeBytes = importedSize;
|
||||
_all[n].Size = BuildReportTool.Util.GetBytesReadable(importedSize);
|
||||
}*/
|
||||
}
|
||||
|
||||
|
||||
public void PopulateImportedSizes()
|
||||
{
|
||||
for (int n = 0, len = _all.Length; n < len; ++n)
|
||||
{
|
||||
/*if (BuildReportTool.Util.IsFileAUnityAsset(_all[n].Name))
|
||||
{
|
||||
// Scene files/terrain files/scriptable object files/etc. always seem to be only 4kb in the library,
|
||||
// no matter how large the actual file in the assets folder really is.
|
||||
// The 4kb is probably just metadata/reference to the actual file itself.
|
||||
// Makes sense since these file types are "native" to unity, so no importing is necessary.
|
||||
//
|
||||
// In this case, the raw size (size of the file in the assets folder) counts as the imported size
|
||||
// so just use the raw size.
|
||||
|
||||
_all[n].ImportedSizeBytes = _all[n].RawSizeBytes;
|
||||
_all[n].ImportedSize = _all[n].RawSize;
|
||||
}
|
||||
else*/
|
||||
{
|
||||
var importedSize = BRT_LibCacheUtil.GetImportedFileSize(_all[n].Name);
|
||||
|
||||
_all[n].ImportedSizeBytes = importedSize;
|
||||
_all[n].ImportedSize = BuildReportTool.Util.GetBytesReadable(importedSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void PopulateSizeInAssetsFolder()
|
||||
{
|
||||
var projectPath = BuildReportTool.Util.GetProjectPath(Application.dataPath);
|
||||
for (int n = 0, len = _all.Length; n < len; ++n)
|
||||
{
|
||||
string assetImportedPath = projectPath + BuildReportTool.Util.MyHtmlDecode(_all[n].Name);
|
||||
|
||||
var size = BuildReportTool.Util.GetFileSizeInBytes(assetImportedPath);
|
||||
_all[n].SizeInAssetsFolderBytes = size;
|
||||
_all[n].SizeInAssetsFolder = BuildReportTool.Util.GetBytesReadable(size);
|
||||
}
|
||||
}
|
||||
|
||||
public void RecalculatePercentages(double totalSize)
|
||||
{
|
||||
//Debug.Log("Recalculate Percentage Start");
|
||||
|
||||
if (_all != null)
|
||||
{
|
||||
// if the all list is available,
|
||||
// prefer using that to get the total size
|
||||
|
||||
totalSize = 0;
|
||||
|
||||
for (int n = 0, len = _all.Length; n < len; ++n)
|
||||
{
|
||||
totalSize += _all[n].UsableSize;
|
||||
}
|
||||
}
|
||||
|
||||
if (_all != null)
|
||||
{
|
||||
for (int n = 0, len = _all.Length; n < len; ++n)
|
||||
{
|
||||
_all[n].Percentage =
|
||||
Math.Round((_all[n].UsableSize / totalSize) * 100, 2, MidpointRounding.AwayFromZero);
|
||||
//Debug.Log("Percentage for: " + n + " " + _all[n].Name + " = " + _all[n].Percentage + " = " + _all[n].UsableSize + " / " + totalSize);
|
||||
}
|
||||
}
|
||||
|
||||
if (_perCategory != null)
|
||||
{
|
||||
for (int catIdx = 0, catLen = _perCategory.Length; catIdx < catLen; ++catIdx)
|
||||
{
|
||||
for (int n = 0, len = _perCategory[catIdx].Length; n < len; ++n)
|
||||
{
|
||||
_perCategory[catIdx][n].Percentage =
|
||||
Math.Round((_perCategory[catIdx][n].UsableSize / totalSize) * 100, 2,
|
||||
MidpointRounding.AwayFromZero);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Debug.Log("Recalculate Percentage End");
|
||||
}
|
||||
|
||||
|
||||
// Commands: Initialization
|
||||
// ==================================================================================
|
||||
|
||||
public void Init(BuildReportTool.SizePart[] all, BuildReportTool.SizePart[][] perCategory, int numberOfTop,
|
||||
FileFilterGroup fileFilters)
|
||||
{
|
||||
All = all;
|
||||
PostSetListAll(numberOfTop);
|
||||
_perCategory = perCategory;
|
||||
|
||||
_viewOffsets = new int[1 + PerCategory.Length]; // +1 since we need to include the "All" list
|
||||
|
||||
if (_lastSortType == SortType.None)
|
||||
{
|
||||
// sort by raw size, descending, by default
|
||||
Sort(SortType.RawSize, SortOrder.Descending, fileFilters);
|
||||
}
|
||||
else
|
||||
{
|
||||
Sort(_lastSortType, _lastSortOrder, fileFilters);
|
||||
}
|
||||
|
||||
RefreshFilterLabels(fileFilters);
|
||||
}
|
||||
|
||||
public void Init(BuildReportTool.SizePart[] all, BuildReportTool.SizePart[][] perCategory, int numberOfTop,
|
||||
FileFilterGroup fileFilters, SortType newSortType, SortOrder newSortOrder)
|
||||
{
|
||||
_lastSortType = newSortType;
|
||||
_lastSortOrder = newSortOrder;
|
||||
|
||||
Init(all, perCategory, numberOfTop, fileFilters);
|
||||
}
|
||||
|
||||
public void Reinit(BuildReportTool.SizePart[] all, BuildReportTool.SizePart[][] perCategory, int numberOfTop)
|
||||
{
|
||||
All = all;
|
||||
PostSetListAll(numberOfTop);
|
||||
_perCategory = perCategory;
|
||||
}
|
||||
|
||||
public void AssignPerCategoryList(BuildReportTool.SizePart[][] perCategory)
|
||||
{
|
||||
_perCategory = perCategory;
|
||||
_viewOffsets = new int[1 + _perCategory.Length]; // +1 since we need to include the "All" list
|
||||
}
|
||||
|
||||
public void RefreshFilterLabels(FileFilterGroup fileFiltersToUse)
|
||||
{
|
||||
_labels = new string[1 + PerCategory.Length];
|
||||
_labels[0] = string.Format("All ({0})", All.Length.ToString());
|
||||
for (int n = 0, len = fileFiltersToUse.Count; n < len; ++n)
|
||||
{
|
||||
_labels[n + 1] = string.Format("{0} ({1})", fileFiltersToUse[n].Label, PerCategory[n].Length.ToString());
|
||||
}
|
||||
|
||||
_labels[_labels.Length - 1] = string.Format("Unknown ({0})", PerCategory[PerCategory.Length - 1].Length.ToString());
|
||||
}
|
||||
|
||||
|
||||
// Sum Selection
|
||||
// ==================================================================================
|
||||
|
||||
[SerializeField]
|
||||
Dictionary<string, BuildReportTool.SizePart> _selectedForSum = new Dictionary<string, BuildReportTool.SizePart>();
|
||||
|
||||
BuildReportTool.SizePart _lastSelected;
|
||||
|
||||
|
||||
// Sum Selection: Queries
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
public bool InSumSelection(BuildReportTool.SizePart b)
|
||||
{
|
||||
return _selectedForSum.ContainsKey(b.Name);
|
||||
}
|
||||
|
||||
double GetSizeOfSumSelection()
|
||||
{
|
||||
double total = 0;
|
||||
foreach (var pair in _selectedForSum)
|
||||
{
|
||||
if (pair.Value.UsableSize > 0)
|
||||
{
|
||||
total += pair.Value.UsableSize;
|
||||
}
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
public double GetPercentageOfSumSelection()
|
||||
{
|
||||
double total = 0;
|
||||
foreach (var pair in _selectedForSum)
|
||||
{
|
||||
if (pair.Value.Percentage > 0)
|
||||
{
|
||||
if (pair.Value.Percentage > 0)
|
||||
{
|
||||
total += pair.Value.Percentage;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
public string GetReadableSizeOfSumSelection()
|
||||
{
|
||||
return BuildReportTool.Util.GetBytesReadable(GetSizeOfSumSelection());
|
||||
}
|
||||
|
||||
public bool AtLeastOneSelectedForSum
|
||||
{
|
||||
get { return _selectedForSum.Count > 0; }
|
||||
}
|
||||
|
||||
public bool IsNothingSelected
|
||||
{
|
||||
get { return _selectedForSum.Count <= 0; }
|
||||
}
|
||||
|
||||
public Dictionary<string, SizePart>.Enumerator GetSelectedEnumerator()
|
||||
{
|
||||
return _selectedForSum.GetEnumerator();
|
||||
}
|
||||
|
||||
public int GetSelectedCount()
|
||||
{
|
||||
return _selectedForSum.Count;
|
||||
}
|
||||
|
||||
public SizePart GetLastSelected()
|
||||
{
|
||||
return _lastSelected;
|
||||
}
|
||||
|
||||
|
||||
// Sum Selection: Commands
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
public void ToggleSumSelection(BuildReportTool.SizePart b)
|
||||
{
|
||||
if (InSumSelection(b))
|
||||
{
|
||||
RemoveFromSumSelection(b);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddToSumSelection(b);
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveFromSumSelection(BuildReportTool.SizePart b)
|
||||
{
|
||||
_selectedForSum.Remove(b.Name);
|
||||
}
|
||||
|
||||
public void AddToSumSelection(BuildReportTool.SizePart b)
|
||||
{
|
||||
if (_selectedForSum.ContainsKey(b.Name))
|
||||
{
|
||||
// already added
|
||||
return;
|
||||
}
|
||||
|
||||
_selectedForSum.Add(b.Name, b);
|
||||
|
||||
_lastSelected = b;
|
||||
}
|
||||
|
||||
public void AddDisplayedRangeToSumSelection(FileFilterGroup fileFilters, int offset, int range)
|
||||
{
|
||||
BuildReportTool.SizePart[] listForSelection = GetListToDisplay(fileFilters);
|
||||
|
||||
for (int n = offset; n < offset + range; ++n)
|
||||
{
|
||||
if (!InSumSelection(listForSelection[n]))
|
||||
{
|
||||
AddToSumSelection(listForSelection[n]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void AddAllDisplayedToSumSelection(FileFilterGroup fileFilters)
|
||||
{
|
||||
BuildReportTool.SizePart[] listForSelection = GetListToDisplay(fileFilters);
|
||||
|
||||
for (int n = 0; n < listForSelection.Length; ++n)
|
||||
{
|
||||
if (!InSumSelection(listForSelection[n]))
|
||||
{
|
||||
AddToSumSelection(listForSelection[n]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ClearSelection()
|
||||
{
|
||||
_selectedForSum.Clear();
|
||||
}
|
||||
}
|
||||
} // namespace BuildReportTool
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d373b2d2472b03a49a6d03c6c3211211
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
@@ -0,0 +1,269 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
|
||||
namespace BuildReportTool
|
||||
{
|
||||
/// <summary>
|
||||
/// Class for holding a Build Report.
|
||||
/// This is the class that is serialized when saving a Build Report to a file.
|
||||
/// </summary>
|
||||
[System.Serializable, System.Xml.Serialization.XmlRoot("BuildInfo")]
|
||||
public partial class BuildInfo : BuildReportTool.IDataFile
|
||||
{
|
||||
// General Info
|
||||
// ==================================================================================
|
||||
|
||||
/// <summary>
|
||||
/// Name of project folder.
|
||||
/// Included as part of the filename when saved.
|
||||
/// </summary>
|
||||
public string ProjectName;
|
||||
|
||||
/// <summary>
|
||||
/// Type of build, as reported by the Unity Editor log, but as a string.
|
||||
/// Included as part of the filename when saved.
|
||||
/// </summary>
|
||||
public string BuildType;
|
||||
|
||||
// -----------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// When build was created.
|
||||
/// Included as part of the filename when saved.
|
||||
/// </summary>
|
||||
public System.DateTime BuildTimeGot;
|
||||
|
||||
/// <summary>
|
||||
/// When report was created.
|
||||
/// </summary>
|
||||
public System.DateTime TimeGot;
|
||||
|
||||
/// <summary>
|
||||
/// When build was created, in readable format.
|
||||
/// </summary>
|
||||
public string BuildTimeGotReadable;
|
||||
|
||||
/// <summary>
|
||||
/// When report was created, in readable format.
|
||||
/// </summary>
|
||||
public string TimeGotReadable;
|
||||
|
||||
// -----------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// How long it took to create this Build Report.
|
||||
/// </summary>
|
||||
System.TimeSpan _reportGenerationTime;
|
||||
|
||||
/// <inheritdoc cref="_reportGenerationTime"/>
|
||||
[System.Xml.Serialization.XmlIgnore]
|
||||
public System.TimeSpan ReportGenerationTime
|
||||
{
|
||||
get { return _reportGenerationTime; }
|
||||
set { _reportGenerationTime = value; }
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="_reportGenerationTime"/>
|
||||
[System.Xml.Serialization.XmlElement("ReportGenerationTime")]
|
||||
public long ReportGenerationTimeInTicks
|
||||
{
|
||||
get { return _reportGenerationTime.Ticks; }
|
||||
set { _reportGenerationTime = new System.TimeSpan(value); }
|
||||
}
|
||||
|
||||
// -----------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// How long it took to create the build.
|
||||
/// </summary>
|
||||
System.TimeSpan _buildDurationTime;
|
||||
|
||||
[System.Xml.Serialization.XmlIgnore]
|
||||
public System.TimeSpan BuildDurationTime
|
||||
{
|
||||
get { return _buildDurationTime; }
|
||||
set { _buildDurationTime = value; }
|
||||
}
|
||||
|
||||
[System.Xml.Serialization.XmlElement("BuildDurationTime")]
|
||||
public long BuildTimeDurationTicks
|
||||
{
|
||||
get { return _buildDurationTime.Ticks; }
|
||||
set { _buildDurationTime = new System.TimeSpan(value); }
|
||||
}
|
||||
|
||||
// -----------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// Version of Unity that was used in building project.
|
||||
/// </summary>
|
||||
public string UnityVersion = "";
|
||||
|
||||
/// <summary>
|
||||
/// Value of <see cref="EditorApplication.applicationContentsPath"/> during time of build.
|
||||
/// This is the full path where the Unity Editor executable is.
|
||||
/// </summary>
|
||||
public string EditorAppContentsPath = "";
|
||||
|
||||
/// <summary>
|
||||
/// Value of <see cref="UnityEngine.Application.dataPath"/> during time of build.
|
||||
/// This is the full path where the project folder is.
|
||||
/// </summary>
|
||||
public string ProjectAssetsPath = "";
|
||||
|
||||
/// <summary>
|
||||
/// Value of <see cref="EditorUserBuildSettings.GetBuildLocation"/> during time of build.
|
||||
/// This is the full path where the build output is.
|
||||
/// </summary>
|
||||
public string BuildFilePath = "";
|
||||
|
||||
|
||||
// Build Settings at time of Build Report creation
|
||||
// ==================================================================================
|
||||
|
||||
/// <summary>
|
||||
/// If this Build Report recorded the various Build Settings when project was built.
|
||||
/// </summary>
|
||||
public bool HasUnityBuildSettings;
|
||||
|
||||
/// <summary>
|
||||
/// Various Build Settings when project was built.
|
||||
/// </summary>
|
||||
public UnityBuildSettings UnityBuildSettings;
|
||||
|
||||
|
||||
// Unity/OS environment values at time of Build Report creation
|
||||
// ==================================================================================
|
||||
|
||||
//public string[] PrefabsUsedInScenes;
|
||||
|
||||
/// <summary>
|
||||
/// If the output for an Android build additionally had an .obb file beside the .apk file.
|
||||
/// </summary>
|
||||
public bool AndroidUseAPKExpansionFiles;
|
||||
|
||||
/// <summary>
|
||||
/// If the output for an Android build was a project instead of an .apk file.
|
||||
/// </summary>
|
||||
public bool AndroidCreateProject;
|
||||
|
||||
|
||||
// Total sizes
|
||||
// ==================================================================================
|
||||
|
||||
/// <summary>
|
||||
/// Total size of output, in readable format.
|
||||
/// </summary>
|
||||
public string TotalBuildSize = "";
|
||||
|
||||
/// <summary>
|
||||
/// Not used anymore. This is kept here for compatibility
|
||||
/// with opening and displaying old Build Report files.
|
||||
/// This was the total size of output, in readable format.
|
||||
/// </summary>
|
||||
public string CompressedBuildSize = "";
|
||||
|
||||
/// <summary>
|
||||
/// Total size of all assets used in the build, in readable format.
|
||||
/// </summary>
|
||||
public string UsedTotalSize = "";
|
||||
|
||||
/// <summary>
|
||||
/// Total size of all assets *not* used in the build, in readable format.
|
||||
/// </summary>
|
||||
public string UnusedTotalSize = "";
|
||||
|
||||
/// <summary>
|
||||
/// Total size of StreamingAssets folder (if present), in readable format.
|
||||
/// </summary>
|
||||
public string StreamingAssetsSize = "";
|
||||
|
||||
|
||||
// Per-platform specific sizes
|
||||
// -------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// Not used anymore. This is kept here for compatibility
|
||||
/// with opening and displaying old Build Report files.
|
||||
/// This was the size of the .unity3d web build file, in readable format.
|
||||
/// </summary>
|
||||
public string WebFileBuildSize = "";
|
||||
|
||||
/// <summary>
|
||||
/// For Android builds, this is the size of the .apk file, in readable format.
|
||||
/// </summary>
|
||||
public string AndroidApkFileBuildSize = "";
|
||||
|
||||
/// <summary>
|
||||
/// For Android builds that generated an additional .obb file,
|
||||
/// this is the size of the .obb file, in readable format.
|
||||
/// </summary>
|
||||
public string AndroidObbFileBuildSize = "";
|
||||
|
||||
|
||||
// Category Sizes
|
||||
// ==================================================================================
|
||||
|
||||
public BuildReportTool.SizePart[] BuildSizes;
|
||||
|
||||
|
||||
// File entries
|
||||
// ==================================================================================
|
||||
|
||||
/// <summary>
|
||||
/// All Mono/.NET DLL files used in the build, and their file sizes.
|
||||
/// </summary>
|
||||
public BuildReportTool.SizePart[] MonoDLLs;
|
||||
|
||||
/// <summary>
|
||||
/// All managed DLL files from the project's Assets folder
|
||||
/// that were used in the build, and their file sizes.
|
||||
/// </summary>
|
||||
public BuildReportTool.SizePart[] ScriptDLLs;
|
||||
|
||||
/// <summary>
|
||||
/// All the Unity API managed DLL files
|
||||
/// that were used in the build, and their file sizes.
|
||||
/// </summary>
|
||||
public BuildReportTool.SizePart[] UnityEngineDLLs;
|
||||
|
||||
/// <summary>
|
||||
/// File filters used at time of Build Report creation
|
||||
/// </summary>
|
||||
public FileFilterGroup FileFilters;
|
||||
|
||||
/// <summary>
|
||||
/// All files from the project's Assets folder
|
||||
/// that were included in the build, and their file sizes.
|
||||
/// </summary>
|
||||
public AssetList UsedAssets;
|
||||
|
||||
/// <summary>
|
||||
/// All files from the project's Assets folder
|
||||
/// that were *not* included in the build, and their file sizes.
|
||||
/// </summary>
|
||||
public AssetList UnusedAssets;
|
||||
|
||||
/// <summary>
|
||||
/// Scenes included in the build
|
||||
/// </summary>
|
||||
public SceneInBuild[] ScenesInBuild;
|
||||
|
||||
|
||||
// Build Report Tool Options used at time of Build Report creation
|
||||
// ==================================================================================
|
||||
|
||||
public bool IncludedSvnInUnused;
|
||||
public bool IncludedGitInUnused;
|
||||
public bool IncludedBuildReportToolAssetsInUnused;
|
||||
|
||||
public List<SavedOptions.IgnorePattern> IgnorePatternsForUnused;
|
||||
|
||||
public bool UsedAssetsIncludedInCreation;
|
||||
public bool UnusedAssetsIncludedInCreation;
|
||||
public bool UnusedPrefabsIncludedInCreation;
|
||||
|
||||
public bool ProcessUnusedAssetsInBatches = true;
|
||||
public int UnusedAssetsEntriesPerBatch;
|
||||
}
|
||||
} // namespace BuildReportTool
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ff2cf1458371b124d9aca896e244c45e
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
@@ -0,0 +1,602 @@
|
||||
#if UNITY_4 || UNITY_5_0 || UNITY_5_1 || UNITY_5_2
|
||||
#define UNITY_5_2_AND_LESSER
|
||||
#endif
|
||||
|
||||
using UnityEditor;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace BuildReportTool
|
||||
{
|
||||
public partial class BuildInfo
|
||||
{
|
||||
public struct SceneInBuild
|
||||
{
|
||||
public bool Enabled;
|
||||
public string Path;
|
||||
}
|
||||
|
||||
// Queries
|
||||
// ==================================================================================
|
||||
|
||||
public bool HasContents
|
||||
{
|
||||
get
|
||||
{
|
||||
// build sizes can't be empty (they are always there when you build)
|
||||
return !string.IsNullOrEmpty(ProjectName) && (BuildSizes != null && BuildSizes.Length > 0);
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsUnityVersionAtLeast(int majorAtLeast, int minorAtLeast, int patchAtLeast)
|
||||
{
|
||||
return DldUtil.UnityVersion.IsUnityVersionAtLeast(UnityVersion, majorAtLeast, minorAtLeast, patchAtLeast);
|
||||
}
|
||||
|
||||
public bool IsUnityVersionAtMost(int majorAtMost, int minorAtMost, int patchAtMost)
|
||||
{
|
||||
return DldUtil.UnityVersion.IsUnityVersionAtMost(UnityVersion, majorAtMost, minorAtMost, patchAtMost);
|
||||
}
|
||||
|
||||
public string SuitableTitle
|
||||
{
|
||||
get
|
||||
{
|
||||
if (UnityBuildSettings != null && UnityBuildSettings.HasValues &&
|
||||
!string.IsNullOrEmpty(UnityBuildSettings.ProductName))
|
||||
{
|
||||
return UnityBuildSettings.ProductName;
|
||||
}
|
||||
|
||||
return ProjectName;
|
||||
}
|
||||
}
|
||||
|
||||
public string GetTimeReadable()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(BuildTimeGotReadable))
|
||||
{
|
||||
return BuildTimeGotReadable;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(TimeGotReadable))
|
||||
{
|
||||
return TimeGotReadable;
|
||||
}
|
||||
|
||||
return TimeGot.ToString(BuildReportTool.ReportGenerator.TIME_OF_BUILD_FORMAT);
|
||||
}
|
||||
|
||||
public string UnityVersionDisplayed
|
||||
{
|
||||
get
|
||||
{
|
||||
if (UnityBuildSettings != null && UnityBuildSettings.HasValues)
|
||||
{
|
||||
return UnityVersion + (UnityBuildSettings.UsingAdvancedLicense ? " Pro" : "");
|
||||
}
|
||||
|
||||
return UnityVersion;
|
||||
}
|
||||
}
|
||||
|
||||
public string GetDefaultFilename()
|
||||
{
|
||||
return BuildReportTool.Util.GetBuildInfoDefaultFilename(ProjectName, BuildType, BuildTimeGot);
|
||||
}
|
||||
|
||||
public string GetAccompanyingAssetDependenciesFilename()
|
||||
{
|
||||
return BuildReportTool.Util.GetAssetDependenciesDefaultFilename(ProjectName, BuildType, BuildTimeGot);
|
||||
}
|
||||
|
||||
// old size values were only TotalBuildSize and CompressedBuildSize
|
||||
public bool HasOldSizeValues
|
||||
{
|
||||
get
|
||||
{
|
||||
return
|
||||
string.IsNullOrEmpty(UnusedTotalSize) &&
|
||||
string.IsNullOrEmpty(UsedTotalSize) &&
|
||||
string.IsNullOrEmpty(StreamingAssetsSize) &&
|
||||
string.IsNullOrEmpty(WebFileBuildSize) &&
|
||||
string.IsNullOrEmpty(AndroidApkFileBuildSize) &&
|
||||
string.IsNullOrEmpty(AndroidObbFileBuildSize);
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasUsedAssets
|
||||
{
|
||||
get { return UsedAssets != null; }
|
||||
}
|
||||
|
||||
public bool HasUnusedAssets
|
||||
{
|
||||
get { return UnusedAssets != null; }
|
||||
}
|
||||
|
||||
public bool HasStreamingAssets
|
||||
{
|
||||
get { return StreamingAssetsSize != "0 B"; }
|
||||
}
|
||||
|
||||
// Commands
|
||||
// ==================================================================================
|
||||
|
||||
public void UnescapeAssetNames()
|
||||
{
|
||||
if (UsedAssets != null)
|
||||
{
|
||||
UsedAssets.UnescapeAssetNames();
|
||||
}
|
||||
|
||||
if (UnusedAssets != null)
|
||||
{
|
||||
UnusedAssets.UnescapeAssetNames();
|
||||
}
|
||||
}
|
||||
|
||||
public void RecategorizeAssetLists()
|
||||
{
|
||||
FileFilterGroup fileFiltersToUse = FileFilters;
|
||||
|
||||
if (BuildReportTool.Options.ShouldUseConfiguredFileFilters())
|
||||
{
|
||||
fileFiltersToUse = BuildReportTool.FiltersUsed.GetProperFileFilterGroupToUse();
|
||||
//Debug.Log("going to use configured file filters instead... loaded: " + (fileFiltersToUse != null));
|
||||
}
|
||||
|
||||
if (UsedAssets != null)
|
||||
{
|
||||
UsedAssets.AssignPerCategoryList(
|
||||
BuildReportTool.ReportGenerator.SegregateAssetSizesPerCategory(UsedAssets.All, fileFiltersToUse));
|
||||
|
||||
UsedAssets.RefreshFilterLabels(fileFiltersToUse);
|
||||
|
||||
UsedAssets.ResortDefault(BuildReportTool.Options.NumberOfTopLargestUsedAssetsToShow);
|
||||
}
|
||||
|
||||
if (UnusedAssets != null)
|
||||
{
|
||||
UnusedAssets.AssignPerCategoryList(
|
||||
BuildReportTool.ReportGenerator.SegregateAssetSizesPerCategory(UnusedAssets.All, fileFiltersToUse));
|
||||
|
||||
UnusedAssets.RefreshFilterLabels(fileFiltersToUse);
|
||||
|
||||
UnusedAssets.ResortDefault(BuildReportTool.Options.NumberOfTopLargestUnusedAssetsToShow);
|
||||
}
|
||||
}
|
||||
|
||||
public void RecategorizeUsedAssets()
|
||||
{
|
||||
if (UsedAssets == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
FileFilterGroup fileFiltersToUse = FileFilters;
|
||||
|
||||
if (BuildReportTool.Options.ShouldUseConfiguredFileFilters())
|
||||
{
|
||||
fileFiltersToUse = BuildReportTool.FiltersUsed.GetProperFileFilterGroupToUse();
|
||||
//Debug.Log("going to use configured file filters instead... loaded: " + (fileFiltersToUse != null));
|
||||
}
|
||||
|
||||
UsedAssets.AssignPerCategoryList(
|
||||
BuildReportTool.ReportGenerator.SegregateAssetSizesPerCategory(UsedAssets.All, fileFiltersToUse));
|
||||
|
||||
UsedAssets.RefreshFilterLabels(fileFiltersToUse);
|
||||
|
||||
UsedAssets.ResortDefault(BuildReportTool.Options.NumberOfTopLargestUsedAssetsToShow);
|
||||
}
|
||||
|
||||
public void RecategorizeUnusedAssets()
|
||||
{
|
||||
if (UnusedAssets == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
FileFilterGroup fileFiltersToUse = FileFilters;
|
||||
|
||||
if (BuildReportTool.Options.ShouldUseConfiguredFileFilters())
|
||||
{
|
||||
fileFiltersToUse = BuildReportTool.FiltersUsed.GetProperFileFilterGroupToUse();
|
||||
//Debug.Log("going to use configured file filters instead... loaded: " + (fileFiltersToUse != null));
|
||||
}
|
||||
|
||||
UnusedAssets.AssignPerCategoryList(
|
||||
BuildReportTool.ReportGenerator.SegregateAssetSizesPerCategory(UnusedAssets.All, fileFiltersToUse));
|
||||
|
||||
UnusedAssets.RefreshFilterLabels(fileFiltersToUse);
|
||||
|
||||
UnusedAssets.ResortDefault(BuildReportTool.Options.NumberOfTopLargestUnusedAssetsToShow);
|
||||
}
|
||||
|
||||
void CalculateUsedAssetsDerivedSizes()
|
||||
{
|
||||
if (UsedAssets != null)
|
||||
{
|
||||
for (int n = 0, len = UsedAssets.All.Length; n < len; ++n)
|
||||
{
|
||||
UsedAssets.All[n].DerivedSize = BuildReportTool.Util.GetApproxSizeFromString(UsedAssets.All[n].Size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SortSizes()
|
||||
{
|
||||
System.Array.Sort(BuildSizes, delegate(BuildReportTool.SizePart b1, BuildReportTool.SizePart b2)
|
||||
{
|
||||
if (b1.Percentage > b2.Percentage) return -1;
|
||||
else if (b1.Percentage < b2.Percentage) return 1;
|
||||
// if percentages are equal, check actual file size (approximate values)
|
||||
else if (b1.DerivedSize > b2.DerivedSize) return -1;
|
||||
else if (b1.DerivedSize < b2.DerivedSize) return 1;
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// This is called right after generating a build report.
|
||||
/// </summary>
|
||||
public void FixReport()
|
||||
{
|
||||
#if UNITY_5_2_AND_LESSER
|
||||
// this bug has already been fixed since Unity 5.2.1
|
||||
// so we only execute this for Unity 5.2.0 and below
|
||||
|
||||
if (!DldUtil.UnityVersion.IsUnityVersionAtLeast(5, 2, 1))
|
||||
{
|
||||
// --------------------------------------------------------------------------------
|
||||
// fix imported sizes of Resources files
|
||||
|
||||
for (int n = 0; n < UsedAssets.All.Length; ++n)
|
||||
{
|
||||
if (BuildReportTool.Util.IsFileInAPath(UsedAssets.All[n].Name, "/Resources/"))
|
||||
{
|
||||
UsedAssets.All[n].ImportedSizeBytes = BRT_LibCacheUtil.GetImportedFileSize(UsedAssets.All[n].Name);
|
||||
UsedAssets.All[n].ImportedSize =
|
||||
BuildReportTool.Util.GetBytesReadable(UsedAssets.All[n].ImportedSizeBytes);
|
||||
|
||||
UsedAssets.All[n].RawSizeBytes = UsedAssets.All[n].ImportedSizeBytes;
|
||||
UsedAssets.All[n].RawSize = UsedAssets.All[n].ImportedSize;
|
||||
|
||||
UsedAssets.All[n].DerivedSize = 0;
|
||||
UsedAssets.All[n].Percentage = -1;
|
||||
}
|
||||
}
|
||||
|
||||
UsedAssets.ResortDefault(BuildReportTool.Options.NumberOfTopLargestUsedAssetsToShow);
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
// recalculate percentages
|
||||
|
||||
var totalSizePart = BuildSizes.FirstOrDefault(part => part.IsTotal);
|
||||
if (totalSizePart != null && System.Math.Abs(totalSizePart.DerivedSize) < 0.01)
|
||||
{
|
||||
var totalSize = GetTotalSize();
|
||||
ChangeTotalSize(totalSize);
|
||||
}
|
||||
|
||||
// add textures, meshes, sounds, and animations that are in resources folder to the build size
|
||||
// since they are not included anymore in Unity 5
|
||||
|
||||
var resourcesTextureSizeSum =
|
||||
GetSizeSumForUsedAssets("/Resources/", BuildReportTool.Util.IsTextureFile);
|
||||
AddToSize("Textures", resourcesTextureSizeSum);
|
||||
|
||||
var resourcesMeshSizeSum = GetSizeSumForUsedAssets("/Resources/", BuildReportTool.Util.IsMeshFile);
|
||||
AddToSize("Meshes", resourcesMeshSizeSum);
|
||||
|
||||
var resourcesSoundsSizeSum = GetSizeSumForUsedAssets("/Resources/", BuildReportTool.Util.IsSoundFile);
|
||||
AddToSize("Sounds", resourcesSoundsSizeSum);
|
||||
|
||||
var resourcesAnimationsSizeSum =
|
||||
GetSizeSumForUsedAssets("/Resources/", BuildReportTool.Util.IsAnimationFile);
|
||||
AddToSize("Animations", resourcesAnimationsSizeSum);
|
||||
|
||||
AddToTotalSize(resourcesTextureSizeSum);
|
||||
AddToTotalSize(resourcesMeshSizeSum);
|
||||
AddToTotalSize(resourcesSoundsSizeSum);
|
||||
AddToTotalSize(resourcesAnimationsSizeSum);
|
||||
|
||||
RecalculatePercentages();
|
||||
|
||||
// sort sizes again since we modified them
|
||||
SortSizes();
|
||||
}
|
||||
#else
|
||||
// newer versions of Unity (2017 and up)
|
||||
// has a bug where the total size reported is actually the final build's size,
|
||||
// instead of the total of the sizes indicated in the build log.
|
||||
// so we recalculate the percentages.
|
||||
// this is most noticeable when the percentages
|
||||
// indicated don't really total up to 100, not even close to 90
|
||||
RecalculatePercentages();
|
||||
|
||||
// sort sizes again since we modified them
|
||||
SortSizes();
|
||||
#endif
|
||||
}
|
||||
|
||||
// Events
|
||||
// ==================================================================================
|
||||
|
||||
public void OnBeforeSave()
|
||||
{
|
||||
}
|
||||
|
||||
public void OnAfterLoad()
|
||||
{
|
||||
if (HasContents)
|
||||
{
|
||||
CalculateUsedAssetsDerivedSizes();
|
||||
UnescapeAssetNames();
|
||||
RecategorizeAssetLists();
|
||||
}
|
||||
}
|
||||
|
||||
// Helper methods
|
||||
// ==================================================================================
|
||||
|
||||
double GetTotalSize()
|
||||
{
|
||||
if (BuildSizes == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
double totalSize = 0;
|
||||
for (int n = 0, len = BuildSizes.Length; n < len; ++n)
|
||||
{
|
||||
if (!BuildSizes[n].IsTotal)
|
||||
{
|
||||
totalSize += BuildSizes[n].DerivedSize;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return totalSize;
|
||||
}
|
||||
|
||||
void RecalculatePercentages()
|
||||
{
|
||||
//Debug.Log("RecalculatePercentages() called");
|
||||
|
||||
|
||||
double totalSize = GetTotalSize();
|
||||
|
||||
//Debug.LogFormat("BuildSizes total: {0}", totalSize);
|
||||
|
||||
for (int n = 0, len = BuildSizes.Length; n < len; ++n)
|
||||
{
|
||||
BuildSizes[n].Percentage = System.Math.Round((BuildSizes[n].UsableSize / totalSize) * 100, 2,
|
||||
System.MidpointRounding.AwayFromZero);
|
||||
}
|
||||
|
||||
|
||||
// note: only Used Assets are shown the percentages so we
|
||||
// don't bother recalculating percentage for Unused Assets
|
||||
if (UsedAssets != null)
|
||||
{
|
||||
UsedAssets.RecalculatePercentages(totalSize);
|
||||
}
|
||||
|
||||
ChangeTotalSize(totalSize);
|
||||
}
|
||||
|
||||
long GetSizeSumForUsedAssets(string assetFolderName, System.Func<string, bool> fileTypePredicate)
|
||||
{
|
||||
if (UsedAssets == null || UsedAssets.All == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return UsedAssets.All.Where(part =>
|
||||
BuildReportTool.Util.IsFileInAPath(part.Name, assetFolderName) &&
|
||||
fileTypePredicate(part.Name))
|
||||
.Sum(part => BRT_LibCacheUtil.GetImportedFileSize(part.Name));
|
||||
}
|
||||
|
||||
static void AddToSize(BuildReportTool.SizePart buildSize, long sizeToAdd)
|
||||
{
|
||||
if (buildSize != null)
|
||||
{
|
||||
buildSize.DerivedSize += sizeToAdd;
|
||||
buildSize.Size = BuildReportTool.Util.GetBytesReadable(buildSize.DerivedSize);
|
||||
}
|
||||
}
|
||||
|
||||
void AddToSize(string buildSizeName, long sizeToAdd)
|
||||
{
|
||||
if (sizeToAdd == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
BuildReportTool.SizePart buildSize = BuildSizes.FirstOrDefault(part => part.Name == buildSizeName);
|
||||
|
||||
if (buildSize != null)
|
||||
{
|
||||
//Debug.LogFormat("{0} size before: {1}", buildSizeName, buildSize.DerivedSize);
|
||||
|
||||
AddToSize(buildSize, sizeToAdd);
|
||||
|
||||
//Debug.LogFormat("{0} size after: {1}", buildSizeName, buildSize.DerivedSize);
|
||||
}
|
||||
}
|
||||
|
||||
void AddToTotalSize(long sizeToAdd)
|
||||
{
|
||||
if (sizeToAdd == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
BuildReportTool.SizePart buildSize = BuildSizes.FirstOrDefault(part => part.IsTotal);
|
||||
|
||||
if (buildSize != null)
|
||||
{
|
||||
//Debug.LogFormat("total size before: {0}", buildSize.DerivedSize);
|
||||
|
||||
AddToSize(buildSize, sizeToAdd);
|
||||
|
||||
UsedTotalSize = buildSize.Size;
|
||||
|
||||
//Debug.LogFormat("total size after: {0}", buildSize.DerivedSize);
|
||||
}
|
||||
}
|
||||
|
||||
void ChangeTotalSize(double newSize)
|
||||
{
|
||||
if (System.Math.Abs(newSize) < 0.01)
|
||||
{
|
||||
// disallow zero total size
|
||||
return;
|
||||
}
|
||||
|
||||
BuildReportTool.SizePart totalSize = BuildSizes.FirstOrDefault(part => part.IsTotal);
|
||||
|
||||
if (totalSize != null)
|
||||
{
|
||||
//Debug.LogFormat("total size before: {0}", totalSize.DerivedSize);
|
||||
|
||||
totalSize.DerivedSize = newSize;
|
||||
totalSize.Size = BuildReportTool.Util.GetBytesReadable(totalSize.DerivedSize);
|
||||
|
||||
UsedTotalSize = totalSize.Size;
|
||||
|
||||
//Debug.LogFormat("total size after: {0}", totalSize.DerivedSize);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// temp variables that are not serialized into the XML file
|
||||
// ==================================================================================
|
||||
|
||||
// only used while generating the build report or opening one
|
||||
|
||||
/// <summary>
|
||||
/// Needed for ParseDLLs
|
||||
/// </summary>
|
||||
[System.Xml.Serialization.XmlIgnore]
|
||||
public ApiCompatibilityLevel MonoLevel;
|
||||
|
||||
/// <summary>
|
||||
/// Needed for ParseDLLs
|
||||
/// </summary>
|
||||
[System.Xml.Serialization.XmlIgnore]
|
||||
public StrippingLevel CodeStrippingLevel;
|
||||
|
||||
|
||||
public void SetScenes(EditorBuildSettingsScene[] newScenes)
|
||||
{
|
||||
var len = newScenes.Length;
|
||||
ScenesInBuild = new SceneInBuild[len];
|
||||
for (int n = 0; n < len; ++n)
|
||||
{
|
||||
ScenesInBuild[n].Enabled = newScenes[n].enabled;
|
||||
ScenesInBuild[n].Path = newScenes[n].path;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetScenes(string[] newScenes)
|
||||
{
|
||||
var len = newScenes.Length;
|
||||
ScenesInBuild = new SceneInBuild[len];
|
||||
for (int n = 0; n < len; ++n)
|
||||
{
|
||||
ScenesInBuild[n].Enabled = true;
|
||||
ScenesInBuild[n].Path = newScenes[n];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int _unusedAssetsBatchIdx;
|
||||
|
||||
public int UnusedAssetsBatchIdx
|
||||
{
|
||||
get { return _unusedAssetsBatchIdx; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Last asset number that each batch displays.
|
||||
/// </summary>
|
||||
[System.Xml.Serialization.XmlIgnore]
|
||||
public List<int> UnusedAssetsBatchFinalNum = new List<int>();
|
||||
|
||||
public void ResetUnusedAssetsBatchData()
|
||||
{
|
||||
_unusedAssetsBatchIdx = 0;
|
||||
UnusedAssetsBatchFinalNum.Clear();
|
||||
}
|
||||
|
||||
public void MoveUnusedAssetsBatchNumToNext()
|
||||
{
|
||||
++_unusedAssetsBatchIdx;
|
||||
}
|
||||
|
||||
public void MoveUnusedAssetsBatchNumToPrev()
|
||||
{
|
||||
if (_unusedAssetsBatchIdx == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
--_unusedAssetsBatchIdx;
|
||||
}
|
||||
|
||||
// ---------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// Full path where this Build Report is saved in the local storage.
|
||||
/// </summary>
|
||||
string _savedPath;
|
||||
|
||||
/// <inheritdoc cref="_savedPath"/>
|
||||
public string SavedPath
|
||||
{
|
||||
get { return _savedPath; }
|
||||
}
|
||||
|
||||
public void SetSavedPath(string val)
|
||||
{
|
||||
_savedPath = val.Replace("\\", "/");
|
||||
}
|
||||
|
||||
// ---------------------------------------
|
||||
|
||||
BuildTarget _buildTarget;
|
||||
|
||||
public BuildTarget BuildTargetUsed
|
||||
{
|
||||
get { return _buildTarget; }
|
||||
}
|
||||
|
||||
public void SetBuildTargetUsed(BuildTarget val)
|
||||
{
|
||||
_buildTarget = val;
|
||||
}
|
||||
|
||||
// ---------------------------------------
|
||||
|
||||
bool _refreshRequest;
|
||||
|
||||
public void FlagOkToRefresh()
|
||||
{
|
||||
_refreshRequest = true;
|
||||
}
|
||||
|
||||
public void FlagFinishedRefreshing()
|
||||
{
|
||||
_refreshRequest = false;
|
||||
}
|
||||
|
||||
public bool RequestedToRefresh
|
||||
{
|
||||
get { return _refreshRequest; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 255e387177d750b4caac40a5459299f9
|
||||
timeCreated: 1557585214
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,82 @@
|
||||
namespace BuildReportTool
|
||||
{
|
||||
/// <summary>
|
||||
/// Per platform identification.
|
||||
/// Needed to handle special cases.
|
||||
/// Example: some platforms have a compressed build, some do not.
|
||||
/// Also, native plugins are handled differently in each platform.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Meant to be similar to <see cref="UnityEditor.BuildTarget"/>,
|
||||
/// except here we don't mark any value obsolete, for backwards compatibility
|
||||
/// with old Build Reports.
|
||||
/// </remarks>
|
||||
public enum BuildPlatform
|
||||
{
|
||||
None = 0,
|
||||
|
||||
// -------
|
||||
// Mobiles
|
||||
// -------
|
||||
|
||||
Android = 1,
|
||||
iOS,
|
||||
tvOS,
|
||||
Blackberry,
|
||||
WindowsPhone8,
|
||||
Tizen,
|
||||
|
||||
|
||||
// --------
|
||||
// Web
|
||||
// --------
|
||||
|
||||
Web = 100,
|
||||
Flash,
|
||||
WebGL,
|
||||
|
||||
|
||||
// --------
|
||||
// Desktops
|
||||
// --------
|
||||
|
||||
// distinctions between 32 or 64 bit need to be made to
|
||||
// determine which existing native plugins are used or not
|
||||
|
||||
MacOSX32 = 200,
|
||||
MacOSX64,
|
||||
MacOSXUniversal,
|
||||
|
||||
Windows32 = 300,
|
||||
Windows64,
|
||||
WindowsStoreApp,
|
||||
|
||||
Linux32 = 400,
|
||||
Linux64,
|
||||
LinuxUniversal,
|
||||
LinuxHeadless,
|
||||
EmbeddedLinux,
|
||||
|
||||
|
||||
// ------
|
||||
// Consoles
|
||||
// ------
|
||||
|
||||
// currently not handled in any special way (probably needs to be):
|
||||
|
||||
Xbox360 = 500,
|
||||
XboxOne,
|
||||
XboxSeries,
|
||||
|
||||
PS3 = 600,
|
||||
PSVitaNative,
|
||||
PSMobile,
|
||||
PS4,
|
||||
PS5,
|
||||
|
||||
Wii = 700,
|
||||
WiiU,
|
||||
Nintendo3DS,
|
||||
Switch,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1f8c3277dd7544144be1fcb1a76b0c0c
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
@@ -0,0 +1,40 @@
|
||||
namespace BuildReportTool
|
||||
{
|
||||
/// <summary>
|
||||
/// Platforms that are shown in the Build Settings Screen
|
||||
/// </summary>
|
||||
public enum BuildSettingCategory
|
||||
{
|
||||
None = 0,
|
||||
|
||||
WindowsDesktopStandalone = 100,
|
||||
WindowsStoreApp,
|
||||
MacStandalone = 200,
|
||||
LinuxStandalone = 250,
|
||||
|
||||
WebPlayer = 300,
|
||||
FlashPlayer,
|
||||
WebGL,
|
||||
|
||||
iOS = 400,
|
||||
tvOS,
|
||||
Android = 500,
|
||||
Blackberry = 600,
|
||||
WindowsPhone8,
|
||||
Tizen,
|
||||
|
||||
Xbox360 = 700,
|
||||
XboxOne,
|
||||
XboxSeries,
|
||||
|
||||
PS3 = 800,
|
||||
PS4,
|
||||
PSVita,
|
||||
PSM,
|
||||
PS5,
|
||||
|
||||
Switch = 900,
|
||||
|
||||
SamsungTV = 1000,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1fb3aa40651b3a24eb3280438e0ca363
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
@@ -0,0 +1,12 @@
|
||||
|
||||
namespace BuildReportTool
|
||||
{
|
||||
public interface IDataFile
|
||||
{
|
||||
void OnBeforeSave();
|
||||
void OnAfterLoad();
|
||||
void SetSavedPath(string savedPath);
|
||||
string SavedPath { get; }
|
||||
string GetDefaultFilename();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 68ce3abd878aabc408cfe36da6d6f84c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,261 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BuildReportTool
|
||||
{
|
||||
[System.Serializable, System.Xml.Serialization.XmlRoot("MeshData")]
|
||||
public class MeshData : BuildReportTool.IDataFile
|
||||
{
|
||||
// ==================================================================================
|
||||
|
||||
/// <summary>
|
||||
/// Name of project folder.
|
||||
/// Included as part of the filename when saved.
|
||||
/// </summary>
|
||||
public string ProjectName;
|
||||
|
||||
/// <summary>
|
||||
/// Type of build that the project was configured to, at the time that MeshData was collected.
|
||||
/// Included as part of the filename when saved.
|
||||
/// </summary>
|
||||
public string BuildType;
|
||||
|
||||
/// <summary>
|
||||
/// When MeshData was collected.
|
||||
/// Included as part of the filename when saved.
|
||||
/// </summary>
|
||||
public System.DateTime TimeGot;
|
||||
|
||||
public string GetDefaultFilename()
|
||||
{
|
||||
return BuildReportTool.Util.GetMeshDataDefaultFilename(ProjectName, BuildType, TimeGot);
|
||||
}
|
||||
|
||||
public string GetAccompanyingBuildReportFilename()
|
||||
{
|
||||
return BuildReportTool.Util.GetBuildInfoDefaultFilename(ProjectName, BuildType, TimeGot);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Full path where this MeshData is saved in the local storage.
|
||||
/// </summary>
|
||||
string _savedPath;
|
||||
|
||||
/// <inheritdoc cref="_savedPath"/>
|
||||
public string SavedPath
|
||||
{
|
||||
get { return _savedPath; }
|
||||
}
|
||||
|
||||
public void SetSavedPath(string val)
|
||||
{
|
||||
_savedPath = val.Replace("\\", "/");
|
||||
}
|
||||
|
||||
public bool HasContents
|
||||
{
|
||||
get { return _meshData.Count > 0; }
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
_meshData.Clear();
|
||||
}
|
||||
|
||||
// ==================================================================================
|
||||
|
||||
public enum DataId
|
||||
{
|
||||
None,
|
||||
MeshFilterCount,
|
||||
SkinnedMeshRendererCount,
|
||||
SubMeshCount,
|
||||
VertexCount,
|
||||
TriangleCount,
|
||||
AnimationType,
|
||||
AnimationClipCount,
|
||||
}
|
||||
|
||||
public const string TOOLTIP_TEXT_MESH_FILTER_COUNT = @"<b><color=white>Non-skinned Mesh Count</color></b>
|
||||
|
||||
Number of MeshFilter components in the asset.";
|
||||
|
||||
public const string TOOLTIP_TEXT_SKINNED_MESH_RENDERER_COUNT = @"<b><color=white>Skinned Mesh Count</color></b>
|
||||
|
||||
Number of SkinnedMeshRenderer components in the asset.";
|
||||
|
||||
public const string TOOLTIP_TEXT_SUB_MESH_COUNT = @"<b><color=white>Sub-Mesh Count</color></b>
|
||||
|
||||
Total number of sub-meshes in the asset.";
|
||||
|
||||
public const string TOOLTIP_TEXT_VERTEX_COUNT = @"<b><color=white>Vertex Count</color></b>
|
||||
|
||||
Total number of vertices from all meshes in the asset.
|
||||
|
||||
This is the number of vertices <b>used in the triangles</b>. Some vertices are re-used, which means the number here will normally be higher than what 3d programs usually display.
|
||||
|
||||
For example, a regular cube will have 24 in its vertex count, instead of 8 (4 vertices for each face, 6 faces in total, 4 x 6 = 24).";
|
||||
|
||||
public const string TOOLTIP_TEXT_TRIANGLE_COUNT = @"<b><color=white>Face Count</color></b>
|
||||
|
||||
Total number of triangles from all meshes in the asset.
|
||||
|
||||
If <b><color=white>Keep Quads</color></b> was turned on in the asset's Import Settings, then this count is a mix of triangles and quads.";
|
||||
|
||||
public const string TOOLTIP_TEXT_ANIMATION_TYPE = @"<b><color=white>Animation Type</color></b>
|
||||
|
||||
Whether this asset is set to use Humanoid, Generic, or Legacy type of animation.";
|
||||
|
||||
public const string TOOLTIP_TEXT_ANIMATION_CLIP_COUNT = @"<b><color=white>Animation Clip Count</color></b>
|
||||
|
||||
Number of imported Animation Clips in the asset.";
|
||||
|
||||
public static string GetTooltipTextFromId(DataId textureDataId)
|
||||
{
|
||||
switch (textureDataId)
|
||||
{
|
||||
case DataId.MeshFilterCount:
|
||||
return TOOLTIP_TEXT_MESH_FILTER_COUNT;
|
||||
case DataId.SkinnedMeshRendererCount:
|
||||
return TOOLTIP_TEXT_SKINNED_MESH_RENDERER_COUNT;
|
||||
case DataId.SubMeshCount:
|
||||
return TOOLTIP_TEXT_SUB_MESH_COUNT;
|
||||
case DataId.VertexCount:
|
||||
return TOOLTIP_TEXT_VERTEX_COUNT;
|
||||
case DataId.TriangleCount:
|
||||
return TOOLTIP_TEXT_TRIANGLE_COUNT;
|
||||
case DataId.AnimationType:
|
||||
return TOOLTIP_TEXT_ANIMATION_TYPE;
|
||||
case DataId.AnimationClipCount:
|
||||
return TOOLTIP_TEXT_ANIMATION_CLIP_COUNT;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
// ==================================================================================
|
||||
|
||||
public struct Entry
|
||||
{
|
||||
/// <summary>
|
||||
/// Number of MeshFilter components in the asset.
|
||||
/// </summary>
|
||||
public int MeshFilterCount;
|
||||
|
||||
/// <summary>
|
||||
/// Number of SkinnedMeshRenderer components in the asset.
|
||||
/// </summary>
|
||||
public int SkinnedMeshRendererCount;
|
||||
|
||||
/// <summary>
|
||||
/// Total number of meshes in the asset.
|
||||
/// </summary>
|
||||
public int SubMeshCount;
|
||||
|
||||
/// <summary>
|
||||
/// Number of vertices in the asset.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>This is the number of vertices <b>used in the triangles</b>.
|
||||
/// Some vertices are re-used, which means the number here will
|
||||
/// normally be higher than what 3d programs usually display.</para>
|
||||
///
|
||||
/// <para>For example, a regular cube will have 24 in its vertex count, instead of 8.</para>
|
||||
///
|
||||
/// <para>4 vertices for each face, 6 faces in total, 4 x 6 = 24</para>
|
||||
///
|
||||
/// <para>This is the total from all meshes in the asset.</para>
|
||||
/// </remarks>
|
||||
public int VertexCount;
|
||||
|
||||
/// <summary>
|
||||
/// Number of triangles in the asset.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is the total triangles from all meshes in the asset.
|
||||
/// </remarks>
|
||||
public int TriangleCount;
|
||||
|
||||
public string AnimationType;
|
||||
public int AnimationClipCount;
|
||||
|
||||
public string ToDisplayedValue(DataId dataId)
|
||||
{
|
||||
switch (dataId)
|
||||
{
|
||||
case DataId.MeshFilterCount:
|
||||
return MeshFilterCount.ToString("N0");
|
||||
case DataId.SkinnedMeshRendererCount:
|
||||
return SkinnedMeshRendererCount.ToString("N0");
|
||||
case DataId.SubMeshCount:
|
||||
return SubMeshCount.ToString("N0");
|
||||
case DataId.VertexCount:
|
||||
return VertexCount.ToString("N0");
|
||||
case DataId.TriangleCount:
|
||||
return TriangleCount.ToString("N0");
|
||||
case DataId.AnimationType:
|
||||
return AnimationType;
|
||||
case DataId.AnimationClipCount:
|
||||
return AnimationClipCount.ToString("N0");
|
||||
// ------------------------
|
||||
default:
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ==================================================================================
|
||||
|
||||
Dictionary<string, Entry> _meshData = new Dictionary<string, Entry>();
|
||||
|
||||
public List<string> Assets;
|
||||
public List<Entry> Data;
|
||||
|
||||
public Dictionary<string, Entry> GetMeshData()
|
||||
{
|
||||
return _meshData;
|
||||
}
|
||||
|
||||
// ==================================================================================
|
||||
|
||||
public void OnBeforeSave()
|
||||
{
|
||||
if (Assets != null)
|
||||
{
|
||||
Assets.Clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
Assets = new List<string>();
|
||||
}
|
||||
|
||||
Assets.AddRange(_meshData.Keys);
|
||||
|
||||
if (Data != null)
|
||||
{
|
||||
Data.Clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
Data = new List<Entry>();
|
||||
}
|
||||
|
||||
Data.AddRange(_meshData.Values);
|
||||
}
|
||||
|
||||
public void OnAfterLoad()
|
||||
{
|
||||
_meshData.Clear();
|
||||
|
||||
//var platformName = TextureData.GetPlatformNameFromBuildType(BuildType);
|
||||
var len = Mathf.Min(Assets.Count, Data.Count);
|
||||
for (int n = 0; n < len; ++n)
|
||||
{
|
||||
var entryToModify = Data[n];
|
||||
//entryToModify.UpdateShownSettings(platformName);
|
||||
Data[n] = entryToModify; // have to assign it back, Entry is a struct
|
||||
|
||||
_meshData.Add(Assets[n], Data[n]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cf4f49671de37b7448425bc0da869f81
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,241 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BuildReportTool
|
||||
{
|
||||
[System.Serializable, System.Xml.Serialization.XmlRoot("PrefabData")]
|
||||
public class PrefabData : BuildReportTool.IDataFile
|
||||
{
|
||||
// ==================================================================================
|
||||
|
||||
/// <summary>
|
||||
/// Name of project folder.
|
||||
/// Included as part of the filename when saved.
|
||||
/// </summary>
|
||||
public string ProjectName;
|
||||
|
||||
/// <summary>
|
||||
/// Type of build that the project was configured to, at the time that PrefabData was collected.
|
||||
/// Included as part of the filename when saved.
|
||||
/// </summary>
|
||||
public string BuildType;
|
||||
|
||||
/// <summary>
|
||||
/// When PrefabData was collected.
|
||||
/// Included as part of the filename when saved.
|
||||
/// </summary>
|
||||
public System.DateTime TimeGot;
|
||||
|
||||
public string GetDefaultFilename()
|
||||
{
|
||||
return BuildReportTool.Util.GetPrefabDataDefaultFilename(ProjectName, BuildType, TimeGot);
|
||||
}
|
||||
|
||||
public string GetAccompanyingBuildReportFilename()
|
||||
{
|
||||
return BuildReportTool.Util.GetBuildInfoDefaultFilename(ProjectName, BuildType, TimeGot);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Full path where this PrefabData is saved in the local storage.
|
||||
/// </summary>
|
||||
string _savedPath;
|
||||
|
||||
/// <inheritdoc cref="_savedPath"/>
|
||||
public string SavedPath
|
||||
{
|
||||
get { return _savedPath; }
|
||||
}
|
||||
|
||||
public void SetSavedPath(string val)
|
||||
{
|
||||
_savedPath = val.Replace("\\", "/");
|
||||
}
|
||||
|
||||
public bool HasContents
|
||||
{
|
||||
get { return _prefabData.Count > 0; }
|
||||
}
|
||||
|
||||
// ==================================================================================
|
||||
|
||||
public const int FLAG_CONTRIBUTE_GI = 1;
|
||||
public const int FLAG_OCCLUDER_STATIC = 1 << 1;
|
||||
public const int FLAG_BATCHING_STATIC = 1 << 2;
|
||||
public const int FLAG_NAVIGATION_STATIC = 1 << 3;
|
||||
public const int FLAG_OCCLUDEE_STATIC = 1 << 4;
|
||||
public const int FLAG_OFF_MESH_LINK_GENERATION = 1 << 5;
|
||||
public const int FLAG_REFLECTION_PROBE_STATIC = 1 << 6;
|
||||
|
||||
public struct Entry
|
||||
{
|
||||
/// <summary>
|
||||
/// Value from <see cref="StaticEditorFlags"/> of prefab's GameObject.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// ContributeGI = 1<br/>
|
||||
/// OccluderStatic = 2<br/>
|
||||
/// BatchingStatic = 4<br/>
|
||||
/// NavigationStatic = 8<br/>
|
||||
/// OccludeeStatic = 16<br/>
|
||||
/// OffMeshLinkGeneration = 32<br/>
|
||||
/// ReflectionProbeStatic = 64<br/><br/>
|
||||
/// Note: NavigationStatic and OffMeshLinkGeneration has been removed in 2022,
|
||||
/// They have since moved to a package and are in components.
|
||||
/// </remarks>
|
||||
public int StaticEditorFlags;
|
||||
public int ChildStaticEditorFlags;
|
||||
|
||||
public bool HasContributeGI => (StaticEditorFlags & FLAG_CONTRIBUTE_GI) != 0;
|
||||
public bool HasBatchingStatic => (StaticEditorFlags & FLAG_BATCHING_STATIC) != 0;
|
||||
public bool HasReflectionProbeStatic => (StaticEditorFlags & FLAG_REFLECTION_PROBE_STATIC) != 0;
|
||||
public bool HasOccluderStatic => (StaticEditorFlags & FLAG_OCCLUDER_STATIC) != 0;
|
||||
public bool HasOccludeeStatic => (StaticEditorFlags & FLAG_OCCLUDEE_STATIC) != 0;
|
||||
public bool HasNavigationStatic => (StaticEditorFlags & FLAG_NAVIGATION_STATIC) != 0;
|
||||
public bool HasOffMeshLinkGeneration => (StaticEditorFlags & FLAG_OFF_MESH_LINK_GENERATION) != 0;
|
||||
|
||||
bool ChildHasContributeGI => (ChildStaticEditorFlags & FLAG_CONTRIBUTE_GI) != 0;
|
||||
bool ChildHasBatchingStatic => (ChildStaticEditorFlags & FLAG_BATCHING_STATIC) != 0;
|
||||
bool ChildHasReflectionProbeStatic => (ChildStaticEditorFlags & FLAG_REFLECTION_PROBE_STATIC) != 0;
|
||||
bool ChildHasOccluderStatic => (ChildStaticEditorFlags & FLAG_OCCLUDER_STATIC) != 0;
|
||||
bool ChildHasOccludeeStatic => (ChildStaticEditorFlags & FLAG_OCCLUDEE_STATIC) != 0;
|
||||
bool ChildHasNavigationStatic => (ChildStaticEditorFlags & FLAG_NAVIGATION_STATIC) != 0;
|
||||
bool ChildHasOffMeshLinkGeneration => (ChildStaticEditorFlags & FLAG_OFF_MESH_LINK_GENERATION) != 0;
|
||||
|
||||
// 2 means it has that flag at the root level, 1 means it has that flag in one of its child GameObjects
|
||||
public int ContributeGIValue => HasContributeGI ? 2 : ChildHasContributeGI ? 1 : 0;
|
||||
public int BatchingStaticValue => HasBatchingStatic ? 2 : ChildHasBatchingStatic ? 1 : 0;
|
||||
public int ReflectionProbeStaticValue => HasReflectionProbeStatic ? 2 : ChildHasReflectionProbeStatic ? 1 : 0;
|
||||
public int OccluderStaticValue => HasOccluderStatic ? 2 : ChildHasOccluderStatic ? 1 : 0;
|
||||
public int OccludeeStaticValue => HasOccludeeStatic ? 2 : ChildHasOccludeeStatic ? 1 : 0;
|
||||
public int NavigationStaticValue => HasNavigationStatic ? 2 : ChildHasNavigationStatic ? 1 : 0;
|
||||
public int OffMeshLinkGenerationValue => HasOffMeshLinkGeneration ? 2 : ChildHasOffMeshLinkGeneration ? 1 : 0;
|
||||
|
||||
public string HasValue(DataId prefabDataId)
|
||||
{
|
||||
switch (prefabDataId)
|
||||
{
|
||||
case DataId.ContributeGI:
|
||||
return HasContributeGI ? "<b>Yes</b>" : ChildHasContributeGI ? "<b>Yes</b> (in child GameObject)" : "No";
|
||||
case DataId.BatchingStatic:
|
||||
return HasBatchingStatic ? "<b>Yes</b>" : ChildHasBatchingStatic ? "<b>Yes</b> (in child GameObject)" : "No";
|
||||
case DataId.ReflectionProbeStatic:
|
||||
return HasReflectionProbeStatic ? "<b>Yes</b>" : ChildHasReflectionProbeStatic ? "<b>Yes</b> (in child GameObject)" : "No";
|
||||
case DataId.OccluderStatic:
|
||||
return HasOccluderStatic ? "<b>Yes</b>" : ChildHasOccluderStatic ? "<b>Yes</b> (in child GameObject)" : "No";
|
||||
case DataId.OccludeeStatic:
|
||||
return HasOccludeeStatic ? "<b>Yes</b>" : ChildHasOccludeeStatic ? "<b>Yes</b> (in child GameObject)" : "No";
|
||||
case DataId.NavigationStatic:
|
||||
return HasNavigationStatic ? "<b>Yes</b>" : ChildHasNavigationStatic ? "<b>Yes</b> (in child GameObject)" : "No";
|
||||
case DataId.OffMeshLinkGeneration:
|
||||
return HasOffMeshLinkGeneration ? "<b>Yes</b>" : ChildHasOffMeshLinkGeneration ? "<b>Yes</b> (in child GameObject)" : "No";
|
||||
default:
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Key is asset path.
|
||||
/// </summary>
|
||||
Dictionary<string, Entry> _prefabData = new Dictionary<string, Entry>();
|
||||
|
||||
public List<string> Assets;
|
||||
public List<Entry> Data;
|
||||
|
||||
public Dictionary<string, Entry> GetPrefabData()
|
||||
{
|
||||
return _prefabData;
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
_prefabData.Clear();
|
||||
}
|
||||
|
||||
// ==================================================================================
|
||||
|
||||
public enum DataId
|
||||
{
|
||||
None,
|
||||
ContributeGI,
|
||||
BatchingStatic,
|
||||
ReflectionProbeStatic,
|
||||
OccluderStatic,
|
||||
OccludeeStatic,
|
||||
NavigationStatic,
|
||||
OffMeshLinkGeneration,
|
||||
}
|
||||
|
||||
public static string GetTooltipTextFromId(DataId flag)
|
||||
{
|
||||
switch (flag)
|
||||
{
|
||||
case DataId.ContributeGI:
|
||||
return "<b><color=white>Contribute Global Illumination</color></b>\n\nWhether the Mesh Renderers inside the GameObject are included in global illumination calculations.";
|
||||
case DataId.BatchingStatic:
|
||||
return "<b><color=white>Static Batching</color></b>\n\nWhether the GameObject's Mesh is combined with other eligible Meshes, to potentially reduce runtime rendering costs.";
|
||||
case DataId.ReflectionProbeStatic:
|
||||
return "<b><color=white>Reflection Probe Static</color></b>\n\nWhether the GameObject is included when precomputing data for Reflection Probes whose Type is Baked.";
|
||||
case DataId.OccluderStatic:
|
||||
return "<b><color=white>Occluder Static</color></b>\n\nWhether the GameObject is marked as a Static Occluder in the occlusion culling system.";
|
||||
case DataId.OccludeeStatic:
|
||||
return "<b><color=white>Occludee Static</color></b>\n\nWhether the GameObject is marked as a Static Occludee in the occlusion culling system.";
|
||||
case DataId.NavigationStatic:
|
||||
#if UNITY_2022_2_OR_NEWER
|
||||
return "<b><color=white>Navigation Static</color></b>\n\nWhether the GameObject is included when precomputing navigation data.\n\n<i>Note: This property is deprecated in Unity 2022.2 and beyond. The precise selection of the objects is now done using NavMeshBuilder.CollectSources() and NavMeshBuildMarkup.</i>";
|
||||
#else
|
||||
return "<b><color=white>Navigation Static</color></b>\n\nWhether the GameObject is included when precomputing navigation data.";
|
||||
#endif
|
||||
case DataId.OffMeshLinkGeneration:
|
||||
#if UNITY_2022_2_OR_NEWER
|
||||
return "<b><color=white>Off-Mesh Link Generation</color></b>\n\nWhether to attempt generation of an Off-Mesh Link that starts from the GameObject when precomputing navigation data.\n\n<i>Note: This property is deprecated in Unity 2022.2 and beyond. You can now use NavMeshBuilder.CollectSources() and NavMeshBuildMarkup to nominate the objects that will generate Off-Mesh Links.</i>";
|
||||
#else
|
||||
return "<b><color=white>Off-Mesh Link Generation</color></b>\n\nWhether to attempt generation of an Off-Mesh Link that starts from the GameObject when precomputing navigation data.";
|
||||
#endif
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// ==================================================================================
|
||||
|
||||
public void OnBeforeSave()
|
||||
{
|
||||
if (Assets != null)
|
||||
{
|
||||
Assets.Clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
Assets = new List<string>();
|
||||
}
|
||||
|
||||
Assets.AddRange(_prefabData.Keys);
|
||||
|
||||
if (Data != null)
|
||||
{
|
||||
Data.Clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
Data = new List<Entry>();
|
||||
}
|
||||
|
||||
Data.AddRange(_prefabData.Values);
|
||||
}
|
||||
|
||||
public void OnAfterLoad()
|
||||
{
|
||||
_prefabData.Clear();
|
||||
|
||||
var len = Mathf.Min(Assets.Count, Data.Count);
|
||||
for (int n = 0; n < len; ++n)
|
||||
{
|
||||
_prefabData.Add(Assets[n], Data[n]);
|
||||
}
|
||||
}
|
||||
|
||||
// ==================================================================================
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c895cb4eada54084898f13228101ac2e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,175 @@
|
||||
namespace BuildReportTool
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents one entry in an asset list.
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
public class SizePart
|
||||
{
|
||||
/// <summary>
|
||||
/// The filename with path, but relative to project's Assets folder
|
||||
/// </summary>
|
||||
public string Name;
|
||||
|
||||
// -----------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// How much the asset takes up space in the final build, in percentage.
|
||||
/// Value will be from the editor log if possible. If not, it will be calculated manually.
|
||||
/// </summary>
|
||||
public double Percentage;
|
||||
|
||||
// -----------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// For Unused Assets, this is the raw file size as existing in the assets folder, expressed in human-readable format.
|
||||
/// For Used Assets, this is the size upon being built, as found in the Editor log.
|
||||
/// </summary>
|
||||
public string Size;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="Size"/> converted into bytes.
|
||||
/// </summary>
|
||||
public long SizeBytes = -1;
|
||||
|
||||
// same as getting the `Size` but since we now have two size types,
|
||||
// for consistency, we now refer to the size as either RawSize and ImportedSize
|
||||
public string RawSize
|
||||
{
|
||||
get { return Size; }
|
||||
set { Size = value; }
|
||||
}
|
||||
|
||||
public long RawSizeBytes
|
||||
{
|
||||
get { return SizeBytes; }
|
||||
set { SizeBytes = value; }
|
||||
}
|
||||
|
||||
// -----------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// The file size as imported into Unity, expressed in human-readable format.
|
||||
/// If this SizePart is for an asset that has no imported size (e.g. built-in asset)
|
||||
/// this will be empty.
|
||||
/// </summary>
|
||||
public string ImportedSize;
|
||||
|
||||
/// <summary>
|
||||
/// The imported file size, expressed in bytes.
|
||||
/// </summary>
|
||||
public long ImportedSizeBytes;
|
||||
|
||||
// -----------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// For Used Assets, this is the file size as existing in the assets folder, expressed in human-readable format.
|
||||
/// </summary>
|
||||
public string SizeInAssetsFolder;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="SizeInAssetsFolder"/> in bytes
|
||||
/// </summary>
|
||||
public long SizeInAssetsFolderBytes = -1;
|
||||
|
||||
// -----------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// In cases where we don't have exact values of file size (we just got it from
|
||||
/// editor log as string, which was converted to readable format already).
|
||||
///
|
||||
/// Expressed in bytes (but with fractions because of the inaccuracies).
|
||||
///
|
||||
/// This applies to the "Used Assets" list
|
||||
/// </summary>
|
||||
public double DerivedSize;
|
||||
|
||||
// -----------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// Helper function to get the proper raw file size
|
||||
/// </summary>
|
||||
public double UsableSize
|
||||
{
|
||||
get
|
||||
{
|
||||
if (DerivedSize > 0)
|
||||
return DerivedSize;
|
||||
|
||||
if (SizeBytes > 0)
|
||||
return SizeBytes;
|
||||
|
||||
return ImportedSizeBytes;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return value of imported size, but if unavailable, will return raw size instead.
|
||||
/// </summary>
|
||||
public double ImportedSizeOrRawSize
|
||||
{
|
||||
get
|
||||
{
|
||||
if (ImportedSizeBytes > 0)
|
||||
return ImportedSizeBytes;
|
||||
|
||||
if (DerivedSize > 0)
|
||||
return DerivedSize;
|
||||
|
||||
if (SizeBytes > 0)
|
||||
return SizeBytes;
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------
|
||||
|
||||
public bool IsTotal
|
||||
{
|
||||
get { return Name == "Complete size"; }
|
||||
}
|
||||
|
||||
public bool IsStreamingAssets
|
||||
{
|
||||
get { return Name == "Streaming Assets"; }
|
||||
}
|
||||
|
||||
public void SetNameToStreamingAssets()
|
||||
{
|
||||
Name = "Streaming Assets";
|
||||
}
|
||||
|
||||
// -----------------------------------
|
||||
|
||||
string _auxTextData;
|
||||
public string GetTextAuxData()
|
||||
{
|
||||
return _auxTextData;
|
||||
}
|
||||
public void SetTextAuxData(string newTextAuxData)
|
||||
{
|
||||
_auxTextData = newTextAuxData;
|
||||
}
|
||||
|
||||
int _auxIntData;
|
||||
public int GetIntAuxData()
|
||||
{
|
||||
return _auxIntData;
|
||||
}
|
||||
public void SetIntAuxData(int newIntAuxData)
|
||||
{
|
||||
_auxIntData = newIntAuxData;
|
||||
}
|
||||
|
||||
float _auxFloatData;
|
||||
public float GetFloatAuxData()
|
||||
{
|
||||
return _auxFloatData;
|
||||
}
|
||||
public void SetFloatAuxData(float newFloatAuxData)
|
||||
{
|
||||
_auxFloatData = newFloatAuxData;
|
||||
}
|
||||
}
|
||||
} // namespace BuildReportTool
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bd77e3ddfe6ee2740941954bc63b33ea
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 48b80b2ac78470a4ab79a155399eaf96
|
||||
timeCreated: 1569202075
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,481 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BuildReportTool
|
||||
{
|
||||
/// <summary>
|
||||
/// Any attempt to serialize <see cref="UnityEditor.Build.Reporting.BuildReport"/> results in errors:<br/><br/>
|
||||
///
|
||||
/// When using <see cref="System.Runtime.Serialization.Formatters.Binary.BinaryFormatter"/>:<br/>
|
||||
/// <c>SerializationException: Type 'UnityEditor.Build.Reporting.BuildReport' in Assembly 'UnityEditor, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable.</c><br/><br/>
|
||||
///
|
||||
/// When using <see cref="UnityEngine.JsonUtility"/>:<br/>
|
||||
/// <c>ArgumentException: JsonUtility.ToJson does not support engine types.</c><br/><br/>
|
||||
///
|
||||
/// When using <see cref="System.Xml.Serialization.XmlSerializer"/>:<br/>
|
||||
/// It works, but only <see cref="UnityEditor.Build.Reporting.BuildReport.name"/> and <see cref="UnityEditor.Build.Reporting.BuildReport.hideFlags"/> get serialized. The actual important data doesn't get saved.<br/>
|
||||
/// Note: There is <see cref="System.Xml.Serialization.XmlAttributeOverrides"/> but that still can't serialize read-only properties.
|
||||
/// <see cref="UnityEditor.Build.Reporting.BuildReport"/> unfortunately has some important read-only properties such as
|
||||
/// <see cref="UnityEditor.Build.Reporting.BuildReport.files"/> and <see cref="UnityEditor.Build.Reporting.BuildReport.steps"/>.<br/><br/>
|
||||
///
|
||||
/// So we have to make this dummy class that essentially mimics <see cref="UnityEditor.Build.Reporting.BuildReport"/>, but defined as properly serializable this time.
|
||||
/// We also favor saving enums into strings since they are merely displayed for the user, and will not be further processed.
|
||||
/// Converting them to string also helps with backwards compatibility in case a future version of Unity deletes an enum value or renames it.
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
public class UnityBuildReport : BuildReportTool.IDataFile
|
||||
{
|
||||
/// <summary>
|
||||
/// Name of project folder.
|
||||
/// Included as part of the filename when saved.
|
||||
/// </summary>
|
||||
public string ProjectName;
|
||||
|
||||
/// <summary>
|
||||
/// Type of build that the project was configured to, at the time that UnityBuildReport was collected.
|
||||
/// Included as part of the filename when saved.
|
||||
/// </summary>
|
||||
public string BuildType;
|
||||
|
||||
/// <summary>
|
||||
/// When UnityBuildReport was collected.
|
||||
/// Included as part of the filename when saved.
|
||||
/// </summary>
|
||||
public System.DateTime TimeGot;
|
||||
|
||||
public ulong TotalSize;
|
||||
|
||||
public System.DateTime BuildStartedAt;
|
||||
public System.TimeSpan BuildTotalTime;
|
||||
|
||||
public UnityEditor.BuildOptions BuildOptions;
|
||||
|
||||
public bool HasBuildOption(UnityEditor.BuildOptions optionToCheck)
|
||||
{
|
||||
return (BuildOptions & optionToCheck) == optionToCheck;
|
||||
}
|
||||
|
||||
// -----------------------------------------
|
||||
|
||||
public OutputFile[] OutputFiles;
|
||||
public BuildProcessStep[] BuildProcessSteps;
|
||||
|
||||
#if UNITY_2018_1_OR_NEWER
|
||||
public void SetFrom(UnityEditor.Build.Reporting.BuildReport buildReport)
|
||||
{
|
||||
TotalSize = buildReport.summary.totalSize;
|
||||
BuildStartedAt = buildReport.summary.buildStartedAt;
|
||||
BuildTotalTime = buildReport.summary.totalTime;
|
||||
|
||||
string outputFolder = buildReport.summary.outputPath;
|
||||
int outputPathLength;
|
||||
|
||||
if (System.IO.Directory.Exists(outputFolder))
|
||||
{
|
||||
if (outputFolder.EndsWith("/") || outputFolder.EndsWith("\\"))
|
||||
{
|
||||
outputPathLength = outputFolder.Length;
|
||||
}
|
||||
else
|
||||
{
|
||||
// +1 for the trailing slash, we want to remove
|
||||
// the slash at the start of our file entries
|
||||
outputPathLength = outputFolder.Length+1;
|
||||
}
|
||||
}
|
||||
else if (System.IO.File.Exists(outputFolder))
|
||||
{
|
||||
// output path is a file, likely the executable file
|
||||
// so get the parent folder of that file
|
||||
outputFolder = System.IO.Path.GetDirectoryName(outputFolder);
|
||||
|
||||
if (!string.IsNullOrEmpty(outputFolder))
|
||||
{
|
||||
// +1 for the trailing slash, we want to remove
|
||||
// the slash at the start of our file entries
|
||||
outputPathLength = outputFolder.Length+1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// output file has no parent folder?
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// output path doesn't exist
|
||||
outputPathLength = 0;
|
||||
}
|
||||
|
||||
BuildOptions = buildReport.summary.options;
|
||||
|
||||
outputFolder = outputFolder.Replace("\\", "/");
|
||||
|
||||
#if !UNITY_2022_2_OR_NEWER
|
||||
var files = buildReport.files;
|
||||
#else
|
||||
var files = buildReport.GetFiles();
|
||||
#endif
|
||||
var outputFiles = new List<OutputFile>(files.Length);
|
||||
OutputFiles = new OutputFile[files.Length];
|
||||
for (int i = 0; i < files.Length; ++i)
|
||||
{
|
||||
if (!files[i].path.StartsWith(outputFolder))
|
||||
{
|
||||
// file is not inside the build folder, likely a temporary or debug file (like a pdb file)
|
||||
//Debug.Log($"Found file not in build {i}: {buildReport.files[i].path}");
|
||||
continue;
|
||||
}
|
||||
|
||||
OutputFile newEntry;
|
||||
newEntry.FilePath = files[i].path.Substring(outputPathLength);
|
||||
newEntry.Role = files[i].role;
|
||||
newEntry.Size = files[i].size;
|
||||
outputFiles.Add(newEntry);
|
||||
}
|
||||
OutputFiles = outputFiles.ToArray();
|
||||
|
||||
_totalBuildTime = new TimeSpan(0);
|
||||
BuildProcessSteps = new BuildProcessStep[buildReport.steps.Length];
|
||||
for (int i = 0; i < BuildProcessSteps.Length; ++i)
|
||||
{
|
||||
BuildProcessSteps[i].Depth = buildReport.steps[i].depth;
|
||||
BuildProcessSteps[i].Name = buildReport.steps[i].name;
|
||||
BuildProcessSteps[i].Duration = buildReport.steps[i].duration;
|
||||
|
||||
if (BuildProcessSteps[i].Depth == 1)
|
||||
{
|
||||
_totalBuildTime += BuildProcessSteps[i].Duration;
|
||||
}
|
||||
|
||||
BuildProcessSteps[i].SetInfoLogCount(0);
|
||||
BuildProcessSteps[i].SetWarnLogCount(0);
|
||||
BuildProcessSteps[i].SetErrorLogCount(0);
|
||||
|
||||
BuildProcessSteps[i].SetCollapsedInfoLogCount(0);
|
||||
BuildProcessSteps[i].SetCollapsedWarnLogCount(0);
|
||||
BuildProcessSteps[i].SetCollapsedErrorLogCount(0);
|
||||
|
||||
var messages = buildReport.steps[i].messages;
|
||||
if (messages == null || messages.Length == 0)
|
||||
{
|
||||
BuildProcessSteps[i].BuildLogMessages = null;
|
||||
BuildProcessSteps[i].SetCollapsedBuildLogMessages(null);
|
||||
}
|
||||
else
|
||||
{
|
||||
BuildProcessSteps[i].BuildLogMessages = new BuildLogMessage[messages.Length];
|
||||
var collapsedMessages = new List<BuildLogMessage>();
|
||||
for (int m = 0; m < messages.Length; ++m)
|
||||
{
|
||||
BuildProcessSteps[i].BuildLogMessages[m].Message = messages[m].content;
|
||||
|
||||
var logType = messages[m].type;
|
||||
BuildProcessSteps[i].BuildLogMessages[m].LogType = logType.ToString();
|
||||
if (logType == LogType.Log)
|
||||
{
|
||||
BuildProcessSteps[i].IncrementInfoLogCount();
|
||||
}
|
||||
else if (logType == LogType.Warning)
|
||||
{
|
||||
BuildProcessSteps[i].IncrementWarnLogCount();
|
||||
}
|
||||
else
|
||||
{
|
||||
BuildProcessSteps[i].IncrementErrorLogCount();
|
||||
}
|
||||
|
||||
bool alreadyIn = false;
|
||||
for (int c = 0; c < collapsedMessages.Count; ++c)
|
||||
{
|
||||
if (collapsedMessages[c].Message == messages[m].content)
|
||||
{
|
||||
var entryToModify = collapsedMessages[c];
|
||||
entryToModify.SetCount(collapsedMessages[c].Count+1);
|
||||
collapsedMessages[c] = entryToModify;
|
||||
alreadyIn = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (alreadyIn)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var entryToAdd = BuildProcessSteps[i].BuildLogMessages[m];
|
||||
entryToAdd.SetCount(1);
|
||||
collapsedMessages.Add(entryToAdd);
|
||||
|
||||
if (logType == LogType.Log)
|
||||
{
|
||||
BuildProcessSteps[i].IncrementCollapsedInfoLogCount();
|
||||
}
|
||||
else if (logType == LogType.Warning)
|
||||
{
|
||||
BuildProcessSteps[i].IncrementCollapsedWarnLogCount();
|
||||
}
|
||||
else
|
||||
{
|
||||
BuildProcessSteps[i].IncrementCollapsedErrorLogCount();
|
||||
}
|
||||
}
|
||||
|
||||
BuildProcessSteps[i].SetCollapsedBuildLogMessages(collapsedMessages.ToArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// -----------------------------------------
|
||||
|
||||
TimeSpan _totalBuildTime;
|
||||
|
||||
public TimeSpan TotalBuildTime { get { return _totalBuildTime; } }
|
||||
|
||||
public void OnBeforeSave()
|
||||
{
|
||||
}
|
||||
|
||||
public void OnAfterLoad()
|
||||
{
|
||||
_totalBuildTime = new TimeSpan(0);
|
||||
for (int i = 0; i < BuildProcessSteps.Length; ++i)
|
||||
{
|
||||
if (BuildProcessSteps[i].Depth == 1)
|
||||
{
|
||||
_totalBuildTime += BuildProcessSteps[i].Duration;
|
||||
}
|
||||
|
||||
var messages = BuildProcessSteps[i].BuildLogMessages;
|
||||
|
||||
if (messages != null)
|
||||
{
|
||||
var collapsedMessages = new List<BuildLogMessage>();
|
||||
|
||||
BuildProcessSteps[i].SetInfoLogCount(0);
|
||||
BuildProcessSteps[i].SetWarnLogCount(0);
|
||||
BuildProcessSteps[i].SetErrorLogCount(0);
|
||||
|
||||
BuildProcessSteps[i].SetCollapsedInfoLogCount(0);
|
||||
BuildProcessSteps[i].SetCollapsedWarnLogCount(0);
|
||||
BuildProcessSteps[i].SetCollapsedErrorLogCount(0);
|
||||
|
||||
for (int m = 0; m < messages.Length; ++m)
|
||||
{
|
||||
var logType = GetLogType(messages[m].LogType);
|
||||
|
||||
switch (logType)
|
||||
{
|
||||
case CheckLogType.Info:
|
||||
BuildProcessSteps[i].IncrementInfoLogCount();
|
||||
break;
|
||||
case CheckLogType.Warn:
|
||||
BuildProcessSteps[i].IncrementWarnLogCount();
|
||||
break;
|
||||
case CheckLogType.Error:
|
||||
BuildProcessSteps[i].IncrementErrorLogCount();
|
||||
break;
|
||||
}
|
||||
|
||||
bool alreadyIn = false;
|
||||
for (int c = 0; c < collapsedMessages.Count; ++c)
|
||||
{
|
||||
if (collapsedMessages[c].Message == messages[m].Message)
|
||||
{
|
||||
var entryToModify = collapsedMessages[c];
|
||||
entryToModify.SetCount(collapsedMessages[c].Count+1);
|
||||
collapsedMessages[c] = entryToModify;
|
||||
alreadyIn = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (alreadyIn)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var entryToAdd = messages[m];
|
||||
entryToAdd.SetCount(1);
|
||||
collapsedMessages.Add(entryToAdd);
|
||||
|
||||
switch (logType)
|
||||
{
|
||||
case CheckLogType.Info:
|
||||
BuildProcessSteps[i].IncrementCollapsedInfoLogCount();
|
||||
break;
|
||||
case CheckLogType.Warn:
|
||||
BuildProcessSteps[i].IncrementCollapsedWarnLogCount();
|
||||
break;
|
||||
case CheckLogType.Error:
|
||||
BuildProcessSteps[i].IncrementCollapsedErrorLogCount();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
BuildProcessSteps[i].SetCollapsedBuildLogMessages(collapsedMessages.ToArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum CheckLogType
|
||||
{
|
||||
Info,
|
||||
Warn,
|
||||
Error,
|
||||
}
|
||||
|
||||
static CheckLogType GetLogType(string logType)
|
||||
{
|
||||
if (logType.Contains("Warn"))
|
||||
{
|
||||
return CheckLogType.Warn;
|
||||
}
|
||||
else if (logType.Contains("Log"))
|
||||
{
|
||||
return CheckLogType.Info;
|
||||
}
|
||||
else
|
||||
{
|
||||
return CheckLogType.Error;
|
||||
}
|
||||
}
|
||||
|
||||
string _savedPath;
|
||||
|
||||
public void SetSavedPath(string savedPath)
|
||||
{
|
||||
_savedPath = savedPath.Replace("\\", "/");
|
||||
}
|
||||
|
||||
public string SavedPath { get { return _savedPath; } }
|
||||
|
||||
public string GetDefaultFilename()
|
||||
{
|
||||
return BuildReportTool.Util.GetUnityBuildReportDefaultFilename(ProjectName, BuildType, TimeGot);
|
||||
}
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public struct OutputFile
|
||||
{
|
||||
public string FilePath;
|
||||
public string Role;
|
||||
public ulong Size;
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public struct BuildProcessStep
|
||||
{
|
||||
public int Depth;
|
||||
public string Name;
|
||||
public BuildLogMessage[] BuildLogMessages;
|
||||
|
||||
int _infoLogCount;
|
||||
int _warnLogCount;
|
||||
int _errorLogCount;
|
||||
|
||||
public int InfoLogCount { get { return _infoLogCount; } }
|
||||
public int WarnLogCount { get { return _warnLogCount; } }
|
||||
public int ErrorLogCount { get { return _errorLogCount; } }
|
||||
|
||||
public void IncrementInfoLogCount()
|
||||
{
|
||||
++_infoLogCount;
|
||||
}
|
||||
public void IncrementWarnLogCount()
|
||||
{
|
||||
++_warnLogCount;
|
||||
}
|
||||
public void IncrementErrorLogCount()
|
||||
{
|
||||
++_errorLogCount;
|
||||
}
|
||||
|
||||
public void SetInfoLogCount(int newInfoLogCount)
|
||||
{
|
||||
_infoLogCount = newInfoLogCount;
|
||||
}
|
||||
public void SetWarnLogCount(int newWarnLogCount)
|
||||
{
|
||||
_warnLogCount = newWarnLogCount;
|
||||
}
|
||||
public void SetErrorLogCount(int newErrorLogCount)
|
||||
{
|
||||
_errorLogCount = newErrorLogCount;
|
||||
}
|
||||
|
||||
BuildLogMessage[] _collapsedBuildLogMessages;
|
||||
public BuildLogMessage[] CollapsedBuildLogMessages { get { return _collapsedBuildLogMessages; } }
|
||||
public void SetCollapsedBuildLogMessages(BuildLogMessage[] newCollapsedBuildLogMessages)
|
||||
{
|
||||
_collapsedBuildLogMessages = newCollapsedBuildLogMessages;
|
||||
}
|
||||
|
||||
int _collapsedInfoLogCount;
|
||||
int _collapsedWarnLogCount;
|
||||
int _collapsedErrorLogCount;
|
||||
|
||||
public int CollapsedInfoLogCount { get { return _collapsedInfoLogCount; } }
|
||||
public int CollapsedWarnLogCount { get { return _collapsedWarnLogCount; } }
|
||||
public int CollapsedErrorLogCount { get { return _collapsedErrorLogCount; } }
|
||||
|
||||
public void IncrementCollapsedInfoLogCount()
|
||||
{
|
||||
++_collapsedInfoLogCount;
|
||||
}
|
||||
public void IncrementCollapsedWarnLogCount()
|
||||
{
|
||||
++_collapsedWarnLogCount;
|
||||
}
|
||||
public void IncrementCollapsedErrorLogCount()
|
||||
{
|
||||
++_collapsedErrorLogCount;
|
||||
}
|
||||
|
||||
public void SetCollapsedInfoLogCount(int newInfoLogCount)
|
||||
{
|
||||
_collapsedInfoLogCount = newInfoLogCount;
|
||||
}
|
||||
public void SetCollapsedWarnLogCount(int newWarnLogCount)
|
||||
{
|
||||
_collapsedWarnLogCount = newWarnLogCount;
|
||||
}
|
||||
public void SetCollapsedErrorLogCount(int newErrorLogCount)
|
||||
{
|
||||
_collapsedErrorLogCount = newErrorLogCount;
|
||||
}
|
||||
|
||||
TimeSpan _duration;
|
||||
|
||||
[System.Xml.Serialization.XmlIgnore]
|
||||
public System.TimeSpan Duration
|
||||
{
|
||||
get { return _duration; }
|
||||
set { _duration = value; }
|
||||
}
|
||||
|
||||
[System.Xml.Serialization.XmlElement("Duration")]
|
||||
public long DurationTicks
|
||||
{
|
||||
get { return _duration.Ticks; }
|
||||
set { _duration = new System.TimeSpan(value); }
|
||||
}
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public struct BuildLogMessage
|
||||
{
|
||||
public string LogType;
|
||||
public string Message;
|
||||
|
||||
int _count;
|
||||
public int Count { get { return _count; } }
|
||||
public void SetCount(int newCount)
|
||||
{
|
||||
_count = newCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 03a282002dba381488048a845cde9c83
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a455a7863b26e8b46bf0c0b6c3634ccb
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
@@ -0,0 +1,701 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace BuildReportTool
|
||||
{
|
||||
public partial class UnityBuildSettings
|
||||
{
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.EditorUserBuildSettings.forceOptimizeScriptCompilation"/>
|
||||
/// Added in Unity 5.2.2
|
||||
/// Marked as obsolete in Unity 2017.1.
|
||||
/// </summary>
|
||||
public bool ForceOptimizeScriptCompilation;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.EditorUserBuildSettings.buildScriptsOnly"/>
|
||||
/// No longer needed since we can use <see cref="UnityEditor.BuildOptions.BuildScriptsOnly"/>
|
||||
/// </summary>
|
||||
public bool BuildScriptsOnly;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.stripPhysics"/>
|
||||
/// Added in Unity 4. Removed in Unity 5
|
||||
/// </summary>
|
||||
public bool StripPhysicsCode;
|
||||
|
||||
|
||||
// Web Player Settings
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.defaultWebScreenWidth"/>
|
||||
/// Removed in Unity 5.6
|
||||
/// </summary>
|
||||
public int WebPlayerDefaultScreenWidth;
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.defaultWebScreenHeight"/>
|
||||
/// Removed in Unity 5.6
|
||||
/// </summary>
|
||||
public int WebPlayerDefaultScreenHeight;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.EditorUserBuildSettings.webPlayerStreamed"/>
|
||||
/// Removed in Unity 5.6
|
||||
/// </summary>
|
||||
public bool WebPlayerEnableStreaming;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.EditorUserBuildSettings.webPlayerOfflineDeployment"/>
|
||||
/// Removed in Unity 5.6
|
||||
/// </summary>
|
||||
public bool WebPlayerDeployOffline;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.firstStreamedLevelWithResources"/>
|
||||
/// Removed in Unity 5.3
|
||||
/// </summary>
|
||||
public int WebPlayerFirstStreamedLevelWithResources;
|
||||
|
||||
|
||||
// WebGL Settings
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.EditorUserBuildSettings.webGLOptimizationLevel"/>
|
||||
/// Removed in Unity 5.4
|
||||
/// </summary>
|
||||
public string WebGLOptimizationLevel;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.EditorUserBuildSettings.webGLUsePreBuiltUnityEngine"/>
|
||||
/// Added in Unity 5.4.
|
||||
/// Marked as obsolete in 2019.1 onwards.
|
||||
/// </summary>
|
||||
public bool WebGLUsePreBuiltUnityEngine;
|
||||
|
||||
|
||||
// Mac OS X-only Build Settings
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.macFullscreenMode"/>
|
||||
/// Marked as obsolete in Unity 2018.
|
||||
/// Use <see cref="UnityEditor.PlayerSettings.fullScreenMode"/> (stored in <see cref="StandaloneFullScreenModeUsed"/>)
|
||||
/// </summary>
|
||||
public string MacFullscreenModeUsed;
|
||||
|
||||
|
||||
// Windows Store App-only Build Settings
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.EditorUserBuildSettings.metroGenerateReferenceProjects"/>
|
||||
/// Added in Unity 5.
|
||||
/// Removed in Unity 2019.1.
|
||||
/// </summary>
|
||||
public bool WSAGenerateReferenceProjects;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.EditorUserBuildSettings.wsaSDK"/>
|
||||
/// Marked as obsolete.
|
||||
/// </summary>
|
||||
public string WSASDK;
|
||||
|
||||
|
||||
// iOS-only Build Settings
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.EditorUserBuildSettings.appendProject"/>
|
||||
/// Removed in Unity 5.
|
||||
/// </summary>
|
||||
public bool iOSAppendedToProject;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.EditorUserBuildSettings.symlinkLibraries"/>
|
||||
/// Replaced by <see cref="UnityEditor.BuildOptions.SymlinkSources"/>
|
||||
/// </summary>
|
||||
public bool iOSSymlinkLibraries;
|
||||
|
||||
|
||||
// BlackBerry-only Build Settings
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.EditorUserBuildSettings.blackberryBuildSubtarget"/>
|
||||
/// Removed in Unity 5.4
|
||||
/// </summary>
|
||||
public string BlackBerryBuildSubtarget;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.EditorUserBuildSettings.blackberryBuildType"/>
|
||||
/// Removed in Unity 5.4
|
||||
/// </summary>
|
||||
public string BlackBerryBuildType;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.BlackBerry.authorId"/>
|
||||
/// Removed in Unity 5
|
||||
/// </summary>
|
||||
public string BlackBerryAuthorID;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.BlackBerry.deviceAddress"/>
|
||||
/// Removed in Unity 5.4
|
||||
/// </summary>
|
||||
public string BlackBerryDeviceAddress;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.BlackBerry.saveLogPath"/>
|
||||
/// Removed in Unity 5.4
|
||||
/// </summary>
|
||||
public string BlackBerrySaveLogPath;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.BlackBerry.tokenPath"/>
|
||||
/// Removed in Unity 5.4
|
||||
/// </summary>
|
||||
public string BlackBerryTokenPath;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.BlackBerry.tokenAuthor"/>
|
||||
/// Removed in Unity 5.4
|
||||
/// </summary>
|
||||
public string BlackBerryTokenAuthor;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.BlackBerry.tokenExpires"/>
|
||||
/// Removed in Unity 5.4
|
||||
/// </summary>
|
||||
public string BlackBerryTokenExpiration;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.BlackBerry.HasCameraPermissions"/>
|
||||
/// Removed in Unity 5.4
|
||||
/// </summary>
|
||||
public bool BlackBerryHasCamPermissions;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.BlackBerry.HasMicrophonePermissions"/>
|
||||
/// Removed in Unity 5.4
|
||||
/// </summary>
|
||||
public bool BlackBerryHasMicPermissions;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.BlackBerry.HasGPSPermissions"/>
|
||||
/// Removed in Unity 5.4
|
||||
/// </summary>
|
||||
public bool BlackBerryHasGpsPermissions;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.BlackBerry.HasIdentificationPermissions"/>
|
||||
/// Removed in Unity 5.4
|
||||
/// </summary>
|
||||
public bool BlackBerryHasIdPermissions;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.BlackBerry.HasSharedPermissions"/>
|
||||
/// Removed in Unity 5.4
|
||||
/// </summary>
|
||||
public bool BlackBerryHasSharedPermissions;
|
||||
|
||||
|
||||
// XBox 360 Build Settings
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.EditorUserBuildSettings.xboxBuildSubtarget"/>
|
||||
/// Removed in Unity 5.5
|
||||
/// </summary>
|
||||
public string Xbox360BuildSubtarget;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.EditorUserBuildSettings.xboxRunMethod"/>
|
||||
/// Removed in Unity 5.5
|
||||
/// </summary>
|
||||
public string Xbox360RunMethod;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.xboxTitleId"/>
|
||||
/// Removed in Unity 5.5
|
||||
/// </summary>
|
||||
public string Xbox360TitleId;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.xboxImageXexFilePath"/>
|
||||
/// Removed in Unity 5.5
|
||||
/// </summary>
|
||||
public string Xbox360ImageXexFilePath;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.xboxSpaFilePath"/>
|
||||
/// Removed in Unity 5.5
|
||||
/// </summary>
|
||||
public string Xbox360SpaFilePath;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.xboxGenerateSpa"/>
|
||||
/// Removed in Unity 5.5
|
||||
/// </summary>
|
||||
public bool Xbox360AutoGenerateSpa;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.xboxEnableKinect"/>
|
||||
/// Removed in Unity 5.5
|
||||
/// </summary>
|
||||
public bool Xbox360EnableKinect;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.xboxEnableKinectAutoTracking"/>
|
||||
/// Removed in Unity 5.5
|
||||
/// </summary>
|
||||
public bool Xbox360EnableKinectAutoTracking;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.xboxEnableSpeech"/>
|
||||
/// Removed in Unity 5.5
|
||||
/// </summary>
|
||||
public bool Xbox360EnableSpeech;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.xboxEnableAvatar"/>
|
||||
/// Removed in Unity 5.5
|
||||
/// </summary>
|
||||
public bool Xbox360EnableAvatar;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.xboxSpeechDB"/>
|
||||
/// Removed in Unity 5.5
|
||||
/// </summary>
|
||||
public uint Xbox360SpeechDB;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.xboxAdditionalTitleMemorySize"/>
|
||||
/// Removed in Unity 5.5
|
||||
/// </summary>
|
||||
public int Xbox360AdditionalTitleMemSize;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.xboxDeployKinectResources"/>
|
||||
/// Removed in Unity 5.5
|
||||
/// </summary>
|
||||
public bool Xbox360DeployKinectResources;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.xboxDeployKinectHeadOrientation"/>
|
||||
/// Removed in Unity 5.5
|
||||
/// </summary>
|
||||
public bool Xbox360DeployKinectHeadOrientation;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.xboxDeployKinectHeadPosition"/>
|
||||
/// Removed in Unity 5.5
|
||||
/// </summary>
|
||||
public bool Xbox360DeployKinectHeadPosition;
|
||||
|
||||
|
||||
// PS3 Build Settings
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.EditorUserBuildSettings.compressWithPsArc"/>
|
||||
/// Marked as obsolete in Unity 2021.2
|
||||
/// </summary>
|
||||
public bool CompressBuildWithPsArc;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.EditorUserBuildSettings.sceBuildSubtarget"/>
|
||||
/// Removed in Unity 5.5
|
||||
/// </summary>
|
||||
public string SCEBuildSubtarget;
|
||||
|
||||
// paths
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.ps3TitleConfigPath"/>
|
||||
/// Removed in Unity 5.5
|
||||
/// </summary>
|
||||
public string PS3TitleConfigFilePath;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.ps3DLCConfigPath"/>
|
||||
/// Removed in Unity 5.5
|
||||
/// </summary>
|
||||
public string PS3DLCConfigFilePath;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.ps3ThumbnailPath"/>
|
||||
/// Removed in Unity 5.5
|
||||
/// </summary>
|
||||
public string PS3ThumbnailFilePath;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.ps3BackgroundPath"/>
|
||||
/// Removed in Unity 5.5
|
||||
/// </summary>
|
||||
public string PS3BackgroundImageFilePath;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.ps3SoundPath"/>
|
||||
/// Removed in Unity 5.5
|
||||
/// </summary>
|
||||
public string PS3BackgroundSoundFilePath;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.ps3TrophyPackagePath"/>
|
||||
/// Removed in Unity 5.5
|
||||
/// </summary>
|
||||
public string PS3TrophyPackagePath;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.ps3TrialMode"/>
|
||||
/// Removed in Unity 5.5
|
||||
/// </summary>
|
||||
public bool PS3InTrialMode;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.PS3.DisableDolbyEncoding"/>
|
||||
/// Added in Unity 5
|
||||
/// Removed in Unity 5.5
|
||||
/// </summary>
|
||||
public bool PS3DisableDolbyEncoding;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.PS3.EnableMoveSupport"/>
|
||||
/// Added in Unity 5
|
||||
/// Removed in Unity 5.5
|
||||
/// </summary>
|
||||
public bool PS3EnableMoveSupport;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.PS3.UseSPUForUmbra"/>
|
||||
/// Added in Unity 5
|
||||
/// Removed in Unity 5.5
|
||||
/// </summary>
|
||||
public bool PS3UseSPUForUmbra;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.PS3.EnableVerboseMemoryStats"/>
|
||||
/// Added in Unity 5
|
||||
/// Removed in Unity 5.5
|
||||
/// </summary>
|
||||
public bool PS3EnableVerboseMemoryStats;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.PS3.videoMemoryForAudio"/>
|
||||
/// Added in Unity 5
|
||||
/// Removed in Unity 5.5
|
||||
/// </summary>
|
||||
public int PS3VideoMemoryForAudio;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.PS3.videoMemoryForVertexBuffers"/>
|
||||
/// Removed in Unity 5.5
|
||||
/// </summary>
|
||||
public int PS3VideoMemoryForVertexBuffers;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.ps3BootCheckMaxSaveGameSizeKB"/>
|
||||
/// Removed in Unity 5.5
|
||||
/// </summary>
|
||||
public int PS3BootCheckMaxSaveGameSizeKB;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.ps3SaveGameSlots"/>
|
||||
/// Removed in Unity 5.5
|
||||
/// </summary>
|
||||
public int PS3SaveGameSlots;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.ps3TrophyCommId"/>
|
||||
/// Removed in Unity 5.5
|
||||
/// </summary>
|
||||
public string PS3NpCommsId;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.ps3TrophyCommSig"/>
|
||||
/// Removed in Unity 5.5
|
||||
/// </summary>
|
||||
public string PS3NpCommsSig;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.PS3.npAgeRating"/>
|
||||
/// Added in Unity 5
|
||||
/// Removed in Unity 5.5
|
||||
/// </summary>
|
||||
public int PS3NpAgeRating;
|
||||
|
||||
|
||||
// PS Vita Build Settings
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.psp2NPTrophyPackPath"/>
|
||||
/// Replaced in Unity 5 with <see cref="UnityEditor.PlayerSettings.PSVita.npTrophyPackPath"/>
|
||||
/// Removed in Unity 2018.3
|
||||
/// </summary>
|
||||
public string PSVTrophyPackagePath;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.psp2ParamSfxPath"/>
|
||||
/// Replaced in Unity 5 with <see cref="UnityEditor.PlayerSettings.PSVita.paramSfxPath"/>
|
||||
/// Removed in Unity 2018.3
|
||||
/// </summary>
|
||||
public string PSVParamSfxPath;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.psp2NPCommsID"/>
|
||||
/// Replaced in Unity 5 with <see cref="UnityEditor.PlayerSettings.PSVita.npCommunicationsID"/>
|
||||
/// Removed in Unity 2018.3
|
||||
/// </summary>
|
||||
public string PSVNpCommsId;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.psp2NPCommsSig"/>
|
||||
/// Replaced in Unity 5 with <see cref="UnityEditor.PlayerSettings.PSVita.npCommsSig"/>
|
||||
/// Removed in Unity 2018.3
|
||||
/// </summary>
|
||||
public string PSVNpCommsSig;
|
||||
|
||||
|
||||
// new values in Unity 5:
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.EditorUserBuildSettings.psp2BuildSubtarget"/>
|
||||
/// Removed in Unity 2018.3
|
||||
/// </summary>
|
||||
public string PSVBuildSubtarget;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.PSVita.shortTitle"/>
|
||||
/// Removed in Unity 2018.3
|
||||
/// </summary>
|
||||
public string PSVShortTitle;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.PSVita.appVersion"/>
|
||||
/// Removed in Unity 2018.3
|
||||
/// </summary>
|
||||
public string PSVAppVersion;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.PSVita.masterVersion"/>
|
||||
/// Removed in Unity 2018.3
|
||||
/// </summary>
|
||||
public string PSVMasterVersion;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.PSVita.category"/>
|
||||
/// Removed in Unity 2018.3
|
||||
/// </summary>
|
||||
public string PSVAppCategory;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.PSVita.contentID"/>
|
||||
/// Removed in Unity 2018.3
|
||||
/// </summary>
|
||||
public string PSVContentId;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.PSVita.npAgeRating"/>
|
||||
/// Removed in Unity 2018.3
|
||||
/// </summary>
|
||||
public string PSVNpAgeRating;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.PSVita.parentalLevel"/>
|
||||
/// Removed in Unity 2018.3
|
||||
/// </summary>
|
||||
public string PSVParentalLevel;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.PSVita.drmType"/>
|
||||
/// Removed in Unity 2018.3
|
||||
/// </summary>
|
||||
public string PSVDrmType;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.PSVita.upgradable"/>
|
||||
/// Removed in Unity 2018.3
|
||||
/// </summary>
|
||||
public bool PSVUpgradable;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.PSVita.tvBootMode"/>
|
||||
/// Removed in Unity 2018.3
|
||||
/// </summary>
|
||||
public string PSVTvBootMode;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.PSVita.acquireBGM"/>
|
||||
/// Removed in Unity 2018.3
|
||||
/// </summary>
|
||||
public bool PSVAcquireBgm;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.PSVita.AllowTwitterDialog"/>
|
||||
/// Removed in Unity 2018.3
|
||||
/// </summary>
|
||||
public bool PSVAllowTwitterDialog;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.PSVita.mediaCapacity"/>
|
||||
/// Removed in Unity 2018.3
|
||||
/// </summary>
|
||||
public string PSVMediaCapacity;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.PSVita.storageType"/>
|
||||
/// Removed in Unity 2018.3
|
||||
/// </summary>
|
||||
public string PSVStorageType;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.PSVita.tvDisableEmu"/>
|
||||
/// Removed in Unity 2018.3
|
||||
/// </summary>
|
||||
public bool PSVTvDisableEmu;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.PSVita.npSupportGBMorGJP"/>
|
||||
/// Removed in Unity 2018.3
|
||||
/// </summary>
|
||||
public bool PSVNpSupportGbmOrGjp;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.PSVita.powerMode"/>
|
||||
/// Removed in Unity 2018.3
|
||||
/// </summary>
|
||||
public string PSVPowerMode;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.PSVita.useLibLocation"/>
|
||||
/// Removed in Unity 2018.3
|
||||
/// </summary>
|
||||
public bool PSVUseLibLocation;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.PSVita.healthWarning"/>
|
||||
/// Removed in Unity 2018.3
|
||||
/// </summary>
|
||||
public bool PSVHealthWarning;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.PSVita.enterButtonAssignment"/>
|
||||
/// Removed in Unity 2018.3
|
||||
/// </summary>
|
||||
public string PSVEnterButtonAssignment;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.PSVita.infoBarColor"/>
|
||||
/// Removed in Unity 2018.3
|
||||
/// </summary>
|
||||
public bool PSVInfoBarColor;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.PSVita.infoBarOnStartup"/>
|
||||
/// Removed in Unity 2018.3
|
||||
/// </summary>
|
||||
public bool PSVShowInfoBarOnStartup;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.PSVita.saveDataQuota"/>
|
||||
/// Removed in Unity 2018.3
|
||||
/// </summary>
|
||||
public int PSVSaveDataQuota;
|
||||
|
||||
// paths
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.PSVita.patchChangeInfoPath"/>
|
||||
/// Removed in Unity 2018.3
|
||||
/// </summary>
|
||||
public string PSVPatchChangeInfoPath;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.PSVita.patchOriginalPackage"/>
|
||||
/// Removed in Unity 2018.3
|
||||
/// </summary>
|
||||
public string PSVPatchOriginalPackPath;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.PSVita.keystoneFile"/>
|
||||
/// Removed in Unity 2018.3
|
||||
/// </summary>
|
||||
public string PSVKeystoneFilePath;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.PSVita.liveAreaBackroundPath"/>
|
||||
/// Removed in Unity 2018.3
|
||||
/// </summary>
|
||||
public string PSVLiveAreaBgImagePath;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.PSVita.liveAreaGatePath"/>
|
||||
/// Removed in Unity 2018.3
|
||||
/// </summary>
|
||||
public string PSVLiveAreaGateImagePath;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.PSVita.liveAreaPath"/>
|
||||
/// Removed in Unity 2018.3
|
||||
/// </summary>
|
||||
public string PSVCustomLiveAreaPath;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.PSVita.liveAreaTrialPath"/>
|
||||
/// Removed in Unity 2018.3
|
||||
/// </summary>
|
||||
public string PSVLiveAreaTrialPath;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.PSVita.manualPath"/>
|
||||
/// Removed in Unity 2018.3
|
||||
/// </summary>
|
||||
public string PSVManualPath;
|
||||
|
||||
|
||||
// Samsung TV Build Settings
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.SamsungTV.deviceAddress"/>
|
||||
/// Removed in Unity 2017.3
|
||||
/// </summary>
|
||||
public string SamsungTVDeviceAddress; //
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.SamsungTV.productAuthor"/>
|
||||
/// Added in Unity 5
|
||||
/// Removed in Unity 2017.3
|
||||
/// </summary>
|
||||
public string SamsungTVAuthor;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.SamsungTV.productAuthorEmail"/>
|
||||
/// Added in Unity 5
|
||||
/// Removed in Unity 2017.3
|
||||
/// </summary>
|
||||
public string SamsungTVAuthorEmail;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.SamsungTV.productLink"/>
|
||||
/// Added in Unity 5
|
||||
/// Removed in Unity 2017.3
|
||||
/// </summary>
|
||||
public string SamsungTVAuthorWebsiteUrl;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.SamsungTV.productCategory"/>
|
||||
/// Added in Unity 5
|
||||
/// Removed in Unity 2017.3
|
||||
/// </summary>
|
||||
public string SamsungTVCategory;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UnityEditor.PlayerSettings.SamsungTV.productDescription"/>
|
||||
/// Added in Unity 5
|
||||
/// Removed in Unity 2017.3
|
||||
/// </summary>
|
||||
public string SamsungTVDescription;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d17631212dc3ec94bb8381f70cd68e39
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f18047722c58f9e419c8cb7cfbb5de8b
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d254566b71214ab4ab8bbb6b6e1ac4be
|
||||
timeCreated: 1558257280
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,175 @@
|
||||
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BuildReportTool
|
||||
{
|
||||
public static class MeshDataGenerator
|
||||
{
|
||||
public static void CreateForUsedAssetsOnly(MeshData data, BuildReportTool.BuildInfo buildInfo, bool debugLog = false)
|
||||
{
|
||||
if (buildInfo == null)
|
||||
{
|
||||
if (debugLog) Debug.LogError("Can't create MeshData for Used Assets, BuildInfo is null");
|
||||
return;
|
||||
}
|
||||
if (debugLog) Debug.Log("Will create MeshData for Used Assets");
|
||||
|
||||
var meshDataEntries = data.GetMeshData();
|
||||
meshDataEntries.Clear();
|
||||
|
||||
AppendMeshData(data, buildInfo.UsedAssets.All, false, debugLog);
|
||||
}
|
||||
|
||||
public static void CreateForAllAssets(MeshData data, BuildReportTool.BuildInfo buildInfo, bool debugLog = false)
|
||||
{
|
||||
if (buildInfo == null)
|
||||
{
|
||||
if (debugLog) Debug.LogError("Can't create MeshData for Used & Unused Assets, BuildInfo is null");
|
||||
return;
|
||||
}
|
||||
if (debugLog) Debug.Log("Will create MeshData for Used & Unused Assets");
|
||||
|
||||
var meshDataEntries = data.GetMeshData();
|
||||
meshDataEntries.Clear();
|
||||
|
||||
AppendMeshData(data, buildInfo.UsedAssets.All, false, debugLog);
|
||||
AppendMeshData(data, buildInfo.UnusedAssets.All, false, debugLog);
|
||||
}
|
||||
|
||||
static void AppendMeshData(MeshData data, IList<SizePart> assets, bool overwriteExistingEntries, bool debugLog = false)
|
||||
{
|
||||
if (debugLog) Debug.LogFormat("Creating Mesh Data for {0} assets", assets.Count.ToString());
|
||||
|
||||
var meshDataEntries = data.GetMeshData();
|
||||
|
||||
for (int n = 0; n < assets.Count; ++n)
|
||||
{
|
||||
if (!Util.IsMeshFile(assets[n].Name))
|
||||
{
|
||||
// this asset is not a mesh, skip it
|
||||
continue;
|
||||
}
|
||||
|
||||
if (meshDataEntries.ContainsKey(assets[n].Name))
|
||||
{
|
||||
if (!overwriteExistingEntries)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
var newEntry = CreateEntry(assets[n].Name, debugLog);
|
||||
meshDataEntries[assets[n].Name] = newEntry;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var newEntry = CreateEntry(assets[n].Name, debugLog);
|
||||
meshDataEntries.Add(assets[n].Name, newEntry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static readonly List<MeshFilter> MeshFilters = new List<MeshFilter>();
|
||||
static readonly List<SkinnedMeshRenderer> SkinnedMeshRenderers = new List<SkinnedMeshRenderer>();
|
||||
#if UNITY_5_5_OR_NEWER
|
||||
static readonly List<int> TriangleBuffer = new List<int>();
|
||||
#endif
|
||||
|
||||
static MeshData.Entry CreateEntry(string assetPath, bool debugLog = false)
|
||||
{
|
||||
var assetImporter = AssetImporter.GetAtPath(assetPath);
|
||||
if (assetImporter == null)
|
||||
{
|
||||
if (debugLog) Debug.LogErrorFormat("AssetImporter.GetAtPath returned null for {0}", assetPath);
|
||||
return new MeshData.Entry();
|
||||
}
|
||||
|
||||
var modelImporter = assetImporter as ModelImporter;
|
||||
if (modelImporter == null)
|
||||
{
|
||||
if (debugLog) Debug.LogErrorFormat("AssetImporter is not a ModelImporter for {0}", assetPath);
|
||||
return new MeshData.Entry();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
if (debugLog) Debug.LogFormat("Inspecting Model: {0}", assetPath);
|
||||
|
||||
var result = new MeshData.Entry();
|
||||
|
||||
result.AnimationType = modelImporter.animationType.ToString();
|
||||
if (modelImporter.clipAnimations != null && modelImporter.clipAnimations.Length > 0)
|
||||
{
|
||||
result.AnimationClipCount = modelImporter.clipAnimations.Length;
|
||||
}
|
||||
else
|
||||
{
|
||||
result.AnimationClipCount = modelImporter.defaultClipAnimations.Length;
|
||||
}
|
||||
|
||||
int totalSubMeshCount = 0;
|
||||
int totalVertexCount = 0;
|
||||
int totalTriangleCount = 0;
|
||||
result.MeshFilterCount = 0;
|
||||
result.SkinnedMeshRendererCount = 0;
|
||||
var loadedModel = AssetDatabase.LoadAssetAtPath(assetPath, typeof(GameObject)) as GameObject;
|
||||
if (loadedModel != null)
|
||||
{
|
||||
loadedModel.GetComponentsInChildren(true, MeshFilters);
|
||||
result.MeshFilterCount = MeshFilters.Count;
|
||||
for (int n = 0; n < MeshFilters.Count; ++n)
|
||||
{
|
||||
int subMeshCount = MeshFilters[n].sharedMesh.subMeshCount;
|
||||
totalSubMeshCount += subMeshCount;
|
||||
totalVertexCount += MeshFilters[n].sharedMesh.vertexCount;
|
||||
|
||||
for (int m = 0; m < subMeshCount; ++m)
|
||||
{
|
||||
#if UNITY_2017_3_OR_NEWER
|
||||
MeshFilters[n].sharedMesh.GetTriangles(TriangleBuffer, m, false);
|
||||
totalTriangleCount += TriangleBuffer.Count/3;
|
||||
#elif UNITY_5_5_OR_NEWER
|
||||
MeshFilters[n].sharedMesh.GetTriangles(TriangleBuffer, m);
|
||||
totalTriangleCount += TriangleBuffer.Count/3;
|
||||
#else
|
||||
var triangles = MeshFilters[n].sharedMesh.GetTriangles(m);
|
||||
totalTriangleCount += triangles.Length/3;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
loadedModel.GetComponentsInChildren(true, SkinnedMeshRenderers);
|
||||
result.SkinnedMeshRendererCount = SkinnedMeshRenderers.Count;
|
||||
for (int n = 0; n < SkinnedMeshRenderers.Count; ++n)
|
||||
{
|
||||
int subMeshCount = SkinnedMeshRenderers[n].sharedMesh.subMeshCount;
|
||||
totalSubMeshCount += subMeshCount;
|
||||
totalVertexCount += SkinnedMeshRenderers[n].sharedMesh.vertexCount;
|
||||
|
||||
for (int m = 0; m < subMeshCount; ++m)
|
||||
{
|
||||
#if UNITY_2017_3_OR_NEWER
|
||||
SkinnedMeshRenderers[n].sharedMesh.GetTriangles(TriangleBuffer, m, false);
|
||||
totalTriangleCount += TriangleBuffer.Count/3;
|
||||
#elif UNITY_5_5_OR_NEWER
|
||||
SkinnedMeshRenderers[n].sharedMesh.GetTriangles(TriangleBuffer, m);
|
||||
totalTriangleCount += TriangleBuffer.Count/3;
|
||||
#else
|
||||
var triangles = SkinnedMeshRenderers[n].sharedMesh.GetTriangles(m);
|
||||
totalTriangleCount += triangles.Length/3;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result.SubMeshCount = totalSubMeshCount;
|
||||
result.VertexCount = totalVertexCount;
|
||||
result.TriangleCount = totalTriangleCount;
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d10c934291eb6f44c8a1e76c63795dfc
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,162 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BuildReportTool
|
||||
{
|
||||
public static class PrefabDataGenerator
|
||||
{
|
||||
public static void CreateForUsedAssetsOnly(PrefabData data, BuildReportTool.BuildInfo buildInfo, bool debugLog = false)
|
||||
{
|
||||
if (buildInfo == null)
|
||||
{
|
||||
if (debugLog) Debug.LogError("Can't create MeshData for Used Assets, BuildInfo is null");
|
||||
return;
|
||||
}
|
||||
if (debugLog) Debug.Log("Will create MeshData for Used Assets");
|
||||
|
||||
var prefabDataEntries = data.GetPrefabData();
|
||||
prefabDataEntries.Clear();
|
||||
|
||||
AppendPrefabData(data, buildInfo.UsedAssets.All, false, debugLog);
|
||||
}
|
||||
|
||||
static void AppendPrefabData(PrefabData data, IList<SizePart> assets, bool overwriteExistingEntries, bool debugLog = false)
|
||||
{
|
||||
var prefabDataEntries = data.GetPrefabData();
|
||||
|
||||
for (int n = 0; n < assets.Count; ++n)
|
||||
{
|
||||
if (!assets[n].Name.EndsWith(".prefab", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (prefabDataEntries.ContainsKey(assets[n].Name))
|
||||
{
|
||||
if (!overwriteExistingEntries)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
var newEntry = CreateEntry(assets[n].Name, debugLog);
|
||||
prefabDataEntries[assets[n].Name] = newEntry;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var newEntry = CreateEntry(assets[n].Name, debugLog);
|
||||
prefabDataEntries.Add(assets[n].Name, newEntry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static PrefabData.Entry CreateEntry(string assetPath, bool debugLog = false)
|
||||
{
|
||||
var prefabAsset = AssetDatabase.LoadAssetAtPath<GameObject>(assetPath);
|
||||
if (prefabAsset == null)
|
||||
{
|
||||
return new PrefabData.Entry();
|
||||
}
|
||||
|
||||
var newEntry = new PrefabData.Entry();
|
||||
StaticEditorFlags flags = GameObjectUtility.GetStaticEditorFlags(prefabAsset);
|
||||
newEntry.StaticEditorFlags = GetIntFlags(flags);
|
||||
|
||||
int childStaticEditorFlags = 0;
|
||||
childStaticEditorFlags = UpdateChildStaticEditorFlags(newEntry.StaticEditorFlags, childStaticEditorFlags, PrefabData.FLAG_CONTRIBUTE_GI, prefabAsset.transform);
|
||||
childStaticEditorFlags = UpdateChildStaticEditorFlags(newEntry.StaticEditorFlags, childStaticEditorFlags, PrefabData.FLAG_BATCHING_STATIC, prefabAsset.transform);
|
||||
childStaticEditorFlags = UpdateChildStaticEditorFlags(newEntry.StaticEditorFlags, childStaticEditorFlags, PrefabData.FLAG_OCCLUDER_STATIC, prefabAsset.transform);
|
||||
childStaticEditorFlags = UpdateChildStaticEditorFlags(newEntry.StaticEditorFlags, childStaticEditorFlags, PrefabData.FLAG_OCCLUDEE_STATIC, prefabAsset.transform);
|
||||
childStaticEditorFlags = UpdateChildStaticEditorFlags(newEntry.StaticEditorFlags, childStaticEditorFlags, PrefabData.FLAG_REFLECTION_PROBE_STATIC, prefabAsset.transform);
|
||||
#if !UNITY_2022_2_OR_NEWER
|
||||
childStaticEditorFlags = UpdateChildStaticEditorFlags(newEntry.StaticEditorFlags, childStaticEditorFlags, PrefabData.FLAG_NAVIGATION_STATIC, prefabAsset.transform);
|
||||
childStaticEditorFlags = UpdateChildStaticEditorFlags(newEntry.StaticEditorFlags, childStaticEditorFlags, PrefabData.FLAG_OFF_MESH_LINK_GENERATION, prefabAsset.transform);
|
||||
#endif
|
||||
newEntry.ChildStaticEditorFlags = childStaticEditorFlags;
|
||||
|
||||
return newEntry;
|
||||
}
|
||||
|
||||
static int UpdateChildStaticEditorFlags(int rootLevelStaticEditorFlags, int childStaticEditorFlags, int flagValue, Transform rootTransform)
|
||||
{
|
||||
if ((rootLevelStaticEditorFlags & flagValue) != 0)
|
||||
{
|
||||
// root level is already on
|
||||
return childStaticEditorFlags;
|
||||
}
|
||||
|
||||
// check children of rootTransform to see if flag is turned on for any of them
|
||||
var stack = new Stack<Transform>();
|
||||
stack.Push(rootTransform);
|
||||
|
||||
while (stack.Count > 0)
|
||||
{
|
||||
Transform iterator = stack.Pop();
|
||||
|
||||
for (int i = 0; i < iterator.childCount; i++)
|
||||
{
|
||||
Transform child = iterator.GetChild(i);
|
||||
StaticEditorFlags childFlags = GameObjectUtility.GetStaticEditorFlags(child.gameObject);
|
||||
int intChildFlags = GetIntFlags(childFlags);
|
||||
if ((intChildFlags & flagValue) != 0)
|
||||
{
|
||||
// this child has the flag
|
||||
childStaticEditorFlags |= flagValue;
|
||||
return childStaticEditorFlags;
|
||||
}
|
||||
stack.Push(child);
|
||||
}
|
||||
}
|
||||
return childStaticEditorFlags;
|
||||
}
|
||||
|
||||
static int GetIntFlags(StaticEditorFlags flags)
|
||||
{
|
||||
// Unity might change the value of these flags in a future version, so we explicitly convert it ourselves
|
||||
int intFlags = 0;
|
||||
|
||||
if (flags.Has(StaticEditorFlags.ContributeGI))
|
||||
{
|
||||
intFlags |= PrefabData.FLAG_CONTRIBUTE_GI;
|
||||
}
|
||||
if (flags.Has(StaticEditorFlags.OccluderStatic))
|
||||
{
|
||||
intFlags |= PrefabData.FLAG_OCCLUDER_STATIC;
|
||||
}
|
||||
if (flags.Has(StaticEditorFlags.BatchingStatic))
|
||||
{
|
||||
intFlags |= PrefabData.FLAG_BATCHING_STATIC;
|
||||
}
|
||||
#if !UNITY_2022_2_OR_NEWER
|
||||
if (flags.Has(StaticEditorFlags.NavigationStatic))
|
||||
{
|
||||
intFlags |= PrefabData.FLAG_NAVIGATION_STATIC;
|
||||
}
|
||||
#endif
|
||||
if (flags.Has(StaticEditorFlags.OccludeeStatic))
|
||||
{
|
||||
intFlags |= PrefabData.FLAG_OCCLUDEE_STATIC;
|
||||
}
|
||||
#if !UNITY_2022_2_OR_NEWER
|
||||
if (flags.Has(StaticEditorFlags.OffMeshLinkGeneration))
|
||||
{
|
||||
intFlags |= PrefabData.FLAG_OFF_MESH_LINK_GENERATION;
|
||||
}
|
||||
#endif
|
||||
if (flags.Has(StaticEditorFlags.ReflectionProbeStatic))
|
||||
{
|
||||
intFlags |= PrefabData.FLAG_REFLECTION_PROBE_STATIC;
|
||||
}
|
||||
|
||||
return intFlags;
|
||||
}
|
||||
|
||||
static bool Has(this StaticEditorFlags f, StaticEditorFlags flagToCheck)
|
||||
{
|
||||
return (f & flagToCheck) != 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 38b06f03b322c3f4ca4d44824c124682
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2fa31ef0bf24b9d49be86ab12b9e59e2
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
@@ -0,0 +1,251 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
namespace BuildReportTool
|
||||
{
|
||||
public partial class ReportGenerator
|
||||
{
|
||||
public static void OnPreBuild()
|
||||
{
|
||||
BuildReportTool.Util.SaveBuildTime();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create and save a Build Report. This is meant to be used for users who have a
|
||||
/// custom build script, or is automating a project build command from the command line.
|
||||
///
|
||||
/// The Editor log needs to have build data for this to work,
|
||||
/// so only call this after <see cref="UnityEditor.BuildPipeline.BuildPlayer"/>.
|
||||
/// </summary>
|
||||
///
|
||||
/// <remarks>
|
||||
/// <para>This overload will make use of the project's current build settings.</para>
|
||||
///
|
||||
/// <para>Specifically, that means it will retrieve the list of scenes from
|
||||
/// <see cref="UnityEditor.EditorBuildSettings.scenes"/>, the build location using
|
||||
/// <see cref="UnityEditor.EditorUserBuildSettings.GetBuildLocation"/>, and the build target
|
||||
/// using <see cref="UnityEditor.EditorUserBuildSettings.activeBuildTarget"/>.</para>
|
||||
///
|
||||
/// <para>If your build scripts are overriding the project's current build settings,
|
||||
/// you should use <see cref="CreateReport(string[], string, BuildTarget, string, string)"/>
|
||||
/// instead.</para>
|
||||
/// </remarks>
|
||||
///
|
||||
/// <param name="customEditorLogPath">If your Unity Editor log file is not in
|
||||
/// the default path, specify it here. Otherwise, leave this null so that
|
||||
/// BuildReportTool will just use the default location of the Editor.log file.</param>
|
||||
///
|
||||
/// <param name="customSavePath">Path to folder where the Build Report XML file will be saved.
|
||||
/// Leave this null so that BuildReportTool will just use the path specified in the saved options.</param>
|
||||
///
|
||||
/// <returns>The full path and filename of the created Build Report XML file,
|
||||
/// or null if no Build Report was created.</returns>
|
||||
public static string CreateReport(string customEditorLogPath = null, string customSavePath = null)
|
||||
{
|
||||
return CreateReport(null, null, EditorUserBuildSettings.activeBuildTarget,
|
||||
customEditorLogPath, customSavePath);
|
||||
}
|
||||
|
||||
#if UNITY_5_5_OR_NEWER
|
||||
/// <summary>
|
||||
/// Create and save a Build Report. This is meant to be used for users who have a
|
||||
/// custom build script, or is automating a project build command from the command line.
|
||||
///
|
||||
/// The Editor log needs to have build data for this to work,
|
||||
/// so only call this after <see cref="UnityEditor.BuildPipeline.BuildPlayer"/>.
|
||||
/// </summary>
|
||||
///
|
||||
/// <remarks>
|
||||
/// <para>This overload will retrieve the list of scenes, the build location, and the
|
||||
/// build target from the <see cref="UnityEditor.BuildPlayerOptions"/> that you pass.
|
||||
/// If your custom build script makes a BuildPlayerOptions, you can use this method
|
||||
/// to re-use that BuildPlayerOptions for generating the Build Report.</para>
|
||||
///
|
||||
/// <para><see cref="BuildPlayerOptions.locationPathName"/> can be set to the build folder's absolute path,
|
||||
/// but if there are multiple builds in that path, this should be set to the
|
||||
/// absolute path to the build file itself instead
|
||||
/// (e.g. exe file for Windows Standalone, apk file for Android, etc.).</para>
|
||||
/// </remarks>
|
||||
///
|
||||
/// <param name="buildPlayerOptions">The <see cref="UnityEditor.BuildPlayerOptions"/>
|
||||
/// that was used to create the build.</param>
|
||||
///
|
||||
/// <param name="customEditorLogPath">If your Unity Editor log file is not in
|
||||
/// the default path, specify it here. Otherwise, leave this null so that
|
||||
/// BuildReportTool will just use the default location of the Editor.log file.</param>
|
||||
///
|
||||
/// <param name="customSavePath">Path to folder where the Build Report XML file will be saved.
|
||||
/// Leave this null so that BuildReportTool will just use the path specified in the saved options.</param>
|
||||
///
|
||||
/// <returns>The full path and filename of the created Build Report XML file,
|
||||
/// or null if no Build Report was created.</returns>
|
||||
public static string CreateReport(BuildPlayerOptions buildPlayerOptions,
|
||||
string customEditorLogPath = null, string customSavePath = null)
|
||||
{
|
||||
return CreateReport(buildPlayerOptions.scenes, buildPlayerOptions.locationPathName, buildPlayerOptions.target,
|
||||
customEditorLogPath, customSavePath);
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Create and save a Build Report. This is meant to be used for users who have a
|
||||
/// custom build script, or is automating a project build command from the command line.
|
||||
///
|
||||
/// The Editor log needs to have build data for this to work,
|
||||
/// so only call this after <see cref="UnityEditor.BuildPipeline.BuildPlayer"/>.
|
||||
/// </summary>
|
||||
///
|
||||
/// <remarks>
|
||||
/// <para>If your custom build scripts override the project's build settings,
|
||||
/// this overload allows you to explicitly specify the list of scenes, the build
|
||||
/// location, and the build target yourself.</para>
|
||||
///
|
||||
/// <para>But if your build scripts didn't override the project's build settings,
|
||||
/// you can instead use <see cref="CreateReport(string, string)"/>.</para>
|
||||
/// </remarks>
|
||||
///
|
||||
/// <param name="scenes">Which scenes were included in the build. Can be set to null
|
||||
/// so that BuildReportTool will just use UnityEditor.EditorBuildSettings.scenes instead.
|
||||
/// If you specified your own list of scenes when building, you should pass them here.</param>
|
||||
///
|
||||
/// <param name="buildLocation">Absolute path where the build was saved to. Can be set to null so that
|
||||
/// BuildReportTool will just use Unity's <see cref="UnityEditor.EditorUserBuildSettings.GetBuildLocation"/>
|
||||
/// instead. If you specified your own build location, you should set it here.
|
||||
///
|
||||
/// You can specify only the path to the build folder, but if there are multiple builds
|
||||
/// in that folder, it is best to specify the path to the build file itself
|
||||
/// (e.g. exe file for Windows Standalone, apk file for Android, etc.).</param>
|
||||
///
|
||||
/// <param name="buildTarget">Type of build platform being made. You can just pass
|
||||
/// UnityEditor.EditorUserBuildSettings.activeBuildTarget if you didn't explicitly
|
||||
/// set this. If you specified your own build target, you should pass it here.</param>
|
||||
///
|
||||
/// <param name="customEditorLogPath">If your Unity Editor log file is not in the
|
||||
/// default path, specify it here. Otherwise, leave this null so that BuildReportTool
|
||||
/// will just use the default location of the Editor.log file.</param>
|
||||
///
|
||||
/// <param name="customSavePath">Path to folder where the Build Report XML file will be saved.
|
||||
/// Leave this null so that BuildReportTool will just use the path specified in the saved options.</param>
|
||||
///
|
||||
/// <returns>The full path and filename of the created Build Report XML file,
|
||||
/// or null if no Build Report was created.</returns>
|
||||
public static string CreateReport(string[] scenes, string buildLocation, BuildTarget buildTarget,
|
||||
string customEditorLogPath = null, string customSavePath = null)
|
||||
{
|
||||
BuildReportTool.Util.BuildTargetOfLastBuild = buildTarget;
|
||||
|
||||
var editorLogPathToUse = !string.IsNullOrEmpty(customEditorLogPath)
|
||||
? customEditorLogPath
|
||||
: BuildReportTool.Util.UsedEditorLogPath;
|
||||
|
||||
if (!DoesEditorLogHaveBuildInfo(editorLogPathToUse))
|
||||
{
|
||||
if (BuildReportTool.Util.IsDefaultEditorLogPathOverridden)
|
||||
{
|
||||
Debug.LogWarning(string.Format(NO_BUILD_INFO_OVERRIDDEN_LOG_WARNING, editorLogPathToUse,
|
||||
BuildReportTool.Options.FoundPathForSavedOptions));
|
||||
}
|
||||
else if (CheckIfUnityHasNoLogArgument())
|
||||
{
|
||||
Debug.LogWarning(NO_BUILD_INFO_NO_LOG_WARNING);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning(NO_BUILD_INFO_WARNING);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
var timeNow = System.DateTime.Now;
|
||||
_lastPathToBuiltProject = buildLocation;
|
||||
|
||||
Init(true, ref _lastKnownBuildInfo, scenes);
|
||||
_lastKnownBuildInfo.TimeGot = timeNow;
|
||||
_lastKnownBuildInfo.TimeGotReadable = timeNow.ToString(TIME_OF_BUILD_FORMAT);
|
||||
|
||||
System.DateTime timeBuildStarted;
|
||||
if (BuildReportTool.Util.HasBuildTime())
|
||||
{
|
||||
timeBuildStarted = BuildReportTool.Util.LoadBuildTime();
|
||||
}
|
||||
else
|
||||
{
|
||||
timeBuildStarted = timeNow;
|
||||
}
|
||||
|
||||
if (BuildReportTool.Options.CalculateAssetDependencies)
|
||||
{
|
||||
if (_lastKnownAssetDependencies == null)
|
||||
{
|
||||
_lastKnownAssetDependencies = new BuildReportTool.AssetDependencies();
|
||||
}
|
||||
|
||||
_lastKnownAssetDependencies.TimeGot = timeBuildStarted;
|
||||
}
|
||||
|
||||
if (BuildReportTool.Options.CollectTextureImportSettings)
|
||||
{
|
||||
if (_lastKnownTextureData == null)
|
||||
{
|
||||
_lastKnownTextureData = new BuildReportTool.TextureData();
|
||||
}
|
||||
|
||||
_lastKnownTextureData.TimeGot = timeBuildStarted;
|
||||
}
|
||||
|
||||
if (BuildReportTool.Options.CollectMeshData)
|
||||
{
|
||||
if (_lastKnownMeshData == null)
|
||||
{
|
||||
_lastKnownMeshData = new BuildReportTool.MeshData();
|
||||
}
|
||||
|
||||
_lastKnownMeshData.TimeGot = timeBuildStarted;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_lastKnownMeshData != null)
|
||||
{
|
||||
_lastKnownMeshData.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
if (BuildReportTool.Options.CollectPrefabData)
|
||||
{
|
||||
if (_lastKnownPrefabData == null)
|
||||
{
|
||||
_lastKnownPrefabData = new BuildReportTool.PrefabData();
|
||||
}
|
||||
|
||||
_lastKnownPrefabData.TimeGot = timeBuildStarted;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_lastKnownPrefabData != null)
|
||||
{
|
||||
_lastKnownPrefabData.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
_lastEditorLogPath = editorLogPathToUse;
|
||||
|
||||
if (BuildReportTool.Options.IncludeUnusedPrefabsInReportCreation)
|
||||
{
|
||||
RefreshListOfAllPrefabsUsedInAllScenesIncludedInBuild();
|
||||
}
|
||||
else
|
||||
{
|
||||
ClearListOfAllPrefabsUsedInAllScenes();
|
||||
}
|
||||
|
||||
CommitAdditionalInfoToCache();
|
||||
|
||||
CreateBuildReport(_lastKnownBuildInfo);
|
||||
|
||||
var savedFilePath = OnFinishedGetValues(_lastKnownBuildInfo, _lastKnownAssetDependencies, _lastKnownTextureData, _lastKnownMeshData, _lastKnownPrefabData, customSavePath);
|
||||
|
||||
return savedFilePath;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5d7223604cc43df4689a667b69fa4101
|
||||
timeCreated: 1559195468
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,586 @@
|
||||
#define BRT_USE_INTERNAL_TEXTURE_IMPORTER_METHODS
|
||||
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BuildReportTool
|
||||
{
|
||||
public static class TextureDataGenerator
|
||||
{
|
||||
public static void CreateForUsedAssetsOnly(TextureData data, BuildReportTool.BuildInfo buildInfo, bool debugLog = false)
|
||||
{
|
||||
if (buildInfo == null)
|
||||
{
|
||||
if (debugLog) Debug.LogError("Can't create TextureData for Used Assets, BuildInfo is null");
|
||||
return;
|
||||
}
|
||||
if (debugLog) Debug.Log("Will create TextureData for Used Assets");
|
||||
|
||||
BuildReportTool.BuildPlatform buildPlatform = BuildReportTool.ReportGenerator.GetBuildPlatformFromString(buildInfo.BuildType, buildInfo.BuildTargetUsed);
|
||||
|
||||
var textureDataEntries = data.GetTextureData();
|
||||
textureDataEntries.Clear();
|
||||
|
||||
AppendTextureData(data, buildPlatform, buildInfo.UsedAssets.All, false, debugLog);
|
||||
}
|
||||
|
||||
public static void CreateForAllAssets(TextureData data, BuildReportTool.BuildInfo buildInfo, bool debugLog = false)
|
||||
{
|
||||
if (buildInfo == null)
|
||||
{
|
||||
if (debugLog) Debug.LogError("Can't create TextureData for Used & Unused Assets, BuildInfo is null");
|
||||
return;
|
||||
}
|
||||
if (debugLog) Debug.Log("Will create TextureData for Used & Unused Assets");
|
||||
|
||||
BuildReportTool.BuildPlatform buildPlatform = BuildReportTool.ReportGenerator.GetBuildPlatformFromString(buildInfo.BuildType, buildInfo.BuildTargetUsed);
|
||||
|
||||
var textureDataEntries = data.GetTextureData();
|
||||
textureDataEntries.Clear();
|
||||
|
||||
AppendTextureData(data, buildPlatform, buildInfo.UsedAssets.All, false, debugLog);
|
||||
AppendTextureData(data, buildPlatform, buildInfo.UnusedAssets.All, false, debugLog);
|
||||
}
|
||||
|
||||
static void AppendTextureData(TextureData data, BuildReportTool.BuildPlatform buildPlatform, IList<SizePart> assets, bool overwriteExistingEntries, bool debugLog = false)
|
||||
{
|
||||
if (debugLog) Debug.LogFormat("Creating Texture Data for {0} assets", assets.Count.ToString());
|
||||
|
||||
var platformString = GetPlatformString(buildPlatform);
|
||||
var textureDataEntries = data.GetTextureData();
|
||||
|
||||
for (int n = 0; n < assets.Count; ++n)
|
||||
{
|
||||
if (!Util.IsTextureFile(assets[n].Name))
|
||||
{
|
||||
// this asset is not an image, skip it
|
||||
continue;
|
||||
}
|
||||
|
||||
if (textureDataEntries.ContainsKey(assets[n].Name))
|
||||
{
|
||||
if (!overwriteExistingEntries)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
var newEntry = CreateEntry(assets[n].Name, platformString, debugLog);
|
||||
textureDataEntries[assets[n].Name] = newEntry;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var newEntry = CreateEntry(assets[n].Name, platformString, debugLog);
|
||||
textureDataEntries.Add(assets[n].Name, newEntry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const int ANISO_LEVEL_IF_VALUE_IS_NEGATIVE_ONE = 1;
|
||||
const int COMPRESSION_QUALITY_IF_VALUE_IS_NEGATIVE_ONE = 50;
|
||||
const string WRAP_MODE_IF_VALUE_IS_NEGATIVE_ONE = "Repeat";
|
||||
|
||||
static TextureData.Entry CreateEntry(string assetPath, string platform, bool debugLog = false)
|
||||
{
|
||||
var assetImporter = AssetImporter.GetAtPath(assetPath);
|
||||
if (assetImporter == null)
|
||||
{
|
||||
if (debugLog) Debug.LogErrorFormat("AssetImporter.GetAtPath returned null for {0}", assetPath);
|
||||
return new TextureData.Entry();
|
||||
}
|
||||
|
||||
var textureImporter = assetImporter as TextureImporter;
|
||||
if (textureImporter == null)
|
||||
{
|
||||
if (debugLog) Debug.LogErrorFormat("AssetImporter is not a TextureImporter for {0}", assetPath);
|
||||
return new TextureData.Entry();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
if (debugLog) Debug.LogFormat("Inspecting Texture: {0}", assetPath);
|
||||
|
||||
var result = new TextureData.Entry();
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
// textureImporter.textureType: enum (whether it's GUI, lightmap, normal map, sprite, etc.)
|
||||
result.TextureType = TextureTypeToReadableString(textureImporter.textureType);
|
||||
|
||||
#if UNITY_5_5_OR_NEWER
|
||||
result.IsSRGB = textureImporter.sRGBTexture;
|
||||
#else
|
||||
result.IsSRGB = !textureImporter.linearTexture; // obsolete in Unity 5.5
|
||||
#endif
|
||||
if (result.IsSRGB)
|
||||
{
|
||||
switch (textureImporter.textureType)
|
||||
{
|
||||
#if UNITY_5_5_OR_NEWER
|
||||
case TextureImporterType.NormalMap:
|
||||
#else
|
||||
case TextureImporterType.Bump:
|
||||
#endif
|
||||
case TextureImporterType.Lightmap:
|
||||
#if UNITY_5_5_OR_NEWER
|
||||
case TextureImporterType.SingleChannel:
|
||||
#endif
|
||||
if (debugLog) Debug.LogWarningFormat("Texture: {0} was marked as sRGB but it is a {1}", assetPath, result.TextureType);
|
||||
result.IsSRGB = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#if UNITY_5_5_OR_NEWER
|
||||
result.AlphaSource = textureImporter.alphaSource.ToString();
|
||||
#else
|
||||
result.AlphaSource = null;
|
||||
#endif
|
||||
result.AlphaIsTransparency = textureImporter.alphaIsTransparency;
|
||||
#if UNITY_2020_1_OR_NEWER
|
||||
result.IgnorePngGamma = textureImporter.ignorePngGamma;
|
||||
#else
|
||||
result.IgnorePngGamma = false; // doesn't exist yet in Unity 2019 and below
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
result.IsReadable = textureImporter.isReadable;
|
||||
result.MipMapGenerated = textureImporter.mipmapEnabled;
|
||||
result.MipMapFilter = textureImporter.mipmapFilter.ToString();
|
||||
#if UNITY_2018_2_OR_NEWER
|
||||
result.StreamingMipMaps = textureImporter.streamingMipmaps;
|
||||
#else
|
||||
result.StreamingMipMaps = false; // doesn't exist yet in Unity 2018.1 and below
|
||||
#endif
|
||||
result.BorderMipMaps = textureImporter.borderMipmap;
|
||||
#if UNITY_2017_1_OR_NEWER
|
||||
result.PreserveCoverageMipMaps = textureImporter.mipMapsPreserveCoverage;
|
||||
#else
|
||||
result.PreserveCoverageMipMaps = false;
|
||||
#endif
|
||||
result.FadeOutMipMaps = textureImporter.fadeout;
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
result.SpriteImportMode = textureImporter.spriteImportMode.ToString();
|
||||
#if !UNITY_2022_2_OR_NEWER
|
||||
result.SpritePackingTag = textureImporter.spritePackingTag;
|
||||
#else
|
||||
result.SpritePackingTag = null; // Sprite Packing Tag removed, replaced with Sprite Atlas assets
|
||||
#endif
|
||||
result.SpritePixelsPerUnit = textureImporter.spritePixelsPerUnit;
|
||||
result.QualifiesForSpritePacking = textureImporter.qualifiesForSpritePacking;
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
result.WrapMode = WrapModeToReadableString(textureImporter.wrapMode);
|
||||
#if UNITY_2017_1_OR_NEWER
|
||||
result.WrapModeU = WrapModeToReadableString(textureImporter.wrapModeU);
|
||||
result.WrapModeV = WrapModeToReadableString(textureImporter.wrapModeV);
|
||||
result.WrapModeW = WrapModeToReadableString(textureImporter.wrapModeW);
|
||||
#else
|
||||
result.WrapModeU = null;
|
||||
result.WrapModeV = null;
|
||||
result.WrapModeW = null;
|
||||
#endif
|
||||
|
||||
result.FilterMode = textureImporter.filterMode.ToString();
|
||||
|
||||
result.AnisoLevel = textureImporter.anisoLevel;
|
||||
|
||||
if (result.AnisoLevel == -1)
|
||||
{
|
||||
result.AnisoLevel = ANISO_LEVEL_IF_VALUE_IS_NEGATIVE_ONE;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
result.MaxTextureSize = textureImporter.maxTextureSize;
|
||||
#if UNITY_5_5_OR_NEWER
|
||||
var defaultSettings = textureImporter.GetDefaultPlatformTextureSettings();
|
||||
|
||||
#if UNITY_2017_2_OR_NEWER
|
||||
result.TextureResizeAlgorithm = defaultSettings.resizeAlgorithm.ToString();
|
||||
#else
|
||||
result.TextureResizeAlgorithm = string.Empty;
|
||||
#endif
|
||||
if (defaultSettings.format == TextureImporterFormat.Automatic)
|
||||
{
|
||||
result.TextureFormat = textureImporter.GetAutomaticFormat(platform).ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
result.TextureFormat = defaultSettings.format.ToString();
|
||||
}
|
||||
result.CompressionType = CompressionTypeToReadableString(defaultSettings.textureCompression);
|
||||
result.CompressionIsCrunched = defaultSettings.crunchedCompression;
|
||||
#else
|
||||
// Unity 5.4 and below
|
||||
result.TextureResizeAlgorithm = null;
|
||||
result.TextureFormat = TextureFormatToReadableString(textureImporter.textureFormat);
|
||||
result.CompressionType = null; // no compression type in Unity 5.4 and below
|
||||
result.CompressionIsCrunched = false; // no crunch compression in Unity 5.4 and below
|
||||
#endif
|
||||
result.CompressionQuality = textureImporter.compressionQuality;
|
||||
if (result.CompressionQuality == -1)
|
||||
{
|
||||
result.CompressionQuality = COMPRESSION_QUALITY_IF_VALUE_IS_NEGATIVE_ONE;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
#if UNITY_5_5_OR_NEWER
|
||||
var overrideSettings = !string.IsNullOrEmpty(platform) ? textureImporter.GetPlatformTextureSettings(platform) : null;
|
||||
if (overrideSettings != null && overrideSettings.overridden)
|
||||
{
|
||||
result.PlatformSettingsOverriden = true;
|
||||
result.OverridingMaxTextureSize = overrideSettings.maxTextureSize;
|
||||
#if UNITY_2017_2_OR_NEWER
|
||||
result.OverridingTextureResizeAlgorithm = overrideSettings.resizeAlgorithm.ToString();
|
||||
#else
|
||||
result.OverridingTextureResizeAlgorithm = string.Empty;
|
||||
#endif
|
||||
if (overrideSettings.format == TextureImporterFormat.Automatic)
|
||||
{
|
||||
result.OverridingTextureFormat = textureImporter.GetAutomaticFormat(platform).ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
result.OverridingTextureFormat = overrideSettings.format.ToString();
|
||||
}
|
||||
result.OverridingCompressionType = CompressionTypeToReadableString(overrideSettings.textureCompression);
|
||||
result.OverridingCompressionIsCrunched = overrideSettings.crunchedCompression;
|
||||
result.OverridingCompressionQuality = overrideSettings.compressionQuality;
|
||||
if (result.OverridingCompressionQuality == -1)
|
||||
{
|
||||
result.OverridingCompressionQuality = COMPRESSION_QUALITY_IF_VALUE_IS_NEGATIVE_ONE;
|
||||
}
|
||||
|
||||
if (debugLog && result.TextureFormat != result.OverridingTextureFormat)
|
||||
Debug.LogFormat("TextureDataGenerator: {0} for {1} format overriden from {2} to {3}",
|
||||
platform, assetPath, result.TextureFormat, result.OverridingTextureFormat);
|
||||
|
||||
if (debugLog && result.MaxTextureSize != result.OverridingMaxTextureSize)
|
||||
Debug.LogFormat("TextureDataGenerator: {0} for {1} max size overriden from {2} to {3}",
|
||||
platform, assetPath, result.MaxTextureSize.ToString(), result.OverridingMaxTextureSize.ToString());
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
result.PlatformSettingsOverriden = false;
|
||||
result.OverridingMaxTextureSize = 0;
|
||||
result.OverridingTextureResizeAlgorithm = null;
|
||||
result.OverridingTextureFormat = null;
|
||||
result.OverridingCompressionType = null;
|
||||
result.OverridingCompressionIsCrunched = false;
|
||||
result.OverridingCompressionQuality = 0;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
// Note: there are two import settings can make the
|
||||
// imported width/height different from the real width/height:
|
||||
// MaxTextureSize (which is a max limit on the value),
|
||||
// and NPotScale (which will resize to a power-of-two value if specified)
|
||||
|
||||
var loadedTexture = AssetDatabase.LoadAssetAtPath(assetPath, typeof(Texture)) as Texture;
|
||||
|
||||
if (loadedTexture != null)
|
||||
{
|
||||
result.ImportedWidth = loadedTexture.width;
|
||||
result.ImportedHeight = loadedTexture.height;
|
||||
|
||||
if (debugLog)
|
||||
Debug.LogFormat("Got imported dimensions (using AssetDatabase.LoadAssetAtPath Texture) for {0} {1}x{2}",
|
||||
assetPath, result.ImportedWidth.ToString(), result.ImportedHeight.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (debugLog)
|
||||
Debug.LogErrorFormat("Could not get imported width and height, AssetDatabase.LoadAssetAtPath returned null for {0}", assetPath);
|
||||
|
||||
// could not load texture, so we can't get imported width and height
|
||||
result.ImportedWidth = 0;
|
||||
result.ImportedHeight = 0;
|
||||
}
|
||||
|
||||
result.UpdateShownSettings(platform);
|
||||
|
||||
if (textureImporter.npotScale == TextureImporterNPOTScale.None)
|
||||
{
|
||||
if (Mathf.IsPowerOfTwo(result.ImportedWidth) && Mathf.IsPowerOfTwo(result.ImportedHeight))
|
||||
{
|
||||
result.NPotScale = BuildReportTool.TextureData.NPOT_SCALE_NONE_IS_POT;
|
||||
}
|
||||
else
|
||||
{
|
||||
result.NPotScale = BuildReportTool.TextureData.NPOT_SCALE_NONE_NOT_POT;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result.NPotScale = textureImporter.npotScale.ToString();
|
||||
}
|
||||
|
||||
var gotDimensions = GetImageRealWidthAndHeight(assetPath, textureImporter, debugLog);
|
||||
result.RealWidth = gotDimensions.Width;
|
||||
result.RealHeight = gotDimensions.Height;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// ========================================================================================
|
||||
|
||||
#if !UNITY_5_5_OR_NEWER
|
||||
static string TextureFormatToReadableString(TextureImporterFormat textureFormat)
|
||||
{
|
||||
return textureFormat.ToString();
|
||||
}
|
||||
#endif
|
||||
|
||||
static string TextureTypeToReadableString(TextureImporterType textureType)
|
||||
{
|
||||
switch (textureType)
|
||||
{
|
||||
#if UNITY_5_5_OR_NEWER
|
||||
case TextureImporterType.Default:
|
||||
return "Default";
|
||||
case TextureImporterType.SingleChannel:
|
||||
return "Single Channel";
|
||||
case TextureImporterType.NormalMap:
|
||||
return "Normal Map";
|
||||
#else
|
||||
case TextureImporterType.Bump:
|
||||
return "Normal Map";
|
||||
#endif
|
||||
case TextureImporterType.GUI:
|
||||
return "GUI";
|
||||
case TextureImporterType.Sprite:
|
||||
return "Sprite";
|
||||
case TextureImporterType.Cursor:
|
||||
return "Cursor";
|
||||
case TextureImporterType.Cookie:
|
||||
return "Cookie";
|
||||
case TextureImporterType.Lightmap:
|
||||
return "Lightmap";
|
||||
#if UNITY_2020_2_OR_NEWER
|
||||
case TextureImporterType.DirectionalLightmap:
|
||||
return "Directional Lightmap";
|
||||
#endif
|
||||
default:
|
||||
return textureType.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
static string WrapModeToReadableString(TextureWrapMode wrapMode)
|
||||
{
|
||||
switch (wrapMode)
|
||||
{
|
||||
case TextureWrapMode.Repeat:
|
||||
return "Repeat";
|
||||
case TextureWrapMode.Clamp:
|
||||
return "Clamp";
|
||||
#if UNITY_2017_1_OR_NEWER
|
||||
case TextureWrapMode.Mirror:
|
||||
return "Mirror";
|
||||
case TextureWrapMode.MirrorOnce:
|
||||
return "MirrorOnce";
|
||||
#endif
|
||||
default:
|
||||
if ((int)wrapMode == -1)
|
||||
{
|
||||
return WRAP_MODE_IF_VALUE_IS_NEGATIVE_ONE;
|
||||
}
|
||||
return string.Format("Unrecognized ({0})", wrapMode.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
#if UNITY_5_5_OR_NEWER
|
||||
static string CompressionTypeToReadableString(TextureImporterCompression compression)
|
||||
{
|
||||
switch (compression)
|
||||
{
|
||||
case TextureImporterCompression.Uncompressed:
|
||||
return "Uncompressed";
|
||||
case TextureImporterCompression.Compressed:
|
||||
return "Standard Compression";
|
||||
case TextureImporterCompression.CompressedHQ:
|
||||
return "High Quality, Low Compression";
|
||||
case TextureImporterCompression.CompressedLQ:
|
||||
return "Low Quality, High Compression";
|
||||
default:
|
||||
return compression.ToString();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
public static string GetPlatformString(BuildPlatform buildPlatform)
|
||||
{
|
||||
// options for the platform string are:
|
||||
// in Unity 5.5: "Standalone", "Web", "iPhone", "Android", "WebGL", "Windows Store Apps", "Tizen", "PSP2", "PS4", "XboxOne", "Samsung TV", "Nintendo 3DS", "WiiU" and "tvOS"
|
||||
// in Unity 2017.4: "Standalone", "Web", "iPhone", "Android", "WebGL", "Windows Store Apps", "PSP2", "PS4", "XboxOne", "Nintendo 3DS", "WiiU" and "tvOS". Tizen & Samsung TV removed
|
||||
// in Unity 2018.1: "Standalone", "Web", "iPhone", "Android", "WebGL", "Windows Store Apps", "PSP2", "PS4", "XboxOne", "Nintendo 3DS" and "tvOS". WiiU removed
|
||||
// in Unity 2018.2: "Standalone", "Web", "iPhone", "Android", "WebGL", "Windows Store Apps", "PSP2", "PS4", "XboxOne", "Nintendo 3DS" and "tvOS". no change
|
||||
// in Unity 2018.3: "Standalone", "Web", "iPhone", "Android", "WebGL", "Windows Store Apps", "PS4", "XboxOne", "Nintendo 3DS" and "tvOS". PSP2 (i.e. PS Vita) removed
|
||||
// in Unity 2018.4: "Standalone", "Web", "iPhone", "Android", "WebGL", "Windows Store Apps", "PS4", "XboxOne", "Nintendo 3DS" and "tvOS". no change
|
||||
// in Unity 2019.3: "Standalone", "Web", "iPhone", "Android", "WebGL", "Windows Store Apps", "PS4", "XboxOne", "Nintendo 3DS" and "tvOS". no change
|
||||
// in Unity 2019.4: "Standalone", "Web", "iPhone", "Android", "WebGL", "Windows Store Apps", "PS4", "XboxOne", "Nintendo Switch" and "tvOS". 3DS removed, Switch added
|
||||
// in Unity 2020.3: "Standalone", "Web", "iPhone", "Android", "WebGL", "Windows Store Apps", "PS4", "XboxOne", "Nintendo Switch" and "tvOS". no change
|
||||
// in Unity 2021.1: "Standalone", "Web", "iPhone", "Android", "WebGL", "Windows Store Apps", "PS4", "XboxOne", "Nintendo Switch" and "tvOS". no change
|
||||
|
||||
switch (buildPlatform)
|
||||
{
|
||||
case BuildPlatform.Android:
|
||||
return "Android";
|
||||
case BuildPlatform.iOS:
|
||||
return "iPhone";
|
||||
case BuildPlatform.Tizen:
|
||||
return "Tizen";
|
||||
case BuildPlatform.Web:
|
||||
return "Web";
|
||||
case BuildPlatform.WebGL:
|
||||
return "WebGL";
|
||||
case BuildPlatform.MacOSX32:
|
||||
case BuildPlatform.MacOSX64:
|
||||
case BuildPlatform.MacOSXUniversal:
|
||||
case BuildPlatform.Linux32:
|
||||
case BuildPlatform.Linux64:
|
||||
case BuildPlatform.LinuxUniversal:
|
||||
case BuildPlatform.Windows32:
|
||||
case BuildPlatform.Windows64:
|
||||
return "Standalone";
|
||||
case BuildPlatform.WindowsStoreApp:
|
||||
return "Windows Store Apps";
|
||||
case BuildPlatform.XboxOne:
|
||||
return "XboxOne";
|
||||
case BuildPlatform.XboxSeries:
|
||||
return "GameCoreXboxSeries";
|
||||
case BuildPlatform.PS4:
|
||||
return "PS4";
|
||||
case BuildPlatform.PS5:
|
||||
return "PS5";
|
||||
case BuildPlatform.PSVitaNative:
|
||||
return "PSP2";
|
||||
case BuildPlatform.WiiU:
|
||||
return "WiiU";
|
||||
case BuildPlatform.Nintendo3DS:
|
||||
return "Nintendo 3DS";
|
||||
case BuildPlatform.Switch:
|
||||
return "Nintendo Switch";
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================================================================
|
||||
|
||||
#if BRT_USE_INTERNAL_TEXTURE_IMPORTER_METHODS
|
||||
#if UNITY_2018_1_OR_NEWER
|
||||
/// <summary>
|
||||
/// <see cref="TextureImporter.GetSourceTextureInformation()"/> for getting image's real width and height.
|
||||
/// This method is private, at least as of Unity 2020.1.17f1.
|
||||
/// </summary>
|
||||
static readonly System.Reflection.MethodInfo TextureImporterGetSourceTextureInformation =
|
||||
typeof(TextureImporter).GetMethod("GetSourceTextureInformation",
|
||||
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="TextureImporter.GetWidthAndHeight(ref int, ref int)"/> for getting image's real width and height.
|
||||
/// This method is internal, at least as of Unity 2020.1.17f1.
|
||||
/// </summary>
|
||||
static readonly System.Reflection.MethodInfo TextureImporterGetWidthAndHeight =
|
||||
typeof(TextureImporter).GetMethod("GetWidthAndHeight",
|
||||
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||
|
||||
static object[] _getWidthAndHeightParameters;
|
||||
#endif
|
||||
|
||||
static ImageUtility.Dimensions GetImageRealWidthAndHeight(string assetPath, TextureImporter textureImporter, bool debugLog = false)
|
||||
{
|
||||
// Using UnityEditor.TextureImporter.GetSourceTextureInformation is preferred, since it will work with all Unity-supported image types.
|
||||
// But since it's a private method, Unity makes no guarantee that it will still be available in future versions.
|
||||
// It's only available starting at Unity 2018.1 (doesn't exist in Unity 2017 and below).
|
||||
// Also, for Unity versions 2018.1 up to 2020.1, the return value itself (the SourceTextureInformation struct),
|
||||
// is in the UnityEditor.Experimental namespace. But starting 2020.2, it has moved out of the Experimental namespace.
|
||||
//
|
||||
// This is why we have multiple fallbacks in case GetSourceTextureInformation doesn't work.
|
||||
//
|
||||
// UnityEditor.TextureImporter.GetWidthAndHeight is a little better, since we don't need to
|
||||
// deal with the UnityEditor.Experimental namespace that way, it also works with all
|
||||
// Unity-supported image types (just like GetSourceTextureInformation), and it exists in Unity 2017.
|
||||
// The only disadvantage is that it requires allocation since it uses ref parameters.
|
||||
//
|
||||
// If for any reason, GetWidthAndHeight doesn't work, ImageUtility.Dimension.Get is our last resort.
|
||||
// It will attempt to open the file, and find the data inside that relates to width and height
|
||||
// (it doesn't require loading the entire image into memory).
|
||||
//
|
||||
// The disadvantage is that among the image types that Unity uses, and the image types
|
||||
// that ImageUtility.Dimension.Get knows, this last resort currently only works
|
||||
// for jpg (currently jfif only), png, gif, and bmp files.
|
||||
//
|
||||
#if BRT_USE_INTERNAL_TEXTURE_IMPORTER_METHODS
|
||||
#if UNITY_2018_1_OR_NEWER
|
||||
if (TextureImporterGetSourceTextureInformation != null)
|
||||
{
|
||||
#if UNITY_2020_2_OR_NEWER // SourceTextureInformation was moved out of Experimental namespace in Unity 2020.2
|
||||
var sourceTextureInfo = (UnityEditor.AssetImporters.SourceTextureInformation)
|
||||
#else
|
||||
var sourceTextureInfo = (UnityEditor.Experimental.AssetImporters.SourceTextureInformation)
|
||||
#endif
|
||||
TextureImporterGetSourceTextureInformation.Invoke(textureImporter, null);
|
||||
|
||||
if (debugLog) Debug.LogFormat("Got dimensions (using GetSourceTextureInformation) for {0} {1}x{2}",
|
||||
assetPath, sourceTextureInfo.width.ToString(), sourceTextureInfo.height.ToString());
|
||||
|
||||
ImageUtility.Dimensions returnValue;
|
||||
returnValue.Width = sourceTextureInfo.width;
|
||||
returnValue.Height = sourceTextureInfo.height;
|
||||
return returnValue;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (TextureImporterGetWidthAndHeight != null)
|
||||
{
|
||||
if (_getWidthAndHeightParameters == null)
|
||||
{
|
||||
_getWidthAndHeightParameters = new object[] { new int(), new int() };
|
||||
}
|
||||
TextureImporterGetWidthAndHeight.Invoke(textureImporter, _getWidthAndHeightParameters);
|
||||
|
||||
ImageUtility.Dimensions returnValue;
|
||||
returnValue.Width = (int)_getWidthAndHeightParameters[0];
|
||||
returnValue.Height = (int)_getWidthAndHeightParameters[1];
|
||||
|
||||
if (debugLog) Debug.LogFormat("Got dimensions (using GetWidthAndHeight) for {0} {1}x{2}",
|
||||
assetPath, returnValue.Width.ToString(), returnValue.Height.ToString());
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
#endif
|
||||
if (assetPath.EndsWith(".jpg", System.StringComparison.OrdinalIgnoreCase) ||
|
||||
assetPath.EndsWith(".jpeg", System.StringComparison.OrdinalIgnoreCase) ||
|
||||
assetPath.EndsWith(".png", System.StringComparison.OrdinalIgnoreCase) ||
|
||||
assetPath.EndsWith(".bmp", System.StringComparison.OrdinalIgnoreCase) ||
|
||||
assetPath.EndsWith(".gif", System.StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
// remove 6 for the "Assets" at the start, before prefixing it with the project path
|
||||
var assetFullPath = string.Format("{0}{1}", Application.dataPath, assetPath.Substring(6));
|
||||
//if (debugLog) Debug.LogFormat("Full path of: {0}\n{1}", assetPath, assetFullPath);
|
||||
|
||||
var returnValue = ImageUtility.Dimension.Get(assetFullPath);
|
||||
|
||||
if (debugLog) Debug.LogFormat("Got dimensions (using ImageDimensions.Get.AsTuple) for {0} {1}x{2}",
|
||||
assetPath, returnValue.Width.ToString(), returnValue.Height.ToString());
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
// none of the options worked. no choice but to return error values
|
||||
return ImageUtility.Dimensions.ErrorValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 76966f4a178ba2846b53e3c1ff9ce031
|
||||
timeCreated: 1569214588
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 90bf8676d542e63418cadd96fce890c4
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cefd81bed49305a4dbe050c93846560e
|
||||
@@ -0,0 +1,236 @@
|
||||
using System;
|
||||
|
||||
namespace BuildReportTool
|
||||
{
|
||||
public static partial class AssetListUtility
|
||||
{
|
||||
public static void SortAssetList(BuildReportTool.SizePart[] assetList, BuildReportTool.AssetList.SortType sortType, BuildReportTool.AssetList.SortOrder sortOrder)
|
||||
{
|
||||
switch (sortType)
|
||||
{
|
||||
case BuildReportTool.AssetList.SortType.RawSize:
|
||||
SortRawSize(assetList, sortOrder);
|
||||
break;
|
||||
case BuildReportTool.AssetList.SortType.ImportedSize:
|
||||
SortImportedSize(assetList, sortOrder);
|
||||
break;
|
||||
case BuildReportTool.AssetList.SortType.ImportedSizeOrRawSize:
|
||||
SortImportedSizeOrRawSize(assetList, sortOrder);
|
||||
break;
|
||||
case BuildReportTool.AssetList.SortType.SizeBeforeBuild:
|
||||
SortSizeBeforeBuild(assetList, sortOrder);
|
||||
break;
|
||||
case BuildReportTool.AssetList.SortType.PercentSize:
|
||||
SortPercentSize(assetList, sortOrder);
|
||||
break;
|
||||
case BuildReportTool.AssetList.SortType.AssetFullPath:
|
||||
SortAssetFullPath(assetList, sortOrder);
|
||||
break;
|
||||
case BuildReportTool.AssetList.SortType.AssetFilename:
|
||||
SortAssetName(assetList, sortOrder);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void SortRawSize(BuildReportTool.SizePart[] assetList, BuildReportTool.AssetList.SortOrder sortOrder)
|
||||
{
|
||||
if (sortOrder == BuildReportTool.AssetList.SortOrder.Descending)
|
||||
{
|
||||
Array.Sort(assetList, delegate(BuildReportTool.SizePart entry1, BuildReportTool.SizePart entry2)
|
||||
{
|
||||
if (entry1.UsableSize > entry2.UsableSize) return -1;
|
||||
if (entry1.UsableSize < entry2.UsableSize) return 1;
|
||||
|
||||
// same size
|
||||
// sort by asset name for assets with same sizes
|
||||
return SortByAssetNameDescending(entry1, entry2);
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
Array.Sort(assetList, delegate(BuildReportTool.SizePart entry1, BuildReportTool.SizePart entry2)
|
||||
{
|
||||
if (entry1.UsableSize > entry2.UsableSize) return 1;
|
||||
if (entry1.UsableSize < entry2.UsableSize) return -1;
|
||||
|
||||
// same size
|
||||
// sort by asset name for assets with same sizes
|
||||
return SortByAssetNameAscending(entry1, entry2);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
static void SortImportedSizeOrRawSize(BuildReportTool.SizePart[] assetList, BuildReportTool.AssetList.SortOrder sortOrder)
|
||||
{
|
||||
if (sortOrder == BuildReportTool.AssetList.SortOrder.Descending)
|
||||
{
|
||||
Array.Sort(assetList, delegate(BuildReportTool.SizePart entry1, BuildReportTool.SizePart entry2)
|
||||
{
|
||||
if (entry1.ImportedSizeOrRawSize > entry2.ImportedSizeOrRawSize) return -1;
|
||||
if (entry1.ImportedSizeOrRawSize < entry2.ImportedSizeOrRawSize) return 1;
|
||||
|
||||
// same size
|
||||
// sort by asset name for assets with same sizes
|
||||
return SortByAssetNameDescending(entry1, entry2);
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
Array.Sort(assetList, delegate(BuildReportTool.SizePart entry1, BuildReportTool.SizePart entry2)
|
||||
{
|
||||
if (entry1.ImportedSizeOrRawSize > entry2.ImportedSizeOrRawSize) return 1;
|
||||
if (entry1.ImportedSizeOrRawSize < entry2.ImportedSizeOrRawSize) return -1;
|
||||
|
||||
// same size
|
||||
// sort by asset name for assets with same sizes
|
||||
return SortByAssetNameAscending(entry1, entry2);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
static void SortImportedSize(BuildReportTool.SizePart[] assetList, BuildReportTool.AssetList.SortOrder sortOrder)
|
||||
{
|
||||
if (sortOrder == BuildReportTool.AssetList.SortOrder.Descending)
|
||||
{
|
||||
Array.Sort(assetList, delegate(BuildReportTool.SizePart entry1, BuildReportTool.SizePart entry2)
|
||||
{
|
||||
if (entry1.ImportedSizeBytes > entry2.ImportedSizeBytes) return -1;
|
||||
if (entry1.ImportedSizeBytes < entry2.ImportedSizeBytes) return 1;
|
||||
|
||||
// same size
|
||||
// sort by asset name for assets with same sizes
|
||||
return SortByAssetNameDescending(entry1, entry2);
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
Array.Sort(assetList, delegate(BuildReportTool.SizePart entry1, BuildReportTool.SizePart entry2)
|
||||
{
|
||||
if (entry1.ImportedSizeBytes > entry2.ImportedSizeBytes) return 1;
|
||||
if (entry1.ImportedSizeBytes < entry2.ImportedSizeBytes) return -1;
|
||||
|
||||
// same size
|
||||
// sort by asset name for assets with same sizes
|
||||
return SortByAssetNameAscending(entry1, entry2);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
static void SortSizeBeforeBuild(BuildReportTool.SizePart[] assetList, BuildReportTool.AssetList.SortOrder sortOrder)
|
||||
{
|
||||
if (sortOrder == BuildReportTool.AssetList.SortOrder.Descending)
|
||||
{
|
||||
Array.Sort(assetList, delegate(BuildReportTool.SizePart entry1, BuildReportTool.SizePart entry2)
|
||||
{
|
||||
if (entry1.SizeInAssetsFolderBytes > entry2.SizeInAssetsFolderBytes) return -1;
|
||||
if (entry1.SizeInAssetsFolderBytes < entry2.SizeInAssetsFolderBytes) return 1;
|
||||
|
||||
// same size
|
||||
// sort by asset name for assets with same sizes
|
||||
return SortByAssetNameDescending(entry1, entry2);
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
Array.Sort(assetList, delegate(BuildReportTool.SizePart entry1, BuildReportTool.SizePart entry2)
|
||||
{
|
||||
if (entry1.SizeInAssetsFolderBytes > entry2.SizeInAssetsFolderBytes) return 1;
|
||||
if (entry1.SizeInAssetsFolderBytes < entry2.SizeInAssetsFolderBytes) return -1;
|
||||
|
||||
// same size
|
||||
// sort by asset name for assets with same sizes
|
||||
return SortByAssetNameAscending(entry1, entry2);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
static void SortPercentSize(BuildReportTool.SizePart[] assetList, BuildReportTool.AssetList.SortOrder sortOrder)
|
||||
{
|
||||
if (sortOrder == BuildReportTool.AssetList.SortOrder.Descending)
|
||||
{
|
||||
Array.Sort(assetList, delegate(BuildReportTool.SizePart entry1, BuildReportTool.SizePart entry2)
|
||||
{
|
||||
if (entry1.Percentage > entry2.Percentage) return -1;
|
||||
if (entry1.Percentage < entry2.Percentage) return 1;
|
||||
|
||||
// same percent
|
||||
// sort by asset name for assets with same percent
|
||||
return SortByAssetFullPathDescending(entry1, entry2);
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
Array.Sort(assetList, delegate(BuildReportTool.SizePart entry1, BuildReportTool.SizePart entry2)
|
||||
{
|
||||
if (entry1.Percentage > entry2.Percentage) return 1;
|
||||
if (entry1.Percentage < entry2.Percentage) return -1;
|
||||
|
||||
// same size
|
||||
// sort by asset name for assets with same sizes
|
||||
return SortByAssetFullPathAscending(entry1, entry2);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
static void SortAssetFullPath(BuildReportTool.SizePart[] assetList, BuildReportTool.AssetList.SortOrder sortOrder)
|
||||
{
|
||||
if (sortOrder == BuildReportTool.AssetList.SortOrder.Descending)
|
||||
{
|
||||
Array.Sort(assetList, SortByAssetFullPathDescending);
|
||||
}
|
||||
else
|
||||
{
|
||||
Array.Sort(assetList, SortByAssetFullPathAscending);
|
||||
}
|
||||
}
|
||||
|
||||
static int SortByAssetFullPathDescending(BuildReportTool.SizePart entry1, BuildReportTool.SizePart entry2)
|
||||
{
|
||||
int result = string.Compare(entry1.Name, entry2.Name, StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int SortByAssetFullPathAscending(BuildReportTool.SizePart entry1, BuildReportTool.SizePart entry2)
|
||||
{
|
||||
int result = string.Compare(entry1.Name, entry2.Name, StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
// invert the result
|
||||
if (result == 1) return -1;
|
||||
if (result == -1) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void SortAssetName(BuildReportTool.SizePart[] assetList, BuildReportTool.AssetList.SortOrder sortOrder)
|
||||
{
|
||||
if (sortOrder == BuildReportTool.AssetList.SortOrder.Descending)
|
||||
{
|
||||
Array.Sort(assetList, SortByAssetNameDescending);
|
||||
}
|
||||
else
|
||||
{
|
||||
Array.Sort(assetList, SortByAssetNameAscending);
|
||||
}
|
||||
}
|
||||
|
||||
static int SortByAssetNameDescending(BuildReportTool.SizePart entry1, BuildReportTool.SizePart entry2)
|
||||
{
|
||||
int result = string.Compare(entry1.Name.GetFileNameOnly(), entry2.Name.GetFileNameOnly(),
|
||||
StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int SortByAssetNameAscending(BuildReportTool.SizePart entry1, BuildReportTool.SizePart entry2)
|
||||
{
|
||||
int result = string.Compare(entry1.Name.GetFileNameOnly(), entry2.Name.GetFileNameOnly(),
|
||||
StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
// invert the result
|
||||
if (result == 1) return -1;
|
||||
if (result == -1) return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 79890ab40b491994db602a062a793219
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,71 @@
|
||||
using System;
|
||||
|
||||
namespace BuildReportTool
|
||||
{
|
||||
public static partial class AssetListUtility
|
||||
{
|
||||
public static void SortAssetList(BuildReportTool.SizePart[] assetList, BuildReportTool.MeshData meshData, MeshData.DataId meshSortType, BuildReportTool.AssetList.SortOrder sortOrder)
|
||||
{
|
||||
switch (meshSortType)
|
||||
{
|
||||
case BuildReportTool.MeshData.DataId.MeshFilterCount:
|
||||
SortMeshData(assetList, meshData, sortOrder, entry => entry.MeshFilterCount);
|
||||
break;
|
||||
case BuildReportTool.MeshData.DataId.SkinnedMeshRendererCount:
|
||||
SortMeshData(assetList, meshData, sortOrder, entry => entry.SkinnedMeshRendererCount);
|
||||
break;
|
||||
case BuildReportTool.MeshData.DataId.SubMeshCount:
|
||||
SortMeshData(assetList, meshData, sortOrder, entry => entry.SubMeshCount);
|
||||
break;
|
||||
case BuildReportTool.MeshData.DataId.VertexCount:
|
||||
SortMeshData(assetList, meshData, sortOrder, entry => entry.VertexCount);
|
||||
break;
|
||||
case BuildReportTool.MeshData.DataId.TriangleCount:
|
||||
SortMeshData(assetList, meshData, sortOrder, entry => entry.TriangleCount);
|
||||
break;
|
||||
case BuildReportTool.MeshData.DataId.AnimationType:
|
||||
SortMeshData(assetList, meshData, sortOrder, entry => entry.AnimationType);
|
||||
break;
|
||||
case BuildReportTool.MeshData.DataId.AnimationClipCount:
|
||||
SortMeshData(assetList, meshData, sortOrder, entry => entry.AnimationClipCount);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void SortMeshData(BuildReportTool.SizePart[] assetList, BuildReportTool.MeshData meshData, BuildReportTool.AssetList.SortOrder sortOrder, Func<BuildReportTool.MeshData.Entry, int> func)
|
||||
{
|
||||
var meshEntries = meshData.GetMeshData();
|
||||
|
||||
for (int n = 0; n < assetList.Length; ++n)
|
||||
{
|
||||
int intValue = 0;
|
||||
if (meshEntries.ContainsKey(assetList[n].Name))
|
||||
{
|
||||
intValue = func(meshEntries[assetList[n].Name]);
|
||||
}
|
||||
|
||||
assetList[n].SetIntAuxData(intValue);
|
||||
}
|
||||
|
||||
SortByInt(assetList, sortOrder);
|
||||
}
|
||||
|
||||
static void SortMeshData(BuildReportTool.SizePart[] assetList, BuildReportTool.MeshData meshData, BuildReportTool.AssetList.SortOrder sortOrder, Func<BuildReportTool.MeshData.Entry, string> func)
|
||||
{
|
||||
var meshEntries = meshData.GetMeshData();
|
||||
|
||||
for (int n = 0; n < assetList.Length; ++n)
|
||||
{
|
||||
string textData = null;
|
||||
if (meshEntries.ContainsKey(assetList[n].Name))
|
||||
{
|
||||
textData = func(meshEntries[assetList[n].Name]);
|
||||
}
|
||||
|
||||
assetList[n].SetTextAuxData(textData);
|
||||
}
|
||||
|
||||
SortByText(assetList, sortOrder);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f73334247e6cf5545871508d6e601fc5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,53 @@
|
||||
using System;
|
||||
|
||||
namespace BuildReportTool
|
||||
{
|
||||
public static partial class AssetListUtility
|
||||
{
|
||||
public static void SortAssetList(BuildReportTool.SizePart[] assetList, BuildReportTool.PrefabData prefabData, PrefabData.DataId prefabSortType, BuildReportTool.AssetList.SortOrder sortOrder)
|
||||
{
|
||||
switch (prefabSortType)
|
||||
{
|
||||
case BuildReportTool.PrefabData.DataId.ContributeGI:
|
||||
SortPrefabData(assetList, prefabData, sortOrder, entry => entry.ContributeGIValue);
|
||||
break;
|
||||
case BuildReportTool.PrefabData.DataId.BatchingStatic:
|
||||
SortPrefabData(assetList, prefabData, sortOrder, entry => entry.BatchingStaticValue);
|
||||
break;
|
||||
case BuildReportTool.PrefabData.DataId.ReflectionProbeStatic:
|
||||
SortPrefabData(assetList, prefabData, sortOrder, entry => entry.ReflectionProbeStaticValue);
|
||||
break;
|
||||
case BuildReportTool.PrefabData.DataId.OccluderStatic:
|
||||
SortPrefabData(assetList, prefabData, sortOrder, entry => entry.OccluderStaticValue);
|
||||
break;
|
||||
case BuildReportTool.PrefabData.DataId.OccludeeStatic:
|
||||
SortPrefabData(assetList, prefabData, sortOrder, entry => entry.OccludeeStaticValue);
|
||||
break;
|
||||
case BuildReportTool.PrefabData.DataId.NavigationStatic:
|
||||
SortPrefabData(assetList, prefabData, sortOrder, entry => entry.NavigationStaticValue);
|
||||
break;
|
||||
case BuildReportTool.PrefabData.DataId.OffMeshLinkGeneration:
|
||||
SortPrefabData(assetList, prefabData, sortOrder, entry => entry.OffMeshLinkGenerationValue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void SortPrefabData(BuildReportTool.SizePart[] assetList, BuildReportTool.PrefabData prefabData, BuildReportTool.AssetList.SortOrder sortOrder, Func<BuildReportTool.PrefabData.Entry, int> func)
|
||||
{
|
||||
var prefabEntries = prefabData.GetPrefabData();
|
||||
|
||||
for (int n = 0; n < assetList.Length; ++n)
|
||||
{
|
||||
int intValue = 0;
|
||||
if (prefabEntries.ContainsKey(assetList[n].Name))
|
||||
{
|
||||
intValue = func(prefabEntries[assetList[n].Name]);
|
||||
}
|
||||
|
||||
assetList[n].SetIntAuxData(intValue);
|
||||
}
|
||||
|
||||
SortByInt(assetList, sortOrder);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9b43049560f4da54c8419cb9700ba7f9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,466 @@
|
||||
using System;
|
||||
|
||||
namespace BuildReportTool
|
||||
{
|
||||
public static partial class AssetListUtility
|
||||
{
|
||||
public static void SortAssetList(BuildReportTool.SizePart[] assetList, BuildReportTool.TextureData textureData, TextureData.DataId textureSortType, BuildReportTool.AssetList.SortOrder sortOrder)
|
||||
{
|
||||
switch (textureSortType)
|
||||
{
|
||||
case BuildReportTool.TextureData.DataId.TextureType:
|
||||
SortTextureData(assetList, textureData, sortOrder, entry => entry.TextureType);
|
||||
break;
|
||||
case BuildReportTool.TextureData.DataId.IsSRGB:
|
||||
SortTextureData(assetList, textureData, sortOrder, entry => entry.IsSRGB);
|
||||
break;
|
||||
case BuildReportTool.TextureData.DataId.AlphaSource:
|
||||
SortTextureData(assetList, textureData, sortOrder, entry => entry.AlphaSource);
|
||||
break;
|
||||
case BuildReportTool.TextureData.DataId.AlphaIsTransparency:
|
||||
SortTextureData(assetList, textureData, sortOrder, entry => entry.AlphaIsTransparency);
|
||||
break;
|
||||
case BuildReportTool.TextureData.DataId.IgnorePngGamma:
|
||||
SortTextureData(assetList, textureData, sortOrder, entry => entry.IgnorePngGamma);
|
||||
break;
|
||||
case BuildReportTool.TextureData.DataId.NPotScale:
|
||||
SortNPotScale(assetList, textureData, sortOrder);
|
||||
break;
|
||||
case BuildReportTool.TextureData.DataId.IsReadable:
|
||||
SortTextureData(assetList, textureData, sortOrder, entry => entry.IsReadable);
|
||||
break;
|
||||
case BuildReportTool.TextureData.DataId.MipMapGenerated:
|
||||
SortTextureData(assetList, textureData, sortOrder, entry => entry.MipMapGenerated);
|
||||
break;
|
||||
case BuildReportTool.TextureData.DataId.MipMapFilter:
|
||||
SortTextureData(assetList, textureData, sortOrder, entry => entry.MipMapFilter);
|
||||
break;
|
||||
case BuildReportTool.TextureData.DataId.StreamingMipMaps:
|
||||
SortTextureData(assetList, textureData, sortOrder, entry => entry.StreamingMipMaps);
|
||||
break;
|
||||
case BuildReportTool.TextureData.DataId.BorderMipMaps:
|
||||
SortTextureData(assetList, textureData, sortOrder, entry => entry.BorderMipMaps);
|
||||
break;
|
||||
case BuildReportTool.TextureData.DataId.PreserveCoverageMipMaps:
|
||||
SortTextureData(assetList, textureData, sortOrder, entry => entry.PreserveCoverageMipMaps);
|
||||
break;
|
||||
case BuildReportTool.TextureData.DataId.FadeOutMipMaps:
|
||||
SortTextureData(assetList, textureData, sortOrder, entry => entry.FadeOutMipMaps);
|
||||
break;
|
||||
case BuildReportTool.TextureData.DataId.SpriteImportMode:
|
||||
SortTextureData(assetList, textureData, sortOrder, entry => entry.SpriteImportMode);
|
||||
break;
|
||||
case BuildReportTool.TextureData.DataId.SpritePackingTag:
|
||||
SortTextureData(assetList, textureData, sortOrder, entry => entry.SpritePackingTag);
|
||||
break;
|
||||
case BuildReportTool.TextureData.DataId.SpritePixelsPerUnit:
|
||||
SortTextureData(assetList, textureData, sortOrder, entry => entry.SpritePixelsPerUnit);
|
||||
break;
|
||||
case BuildReportTool.TextureData.DataId.QualifiesForSpritePacking:
|
||||
SortTextureData(assetList, textureData, sortOrder, entry => entry.QualifiesForSpritePacking);
|
||||
break;
|
||||
case BuildReportTool.TextureData.DataId.WrapMode:
|
||||
SortTextureData(assetList, textureData, sortOrder, entry => entry.WrapMode);
|
||||
break;
|
||||
case BuildReportTool.TextureData.DataId.WrapModeU:
|
||||
SortTextureData(assetList, textureData, sortOrder, entry => entry.WrapModeU);
|
||||
break;
|
||||
case BuildReportTool.TextureData.DataId.WrapModeV:
|
||||
SortTextureData(assetList, textureData, sortOrder, entry => entry.WrapModeV);
|
||||
break;
|
||||
case BuildReportTool.TextureData.DataId.WrapModeW:
|
||||
SortTextureData(assetList, textureData, sortOrder, entry => entry.WrapModeW);
|
||||
break;
|
||||
case BuildReportTool.TextureData.DataId.FilterMode:
|
||||
SortTextureData(assetList, textureData, sortOrder, entry => entry.FilterMode);
|
||||
break;
|
||||
case BuildReportTool.TextureData.DataId.AnisoLevel:
|
||||
SortTextureData(assetList, textureData, sortOrder, entry => entry.AnisoLevel);
|
||||
break;
|
||||
case BuildReportTool.TextureData.DataId.MaxTextureSize:
|
||||
SortTextureData(assetList, textureData, sortOrder, entry => entry.GetShownMaxTextureSize());
|
||||
break;
|
||||
case BuildReportTool.TextureData.DataId.TextureResizeAlgorithm:
|
||||
SortTextureData(assetList, textureData, sortOrder, entry => entry.GetShownTextureResizeAlgorithm());
|
||||
break;
|
||||
case BuildReportTool.TextureData.DataId.TextureFormat:
|
||||
SortTextureData(assetList, textureData, sortOrder, entry => entry.GetShownTextureFormat());
|
||||
break;
|
||||
case BuildReportTool.TextureData.DataId.CompressionType:
|
||||
SortTextureData(assetList, textureData, sortOrder, entry => entry.GetShownCompressionType());
|
||||
break;
|
||||
case BuildReportTool.TextureData.DataId.CompressionIsCrunched:
|
||||
SortTextureData(assetList, textureData, sortOrder, entry => entry.GetShownCompressionIsCrunched());
|
||||
break;
|
||||
case BuildReportTool.TextureData.DataId.CompressionQuality:
|
||||
SortTextureData(assetList, textureData, sortOrder, entry => entry.GetShownCompressionQuality());
|
||||
break;
|
||||
case BuildReportTool.TextureData.DataId.ImportedWidthAndHeight:
|
||||
SortTextureData(assetList, textureData, sortOrder, entry => entry.GetImportedPixelCount());
|
||||
break;
|
||||
case BuildReportTool.TextureData.DataId.RealWidthAndHeight:
|
||||
SortTextureData(assetList, textureData, sortOrder, entry => entry.GetRealPixelCount());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int CompareNPotScale(string nPotScale1, string nPotScale2)
|
||||
{
|
||||
var nPotScale1IsNoneNot = nPotScale1 == BuildReportTool.TextureData.NPOT_SCALE_NONE_NOT_POT;
|
||||
var nPotScale2IsNoneNot = nPotScale1 == BuildReportTool.TextureData.NPOT_SCALE_NONE_NOT_POT;
|
||||
|
||||
if (nPotScale1IsNoneNot && !nPotScale2IsNoneNot)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if (!nPotScale1IsNoneNot && nPotScale2IsNoneNot)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
return string.Compare(nPotScale1, nPotScale2, StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
// =============================================================================================================
|
||||
|
||||
static void SortByInt(BuildReportTool.SizePart[] assetList, BuildReportTool.AssetList.SortOrder sortOrder)
|
||||
{
|
||||
if (sortOrder == BuildReportTool.AssetList.SortOrder.Descending)
|
||||
{
|
||||
Array.Sort(assetList, delegate(BuildReportTool.SizePart entry1, BuildReportTool.SizePart entry2)
|
||||
{
|
||||
int sortResult = entry2.GetIntAuxData().CompareTo(entry1.GetIntAuxData());
|
||||
if (sortResult != 0)
|
||||
{
|
||||
return sortResult;
|
||||
}
|
||||
|
||||
// same texture data
|
||||
// sort by asset size for assets with texture data
|
||||
if (entry1.UsableSize > entry2.UsableSize) return -1;
|
||||
if (entry1.UsableSize < entry2.UsableSize) return 1;
|
||||
|
||||
// same size
|
||||
// sort by asset name for assets with same sizes
|
||||
return SortByAssetNameDescending(entry1, entry2);
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
Array.Sort(assetList, delegate(BuildReportTool.SizePart entry1, BuildReportTool.SizePart entry2)
|
||||
{
|
||||
int sortResult = entry1.GetIntAuxData().CompareTo(entry2.GetIntAuxData());
|
||||
if (sortResult != 0)
|
||||
{
|
||||
return sortResult;
|
||||
}
|
||||
|
||||
// same texture data
|
||||
// sort by asset size for assets with same texture data
|
||||
if (entry1.UsableSize > entry2.UsableSize) return 1;
|
||||
if (entry1.UsableSize < entry2.UsableSize) return -1;
|
||||
|
||||
// same size
|
||||
// sort by asset name for assets with same sizes
|
||||
return SortByAssetNameAscending(entry1, entry2);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
static void SortByFloat(BuildReportTool.SizePart[] assetList, BuildReportTool.AssetList.SortOrder sortOrder)
|
||||
{
|
||||
if (sortOrder == BuildReportTool.AssetList.SortOrder.Descending)
|
||||
{
|
||||
Array.Sort(assetList, delegate(BuildReportTool.SizePart entry1, BuildReportTool.SizePart entry2)
|
||||
{
|
||||
int sortResult = entry1.GetFloatAuxData().CompareTo(entry2.GetFloatAuxData());
|
||||
if (sortResult != 0)
|
||||
{
|
||||
return sortResult;
|
||||
}
|
||||
|
||||
// same texture data
|
||||
// sort by asset size for assets with texture data
|
||||
if (entry1.UsableSize > entry2.UsableSize) return -1;
|
||||
if (entry1.UsableSize < entry2.UsableSize) return 1;
|
||||
|
||||
// same size
|
||||
// sort by asset name for assets with same sizes
|
||||
return SortByAssetNameDescending(entry1, entry2);
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
Array.Sort(assetList, delegate(BuildReportTool.SizePart entry1, BuildReportTool.SizePart entry2)
|
||||
{
|
||||
int sortResult = entry2.GetFloatAuxData().CompareTo(entry1.GetFloatAuxData());
|
||||
if (sortResult != 0)
|
||||
{
|
||||
return sortResult;
|
||||
}
|
||||
|
||||
// same texture data
|
||||
// sort by asset size for assets with same texture data
|
||||
if (entry1.UsableSize > entry2.UsableSize) return 1;
|
||||
if (entry1.UsableSize < entry2.UsableSize) return -1;
|
||||
|
||||
// same size
|
||||
// sort by asset name for assets with same sizes
|
||||
return SortByAssetNameAscending(entry1, entry2);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
static void SortByText(BuildReportTool.SizePart[] assetList, BuildReportTool.AssetList.SortOrder sortOrder)
|
||||
{
|
||||
if (sortOrder == BuildReportTool.AssetList.SortOrder.Descending)
|
||||
{
|
||||
Array.Sort(assetList, delegate(BuildReportTool.SizePart entry1, BuildReportTool.SizePart entry2)
|
||||
{
|
||||
int sortTextureTypeResult = string.Compare(entry1.GetTextAuxData(), entry2.GetTextAuxData(), StringComparison.OrdinalIgnoreCase);
|
||||
if (sortTextureTypeResult != 0)
|
||||
{
|
||||
return sortTextureTypeResult;
|
||||
}
|
||||
|
||||
// same texture type
|
||||
// sort by asset size for assets with same texture types
|
||||
if (entry1.UsableSize > entry2.UsableSize) return -1;
|
||||
if (entry1.UsableSize < entry2.UsableSize) return 1;
|
||||
|
||||
// same size
|
||||
// sort by asset name for assets with same sizes
|
||||
return SortByAssetNameDescending(entry1, entry2);
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
Array.Sort(assetList, delegate(BuildReportTool.SizePart entry1, BuildReportTool.SizePart entry2)
|
||||
{
|
||||
int sortTextureTypeResult = string.Compare(entry2.GetTextAuxData(), entry1.GetTextAuxData(), StringComparison.OrdinalIgnoreCase);
|
||||
if (sortTextureTypeResult != 0)
|
||||
{
|
||||
return sortTextureTypeResult;
|
||||
}
|
||||
|
||||
// same texture type
|
||||
// sort by asset size for assets with same texture types
|
||||
if (entry1.UsableSize > entry2.UsableSize) return 1;
|
||||
if (entry1.UsableSize < entry2.UsableSize) return -1;
|
||||
|
||||
// same size
|
||||
// sort by asset name for assets with same sizes
|
||||
return SortByAssetNameAscending(entry1, entry2);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
static void SortByText(BuildReportTool.SizePart[] assetList, BuildReportTool.AssetList.SortOrder sortOrder, Func<string, string, int> compare)
|
||||
{
|
||||
if (sortOrder == BuildReportTool.AssetList.SortOrder.Descending)
|
||||
{
|
||||
Array.Sort(assetList, delegate(BuildReportTool.SizePart entry1, BuildReportTool.SizePart entry2)
|
||||
{
|
||||
int sortTextureTypeResult = compare(entry1.GetTextAuxData(), entry2.GetTextAuxData());
|
||||
if (sortTextureTypeResult != 0)
|
||||
{
|
||||
return sortTextureTypeResult;
|
||||
}
|
||||
|
||||
// same texture type
|
||||
// sort by asset size for assets with same texture types
|
||||
if (entry1.UsableSize > entry2.UsableSize) return -1;
|
||||
if (entry1.UsableSize < entry2.UsableSize) return 1;
|
||||
|
||||
// same size
|
||||
// sort by asset name for assets with same sizes
|
||||
return SortByAssetNameDescending(entry1, entry2);
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
Array.Sort(assetList, delegate(BuildReportTool.SizePart entry1, BuildReportTool.SizePart entry2)
|
||||
{
|
||||
int sortTextureTypeResult = compare(entry2.GetTextAuxData(), entry1.GetTextAuxData());
|
||||
if (sortTextureTypeResult != 0)
|
||||
{
|
||||
return sortTextureTypeResult;
|
||||
}
|
||||
|
||||
// same texture type
|
||||
// sort by asset size for assets with same texture types
|
||||
if (entry1.UsableSize > entry2.UsableSize) return 1;
|
||||
if (entry1.UsableSize < entry2.UsableSize) return -1;
|
||||
|
||||
// same size
|
||||
// sort by asset name for assets with same sizes
|
||||
return SortByAssetNameAscending(entry1, entry2);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// =============================================================================================================
|
||||
|
||||
static void SortTextureData(BuildReportTool.SizePart[] assetList, BuildReportTool.TextureData textureData, BuildReportTool.AssetList.SortOrder sortOrder, Func<BuildReportTool.TextureData.Entry, bool> func)
|
||||
{
|
||||
var textureEntries = textureData.GetTextureData();
|
||||
|
||||
for (int n = 0; n < assetList.Length; ++n)
|
||||
{
|
||||
int boolValue = 0;
|
||||
if (textureEntries.ContainsKey(assetList[n].Name))
|
||||
{
|
||||
boolValue = func(textureEntries[assetList[n].Name]) ? 1 : 0;
|
||||
}
|
||||
|
||||
assetList[n].SetIntAuxData(boolValue);
|
||||
}
|
||||
|
||||
SortByInt(assetList, sortOrder);
|
||||
}
|
||||
|
||||
static void SortTextureData(BuildReportTool.SizePart[] assetList, BuildReportTool.TextureData textureData, BuildReportTool.AssetList.SortOrder sortOrder, Func<BuildReportTool.TextureData.Entry, string> func)
|
||||
{
|
||||
var textureEntries = textureData.GetTextureData();
|
||||
|
||||
for (int n = 0; n < assetList.Length; ++n)
|
||||
{
|
||||
string textData = null;
|
||||
if (textureEntries.ContainsKey(assetList[n].Name))
|
||||
{
|
||||
textData = func(textureEntries[assetList[n].Name]);
|
||||
}
|
||||
|
||||
assetList[n].SetTextAuxData(textData);
|
||||
}
|
||||
|
||||
SortByText(assetList, sortOrder);
|
||||
}
|
||||
|
||||
static void SortTextureData(BuildReportTool.SizePart[] assetList, BuildReportTool.TextureData textureData, BuildReportTool.AssetList.SortOrder sortOrder, Func<BuildReportTool.TextureData.Entry, float> func)
|
||||
{
|
||||
var textureEntries = textureData.GetTextureData();
|
||||
|
||||
for (int n = 0; n < assetList.Length; ++n)
|
||||
{
|
||||
float floatValue = 0;
|
||||
if (textureEntries.ContainsKey(assetList[n].Name))
|
||||
{
|
||||
floatValue = func(textureEntries[assetList[n].Name]);
|
||||
}
|
||||
|
||||
assetList[n].SetFloatAuxData(floatValue);
|
||||
}
|
||||
|
||||
SortByFloat(assetList, sortOrder);
|
||||
}
|
||||
|
||||
static void SortTextureData(BuildReportTool.SizePart[] assetList, BuildReportTool.TextureData textureData, BuildReportTool.AssetList.SortOrder sortOrder, Func<BuildReportTool.TextureData.Entry, int> func)
|
||||
{
|
||||
var textureEntries = textureData.GetTextureData();
|
||||
|
||||
for (int n = 0; n < assetList.Length; ++n)
|
||||
{
|
||||
int intValue = 0;
|
||||
if (textureEntries.ContainsKey(assetList[n].Name))
|
||||
{
|
||||
intValue = func(textureEntries[assetList[n].Name]);
|
||||
}
|
||||
|
||||
assetList[n].SetIntAuxData(intValue);
|
||||
}
|
||||
|
||||
SortByInt(assetList, sortOrder);
|
||||
}
|
||||
|
||||
// NPotScale sort is special: we want the "None (Not Power of 2)" values to go at top, ignoring alphabetical order for that special value
|
||||
static void SortNPotScale(BuildReportTool.SizePart[] assetList, BuildReportTool.TextureData textureData, BuildReportTool.AssetList.SortOrder sortOrder)
|
||||
{
|
||||
var textureEntries = textureData.GetTextureData();
|
||||
|
||||
for (int n = 0; n < assetList.Length; ++n)
|
||||
{
|
||||
string textData = null;
|
||||
if (textureEntries.ContainsKey(assetList[n].Name))
|
||||
{
|
||||
textData = textureEntries[assetList[n].Name].NPotScale;
|
||||
}
|
||||
|
||||
assetList[n].SetTextAuxData(textData);
|
||||
}
|
||||
|
||||
if (sortOrder == BuildReportTool.AssetList.SortOrder.Descending)
|
||||
{
|
||||
Array.Sort(assetList, delegate(BuildReportTool.SizePart entry1, BuildReportTool.SizePart entry2)
|
||||
{
|
||||
string nPotScale1 = entry1.GetTextAuxData();
|
||||
string nPotScale2 = entry2.GetTextAuxData();
|
||||
|
||||
// put non-power-of-2 at top
|
||||
bool nPotScale1IsNoneNot = nPotScale1 == BuildReportTool.TextureData.NPOT_SCALE_NONE_NOT_POT;
|
||||
bool nPotScale2IsNoneNot = nPotScale2 == BuildReportTool.TextureData.NPOT_SCALE_NONE_NOT_POT;
|
||||
if (nPotScale1IsNoneNot && !nPotScale2IsNoneNot)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if (!nPotScale1IsNoneNot && nPotScale2IsNoneNot)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
// at this point, entry1 and entry 2 are not non-power-of-2 (or both of them are), so compare them as usual
|
||||
int sortTextureTypeResult = string.Compare(nPotScale1, nPotScale2, StringComparison.OrdinalIgnoreCase);
|
||||
if (sortTextureTypeResult != 0)
|
||||
{
|
||||
return sortTextureTypeResult;
|
||||
}
|
||||
|
||||
// same nPotScale type
|
||||
// sort by asset size for assets with same nPotScale types
|
||||
if (entry1.UsableSize > entry2.UsableSize) return -1;
|
||||
if (entry1.UsableSize < entry2.UsableSize) return 1;
|
||||
|
||||
// same size
|
||||
// sort by asset name for assets with same sizes
|
||||
return SortByAssetNameDescending(entry1, entry2);
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
Array.Sort(assetList, delegate(BuildReportTool.SizePart entry1, BuildReportTool.SizePart entry2)
|
||||
{
|
||||
string nPotScale1 = entry1.GetTextAuxData();
|
||||
string nPotScale2 = entry2.GetTextAuxData();
|
||||
|
||||
// put non-power-of-2 at bottom
|
||||
bool nPotScale1IsNoneNot = nPotScale1 == BuildReportTool.TextureData.NPOT_SCALE_NONE_NOT_POT;
|
||||
bool nPotScale2IsNoneNot = nPotScale2 == BuildReportTool.TextureData.NPOT_SCALE_NONE_NOT_POT;
|
||||
if (nPotScale1IsNoneNot && !nPotScale2IsNoneNot)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if (!nPotScale1IsNoneNot && nPotScale2IsNoneNot)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
// at this point, entry1 and entry 2 are not non-power-of-2 (or both of them are), so compare them as usual
|
||||
int sortTextureTypeResult = string.Compare(nPotScale2, nPotScale1, StringComparison.OrdinalIgnoreCase);
|
||||
if (sortTextureTypeResult != 0)
|
||||
{
|
||||
return sortTextureTypeResult;
|
||||
}
|
||||
|
||||
// same nPotScale type
|
||||
// sort by asset size for assets with same nPotScale types
|
||||
if (entry1.UsableSize > entry2.UsableSize) return 1;
|
||||
if (entry1.UsableSize < entry2.UsableSize) return -1;
|
||||
|
||||
// same size
|
||||
// sort by asset name for assets with same sizes
|
||||
return SortByAssetNameAscending(entry1, entry2);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user