• Stars
    star
    385
  • Rank 110,816 (Top 3 %)
  • Language
    C#
  • License
    MIT License
  • Created over 8 years ago
  • Updated about 3 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Redux Architecture for Unity 🎩

Join the chat at https://gitter.im/Unidux/Lobby

Unidux is practical application architecture for Unity3D UI.

It's inspired by Redux.

Install

UPM

Add following two lines to Pacakges/manifest.json.

{
 "com.neuecc.unirx": "https://github.com/neuecc/UniRx.git?path=Assets/Plugins/UniRx/Scripts",
 "me.mattak.unidux": "https://github.com/mattak/Unidux.git?path=Assets/Plugins/Unidux/Scripts",
 // ...
}

Unity package

No longer supported. If you need older versions, import unitypackage from latest releases.

Usage

  1. Create your Unidux singleton and place it to unity scene.
using UniRx;
using Unidux;

public sealed class Unidux : SingletonMonoBehaviour<Unidux>, IStoreAccessor
{
    public TextAsset InitialStateJson;

    private Store<State> _store;

    public IStoreObject StoreObject
    {
        get { return Store; }
    }

    public static State State
    {
        get { return Store.State; }
    }

    public static Subject<State> Subject
    {
        get { return Store.Subject; }
    }

    private static State InitialState
    {
        get
        {
            return Instance.InitialStateJson != null
                ? JsonUtility.FromJson<State>(Instance.InitialStateJson.text)
                : new State();
        }
    }

    public static Store<State> Store
    {
        get { return Instance._store = Instance._store ?? new Store<State>(InitialState, new Count.Reducer()); }
    }

    public static object Dispatch<TAction>(TAction action)
    {
        return Store.Dispatch(action);
    }

    void Update()
    {
        Store.Update();
    }
}

Note: ReplaySubject is a ReactiveX concept provided by UniRx in this example.

  1. Create state class to store application state.
using System;

[Serializable]
public class State : StateBase
{
    public int Count = 0;
}
  1. Define action to change state. Define Reducer to move state.
public static class Count
{
    // specify the possible types of actions
    public enum ActionType
    {
        Increment,
        Decrement
    }

    // actions must have a type and may include a payload
    public class Action
    {
        public ActionType ActionType;
    }

    // ActionCreators creates actions and deliver payloads
    // in redux, you do not dispatch from the ActionCreator to allow for easy testability
    public static class ActionCreator
    {
        public static Action Create(ActionType type)
        {
            return new Action() {ActionType = type};
        }

        public static Action Increment()
        {
            return new Action() {ActionType = ActionType.Increment};
        }

        public static Action Decrement()
        {
            return new Action() {ActionType = ActionType.Decrement};
        }
    }

    // reducers handle state changes
    public class Reducer : ReducerBase<State, Action>
    {
        public override State Reduce(State state, Action action)
        {
            switch (action.ActionType)
            {
                case ActionType.Increment:
                    state.Count++;
                    break;
                case ActionType.Decrement:
                    state.Count--;
                    break;
            }

            return state;
        }
    }
}
  1. Create Renderer to display state and attach it to Text GameObject.
[RequireComponent(typeof(Text))]
public class CountRenderer : MonoBehaviour
{
    void OnEnable()
    {
        var text = this.GetComponent<Text>();

        Unidux.Subject
            .TakeUntilDisable(this)
            .StartWith(Unidux.State)
            .Subscribe(state => text.text = state.Count.ToString())
            .AddTo(this)
            ;
    }
}
  1. Create dispatcher to update count and attach it to GameObject.
[RequireComponent(typeof(Button))]
public class CountDispatcher : MonoBehaviour
{
    public Count.Action Action = Count.ActionCreator.Increment();

    void Start()
    {
        this.GetComponent<Button>()
            .OnClickAsObservable()
            .Subscribe(state => Unidux.Store.Dispatch(Action))
            .AddTo(this)
            ;
    }
}

That's it!

Example

Dependencies

  • UniRx
  • MiniJSON (for Unidux.Experimental.Editor.StateJsonEditor)

API

StateBase

public class State : StateBase
{
    public int Count;
}

<StateBase>.Clone()

State _state = new State();
State _clonedState = _state.Clone();

Create a deep clone of the current state. Useful for Immutability.

Store

IReducer[] reducers = new IReducer[]{};
Store _store = new Store<State>(State, reducers);
// State must extend StateBase

<Store>.State

Get the state as passed to the constructor.

<Store>.Dispatch(object)

Dispatch an event of TAction object, which will trigger a Reducer<TAction>.

<Store>.ApplyMiddlewares(params Middleware[] middlewares)

Apply middlewares to Store object which implement delegate function of Middleware.

<Store>.Update()

When at least one reducer has been executed, trigger all the renderers with a copy of the current state.

<Store>.ForceUpdate()

Trigger all registered renderers with a copy of the current state regardless of any reducers having been executed.

SingletonMonoBehaviour

public class Foo : SingletonMonoBehaviour<Foo> {}

A singleton base class to extend. Extends MonoBehaviour.

<SingletonMonoBehaviour>.Instance

public class Foo : SingletonMonoBehaviour<Foo> {}

Foo.Instance

The instance of the base class.

Performance

Clone()

Default implemention of StateBase.Clone() is not fast, because it uses BinaryFormatter & MemoryStream. And Unidux creates new State on every State chaning (it affects a few milliseconds). So in case of requiring performance, override clone method with your own logic.

e.g.

