Skip to content

Home

Submitting a Unity 3D Game to the Mac App Store

Welcome back to another episode of Continuous Improvement! I'm your host, Victor, and in today's episode, we'll be diving into the process of deploying a Unity 3D game to the App Store.

Now, if you've ever been through the process of releasing a game, you know it's not always straightforward. It requires careful planning, attention to detail, and some technical know-how. In fact, just the other day, I went through this process myself, and let me tell you, it was quite the journey. But don't worry, because today, I'm going to walk you through the key steps I took to successfully deploy my game to the App Store.

Step one: Unity Build Settings. In Unity, navigate to "File," then "Build Settings." From there, select "Platform: PC, Mac & Linux Standalone," and set the "Target Platform" to "Mac OS." Now, click on "Player Settings..." and make sure to configure the following options: set "Default is Full Screen" to true, "Default is Native Resolution" to true, "Capture Single Screen" to false, "Display Resolution Dialog" to false, and enable "Mac App Store Validation."

Step two: Info.plist. In Finder, right-click on your game app and select "Show Package Content." Locate and open the Info.plist file. Ensure that the CFBundleGetInfoString is a valid string and that the CFBundleIdentifier and CFBundleSignature have values that match your bundle ID. Additionally, make sure that the CFBundleShortVersionString and CFBundleVersion are in the correct format, such as "x.x.x." Lastly, add a new key called "LSApplicationCategoryType" with the value "public.app-category.games."

Step three: Entitlements. Create a file named "GAMENAME.entitlements" in your Build folder. Inside this file, include the following:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
        <key>com.apple.security.app-sandbox</key>
        <true/>
    </dict>
    </plist>

Step four: Apple Developer Account. Assuming you already have a paid Apple Developer account, visit the Apple Developer website and go to "Certificates." Select the dropdown for "OS X" and create new certificates for "Mac App Distribution" and "Mac Installer Distribution." Don't forget to save these certificates for later use. After that, go to "Identifiers" and create a Wildcard App ID that matches your bundle ID.

Step five: iTunes Connect. Log in to iTunes Connect, navigate to "My Apps," and click on the "+" button to create a new Mac App. Fill in all the required fields, making sure that the Bundle ID matches the one from previous steps. Additionally, remember to take screenshots and crop them to the correct sizes: 1280 x 800 pixels, 1440 x 900 pixels, 2560 x 1600 pixels, and 2880 x 1800 pixels.

Step six: Application Loader. Download and install the latest version of Application Loader. In the terminal, fix the content permissions using the command "chmod -R a+xr /path/to/GAMENAME.app." Then, sign the app with the entitlements document created earlier using the command "codesign -f -s '3rd Party Mac Developer Application: DEVELOPER NAME' --entitlements "GAMENAME.entitlements" "/AppPath/GAMENAME.app"." You may encounter an error about code objects not being signed, but don't worry! You can use the deep-sign command to resolve this issue. Next, build the ".pkg" file using the command "productbuild --component GAMENAME.app /Applications --sign '3rd Party Mac Developer Installer: DEVELOPER NAME' GAMENAME.pkg."

Remove any existing instances of the game app from your machine, and finally, verify the install by using the command "sudo installer -store -pkg GAMENAME.pkg -target /." Now, open the Application Loader and choose 'Deliver Your App,' selecting the GAMENAME.pkg. If all goes well, the upload should succeed. However, if you encounter any specific errors, address them accordingly.

Step seven: Select the Build. Sometimes, you may receive an email indicating issues with your build's signature. This often occurs when a subcomponent hasn't been signed correctly. In such cases, consult Apple's documentation for further guidance. Otherwise, return to iTunes Connect, select your uploaded build, and change the status from "Preparing for Review" to "Waiting For Review," "Review," and finally, "Ready for Sale."

And there you have it! The key steps to successfully deploying a Unity 3D game to the App Store. I hope this episode has been helpful for those of you going through the same process. Remember, continuous improvement is the key to success, so don't be afraid to learn from your mistakes and keep refining your process. Thanks for tuning in to Continuous Improvement. I'm Victor, and until next time, keep striving for greatness.

