JKFrame 2.0

repository·main·Indexed 43 days ago

https://github.com/joker-yf/jkframe

A modular toolkit for Unity designed for indie developers and small teams. JKFrame 2.0 provides a collection of decoupled, plugin-like systems including Object Pooling (GOP and OP), Event, Save, Audio, Resource, MonoSystem, UI, Scene, and Localization systems, as well as utilities for state machines and Excel-to-ScriptableObject conversion.

Tokens
19K
Snippets
53
Records
68
Agent score
56%

What's inside JKFrame

  1. Overview of JKFrame 2.0

    main

    JKFrame 2.0 is a toolkit designed for indie game developers and small teams. Rather than a rigid framework requiring extensive inheritance, it functions as a toolbox where most features are optional and behave like plugins. You can use specific systems without being forced to implement their interfaces or inherit from their classes.

    Key characteristics:

    • Toolkit Approach: Most features are decoupled and can be used as needed.
    • Plugin-like Functionality: Systems like SaveSystem and AudioSystem can be called directly.
    • Built-in Dependencies: Includes support for the Odin Inspector plugin for enhanced serialization and debugging, and JKLog for logging.
  2. Overview of JKFrame core systems

    main

    JKFrame acts as a toolbox/plugin. Most systems are accessed directly via XXXSystem without requiring you to inherit from specific classes or interfaces.

    Core Systems:

    • Object Pool System: Reuses GameObject or standard class instances with configurable capacities.
    • Event System: A decoupling tool for function calls without needing direct references.
    • Resource System: Supports both Resources and Addressables versions, integrating with object pools for loading/unloading.
    • MonoSystem: Provides Update, FixedUpdate, and Coroutines for non-MonoBehaviour objects.
    • Audio System: Manages BGM (including looping), SFX, and global volume.
    • Save System: Supports multiple saves, automatic caching, player settings (non-save specific), and both Binary (production) and JSON (development) formats.
    • Log System: Controls and saves logs.
    • UI System: Manages UI window layering and Tips.
    • Scene System: Wraps Unity scene loading to monitor progress.
    • Localization System: Supports global/local configurations and an automatic UI localization collector for Text and Image components.

    Additional Tools:

    • State Machine: For script logic.
    • Event Tool: Adds click, mouse enter/drag, collision, trigger, and destruction events to objects without extra scripts.
    • Coroutine Tool: Optimized coroutines to avoid GC.
  3. Overview of the Resource System

    main

    The Resource System manages the acquisition, asynchronous loading, and unloading of Unity resources, GameObjects, and class objects.

    Performance Optimization: When requesting a resource, the system first checks the corresponding Object Pool (GOP or OP). It only performs a standard resource load/instantiation if the pool is empty or does not exist.

    Supported Versions:

    • Resources version: Associates object pools with standard Unity Resources loading/unloading.
    • Addressables version: Associates object pools with Addressables. It includes integration with event tools to automatically call Addressables.Unload when a GameObject is destroyed.

    You can switch between these versions in the framework settings.

  4. Understand the UI Window Data Model

    main

    The UI framework maintains a central registry of all windows in a Dictionary<string, UIWindowData>.

    Each UIWindowData entry contains:

    • isCache: Boolean indicating if the window should be pooled/reused.
    • assetPath: The resource location (Addressables or Resources).
    • layerNum: The rendering priority.
    • instance: The actual active UI_WindowBase instance (null if not currently instantiated).

    By using a windowKey instead of a raw file path as the index, the framework allows multiple distinct window instances to share the same underlying prefab/class resource.

  5. How the Object Pool system works

    main

    The Object Pool system reduces performance overhead and Garbage Collection (GC) by reusing instances instead of frequent Instantiate and Destroy calls.

    JKFrame provides two types of pools:

    1. GameObject Pool (GOP): Manages GameObject instances that exist in the scene (visible in Hierarchy).
    2. Object Pool (OP): Manages non-scene objects like C# classes or material resources.

    Key Features:

    • Capacity Limits: You can set a maxCapacity. If the pool exceeds this limit, new objects being returned to the pool will be Destroyed instead of stored.
    • Pre-warming: You can specify a defaultQuantity during initialization to instantiate and fill the pool with objects immediately.
    • Global vs. Local: Most users should use the global PoolSystem. However, you can build custom pools by holding a PoolModule layer.
  6. Manage UI layers and masks

    main

    The framework implements a layer management system with built-in masking (Mask).

    • Masking Behavior: By default, layers are stacked. If a window is active in a layer, all layers below it are non-interactive. Within the same layer, only the most recently opened window is interactive, ensuring only one window per layer is active at a time.
    • Disabling Masks: You can uncheck the mask option in the UISystem panel to allow interaction across layers.
    • Drag Layer: A special top-level layer called dragLayer is provided for temporary UI placement during drag operations. Access it via UISystem.dragLayer.
  7. Additional Utilities in JKFrame

    main

    Beyond the core systems, JKFrame includes several utility tools:

    • State Machine: For managing script logic states.
    • Event Tool: Binds events like Collision, Trigger, Click, Drag, and custom events to objects.
    • Coroutine Tool: Optimized coroutines designed to avoid Garbage Collection (GC).
    • Excel and ScriptableObject Converter: Enables conversion between Excel and Unity assets (Prefabs, Sprites, etc.). It supports GUID mode (allowing prefab path changes without breaking references) and SubAsset support (e.g., sliced sprites).
  8. Core Systems in JKFrame

    main

    JKFrame provides several specialized systems to handle common game development tasks:

    Primary Systems

    • Object Pool System: Reuses GameObject or standard class instances with configurable capacities.
    • Event System: A decoupling tool that allows function calls without maintaining direct references.
    • Resource System: Supports two modes:
      • Resources version: Manages loading/unloading tied to object pools.
      • Addressables version: Manages loading/unloading tied to object pools; can be combined with the Event tool to automatically call Addressables.Unload upon destruction.
    • MonoSystem: Provides Update, FixedUpdate, and Coroutine functionality to non-MonoBehaviour objects.
    • Audio System: Handles background music (BGM), BGM looping, special effect audio, and global volume control.
    • Save System:
      • Supports multiple save slots.
      • Features automatic caching to reduce disk I/O.
      • Supports saving player settings (data not tied to a specific save slot).
      • Supports JSON (for debugging during development) and Binary (for encryption and size reduction in production).
    • Log System: Provides log control and saving capabilities.
    • UI System: Manages UI window layering and provides a 'Tips' feature.
    • Scene System: A wrapper for Unity scene loading used to monitor loading progress.
    • Localization System: Supports global configurations, local configurations (loaded with GameObjects), and an automatic UI localization collector for Text and Image components.
  9. Extend the Localization System for new data types

    main

    The localization system is extensible. You can add support for new asset types (like AudioClips) by inheriting from LocalizationDataBase and implementing a new data class.

    Implementation Steps:

    1. Create a new class inheriting from LocalizationDataBase.
    2. Add the desired fields (e.g., public AudioClip content;).
    3. Use LocalizationSystem.GetContent<YourNewClass>(key, languageType) to retrieve it.

    Example: Adding Weapon Data

    public class LocalizationWeaponData : LocalizationDataBase
    {
        public string content;
        public string type;
    }
    // Example of a custom data class for localization
    public class LocalizationWeaponData : LocalizationDataBase
    {
        public string content;
        public string type;
    }
  10. Use the Mono Proxy System for non-MonoBehaviour scripts

    main
    Since most framework systems are static utility classes, they cannot natively run Unity Coroutines or lifecycle methods. The MonoSystem (a singleton that must be attached to a GameObject) acts as a proxy. This allows non-MonoBehaviour classes (like StateBase classes in a State Machine) to utilize Unity's lifecycle and coroutine capabilities.
  11. Use serialized wrappers for Dictionary, Vector, and Color

    main

    To ensure compatibility with the save system, the framework provides specialized serialized versions of common Unity/C# types. These wrappers handle the conversion between complex types (like Dictionaries) and simple serializable structures (like Lists).

    • Dictionary: Serialized_Dic (automatically splits into a List for serialization and reconstructs the Dictionary on load).
    • Vector: Serialized_Vector2, Serialized_Vector3 (stores only x, y, z coordinates).
    • Color: Serialized_Color (stores only r, g, b, a).

    Usage: Replace your standard type declarations with these serialized versions. The framework overloads assignment operators and type conversion methods, allowing them to work seamlessly with native Unity types.

  12. Manage GameObjects (GOP) using Addressables

    main

    For Unity GameObject resources, the ResSystem uses Addressables to manage instantiation and pooling. This is known as the GameObject Pool (GOP).

    Initialization

    Initialize a GOP using a keyName or an assetName (the Addressable resource name).

    • maxCapacity: Maximum objects in pool. Excess objects are destroyed.
    • assetName: The Addressable name used to fetch the prefab.
    • defaultQuantity: Number of GameObjects to pre-load and instantiate into the pool.

    Instantiation

    • Synchronous: InstantiateGameObject returns the GameObject immediately. You can also use the generic version InstantiateGameObject<T> to get a specific component directly.
    • Asynchronous: InstantiateGameObjectAsync uses a callback to return the object once loading is complete.
    • autoRelease: If set to true, the system attaches a listener so that when the object is Destroyed, the underlying Addressable resource is automatically released.

    Unloading

    Use PushGameObjectInPool to return a GameObject to its pool. If no pool exists for the object's name/key, an infinite pool is created automatically.

    // Initialize a Bullet pool using Addressable name 'Bullet'
    ResSystem.InitGameObjectPoolForAssetName("Bullet", 30, 30);
    
    // Synchronous instantiation
    GameObject bullet = ResSystem.InstantiateGameObject("Bullet");
    
    // Synchronous instantiation with a component
    Rigidbody rb = ResSystem.InstantiateGameObject<Rigidbody>("Bullet");
    
    // Asynchronous instantiation
    ResSystem.InstantiateGameObjectAsync("Bullet", (GameObject go) => {
        go.transform.position = Vector3.zero;
    });
    
    // Return to pool
    ResSystem.PushGameObjectInPool(bullet, "Bullet");