[Serializable]
class State : StateBase
{
    public override object Clone()
    {
        // implement your custom deep clone code
    }
}

Equals()

Default implemention of StateBase.Equals() and StateElement.Equals() is not fast, because it uses fields and properties reflection. In case of edit state on UniduxPanel's StateEditor, it calls Equals() in order to set IsStateChanged flags automatically. So in case of requiring performance, override Equals() method with your own logic.

e.g.

[Serializable]
class State : StateBase
{
    public override bool Equals(object obj)
    {
        // implement your custom equality check code
    }
}

Thanks

License

MIT

More Repositories

1

Unibus

Unibus is event passing system for Unity3D. 🚀
C#
63
star
2

Unicache

Cache management system for Unity3D 🐷
C#
59
star
3

Nodux

Node base redux inspired framework
C#
21
star
4

UniRxQuiz

Quiz for UniRx learning 🔎
C#
18
star
5

KotlinMoment

SwiftMoment for kotlin. ⏰
Kotlin
14
star
6

LineSample

Unity line mesh sample
C#
13
star
7

CameraUploader

android camera application.
Java
13
star
8

EnumSelection

Unity editor extension to select enum class & value 😁
C#
12
star
9

GeoHex.cs

GeoHex C# script 🦋
C#
10
star
10

AspectRatioLayout

Android Layout component to handle aspect ratio base layout. 📐
Java
9
star
11

TopoMap

TopoMap is topojson rendering utility for Unity3D 🗺
C#
9
star
12

Autumn

Android animator library inspired by Spring. ✨
Java
9
star
13

component

Component pattern to minimize your Android Activity/Fragment. 📦
Java
7
star
14

NumberingEditor

📜Numbering GameObject
C#
5
star
15

UniRxLearning

Learning UniRx with creating their functions
C#
5
star
16

ClipView

Android library for clipping view. 🎃
Java
5
star
17

chrome-DriveImagePermalink

Create Google Drive Image Permalink
JavaScript
4
star
18

gradient_shader

unity simple gradient shader
ShaderLab
3
star
19

android-SigningExportSample

android gradle signing export sample
Java
3
star
20

unitylock

Lock Unity3D files and share with team member
JavaScript
3
star
21

ConsoleSample

C# Console Application Example working on Mac.
C#
3
star
22

bist

control gist files to install.
Shell
3
star
23

OutlinedText

Outlined Text for android
Java
3
star
24

ios-contents-json

Modify xcode's xcassets Contents.json
Ruby
2
star
25

GaucheEuler

Project Euler solution with Gauche
Scheme
2
star
26

loglint

linter by analyzing build log
Go
2
star
27

RetrofitSample

sample for retrofit 2.0.0-beta2
Java
2
star
28

gradle-buildbot-plugin

The gradle plugin which post message to irc.
Shell
2
star
29

FlyingBird

Tutorial for unity beginner.
C#
2
star
30

UnitylockExtension

Unity3D editor extension for unitylock
C#
2
star
31

shikiho

extract shikiho json from html archive
Go
2
star
32

keireki-generator

mendokusai keirekisyo wo rakuni tsukuru
JavaScript
2
star
33

csv2tsv

simple csv2tsv converter
Go
2
star
34

MagicOnionConsoleSample

C#
2
star
35

UnityReduxSample

Redux inspired architecture for unity
C#
2
star
36

swikt

Swift to kotlin transpiler
JavaScript
2
star
37

html-parallax-template

html parallax template
CoffeeScript
1
star
38

xsidr

xml select insert delete replace
Ruby
1
star
39

UIToolkitBinding

Binding class generator for UIToolkit
C#
1
star
40

KotlinAndroidTestSample

TestSample for Kotlin Android project
Kotlin
1
star
41

idontlikearchitecture

I dont like architecture discussion.
C#
1
star
42

TopCoder

Single Round Match
1
star
43

lctee

logcat and tee.
Go
1
star
44

Revival

under development
C#
1
star
45

FoodRecognizer

android image annotation interface supported with opencv
C++
1
star
46

cl-svm

libsvm wrapper in clojure
Clojure
1
star
47

adbtools

Ruby
1
star
48

AutolayoutLabo

projects to show proportional layout in autolayout.
Swift
1
star
49

UnityListView

ListView sample for Unity3D
C#
1
star
50

WaterMark

watermark test
C++
1
star
51

ninja-bot

my hubot
CoffeeScript
1
star
52

UnityHooks

Hooks for Unity
C#
1
star
53

giny

git hosting service for private repository
Ruby
1
star
54

hubot-hello-ninja

The most useless script. just say hello to ninja.
CoffeeScript
1
star
55

Fractal

see mandelbrot set with Android
Java
1
star
56

cathand_android_runner

Android executable for running cathand operation
C++
1
star
57

simplepost

simple post file server on sinatra
Ruby
1
star
58

bow

bag of visual words for python
C++
1
star
59

dotfiles

mac, linux dotfiles
Vim Script
1
star
60

unityguid

List up unity guids
Go
1
star
61

mattak.github.com

playground
HTML
1
star
62

starthaskell

start haskell 2
Haskell
1
star
63

kettou-countdown-firebase

firebase app for GoogleHome
TypeScript
1
star
64

node-xenial

Docker image for node instance on ubuntu 16.04 (xenial)
1
star
65

SceneListGenerator

Unity scene list code generator from EditorBuildSettgins scene list
C#
1
star
66

KotlinJsSample

The sample of kotlin js.
JavaScript
1
star