將Unity 3D遊戲提交到Mac應用商店

經過三個月的週末開發,我們的Unity 3D遊戲已經準備好發布並部署到App Store。然而,這個過程並不直觀。我花了一整夜來解決它。經過許多嘗試和錯誤,我決定在這裡記錄一些關鍵的步驟:

![./2016-05-29.png]

1. Unity生成設置

在Unity中,齁到"檔案" > "建立設置" > "平台: PC, Mac與Linux獨立" > "目標平台: Mac OS"。

點擊"玩家設置...",並配置以下選項:

默認為全屏=真
默認是原生分辨率=真
抓取單一螢幕=假
顯示分辨率對話框=假
Mac應用商店驗證=真
2. Info.plist

在Finder中,右擊遊戲應用並選擇'顯示包內容'。在內容文件夾中,編輯Info.plist文件。確保:

  1. CFBundleGetInfoString是一個有效的字符串。
  2. CFBundleIdentifier和CFBundleSignature的值與bundle id(稍後解釋)匹配。
  3. CFBundleShortVersionString和CFBundleVersion的格式為x.x.x,例如1.0.0。
  4. 新增一個<key>LSApplicationCategoryType</key>,值為<string>public.app-category.games</string>

以下面的例子為例:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
     <!-- ... your keys and values here ... -->
    </dict>
    </plist>
3. 授權資訊

在你的Build文件夾中,創建一個名為GAMENAME.entitlements的文件,添加一個sandbox鍵,如下所示:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
        <key>com.apple.security.app-sandbox</key>
        <true/>
    </dict>
    </plist>
4. Apple開發者帳戶

假設你已經有一個付費的Apple開發者帳戶,訪問 Apple Developer Account。然後,轉到證書並選擇"OS X"的下拉列表。點擊"+"按鈕創建新的證書。你需要完成兩次這個過程以獲取"Mac應用分發"和"Mac安裝程序分發"證書。將它們保存到你的鑰匙鏈以供日後使用。

然後,轉到"識別碼"並選擇"應用ID"標籤。創建一個萬用應用ID,但要確保它與前一步驟中的bundle ID值匹配。例如,我的是unity.victorleungtw.*

5. iTunes Connect

登錄到 iTunes Connect,轉到 我的應用 > "+" > "新的Mac應用",並填寫所需的欄位。確定 Bundle ID 與前一階段的配置相符。前綴欄位應為遊戲名稱,例如在我的情況下,它是ufo

你也需要拍攝屏幕截圖,並將它們修剪到正確的大小。只允許以下的尺寸:

  • 1280 x 800 像素
  • 1440 x 900 像素
  • 2560 x 1600 像素
  • 2880 x 1800 像素
6. 應用加載器

下載並安裝最新的應用加載器,用來提交應用。完成以下步驟:

在終端機中填寫內容權限:

    chmod -R a+xr "/path/to/GAMENAME.app"

用第三步中創建的授權信息文件簽署應用:

    codesign -f -s '3rd Party Mac Developer Application: DEVELOPER NAME' --entitlements "GAMENAME.entitlements" "/AppPath/GAMENAME.app"

你可能會遇到以下的錯誤:

    code object is not signed at all

這是因為子元件沒有簽署。你可以逐個簽署它們,包括libmono.0.dyliblibMonoPosixHelper.dylib,但個更簡單的方法是使用深度簽名命令,如下所示:

    codesign -f -s '3rd Party Mac Developer Application: DEVELOPER NAME' --entitlements "GAMENAME.entitlements

" "/AppPath/GAMENAME.app" --deep

然後,構建.pkg文件:

    productbuild --component GAMENAME.app /Applications --sign "3rd Party Mac Developer Installer: DEVELOPER NAME" GAMENAME.pkg

從你的機器中刪除所有已存在的遊戲應用。然後你可以用下面的命令驗證原則:

    sudo installer -store -pkg GAMENAME.pkg -target /

最後,打開應用加載器,選擇'提交你的應用',並選擇GAMENAME.pkg。如果一切正常,上傳應該會成功。否則,根據相應的錯誤來解決問題。這個過程需要一些時間。

