Last active
December 21, 2016 10:24
-
-
Save austinmao/eaec7f1983bfc549ddd1cd7050a71e89 to your computer and use it in GitHub Desktop.
Unidux + UniRx for character movement
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
public static class Move { | |
// specify the possible types of actions | |
public enum ActionType { | |
Move, | |
Stop | |
} | |
// actions must have a type and may include a payload | |
public class Action { | |
public ActionType actionType; | |
public Vector2 inputVelocity; | |
public Transform playerTransform; // curent transform | |
public Vector3 moveDistance; // movement from current transform | |
} | |
// reducers handle state changes | |
public static class Reducer { | |
public static State Reduce(State state, Action action) { | |
switch (action.actionType) { | |
case ActionType.Move: | |
state.moving = true; | |
// store velocity in state | |
var inputVelocity = state.inputVelocity = action.inputVelocity; | |
// calculate velocity | |
var playerTransform = action.playerTransform; | |
var playerVelocity = (inputVelocity.x * playerTransform.right) + (inputVelocity.y * playerTransform.forward); | |
// calculate and store moveDistance in state | |
var moveDistance = state.moveDistance = playerVelocity * Time.fixedDeltaTime; | |
break; | |
case ActionType.Stop: | |
state.moving = false; | |
break; | |
} | |
return state; | |
} | |
} | |
// ActionCreators create 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 Move(Vector3 moveDistance) { | |
// create new action instance | |
Action action_ = new Action(); | |
// specify required actionType and optional payloads | |
action_.actionType = ActionType.Move; | |
// set distance payload | |
action_.moveDistance = moveDistance; | |
// return action to the reducer | |
return action_; | |
} | |
public static Action Stop() { | |
Action action_ = new Action(); | |
action_.actionType = ActionType.Stop; | |
return action_; | |
} | |
} | |
// BoundActionCreators are helper functions to dispatch action creators | |
public static class BoundActionCreator { | |
public static void Move(Vector2 inputVelocity, Transform transform) { | |
UniduxStore.Instance.Store.Dispatch(ActionCreator.Move(inputVelocity)); | |
} | |
public static void Stop() { | |
UniduxStore.Instance.Store.Dispatch(ActionCreator.Stop()); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Obviously incomplete */ | |
// using UnityEngine; | |
// using UniRx; | |
// using UniRx.Triggers; | |
// using Unidux; | |
// public class MoveRenderer : MonoBehaviour { | |
// private State state_ = UniduxStore.Instance.Store.State; | |
// void Start() { | |
// renderMove(); | |
// } | |
// void renderMove(IObservable<Vector2> moveVector) { | |
// state_.moveDistance.Subscribe(inputVelocity => { | |
// var playerVelocity = (inputVelocity.x * transform.right) + (inputVelocity.y * transform.forward); | |
// var distance = playerVelocity * Time.fixedDeltaTime; | |
// // character.Move(distance); | |
// Debug.Log($"going to dispatch {distance}"); | |
// Move.BoundActionCreator.Move(distance); | |
// // UniduxStore.Instance.Store.Dispatch(Move.ActionCreator.Move(distance)); | |
// // TODO: figure out how to dispatch variables | |
// // UniduxStore.Instance.Store.Dispatch(ActionType, distance); | |
// }) | |
// .AddTo(this); | |
// } | |
// } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using UniRx; | |
using UniRx.Triggers; | |
public class PCMoveObserver : MonoBehaviour { | |
void Start() { | |
observeAndDispatchInput(); | |
} | |
void observeAndDispatchInput() { | |
this.FixedUpdateAsObservable() | |
// get inputs by axis | |
.Select(_ => { | |
var x = Input.GetAxis("Horizontal"); | |
var y = Input.GetAxis("Vertical"); | |
return new Vector2(x, y).normalized; | |
}) | |
// performance optimization: only dispatch if non-zero movement | |
.Where(v => v != Vector2.zero) | |
// dispatch inputVelocity and GameObject transform to move reducer | |
.Subscribe(inputVelocity => Move.BoundActionCreator.Move(inputVelocity, transform)) | |
// dispose of the observable if GameObject is disposed | |
.AddTo(this); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using Unidux; | |
public class State : StateBase<State> | |
{ | |
public bool moving { get; set; } | |
public Vector2 inputVelocity { get; set; } | |
public Vector3 moveDistance { get; set; } | |
public override State Clone() { | |
var state = (State)MemberwiseClone(); | |
return state; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Unidux; | |
using UnityEngine; | |
public class UniduxStore : SingletonMonoBehaviour<UniduxStore> { | |
private Store<State> _store; | |
public Store<State> Store { | |
get { | |
if (null == _store) { | |
_store = new Store<State>(new State()); | |
AddReducers(); | |
} | |
return _store; | |
} | |
} | |
void Update() { | |
this.Store.Update(); | |
} | |
// add all reducers here | |
void AddReducers() { | |
_store.AddReducer<Move.Action>(Move.Reducer.Reduce); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment