• HungBui HungBui

    1. Phương án giao tiếp

    Về cơ bản sự giao tiếp chỉ là app và unity send data cho nhau thông qua hệ thống giao tiếp.

    2. Phương án kỹ thuật

    Updating...

    3. Model data giao tiếp

    3.1 Model chung

    {
      "id": "string",
      "type": "string",
      "response": "boolean",
      "payload": {
      }
    }
    
    Properties Type Mô tả
    id string Mã định danh duy nhất để xử lý trả về và call back
    type string Loại dữ liệu sẽ tác động ví dụ "coin", "scene"...
    response boolean Lần gửi data này có cần bên nhận trả lại kết quả hay không?
    payload object Data cụ thể hơn cho từng trường hợp

    3.2 Ví dụ các trường hợp cụ thể

    3.3.1 App request Unity mở một scene cụ thể và không cần trả về kết quả

    {
      "id": "123",
      "type": "open_unity",
      "response": false,
      "payload": {
        "action":"open",
        "destination": "map_lesson"
      }
    }
    

    destination: "map_lesson" : là scene / layout muốn hiển thị. Giá trị này cần được thống nhất giữa app và unity

    3.3.2 App request Unity lấy dữ liệu của coin và cần trả về kết quả

    Request từ App sang Unity

    {
      "id": "4444",
      "type": "coin",
      "response": true,
      "payload": {
        "action": "get"
      }
    }
    

    Response từ Unity trả về cho App, về bản chất là Unity gửi cho App bộ data có id và type cùng loại với Request ở trên

    {
      "id": "4444",
      "type": "coin",
      "response": false,
      "payload": {
        "success": true,
        "message": "Get coin success",
        "current_balance": 1000
      }
    }
    

    4. Model giao tiếp trong MS 2.0

    Phần payload là phần động giữa các lần giao tiếp, cần phải thống nhất giữa App và Unity
    Updating...

    posted in Base read more
  • HungBui HungBui

    Mục tiêu

    Thống nhất về cách sử dụng Debug
    Dễ dàng quản lý debug cũng như tối ưu performance của ứng dụng

    Tổ chức

    Class DebugMonkey

    44ea378e-9f04-49b3-a708-293ae02677fd-image.png

    Giải thích tăng hiệu năng

    1. Vấn Đề Hiệu Năng Khi Debug

    Trong Unity, việc sử dụng Debug.Log, Debug.LogWarning, và Debug.LogError có thể gây ảnh hưởng đến hiệu suất của game, đặc biệt là trên mobile hoặc build final. Nguyên nhân chính:

    • Chuỗi string được tạo dù log có hiển thị hay không

    Ví dụ khi debug theo cách truyền thống:
    Debug.Log("Player position: " + player.transform.position.ToString());
    Dù bạn có tắt debug khi build, nhưng chuỗi "Player position: ..." vẫn được tạo, gây tốn bộ nhớ và CPU không cần thiết.

    2. Giải Pháp DebugMonkey

    Class DebugMonkey sử dụng biểu thức lambda (Func<string>) và điều kiện Conditional để tối ưu hiệu năng debug, ví dụ việc sử dụng DebugMonkey
    DebugMonkey.Log(() => "Player position: " + player.transform.position);
    Nếu điều kiện hiển thị Debug bị tắt , hàm Log() bị loại bỏ hoàn toàn khỏi build (tương đương với việc code không tồn tại)

    Cách dùng

    6ee13e7a-bd65-4769-abae-e9c7619d50e6-image.png
    Sử dụng DebugMonkey với các phương thức tương tự Debug của Unity, lưu ý là sử dụng lamda cho nội dung debug như ảnh trên.

    posted in Base read more
  • HungBui HungBui

    Mục tiêu

    Thống nhất về cùng kiểu guilding
    Tiết kiệm thời gian phát triển guiding trong quá trình dev game

    Tổ chức

    updating...

    Cách dùng

    Kéo prefabs guiding trong Base lên Hierarchy như hình

    576d1e4a-748f-4f0b-8029-43b493d97dea-image.png

    Reference vào đối tượng cần dùng

    6e17d776-ea6c-40e8-bfbf-2583d7e1335e-image.png

    Call các method tương ứng

    9cd1dd1e-4cf0-4942-bd20-bd42889ffb04-image.png

    Các phương thức hỗ trợ

    • Scale: Thay đổi kích thước của hướng dẫn.
    • Tap: Mô phỏng thao tác chạm vào một vị trí.
    • HideTap: Ẩn hiệu ứng chạm.
    • Drag: Mô phỏng thao tác kéo từ một vị trí đến vị trí khác trong một khoảng thời gian.

    Xin hãy đọc thêm ở summary của từng method

    posted in Base read more
  • HungBui HungBui

    Mục tiêu

    Tránh việc coupling giữa game và hệ thống âm thanh bên ngoài
    Thuận lợi cho việc implement SoundManager ở các project khác nhau

    Tổ chức

    updating...

    Cách dùng

    SoundListenner

    Mỗi 1 game cần có 1 object chứa class SoundListenner trên Hierarchy, đối tượng này đã thiết kế sẵn method và phương thức lắng nghe các sự kiện phát âm thanh.

    Sử dụng Observer qua kênh SoundChannel để phát âm thanh mong muốn

    Cách gán SoundListenner lên Hierarchy

    Class SoundListenner đã có sẵn trong project.
    Kéo class SoundListenner vào 1 object tồn tại trên Hierarch như hình dưới đây

    7b376759-1ad0-41e0-8b5b-e87ec5fe3a91-image.png

    SoundManager

    Mỗi 1 game cần có 1 object chứa class SoundManager Fake trên Hierarchy để thực thi các method phát âm thanh

    SoundManager Fake có ý nghĩa là sau này trong game sẽ không thực sự có vì sau này SoundManager sẽ dùng chung của cả project

    Cách get prefabs SoundManager

    SoundManager đã được tổ chức thành prefabs, chỉ cần kéo lên Hierarchy của game để sử dụng như hình dưới đây

    89f03b3e-3765-45a3-9539-aff482ae8b93-image.png

    posted in Base read more
  • HungBui HungBui

    Mục đích

    Nhằm tránh tình trạng không thống nhất và phân mảnh các tài nguyên dùng chung, sẽ có một số tài nguyên được quy định dùng chung tại tài liệu này

    Đặc điểm

    Thông thường các tài nguyên dùng chung sẽ nằm trong các mục được phân quyền cao, khi có vấn đề về việc thay đổi, bổ sung tài nguyên dùng chung sẽ phải làm theo quy trình tại đây (Xem mục Phân quyềnQuy trình đề xuất sửa đổi khi không được phân quyền )

    Danh sách tài nguyên

    1. Core

    Sẽ bổ sung bài viết về hệ thống này sau

    2. Base

    1. Font
    Hiện tại sử dụng 2 font là Nunito-BoldNunito-SemiBold, các game sử dụng chung font này, không tự tạo font mới

    3.ThirdPatty

    1. Demigiant
    Sử dụng cho Tween Tài liệu tại đây
    2. Spine
    Sử dụng cho animation Tài liệu tại đây
    3. TextMesh Pro
    Sử dụng TextMesh Pro Tài liệu tại đây

    Cập nhật ngày 13/3/2025

    posted in Monkey Stories 2.0 read more
  • HungBui HungBui

    Mã nguồn

    1. Source
    https://github.com/eduhub123/monkey_story_2
    2. Flow
    Xem tại đây

    Tổ chức chung

    5cf2b5cf-9b31-486d-aa7c-0a5ea681b78d-image.png

    1. Core
    Bộ phận chung của các project khác nhau (MS, MJ...)

    2. Base
    Phần base của từng project, mỗi project khác nhau

    3. ThridPatty
    Các library bên thứ ba

    4. Game MS
    Nơi chứa các game của project

    Phân quyền

    1. Core, 2. Base, 3. ThridPatty
    Chỉ Leader hoặc thành viên được leader ủy quyền mới được thay đổi nội dung của các thư mục này

    4. Game MS
    Tất cả các thành viên code game sẽ được đặt code ở đây theo git flow tại đây

    Quy trình đề xuất sửa đổi khi không được phân quyền

    Bước 1. Thành viên trao đổi vấn đề với leader hoặc thành viên được leader ủy quyền để được thay đổi khu vực không có quyền thay đổi

    Bước 2. Leader hoặc thành viên được ủy quyền review và thay đổi nếu có theo git flow tại đây

    Bước 3. Thông báo đến thành viên yêu cầu thay đổi hoặc thông báo vào nhóm khi đã có kết quả (chấp nhận hay không chấp nhận đều thông báo)

    posted in Monkey Stories 2.0 read more
  • HungBui HungBui

    Xuất ảnh

    Có 3 kiểu xuất ảnh, tùy vào nhu cầu, mng có thể lựa chọn 1 trong 3

    Kiểu 1: Xuất ảnh theo từng Artboard

    Phím tắt Ctrl + Alt + Shift + S
    Đặc điểm: Chỉ xuất được những vùng bên trong Artboard đang chọn

    artboard.png

    Khung artboard chưa chọn màu xám, khung artboard đang chọn hiện màu đen

    Cách xuất ảnh:
    Cách 1: Chọn Artboard bằng cách ấn chuột trái vào giữa hoặc trong khung của artboard đó, sau đó nhấn tổ hợp phím Ctrl + Alt + Shift + S để hiện cửa sổ xuất ảnh

    Cách 2: Hoặc có thể chọn vào File -> Export -> Save for Web

    a1.png

    Sau khi cửa sổ xuất ảnh hiện ra, điều chỉnh thông số như mong muốn và nhấn Save để xuất ảnh
    a2.png

    Lưu ý tích vào nút Transparency nếu muốn xuất ảnh tách nền trắng
    a3.png

    Kiểu 2: Xuất nhiều Artboard cùng lúc

    Phím tắt Ctrl + Alt + E
    Cách xuất ảnh:
    Chọn vào File -> Export -> Export for Screens

    Hiện lên cửa sổ chọn các artboard mong muốn, sau khi chọn xong, click vào Export Artboard để xuất
    2.1.png

    Kiểu 3: Xuất 1 đối tượng riêng lẻ (Asset export)

    Trên thanh công cụ phía bên phải giao diện Illustrator chọn icon Asset export
    3.2.png

    Nếu không có biểu tượng này thì vào Window -> chọn Asset Export
    3.1.png

    Cửa sổ Asset Export sẽ hiện ra
    3.3.png

    Kéo các đối tượng cần Export vào khung vuông
    3.4.png

    Tùy chỉnh thông số và ấn Export để xuất các đối tượng
    3.5.png

    Lưu ý: Các đối tượng đang trong group sẽ không kéo được vào khung vuông, nên sẽ phải ungroup ra rồi kéo vào, hoặc copy ra ngoài group

    Group, Ungroup

    Group các đối tượng:

    Ví dụ: Với 3 tảng đá riêng lẻ, muốn group vào thì ta cần chọn cả 3, bằng cách:

    • giữ phím Shift sau đó chuột trái vào lần lượt các tảng đá
      4.1.png
    • sau đó chuột phải, chọn Group
      4.2.png

    Ungroup các đối tượng:

    • Chọn Group bằng chuột trái
      5.1.png
    • sau đó chuột phải, chọn Ungroup

    Xuất đối tượng theo khung viền Artboard

    Các bước thực hiện:

    Bước 1: Xác định đối tượng cần xuất và vùng cần xuất
    Click đúp vào đối tượng/group cho đến khi hiện khung object như ảnh dưới
    6.1.png

    Bước 2: Chọn vào biểu tượng Rectangle tool ( phím tắt M )
    6.2.png

    Bước 3: Giữ chuột trái, kéo 1 khung bao trọn toàn bộ object, sao cho cạnh của khung trùng với các cạnh của Artboard
    6.3.png

    Bước 4: Chọn cả 2 bằng cách giữ Shift và nhấn lần lượt vào khung và object
    6.4.png

    Bước 5: Click chuột phải, chọn Make Clipping Mask
    6.5.png

    Sau khi thao tác xong, ta có được 1 mảnh cần xuất của đối tượng
    6.7.png

    Bước 6: Ctrl C đối tượng, sau đó ấn vào tab đầu tiên của thanh Group để thoát khỏi group
    6.7.png

    Bước 7 : Sau đó, Ctrl V đối tượng vào vùng trống của file thiết kế, và xuất như bình thường với Asset Export. Sau khi xong, ta có thể xóa đối tượng đi
    6.8.png

    Loại bỏ thành phần không cần thiết trong object/group

    Bước 1 : Bấm phím A, để con trỏ chuyển từ màu đen sang màu Trắng
    7.1.png

    Bước 2: click chuột trái vào thành phần cần bỏ, ví dụ như text
    7.2.png

    Bước 3: Nhấn delete và xuất như bình thường
    7.3.png

    posted in Chung read more
  • HungBui HungBui

    1. Các bài toán đã thực hiện

    Bài toán Thực trạng Tình trạng Kết quả Cải thiện Người thực hiện
    Base game Các game được phát triển một cách tự phát, không có quy trình cụ thể, khó khăn cho fixbug và phát triển Đã giải quyết được cơ bản về quy trình phát triển game với hệ thống FSM và observer design pattern Game đã có luồng rõ ràng, quá trình phát triển game được rút ngắn, thời gian fixbug nhanh, được đánh giá dễ sử dụng từ dev - Tự động tạo các class chính - Review base mục đích cải thiện, tối ưu và sử dụng thêm các design pattern hợp lý giúp tăng tính mạch lạc và dễ sử dụng của base Hùng Bùi
    Data game Các game khó có thể share giữa các khóa khác nhau do data có thể khác nhau Đã giải quyết bằng cách sử dụng chung bộ data model cho tất cả các game, bộ data đảm bảo cho việc dễ sử dụng và tổng quát Các game có thể chạy độc lập với data mock hoặc data test. Các game dễ dàng tách và đóng gói (cùng với base) Chưa có kế hoạch Hùng Bùi
    Navigation Để chuyển giữa các khóa học đang sử dụng bằng cách gọi thẳng tên scene và khó kiểm soát các yêu cầu khởi tạo của khóa học, phức tạp và khó khăn trong quá trình chuyển đổi giữa các khóa Đã chuyển chung cơ chế chuyển scene do 1 đối tượng quản lý, ở đây sẽ kiểm tra tất cả các điều kiện khởi tạo khóa học cần thiết Thời gian chuyển các khóa được tối ưu, phát triển khóa mới không lo lắng ảnh hưởng đến khóa cũ, tách biệt data của các khóa khác nhau, không cần thiết sẽ không khởi tạo Review lại luồng data học và data đồng bộ của khóa Abc và MStory để tách biệt ra với một số case đặc biệt Hùng Bùi
    Event Mỗi một event có hệ thống properties khác nhau, mỗi khi có một properties mới sẽ phải viết lại method cho event này Đã tạo 1 base event với việc chia các properties chung và thiết kế linh hoạt các properties khác nhau để có thể sử dụng chung method cho các event khác nhau Giảm thời gian phát triển cho chức năng push event Chưa có kế hoạch Tiến ND
    AI Speak Nhiều game sử dụng công nghệ AI Speak nhưng mỗi game sử dụng khác nhau dẫn đến không đồng nhất về luồng và gây khó khăn cho quá trình debug Đã tạo 1 module chung bao gồm đầy đủ từ xin quyền đến thực thi AI Speak với kịch bản online và offline cụ thể Dễ dàng trong việc sử dụng module với input và output rõ ràng, giảm thời gian phát triển chức năng liên quan đến AI Speak Chưa có kế hoạch Hiếu HS
    Tối ưu dung lượng build Các assets trong game đang được build cùng game. Khi phát triển thêm tính năng sẽ tăng build size Sử dụng Addressable nhằm tách các assets của game ra bên ngoài và download về khi cần Build size đã giảm và ổn định hơn. Khi thêm tính năng mới build size sẽ không tăng nhiều Chưa có kế hoạch Hải Ngô
    Support Service Các phần hỗ trợ trong game đang được phát triển riêng biệt, không có quy chuẩn cụ thể, khó khăn trong việc phát triển và fix bug Các phần hỗ trợ được quy chuẩn về dạng service, có Service manager để quản lý. Các service được implement qua Interface để dễ dàng nâng cấp, thay thế khi cần Đã Implement được các services sau: Addressables, Assetbundle, DataSync, Download, EventTracking, Localization, Popup, UserData Cần đưa các service vào toàn bộ hệ thống thay vì chỉ dùng một phần trong MJ5 Hải Ngô, Tùng Đỗ
    Thay đổi visual trong game theo event Khi thay đổi event cần submit lại app. Mỗi khi có event mới tốn thời gian trong việc chỉnh sửa lại app, không tận dụng được event đã làm từ trước Event được quy chuẩn về dạng Theme và hiển thị theo Config. Dễ dàng thêm Event mới. Các event được điều khiển bằng data và hiển thị khi cần thiết Đã hoàn thành theme cho chủ đề giáng sinh Đưa theme ra ngoài và download về khi cần. Bổ sung thêm các theme theo chủ đề khác Hải Ngô
    Tối ưu share và tải tài nguyên Game và tài nguyên có thể share cho nhau nhưng vẫn phải tải lại từ package khác nhau với mỗi khóa học Hệ thống share game, tải tài nguyên chỉ cần 1 lần, các lần sau không cần tải lại QA Testing cho khóa MJ5 Cho pack Event Season + MSpeak (có điều kiện từ data) Hải Ngô (12/12/24)

    2. Các bài toán mong muốn thực hiện

    Bài toán Thực trạng Mong muốn
    Data user Data của tất cả các khóa đang để chung model dù không dùng gây nặng cho user đặc biệt với các user học nhiều khóa, lượng bài học hoàn thành nhiều, hiệu năng giảm - Tách biệt data của các khóa và phần data tặng thưởng riêng, khi cần data nào sẽ load data đó.<br>- Khi bổ sung khóa mới dễ đồng bộ và fixbug, không ảnh hưởng hiệu năng
    UI Map Các map khá giống nhau về mặt UI và chức năng nhưng mỗi map vẫn trên 1 base code khác nhau Gen map tự động theo data setting hoặc kéo thả
    Tặng khóa học Khi tặng khóa học các điều kiện tặng ở client khá phức tạp, phụ thuộc nhiều bên như client và server Xây dựng hệ thống tặng khóa dễ thay đổi điều kiện và dễ setup
    Game framework Mỗi game phải order từ nhiều bên (nội dung > kịch bản > đồ họa > dev) gây mất thời gian phát triển và test thử Xây dựng framework để bộ phận kịch bản + nội dung tự tạo game mong muốn theo quy tắc nhất định
    Tối ưu quy trình dev game Các object game lặp lại qua nhiều game nhưng dev vẫn phải code lại hoặc copy Hệ thống các object chung, tái sử dụng, giảm thời gian dev game

    posted in Base read more