Save
Saving
  • hainv hainv

    • Popup Service là hệ thống quản lý Popup trong MS 2.0
    • Popup Service sẽ sử dụng queue để quản lý thứ tự hiển thị các popup. Chỉ có 1 popup xuất hiện trên màn hình tại 1 thời điểm.
      - Cấu trúc interface IPopupService
      5672ac60-8b29-428a-9931-6d5c49a3d76f-image.png
      - Cấu trúc Popup Data
      3ebbb88d-e273-4587-9af3-7f54c238b218-image.png

    Cách sử dụng

    • Setup một Popup
      • Tạo Popup Controller
        bdbc7d04-daed-475f-8855-2e17dfd120fd-image.png
        • Class của popup controller phải kế thừa lại PopupBase
        • Có thể override lại method DoIntroDoOutro để thực hiện Animation khi mở và đóng popup nếu cần
      • Tạo Popup Prefab
        de99331f-b9b9-44f2-95c7-c281015b0425-image.png
        • Kéo Scripts Popup Controller vào ngang hàng với Canvas của Popup
        • Gọi Hàm Close để đóng popup
      • Kéo Prefab vào Group Popup trong Addressable. Tên của popup trong addressable phải trùng với tên của class Popup Controller
        dcded0a2-a5c8-46c3-ad66-f9c9df247d76-image.png
    • Push Popup lên màn hình
     var popupService = SupportSystem.Instance[SupportSystem.ServiceIDs.PopupService] as IPopupService;
    PopupData popupData = new PopupData()
    {
          //Type của Popup Controller
          popupType = typeof(DemoPopup),
          // Data truyền vào trong Popup. Data này sẽ lấy được khi Popup chạy vào hàm Start.
          data = new Dictionary<string, object>()  
          {
               {"Demo", "Value" }
          }, 
         //Callback khi Popup hiện lên trên màn hình
          OnPopupPushed = (obj) =>   
          {
               DebugMonkey.Log(() => $"Popup Pushed: {obj.GetType().Name}");
          },
          //Callback khi đóng Popup
          OnPopupClosed = () =>
          {
               DebugMonkey.Log(() => "Popup Closed");
          },
          //Override lại sorting của canvas. nếu ko set giá trị thì canvas sẽ giữ nguyên sorting của prefab
          order = 100
    }
    popupService.PushPopup(popupData);
    

    - Editor
    b5a0b4da-b0a7-4d29-a42e-5df0a666c7dd-image.png
    trong Inspector của PopupService, có thể xem được Popup hiện tại trên màn hình vào danh sách Popup trong Queue.Popup sẽ hiển thị lần lượt theo danh sách trong Popups In Queue

    - Các lỗi có thể gặp phải

    • PopupData cant be null => PopupData không thể null
    • PopupDemo is not a Popup => Class PopupDemo không được kế thừa PopupBase
    • Load prefab popup from Addressable failed => Không load được Popup từ Addressables
    • [ERROR] Get Data with Key: {key}. the data type is wrong. cant cast {value.GetType().Name} to {typeof(T).Name} => Key tồn tại trong data nhưng sai value sai định dạng
    • [ERROR] Get Data with Key: {key}. Key not found => Key trong data không tồn tại

    posted in Monkey Stories 2.0 read more
  • hainv hainv

    • Assetbundle Pipeline được quản lý tại git repo:
      https://github.com/eduhub123/MonkeyXAssetBunldeBuilder

    • Script build: CreateAssetBundles.cs

      • Cấu trúc:
        9e972452-2727-4efa-9582-95123cf00916-image.png
    • Khi build Assetbundle, Unity sẽ tự động setting thông số cho từng Assets theo config được đặt sẵn trong code.

    • Assetbundle sẽ được build cho 3 platform:

      • Android
      • Ios
      • Standalone (PC Win)
    • Load file Assetbundles trong MJ5: Scripts: AssetBundleManager.cs

      • Cấu trúc:
        b5b198d6-c3d7-412f-a911-f97608d085f7-image.png

      - Hàm load Assetbundle

      • AssetBundleManager.Instance.GetAssetAward<T>(record);
      • AssetBundleManager.Instance.GetAssetNormal<T>(RecordBundleInfo record)
      • AssetBundleManager.Instance.GetAssetWord<T>(RecordBundleInfo record)
      • AssetBundleManager.Instance.GetAssetStory<T>(RecordBundleInfo record)

      - Assetbundle sẽ tự động download nếu chưa tồn tại

    posted in Chung read more
  • hainv hainv

    Theo dõi chỉ số Crash free:
    https://firebase.google.com/
    Kiểm tra chỉ số free crash trên Firebase Crashlytics.

    861c6c08-6388-4c15-81d5-4b3c16a7fcc9-image.png

    Chỉ số cần quan tâm:
    Crash free users: tỷ lệ user không bị crash.
    Crash free session: tỷ lệ session không bị crash

    Cách tăng chỉ sổ Crash free:
    Kiểm tra mục Issues của crashlytics
    c6ac6c61-c040-4e74-a55f-e0068a5099ca-image.png

    • Nhận biết các lỗi crash từ Unity:
      Các lỗi crash từ Unity thì sẽ có thông tin Unity version
      f26e5232-c586-483d-9531-b2ea229ccfa2-image.png

    - Các lỗi thường gặp phải:

    • Out of memory
    • Lỗi I/O
    • Lỗi do Vulkan trên các máy cũ

    Kiểm tra thêm chi tiết các lỗi crash trên Crashes and ARN của playstore
    15cbcc28-baca-418b-b058-e06033f7b27d-image.png

    posted in Chung read more
  • hainv hainv

    Project build: https://github.com/eduhub123/MonkeyStory2GameBuilder
    Script Auto Build: build_game.bat
    Trong script build cần config các thông tin:
    UNITY_PATH=<Path Unity Editor>
    ADDRESSABLE_PROJECT_PATH=<Path Build Project>
    MAIN_PROJECT_PATH=<Path Monkey Story 2.0 Project>

    Script Build c#: GameBuild.cs

    Cách download game trong MS 2.0
    Cấu trúc

    public interface IGameService
        {
            public void DownloadGameBundle(int gameId, Action<bool> callback);
            public void LoadGameCatalogs(int gameId, Action<bool> callback);
        }
    

    Download Game:

    IGameService gameService = SupportSystem.Instance[SupportSystem.ServiceIDs.GameService] as IGameService;
    gameService.DownloadGameBundle(gameConfigData.GameID, IsSuccess =>
    {
         //Callback sau khi download xong
    });
    

    Load Catalogs

    IGameService gameService = SupportSystem.Instance[SupportSystem.ServiceIDs.GameService] as IGameService;
    gameService.LoadGameCatalogs(gameConfigData.GameID, IsSuccess =>
    {
           if (IsSuccess)
                 //Load Game
           else
           {
                Debug.LogError("Load Game Catalogs Failed");
           }
    });
    

    Sau khi load catalogs thành công thì có thể load game từ Addressables như bình thường

    posted in Monkey Stories 2.0 read more
  • hainv hainv

    Các bước build MJ5 PC:

    • main branch: dev_intergration/pc_build/main

    Bước 1: Github

    • tạo 1 branch mới từ branch main.
    • Merge code mới nhất từ develop_intergration vào branch vừa tạo

    Bước 2: Nâng version

    • Nâng version trong Project Setttings

    Bước 3: Build Standalone

    • Build Addressable: từ menu của unity editor chọn Build/Addressable_Android
      a44cd5b9-3751-4ef1-adba-1bee62949a7d-image.png
    • Build Standalone: Build standalone từ Build Setting như bình thường.

    Bước 4: Đóng gói Installer
    Sử dụng phần mềm Advanced Installer phiên bản 21.3.1

    • Mở file copy_ms.back(19.1) trong project proj.setup
    • Thay thế toàn bộ files trong Application folder bằng files vừa mới build
      09295927-b88f-42fe-8cd9-a5a44c338915-image.png
    • Nâng version trong Project details
      c6beb1ce-e52f-4984-a947-0ff3c47e9446-image.png
    • Bấm build

    posted in Base read more
  • hainv hainv

    • Hệ thống Addressable cho MJ5 sử dụng để build Assets trong Unity (Images, Audio, Prefabs, Scenes)
    • Addressables Version 1.21.19

    - Cấu trúc Groups:

    • Remote Groups: Groups sẽ được đẩy lên cdn và download trong quá trình mở Unity
    • Local Groups: Groups sẽ được build cùng với bản build.

    - Remote Groups

    • Path lưu trữ: {UnityEngine.Application.persistentDataPath}/Addressables
    • Cấu trúc đặt tên group: bắt đầu với GROUPNAME_
    • Các groups có cùng prefix sẽ zip lại cùng với nhau.

    Lưu ý: remote groups chỉ được dependence với các groups có cùng prefix hoặc local groups.

    - Script quản lý Addressable:

    namespace Monkey.Support.Addressable
    {
        public interface IAddressableService
        {
            /// <summary>
            /// Download Addressable Group
            /// </summary>
            /// <param name="groupName">Group Name</param>
            /// <param name="callback">Callback when Download finished</param>
            /// <param name="progress">Callback the progress</param>
            /// <param name="total_retry">No need to change the value</param>
            /// <returns></returns>
            IEnumerator DownloadGroup(string groupName, Action<bool> callback, Action<float> progress = null, int total_retry = 0);
            bool IsNeedDownload(string groupName);
            void LoadAssets<T>(string asset_name, Action<AsyncOperationHandle<T>> callback) where T : UnityEngine.Object;
            bool HasKey(string key);
            /// <summary>
            /// Check when Addressable service ready
            /// </summary>
            /// <returns></returns>
            bool IsServiceActive();
        }
    }
    

    - Cách download group:

    • Kiểm tra xem group có cần download hay không
    IAddressableService addressable = SupportSystem.Instance[SupportSystem.ServiceIDs.AddressableService] as IAddressableService;
    bool isNeedDownload = addressable.IsNeedDownload("GROUP NAME");
    
    • Download Group
    IAddressableService addressable = SupportSystem.Instance[SupportSystem.ServiceIDs.AddressableService] as IAddressableService;
    CoroutineRunner.instance.RunCoroutine(addressable.DownloadGroup("GROUP NAME", isDone => {
      //Callback khi download thành công
      }, progress => {
      //Callback download progress
      }));
    

    - Build Addressables
    Script quản lý build Addressables: RNBuild.cs
    Method: static void BuildAddressable(string buildPlatform)
    Hàm build addressables thực hiện 3 bước:

    • Clean up
    • Build Addressable
    • Zip and upload to cdn

    - Các lỗi thường xảy ra
    Lỗi không load được dependencies

    OperationException : GroupOperation failed because one of its dependencies failed
    RemoteProviderException : Invalid path in AssetBundleProvider: 
    

    cách kiểm tra:

    • Kiểm tra xem group đã được download hay chưa.
    • Kiểm tra xem có assets nào depend đến remote group khác không.
      mở file buildlayout.txt trong folder: MonkeyX\Library\com.unity.addressables
      Kiểm tra Bundle Dependencies và Expanded Bundle Dependencies
      8623aeaf-ec84-456f-bfe0-ce097311ee1f-image.png

    posted in Base read more
  • hainv hainv

    9-Slice Trimmer là package để optimize Sprite hỗ trợ 9-Slice
    Để mở cửa sổ 9-Slice Trimmer. Chọn KH-Tools/Nine-Slice Trimmer trên thanh Menu
    4af61b63-eb82-44c5-b026-bed8f5c58831-image.png

    Cửa sổ của tool như sau:
    9aaa5257-011a-4a07-9b42-d4380e7205e9-image.png

    Hướng dẫn sử dụng:
    Bước 1: Chọn ảnh cần cắt và config vị trí cần slice
    80661fa4-2a51-4c26-9382-54c35934e2d1-image.png

    Bước 2: Bật Read/Write option và Apply
    cd3aa856-27ce-48ac-b3a1-bdfde826622d-image.png

    Bước 3: Kéo Sprite vào Sprite Texture trong tool
    95d4f722-13d5-4354-8416-e76bcf322a1f-image.png

    Bước 4: Bấm Preview để kiểm tra ảnh sau khi cắt đã đúng chưa
    5c63aa72-7688-45c5-ad9c-2f8f20f1e926-image.png

    Bước 5: Bấm Trim & Save để cắt Sprite
    2cda11e2-f615-419c-844f-f3acf2f17e17-image.png

    Bước 6: Tắt Read/Write trong ảnh vừa tạo
    Ảnh mới nhận được
    59092513-ac67-40aa-b92a-d28c41a3d013-image.png

    Tài liệu tham khảo thêm: https://github.com/KingHipUnity/Unity-NineSliceTrimmer/blob/main/README.md

    posted in Monkey Stories 2.0 read more
  • hainv hainv

    Viết thêm Cheat vào file CheatMethodHandle.cs
    01060da7-9512-4f97-8e94-29cf76a25a9f-image.png
    Quy tắc đặt tên Cheat mới

    _<Section> _<Tên Cheat>
    trong đó các Cheat có cùng Section sẽ được gộp vào chung 1 mục

    Cheat hỗ trợ 2 loại hàm void và biến static bool
    ví dụ

     public void _MS2_ShowLog()
     {
         Debug.Log("MS2 Show Log Clicked");
     }
    
     public static bool _IsDemoBool
     {
         get {
             return PlayerPrefs.GetInt("DebugKey_IsDemoBool", 0) == 1;
         }
         set {
             PlayerPrefs.SetInt("DebugKey_IsDemoBool", value ? 1 : 0);
         }
     }
    

    Để sử dụng Cheat, bấm vào button đầu khỉ ở ngoài màn hình
    611a6701-faf7-401d-af18-a2b49e07dae8-image.png

    aaaeecb2-2e3c-4dea-80b7-914643ed9619-image.png

    Click vào Section để mở ra các Cheat trong cùng 1 section
    Click vào từng Cheat để thực hiện hàm cheat

    posted in Monkey Stories 2.0 read more
  • hainv hainv

    Script Build được viết trong File MKBuild.cs

    • Đối với build bằng Unity Editor. Chọn Build trên thanh menu và chọn mục cần build
      da5e8199-4b6f-4646-bfc8-c469a67f32a3-image.png
      Sau khi build xong output file sẽ ở folder Build ( ngang hàng với Folder Assets )
      c25e56eb-7a91-4b75-8d0c-ab61fa0675b3-image.png
      Định dạng file APK: Android_yyyyMd_Hm.apk

    • Đối với sử dụng trong pipeline CI/CD
      Sử dụng Command:
      <Path To Unity Editor> -projectPath <Path To Project> -executeMethod Monkey.BuildTool.Editor.MKBuild.Build -outputPath <Path Output> -buildPlatform <Platform> -isProd true -batchmode -quit
      Platform: bao gồm: Android, iOS
      isProd: true hoặc false

    Ví dụ

    /Applications/Unity/Hub/Editor/2022.3.57f1/Unity.app/Contents/MacOS/Unity -projectPath /Users/monkey/Workspace/monkeyx_ci/monkey_story_2 -executeMethod Monkey.BuildTool.Editor.MKBuild.Build -buildPlatform iOS -isProd true -outputPath /Users/monkey/Workspace/monkeyx_ci/build/ios -batchmode -quit
    

    posted in Monkey Stories 2.0 read more
  • hainv hainv

    Các bước thực hiện để có thể test game bằng Game Tool
    Bước 1: Xoá các thành phần không cần thiết trong game nếu có
    3eec8679-69a8-4824-a028-6addaef20bbf-image.png
    128dd669-a838-4334-986a-3427f9ec9bf0-image.png
    EventSystem, SoundManager, AudioListener đã được load trong Game Tool nên không cần để trong scene game.

    Bước 2: Gán Addressable cho Scene game
    2.1: Mở cửa sổ Addressables Groups bằng cách sau:
    91e26b1b-6e99-419d-8a04-c0a5df57fdda-image.png
    2.2: Kéo Scene game vào group Games trong Addressable. Nếu game ở local thì kéo vào group Games_Local thay vì group Games
    8e5bdf46-8966-4b1d-b855-7b674d884baa-image.png
    2.3: Chuột phải vào Addressable vừa kéo chọn Simplify Addressable Name
    b612b11b-a203-46d1-8968-8f9b6232ba60-image.png

    Bước 3: Thêm Game Config trong File GameConfigSO trong đường dẫn: Assets/5.Manager/GameTool/Data
    a7201cc9-1cb8-4c0e-a245-7f6d7f5282a9-image.png

    • ở mục Asset Key: Điền tên của scene game
    • ở mục Asset Path: Điền đường dẫn đến scene đó
    • ở mục status lưu ý chọn đúng tiến độ của game để hiển thị màu button cho chính xác với quy định chung được diễn giải ở scene
    • IsLocalBuild = true nếu muốn build game ở local

    Bước 4: Chạy Scene GameTool và test lại.
    4f80f3ff-aaf3-499d-bfdb-ce7ee0c7bfba-image.png

    posted in Monkey Stories 2.0 read more