7. 選擇構建

如果你收到了包含如下問題的郵件:

> **無效簽名** — 主應用包game在路徑GAMENAME.app有以下簽名錯誤:在架構i386中的Info.plist無效(plist或簽名已被修改)。

這可能是你的某個子元件沒有正確簽署。你可能需要參考蘋果的文件尋找進一步的指導。

否則,返回到iTunes Connect,選擇已上傳的構建,並將狀態從"準備審查"變更為"等待審查" > "審查" > "銷售準備就緒"。

我希望這個博客文章對你有所幫助,也希望可以為你節省一些時間!:)

Resolving Merge Conflicts for the Unity Game Engine

I'm working with a team of four on a Unity 3D game project over the weekends. It's a lot of fun, but we've encountered problems with version control. Using Git and GitHub, we've faced many merge conflicts that are not easy to resolve; it's not as simple as just deleting a section or performing a forced push:

    <<<<<<< HEAD:main.scene
    Painful
    =======
    Delete me
    >>>>>>>

There are lots of unnecessary local meta files that get pushed to our repository. The solution I've found is not perfect, but it works:

First, open the Unity editor and go to:

    Edit -> Project Settings -> Editor ->
    Select "**Visible Meta files**" in the version control mode

Second, add a .gitignore file like this:

    /[Ll]ibrary/
    /[Tt]emp/
    /[Oo]bj/
    /[Bb]uild/
    /[Bb]uilds/
    /Assets/AssetStoreTools*

    # Autogenerated VS/MD solution and project files
    ExportedObj/
    *.csproj
    *.unityproj
    *.sln
    *.suo
    *.tmp
    *.user
    *.userprefs
    *.pidb
    *.booproj
    *.svd

    # Unity3D generated meta files
    *.pidb.meta

    # Unity3D Generated File On Crash Reports
    sysinfo.txt

    # Builds
    *.apk
    *.unitypackage

    .DS_Store

Then, commit the actual changes and run the following commands:

    git rm -r --cached .
    git add .
    git commit -m "Fixed untracked files"

Third, Unity has a tool called UnityYAMLMerge for merging scene and prefab files. Enable this by creating a .gitconfig file with the following:

    [merge]
    tool = unityyamlmerge

    [mergetool "unityyamlmerge"]
    trustExitCode = false
    cmd = /Applications/Unity/Unity.app/Contents/Tools/UnityYAMLMerge merge -p "$BASE" "$REMOTE" "$LOCAL" "$MERGED"

The next time a teammate clones the project, they may initially see an empty scene. However, there's no need to panic. Simply open the saved main.scene (assuming you have saved the scene and committed it), and everything else should work as expected. I wish Unity had built-in source control like other IDE environments. Happy coding!

Resolving Merge Conflicts for the Unity Game Engine

Welcome back to "Continuous Improvement," the podcast where we explore various challenges and solutions in the world of software development. I'm your host, Victor, and today we have an interesting topic to discuss - version control conflicts in Unity 3D game development.

So, recently, I've been working on a Unity 3D game project with a small team. It's been a lot of fun, but we've encountered some issues with version control, specifically when using Git and GitHub. Merge conflicts have become quite common, and resolving them hasn't been as simple as we initially thought.

Let me illustrate with an example. Imagine you have a merge conflict in a Unity scene file. It looks something like this:

Painful

Now, this type of conflict is not straightforward to manage. Deleting a section or performing a forced push won't solve the problem. So, what can we do about it?

Let's explore a solution I've discovered through trial and error. It's not perfect, but it works. Firstly, open the Unity editor and navigate to:

Edit -> Project Settings -> Editor -> Select "Visible Meta files" in the version control mode.

This will help eliminate unnecessary local meta files from being pushed to the repository. But we're not done yet. We need to add a .gitignore file to our project. Here's an example of what it could look like:

/[Ll]ibrary/
/[Tt]emp/
/[Oo]bj/
/[Bb]uild/
/[Bb]uilds/
/Assets/AssetStoreTools*

