Skip to content

Installation

TinyPlay edited this page Aug 5, 2022 · 1 revision

Installation

Unpack .unitypackage from latest release of this repository to your unity project or just clone this repo and open as Unity Project.

Project tested at Unity 2020.3

Scene Installer

This is a basic class with any project initializations at the scene. Your scene may contains only SceneInstaller and preload all content at fly.

Basic Scene Installer Example:

using Demo.Camera;
using Demo.Input;
using Demo.Player;
using UnityEngine;
using XDot.Core;

namespace Demo
{
    internal class SceneInstaller : BaseInstaller
    {
        private InputPresenter _input;
        
        // Initialize All Basic Presenters on Scene Start
        public override void OnSceneStart()
        {
            _input = new InputPresenter(new InputPresenter.Context { });
        }
    }
}

MVP Triad

Any objects in your game must be contain at least one element from the Triad. Basically you have MVP (Model, View, Presenter) classes.

Simple Presenter Example:

using System;
using Demo.Camera.Handlers;
using UnityEngine;
using XDot.ContentLoader;
using XDot.Core;
using XDot.Events;
using XDot.Handlers;

namespace Demo.Camera
{
    // Simple Camera Presenter
    internal class CameraPresenter : BasePresenter
    {
        public struct Context : IContext
        {
            public Transform Target;            // Camera Target
        }

        private bool _isLoaded = false;
        private GameObject _cameraObject;

        private readonly GameEvent<CameraHandler> _cameraUpdate = new GameEvent<CameraHandler>();
        private Vector3 _camPosition = Vector3.zero;
        private Quaternion _camRotation = Quaternion.identity;
        
        // Presenter Initialization
        public CameraPresenter(Context context) : base(context)
        {
            // Load Model
            CameraModel cameraModel = new CameraModel();
            SetModel(cameraModel);
            LoadModel<CameraModel>(Application.persistentDataPath+"/CameraSettings.dat", handler =>
            {
                Debug.Log($"Failed to load Camera Model. {handler.Message}");
            });
            
            // Load View
            LoadView("Demo/CameraView", LoaderType.Resources, OnViewLoaded, handler => throw new Exception($"Failed to load Camera View. {handler.Message}"));
            
            // Bind GameLoop Events
            EventContainer.Get<GameEvent<FixedUpdateHandler>>().AddListener(OnFixedUpdateHandler);
            EventContainer.Bind(_cameraUpdate);
        }

        // Camera View Loaded
        private void OnViewLoaded(GameObject viewObject)
        {
            // Create Instance of Camera
            _cameraObject = GameObject.Instantiate(viewObject);
            
            // Setup Camera View
            CameraView camView = _cameraObject.GetComponent<CameraView>();
            camView.SetContext(new CameraView.Context
            {
                BasePosition = new CameraHandler
                {
                    Position = _camPosition,
                    Rotation = _camRotation
                }
            });
            SetView(camView);
            
            _isLoaded = true;
        }

        // Game Loop Event (FixedUpdate method analog)
        private void OnFixedUpdateHandler(FixedUpdateHandler updateData)
        {
            Transform currentTarget = GetContext<Context>().Target;
            if(currentTarget==null || !_isLoaded)
                return;
            
            Vector3 dirFromTarget = Quaternion.Euler(new Vector3(GetModel<CameraModel>().CameraAngle, 0f, 0f)) * Vector3.back;
            _camPosition = currentTarget.position + dirFromTarget * GetModel<CameraModel>().CameraDistance;
            _camRotation = Quaternion.LookRotation(-dirFromTarget, Vector3.up);
            _cameraUpdate?.Invoke(new CameraHandler
            {
                Position = _camPosition,
                Rotation = _camRotation
            });
        }
    }
}

Now, Look at View Example:

using System;
using Demo.Camera.Handlers;
using XDot.Core;
using XDot.Events;

namespace Demo.Camera
{
    // All Views are child of BaseView
    internal class CameraView : BaseView
    {
        public struct Context : IContext
        {
            public CameraHandler BasePosition;
        }
        private Context _context;

        // SetContext - it's an analog of constructor for
        // MonoBased Views
        public void SetContext(Context context)
        {
            _context = context;
            
            // Setup Base Position
            transform.SetPositionAndRotation(_context.BasePosition.Position, _context.BasePosition.Rotation);

            // Add Handlers
            EventContainer.Get<GameEvent<CameraHandler>>()?.AddListener(OnCameraUpdate);
        }

        // Unbind Events form Container on Destroy
        private void OnDestroy()
        {
            EventContainer.Unbind(EventContainer.Get<GameEvent<CameraHandler>>());
        }

        // Camera Update Handler
        private void OnCameraUpdate(CameraHandler cameraData)
        {
            transform.SetPositionAndRotation(cameraData.Position, cameraData.Rotation);
        }
    }
}

And our simple Model Example:

using XDot.Core;

namespace Demo.Camera
{
    // Simple Model Class for Camera
    [System.Serializable]
    internal class CameraModel : BaseModel
    {
        public float CameraAngle = 45f;
        public float CameraDistance = 10f;
    }
}

Events Container

You can bind any events using Events Container class. Don't forgot to unbind events before unload scene.

Usage Example:

// For example we have some method for bindings
private void EventContainerSample()
{
    // Simple Events Binding
    GameEvent<MyEventHandler> _myEvent = new GameEvent<MyEventHandler>();
    EventContainer.Bind(_myEvent);
    
    // Add Events Listener
    _myEvent.AddListener(OnEventFired);
    
    // Invoke Events from Container
    // By direct ref or using container
    _myEvent.Invoke(new MyEventHandler{
        Message = "Direct Message"
    });
    
    // Invoke throw container
    EventContainer.Get<MyEventHandler>().Invoke(new MyEventHandler{
        Message = "Container Message"
    });
    
    // Simple Events Unbinding
    EventContainer.Unbind(_myEvent);
}

// Here we grab event data
private void OnEventFired(MyEventHandler handlerData){
    Debug.Log(handlerData);
}

Handler Example:

// For all events we need some handlers
// for example Struct Handler
public struct MyEventHandler
{
    // Here we provide event data
    public string Message;
}

Demo Usage

Just open the Demo scene from: "Assets/Demo/"

General Topics:

Development Info

This framework is under MIT license. Developed by Ilya Rastorguev specially for Pixel Incubator.

Contacts

You can ask me about XDot Framework using Telegram @SodaBoom or by email: iliya-sdt@yandex.ru

Clone this wiki locally