先修复一下,错误的场景 删除不必要的钓场资产 修复into场景 update:更新meta文件,修复报错 update:修复资源 修复第一章节建造 修复建造第三章 update:删除多余内容 update:更新README.md update:还原图标 update:更新README update:更新配置
157 lines
5.4 KiB
C#
157 lines
5.4 KiB
C#
#if UNITY_EDITOR
|
||
using System.IO;
|
||
using UnityEditor;
|
||
using UnityEditor.Callbacks;
|
||
using UnityEngine;
|
||
|
||
#if UNITY_IOS
|
||
using UnityEditor.iOS.Xcode;
|
||
#endif
|
||
|
||
/// <summary>
|
||
/// 在 tysdk <see cref="tysdk.editor.iOSPostBuildProcessor"/> (PostProcessBuild 1000) 之后执行,
|
||
/// 将备选 App 图标打入 iOS 包并写入 Info.plist,供 App Store 产品页优化(图标 A/B)使用。
|
||
/// </summary>
|
||
public static class IOSBuildProcessor
|
||
{
|
||
const int PostProcessOrder = 1001;
|
||
|
||
/// <summary>与 App Store Connect 中「备选图标」标识符保持一致(建议仅字母数字)。</summary>
|
||
public const string AlternateIconIdentifier = "FishingTravelAlt";
|
||
|
||
static readonly string SourceIconProjectPath = "Assets/app_icons/icon_fishing_travel_alt.png";
|
||
|
||
#if UNITY_IOS
|
||
const string DestRelativeFolder = "AlternateAppIcons";
|
||
|
||
static readonly (string fileName, int width, int height)[] IconOutputs =
|
||
{
|
||
("FishingTravelAlt60x60@2x.png", 120, 120),
|
||
("FishingTravelAlt60x60@3x.png", 180, 180),
|
||
("FishingTravelAlt76x76@2x~ipad.png", 152, 152),
|
||
("FishingTravelAlt83.5x83.5@2x~ipad.png", 167, 167),
|
||
};
|
||
#endif
|
||
|
||
[PostProcessBuild(PostProcessOrder)]
|
||
public static void OnPostProcessBuild(BuildTarget target, string pathToBuiltProject)
|
||
{
|
||
#if UNITY_IOS
|
||
if (target != BuildTarget.iOS)
|
||
return;
|
||
|
||
string srcAbs = Path.Combine(Application.dataPath, "app_icons/icon_fishing_travel_alt.png");
|
||
if (!File.Exists(srcAbs))
|
||
{
|
||
Debug.LogError(
|
||
$"[IOSBuildProcessor] 未找到备选图标: {srcAbs}(项目内 {SourceIconProjectPath})。");
|
||
return;
|
||
}
|
||
|
||
byte[] pngBytes = File.ReadAllBytes(srcAbs);
|
||
var srcTex = new Texture2D(2, 2, TextureFormat.RGBA32, false);
|
||
if (!srcTex.LoadImage(pngBytes))
|
||
{
|
||
Debug.LogError("[IOSBuildProcessor] 无法解码 PNG: " + srcAbs);
|
||
Object.DestroyImmediate(srcTex);
|
||
return;
|
||
}
|
||
|
||
string destDir = Path.Combine(pathToBuiltProject, DestRelativeFolder);
|
||
Directory.CreateDirectory(destDir);
|
||
|
||
foreach (var entry in IconOutputs)
|
||
{
|
||
Texture2D scaled = ScaleTexture(srcTex, entry.width, entry.height);
|
||
try
|
||
{
|
||
File.WriteAllBytes(Path.Combine(destDir, entry.fileName), scaled.EncodeToPNG());
|
||
}
|
||
finally
|
||
{
|
||
Object.DestroyImmediate(scaled);
|
||
}
|
||
}
|
||
|
||
Object.DestroyImmediate(srcTex);
|
||
|
||
AddIconsToXcodeProject(pathToBuiltProject);
|
||
MergeAlternateIconsPlist(pathToBuiltProject);
|
||
#else
|
||
if (target == BuildTarget.iOS)
|
||
Debug.LogWarning("[IOSBuildProcessor] 当前编辑器未启用 iOS 模块,已跳过备选图标处理。");
|
||
#endif
|
||
}
|
||
|
||
#if UNITY_IOS
|
||
static Texture2D ScaleTexture(Texture2D source, int width, int height)
|
||
{
|
||
var rt = RenderTexture.GetTemporary(width, height, 0, RenderTextureFormat.ARGB32,
|
||
RenderTextureReadWrite.sRGB);
|
||
var prev = RenderTexture.active;
|
||
Graphics.Blit(source, rt);
|
||
RenderTexture.active = rt;
|
||
var dest = new Texture2D(width, height, TextureFormat.RGBA32, false);
|
||
dest.ReadPixels(new Rect(0, 0, width, height), 0, 0);
|
||
dest.Apply();
|
||
RenderTexture.active = prev;
|
||
RenderTexture.ReleaseTemporary(rt);
|
||
return dest;
|
||
}
|
||
|
||
static void AddIconsToXcodeProject(string pathToBuiltProject)
|
||
{
|
||
string pbxPath = PBXProject.GetPBXProjectPath(pathToBuiltProject);
|
||
var proj = new PBXProject();
|
||
proj.ReadFromFile(pbxPath);
|
||
|
||
string mainTarget = proj.GetUnityMainTargetGuid();
|
||
|
||
foreach (var entry in IconOutputs)
|
||
{
|
||
string relPath = Path.Combine(DestRelativeFolder, entry.fileName).Replace('\\', '/');
|
||
string guid = proj.AddFile(relPath, relPath, PBXSourceTree.Source);
|
||
proj.AddFileToBuild(mainTarget, guid);
|
||
}
|
||
|
||
proj.WriteToFile(pbxPath);
|
||
}
|
||
|
||
static void MergeAlternateIconsPlist(string pathToBuiltProject)
|
||
{
|
||
string plistPath = Path.Combine(pathToBuiltProject, "Info.plist");
|
||
var plist = new PlistDocument();
|
||
plist.ReadFromString(File.ReadAllText(plistPath));
|
||
PlistElementDict root = plist.root;
|
||
|
||
root.SetBoolean("UIApplicationSupportsAlternateIcons", true);
|
||
|
||
PlistElementDict bundleIcons;
|
||
if (!root.values.ContainsKey("CFBundleIcons"))
|
||
bundleIcons = root.CreateDict("CFBundleIcons");
|
||
else
|
||
bundleIcons = root.values["CFBundleIcons"].AsDict();
|
||
|
||
PlistElementDict alternateIcons;
|
||
if (!bundleIcons.values.ContainsKey("CFBundleAlternateIcons"))
|
||
alternateIcons = bundleIcons.CreateDict("CFBundleAlternateIcons");
|
||
else
|
||
alternateIcons = bundleIcons.values["CFBundleAlternateIcons"].AsDict();
|
||
|
||
if (alternateIcons.values.ContainsKey(AlternateIconIdentifier))
|
||
alternateIcons.values.Remove(AlternateIconIdentifier);
|
||
|
||
PlistElementDict iconDict = alternateIcons.CreateDict(AlternateIconIdentifier);
|
||
PlistElementArray files = iconDict.CreateArray("CFBundleIconFiles");
|
||
files.AddString("FishingTravelAlt60x60");
|
||
files.AddString("FishingTravelAlt76x76");
|
||
files.AddString("FishingTravelAlt83.5x83.5");
|
||
iconDict.SetBoolean("UIPrerenderedIcon", false);
|
||
|
||
File.WriteAllText(plistPath, plist.WriteToString());
|
||
}
|
||
#endif
|
||
}
|
||
|
||
#endif
|