# Autogenerated VS/MD solution and project files
ExportedObj/
*.csproj
*.unityproj
*.sln
*.suo
*.tmp
*.user
*.userprefs
*.pidb
*.booproj
*.svd

# Unity3D generated meta files
*.pidb.meta

# Unity3D Generated File On Crash Reports
sysinfo.txt

# Builds
*.apk
*.unitypackage

.DS_Store

Once you have added the .gitignore file, commit the changes. Now, let's run a few commands to clean up the repository and make it ready for proper version control.

git rm -r --cached .
git add .
git commit -m "Fixed untracked files"

These commands will remove untracked files, add the necessary files, and create a commit with a specific message.

Lastly, Unity provides a tool called UnityYAMLMerge specifically designed for merging scene and prefab files. To enable this tool, we need to create a .gitconfig file with the following content:

[merge]
tool = unityyamlmerge

[mergetool "unityyamlmerge"]
trustExitCode = false
cmd = /Applications/Unity/Unity.app/Contents/Tools/UnityYAMLMerge merge -p "$BASE" "$REMOTE" "$LOCAL" "$MERGED"

By configuring Git with this .gitconfig file, we can leverage UnityYAMLMerge to handle these conflicts efficiently.

Keep in mind that when a teammate clones the project for the first time, they might see an empty scene. However, there's no need to panic. By simply opening the saved main.scene (assuming it has been saved and committed previously), everything should work as expected.

I hope these tips and tricks can make your Unity 3D game development experience a little smoother. Wouldn't it be great if Unity offered built-in source control integration like other IDEs? Ah, well, we can still make the most out of the tools we have.

That's all for today's episode of "Continuous Improvement." If you have any questions or suggestions for future topics, feel free to reach out. Until next time, keep coding and striving for excellence. Goodbye!

解決Unity遊戲引擎的合併衝突

我正和一個四人的團隊在周末進行一個Unity 3D遊戲項目的工作。這很有趣,但我們遇到了版本控制的問題。使用Git和GitHub,我們遇到了許多不容易解決的合併衝突; 它不僅僅是刪除一個部分或執行強制推送那麼簡單:

    <<<<<<< HEAD:main.scene
    痛苦
    =======
    刪除我
    >>>>>>>

有很多不必要的本地元資料檔案被推送到我們的存儲庫。我找到的解決方案並不完美,但它有效:

首先,打開Unity編輯器並前往:

    編輯 -> 項目設置 -> 編輯器 ->
    在版本控制模式中選擇 "**可見Meta文件**"

其次,添加一個 .gitignore 資料檔案像這樣:

    /[Ll]ibrary/
    /[Tt]emp/
    /[Oo]bj/
    /[Bb]uild/
    /[Bb]uilds/
    /Assets/AssetStoreTools*

    # 自動生成的VS/MD解決方案和項目文件
    ExportedObj/
    *.csproj
    *.unityproj
    *.sln
    *.suo
    *.tmp
    *.user
    *.userprefs
    *.pidb
    *.booproj
    *.svd

    # Unity3D生成的meta文件
    *.pidb.meta

    # Unity3D在崩潰報告上生成的文件
    sysinfo.txt

    # Builds
    *.apk
    *.unitypackage

    .DS_Store

然後,提交實際的更改並運行以下命令:

    git rm -r --cached .
    git add .
    git commit -m "Fixed untracked files"

第三,Unity有一個叫UnityYAMLMerge的工具用於合併場景和prefab文件。通過創建一個.gitconfig文件並使用以下內容來啟用:

    [merge]
    tool = unityyamlmerge

    [mergetool "unityyamlmerge"]
    trustExitCode = false
    cmd = /Applications/Unity/Unity.app/Contents/Tools/UnityYAMLMerge merge -p "$BASE" "$REMOTE" "$LOCAL" "$MERGED"

下次隊伍的某個成員克隆該項目時,他們可能最初會看到一個空的場景。但是,不必慌張。只需打開已保存的main.scene(假設您已經保存並提交了場景),其他東西就應該如預期的那樣工作。我希望Unity像其他IDE環境一樣內置源代碼控制。編碼愉快!

Trivial Facts About JavaScript Date

Fact 1

The integer value representing the month in JavaScript begins with 0 for January and goes up to 11 for December. For example:

Today's date can be represented as:

> var date = new Date(2016, 3, 29, 11, 10, 30)

instead of:

> var date = new Date(2016, 4, 29, 11, 10, 30)
Fact 2

In JavaScript, the date is based on a time value expressed in milliseconds, whereas the UNIX timestamp is expressed in seconds since 00:00:00 UTC on January 1, 1970.

For example, to convert a UNIX timestamp to a JavaScript date:

> var date = new Date(UNIX_Timestamp * 1000);

Trivial Facts About JavaScript Date

Hello and welcome to another episode of Continuous Improvement, the podcast where we dive into all things programming and web development. I'm your host, Victor, and today we have some interesting facts about dates in JavaScript.

Fact number one: Did you know that in JavaScript, the integer value representing the month actually begins with 0 for January and goes up to 11 for December? It's a common mistake to think that January is represented by 1 and December by 12, but in reality, it starts from 0. So, if you're working with dates in JavaScript, keep that in mind to avoid any confusion.

Let's look at an example. If today's date is April 29, 2016, instead of writing var date = new Date(2016, 4, 29, 11, 10, 30), you should actually write var date = new Date(2016, 3, 29, 11, 10, 30). The month is zero-based, so April is represented by 3 instead of 4. It's a small detail, but an important one to remember.

Now, let's move on to fact number two. In JavaScript, the date is based on a time value expressed in milliseconds, while the UNIX timestamp is expressed in seconds since 00:00:00 UTC on January 1, 1970. This means that if you want to convert a UNIX timestamp into a JavaScript date, you need to multiply the timestamp by 1000.

For instance, if you have a UNIX timestamp and want to represent it as a JavaScript date, you can use the following syntax: var date = new Date(UNIX_Timestamp * 1000). This multiplication by 1000 converts the seconds into milliseconds, which is the required format for JavaScript dates.

And there you have it, two fascinating facts about dates in JavaScript. Remember to always keep the month's zero-based indexing in mind and don't forget to multiply UNIX timestamps by 1000 when converting them to JavaScript dates.

Thank you for listening to this episode of Continuous Improvement. If you enjoyed today's content, make sure to subscribe to our podcast for more programming tips and tricks. Stay curious and keep improving!

關於JavaScript日期的瑣碎事實

事實1

在JavaScript中,代表月份的整數值由0開始表示1月,至11表示12月。例如:

今天的日期可以表示為:

> var date = new Date(2016, 3, 29, 11, 10, 30)

而不是:

> var date = new Date(2016, 4, 29, 11, 10, 30)
事實2

在JavaScript中,日期是基於以毫秒表示的時間值,而UNIX時間戳則是從1970年1月1日00:00:00 UTC開始以秒為單位表示。

例如,要將UNIX時間戳轉換為JavaScriptdate:

> var date = new Date(UNIX_Timestamp * 1000);

It's Not a Tech Problem, Stupid

I enjoy helping people and solving complex problems. However, it's disheartening to encounter issues that fall outside the scope of a programmer's ability to solve them. If you lack an engineering background, you may believe that your challenges are technological in nature—that a website, an app, or a machine learning server might be the solution. But in reality, these are rarely the root causes. Here are what I consider to be your seven most critical issues:

  1. You're Not Delivering on Your Promises: What is the goal of your product? What problem are you trying to solve? Do you understand your customers' needs? How does your product stand out in the market? Do you have control over the delivery process? If not, you might be wasting time and resources building something that nobody wants.

  2. You're Risk-Averse: You fear making significant changes because something might break. Whether it's messy CSS files, deprecated browsers, or spaghetti code that no one wants to touch, these issues demand attention. It's crucial to clean up your tech debt so you can move forward.

  3. You Lack Creativity: Minor aesthetic problems, such as misaligned text or an off-center box, might seem easy to fix but can still detract from the overall design. Consider trusting your designer to make bold visual choices, or hire a user experience specialist to conduct A/B testing. You might also need to invest in high-quality content for SEO.

  4. You Form Superficial and Dishonest Relationships: Your lack of open communication obscures progress and roadblocks. You might be misleading investors with over-promises, creating an illusion that everything is fine. This lack of transparency will ultimately hurt everyone involved.

  5. You Foster Rivalry Within Your Team: Do you know why your team is unhappy? Is there an excessive workload causing burnout? Do they enjoy their work? Is there trust in the system? If the work environment is neither pleasant nor stimulating, it might be time to reconsider your leadership.

  6. You're Less Productive Than You Think: Do you notice a drop in productivity? Unfocused meetings without clear outcomes and trying to multitask without setting priorities not only waste your time but also the time of those around you.

  7. You're Not Humble: You prioritize being right over doing what's right. Because of your seniority and experience, you believe your viewpoint must be correct. Your ego clouds your judgment and prevents you from making objective decisions.

It's easy to identify flaws in software, but it's much harder to spot them in corporate culture. Addressing these fundamental issues should be your first step.

It's Not a Tech Problem, Stupid

Welcome back to another episode of Continuous Improvement, the podcast dedicated to helping you overcome your challenges and be the best version of yourself. I'm your host, Victor, and today we're going to dig deep into a blog post that highlights seven critical issues that may be holding you back. So grab a cup of coffee, sit back, and let's dive in.

Have you ever found yourself encountering problems that seem beyond your scope as a programmer? You may be surprised to learn that the solutions might not lie in technological fixes like websites, apps, or machines. In today's episode, we're going to explore these problems and discuss how you can address them effectively.

Let's start with issue number one.

Issue #1: You're Not Delivering on Your Promises.

It's essential to understand the goal of your product and the problem it solves. Are you delivering what your customers need? Do you stand out in the market? If not, you might be wasting time and resources. Remember, building something nobody wants is a recipe for failure. Take a step back, reassess, and align your product with the needs of your customers.

Moving on to issue number two.

Issue #2: You're Risk-Averse.

Fear of change can often hold us back from making significant improvements. It's crucial to address messy code, maintenance issues, and other technical debts. By cleaning up and embracing necessary changes, you open the door to progress. Don't let the fear of breaking something prevent you from moving forward.

Now, let's discuss issue number three.

Issue #3: You Lack Creativity.

Sometimes, it's the small aesthetic problems that can affect the overall user experience. Trust your designers to make bold choices, and consider conducting A/B testing to gather valuable user feedback. Additionally, investing in high-quality content for SEO can greatly enhance your product's visibility and appeal.

Moving forward, let's focus on issue number four.

Issue #4: You Form Superficial and Dishonest Relationships.

Open and honest communication is the foundation of any successful endeavor. Misleading investors with over-promises and creating a false sense of progress can harm everyone involved. Embrace transparency and foster genuine relationships based on trust, accountability, and clear communication.

Now, let's move on to issue number five.

Issue #5: You Foster Rivalry Within Your Team.

Unhappy teams can have a detrimental effect on productivity and overall success. Take the time to understand why your team may be unhappy. Is the workload overwhelming? Do they enjoy their work? Building a pleasant and stimulating work environment based on trust and respect is vital to the success of your team and your organization as a whole.

Now, let's discuss issue number six.

Issue #6: You're Less Productive Than You Think.

Unfocused meetings, multitasking without setting priorities, and a lack of clear outcomes can significantly impact productivity. Stay focused, set clear goals, and minimize distractions. By managing your time effectively and prioritizing tasks, you'll not only enhance your own productivity but also inspire those around you.

Lastly, let's address issue number seven.

Issue #7: You're Not Humble.

Pride and ego can cloud judgment and hinder growth. Remember, it's not about being right; it's about doing what's right. Embrace humility, listen to others' perspectives, and make objective decisions that benefit the entire team.

And that concludes our exploration of the seven critical issues highlighted in this blog post. Remember, addressing these fundamental problems is the first step toward continuous improvement.

Thank you for joining me on this episode of Continuous Improvement. If you found this discussion helpful, be sure to subscribe to our podcast for more episodes dedicated to your personal and professional development. I'm Victor, and I'll see you next time.