Last active
October 24, 2018 10:27
-
-
Save FNGgames/47021f7604d14369426c2aeddbf82dce to your computer and use it in GitHub Desktop.
View layer abstraction for Entitas (with Unity implementation).
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 System.Collections.Generic; | |
using Entitas; | |
public class AssignGameViewSystem : ReactiveSystem<GameEntity> | |
{ | |
private readonly Contexts _contexts; | |
public AssignGameViewSystem(Contexts contexts) : base(contexts.game) | |
{ | |
_contexts = contexts; | |
} | |
protected override ICollector<GameEntity> GetTrigger(IContext<GameEntity> context) | |
{ | |
return context.CreateCollector(GameMatcher.AssignView); | |
} | |
protected override bool Filter(GameEntity entity) | |
{ | |
return entity.isAssignView && !entity.hasGameView; | |
} | |
protected override void Execute(List<GameEntity> entities) | |
{ | |
foreach (var e in entities) | |
{ | |
var view = _contexts.meta.contentService.instance.CreateView(); | |
view.Link(e, _contexts.game); // game view component is assigned in here | |
e.isAssignView = false; | |
} | |
} | |
} |
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 System.Collections.Generic; | |
using Entitas; | |
public class LoadGameAssetSystem : ReactiveSystem<GameEntity> | |
{ | |
private readonly Contexts _contexts; | |
public LoadGameAssetSystem(Contexts contexts) : base(contexts.game) | |
{ | |
_contexts = contexts; | |
} | |
protected override ICollector<GameEntity> GetTrigger(IContext<GameEntity> context) | |
{ | |
return context.CreateCollector(GameMatcher.Asset); | |
} | |
protected override bool Filter(GameEntity entity) | |
{ | |
return entity.hasAsset && !entity.hasGameView; | |
} | |
protected override void Execute(List<GameEntity> entities) | |
{ | |
foreach (var e in entities) | |
{ | |
var view = _contexts.meta.contentService.instance.LoadAsset(e.asset.name); | |
if (view == null) continue; | |
view.Link(e, _contexts.game); // view component assigned in here | |
} | |
} | |
} |
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 System; | |
using UnityEngine; | |
public class UnityContentService : IContentService | |
{ | |
protected GameObject _viewContainer; | |
protected GameObject _viewPrototype; | |
public UnityContentService() | |
{ | |
// init view container | |
_viewContainer = new GameObject("Views"); | |
_viewContainer.transform.SetParent(_topViewContainer); | |
// game prototype is simple game object | |
_viewPrototype = new GameObject("Game View Prototype"); | |
_viewPrototype.transform.SetParent(_viewContainer.transform); | |
_viewPrototype.SetActive(false); | |
} | |
public IViewController CreateView() | |
{ | |
// spawn new game view | |
var gameObject = GameObject.Instantiate(_viewPrototype); | |
gameObject.transform.SetParent(_viewContainer.transform); | |
return gameObject.AddComponent<UnityViewController>(); | |
} | |
public IViewController LoadAsset(string name) | |
{ | |
// spawn prefab | |
var prefab = CachedResources.Load<GameObject>("Prefabs/Game/"+ name); | |
if (prefab == null) return null; | |
var gameObject = GameObject.Instantiate(prefab); | |
gameObject.transform.SetParent(_viewContainer.transform) | |
var view = gameObject.GetComponent<UnityViewController>(); | |
if (view == null) view = prefab.AddComponent<UnityViewController>(); | |
return view; | |
} | |
} |
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 Entitas; | |
using Entitas.Unity; | |
using UnityEngine; | |
public class UnityGameView : MonoBehaviour, IGameView | |
{ | |
protected GameEntity _entity; | |
protected SpriteRenderer _spriteRenderer; | |
protected Rigidbody2D _rigidBody; | |
protected Collider2D _collider; | |
// IView | |
public virtual void SetActive(bool active) | |
{ | |
gameObject.SetActive(active); | |
} | |
public virtual void SetName(string name) | |
{ | |
gameObject.name = name; | |
} | |
public virtual void Link(IEntity entity, IContext context) | |
{ | |
_entity = (GameEntity) entity; | |
_entity.ReplaceGameView(this); | |
gameObject.Link(_entity, context); | |
_entity.Retain(this); | |
// if this came from an prefab and not a fresh view, copy values | |
// from Unity components to entitas components | |
if (_entity.hasAsset) SyncUnityComponents(); | |
for (var i = 0; i < transform.childCount; i++) | |
{ | |
var childGo = transform.GetChild(i).gameObject; | |
var childView = childGo.GetComponent<UnityGameView>(); | |
if (childView == null) childView = childGo.AddComponent<UnityGameView>(); | |
var e = ((GameContext) context).CreateEntity(); | |
childView.Link(e, context); | |
childView.SyncUnityComponents(); | |
} | |
} | |
public virtual void Unlink() | |
{ | |
gameObject.Unlink(); | |
_entity.Release(this); | |
_entity = null; | |
} | |
public virtual void SetParent(IView parent) | |
{ | |
var parentView = (UnityGameView) parent; | |
if (parentView == null) return; | |
transform.SetParent(parentView.transform); | |
} | |
public virtual void RemoveParent() | |
{ | |
if (_viewContainer != null) transform.SetParent(_viewContainer); | |
} | |
public virtual void DestroyView() | |
{ | |
Destroy(gameObject); | |
} | |
// IGraphics | |
public virtual void SetImage(string name) | |
{ | |
if (_spriteRenderer == null) _spriteRenderer = gameObject.AddComponent<SpriteRenderer>(); | |
_spriteRenderer.sprite = CachedResources.Load<Sprite>("Sprites/Game/" + name); | |
} | |
public virtual void SetImageColor(ColorVector color) | |
{ | |
if (_spriteRenderer == null) return; | |
_spriteRenderer.color = new Color(color.r, color.g, color.b, _spriteRenderer.color.a); | |
} | |
public virtual void SetImageAlpha(float a) | |
{ | |
if (_spriteRenderer == null) return; | |
var color = _spriteRenderer.color; | |
color.a = a; | |
_spriteRenderer.color = color; | |
} | |
public virtual void SetImageRenderOrder(int order) | |
{ | |
if (_spriteRenderer == null) return; | |
_spriteRenderer.sortingOrder = order; | |
} | |
public virtual void RemoveImage() | |
{ | |
if (_spriteRenderer == null) return; | |
Destroy(_spriteRenderer); | |
} | |
// IPhysics | |
public virtual Vector2D Position | |
{ | |
get { return _rigidBody != null ? new Vector2D(_rigidBody.position.x, _rigidBody.position.y) : new Vector2D(transform.position.x, transform.position.y); } | |
set | |
{ | |
if (_rigidBody != null) _rigidBody.position = new Vector2(value.x, value.y); | |
else transform.position = new Vector3(value.x, value.y, 0); | |
} | |
} | |
public virtual Vector2D Velocity | |
{ | |
get { return _rigidBody != null ? new Vector2D(_rigidBody.velocity.x, _rigidBody.velocity.y) : Vector2D.zero; } | |
set { if (_rigidBody != null) _rigidBody.velocity = new Vector2(value.x, value.y); } | |
} | |
public virtual void CreateRigidbody() | |
{ | |
if (_rigidBody != null) return; | |
_rigidBody = gameObject.AddComponent<Rigidbody2D>(); | |
_rigidBody.gravityScale = _rigidBody.drag = 0; | |
_rigidBody.collisionDetectionMode = CollisionDetectionMode2D.Continuous; | |
_rigidBody.interpolation = RigidbodyInterpolation2D.Extrapolate; | |
} | |
public virtual void AddForce(Vector2D force) | |
{ | |
if (_rigidBody == null) return; | |
_rigidBody.AddForce(new Vector2(force.x, force.y)); | |
} | |
public virtual void SetDrag(float drag) | |
{ | |
if (_rigidBody == null) return; | |
_rigidBody.drag = drag; | |
_rigidBody.angularDrag = 10 * drag; | |
} | |
public virtual void SetBounciness(float bounciness) | |
{ | |
if (_rigidBody == null) return; | |
var mat = new PhysicsMaterial2D { bounciness = bounciness }; | |
_rigidBody.sharedMaterial = mat; | |
if (_edgeCollider == null && _collider == null) return; | |
if (_edgeCollider != null) _edgeCollider.sharedMaterial = mat; | |
if (_collider != null) _collider.sharedMaterial = mat; | |
} | |
public virtual void SetMass(float mass) | |
{ | |
if (_rigidBody == null) return; | |
_rigidBody.mass = mass; | |
} | |
public virtual void SetKinematic(bool isKinematic) | |
{ | |
if (_rigidBody == null) return; | |
_rigidBody.isKinematic = isKinematic; | |
} | |
public virtual void SetSimulated(bool isSimulated) | |
{ | |
if (_rigidBody == null) return; | |
_rigidBody.simulated = isSimulated; | |
} | |
public virtual void SetPosition(float x, float y) | |
{ | |
if (_rigidBody == null) return; | |
_rigidBody.position = new Vector2(x, y); | |
} | |
public virtual void CreateCollider() | |
{ | |
if (_collider == null) _collider = gameObject.AddComponent<PolygonCollider2D>(); | |
} | |
public virtual void SetColliderAsTrigger(bool isTrigger) | |
{ | |
if (_collider != null) _collider.isTrigger = true; | |
} | |
public virtual void RemoveRigidbody() | |
{ | |
if (_rigidBody != null) Destroy(_rigidBody); | |
} | |
public virtual void RemoveCollider() | |
{ | |
if (_collider != null) Destroy(_collider); | |
} | |
// sync unity component values to entity component values | |
protected virtual void SyncUnityComponents() | |
{ | |
if (!_entity.hasName) _entity.AddName(name); | |
if (!_entity.hasTag) _entity.AddTag(tag); | |
_spriteRenderer = GetComponent<SpriteRenderer>(); | |
if (_spriteRenderer != null) | |
{ | |
_entity.ReplaceImage(_spriteRenderer.sprite.name); | |
_entity.ReplaceImageColor(_spriteRenderer.color.ToColorVector()); | |
_entity.ReplaceImageAlpha(_spriteRenderer.color.a); | |
_entity.ReplaceImageRenderOrder(_spriteRenderer.sortingOrder); | |
} | |
_rigidBody = GetComponent<Rigidbody2D>(); | |
if (_rigidBody != null) | |
{ | |
_entity.isRigidbody = true; | |
_entity.ReplaceMass(_rigidBody.mass); | |
_entity.ReplaceDrag(_rigidBody.drag); | |
_entity.ReplaceBounciness(_rigidBody.sharedMaterial.bounciness); | |
} | |
_collider = gameObject.GetComponent<Collider2D>(); | |
if (_collider != null) _entity.isCollider = true; | |
var parent = transform.parent; | |
if (parent == null) return; | |
var parentView = transform.parent.gameObject.GetComponent<UnityGameView>(); | |
if (parentView != null) _entity.ReplaceParent(parentView._entity.id.value); | |
} | |
} |
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 Entitas; | |
public interface IContentService | |
{ | |
IViewController CreateView(); | |
IViewController LoadAsset(string name); | |
} | |
public interface IViewController : IView, IGraphics2D, IPhysics2D | |
{ | |
} | |
public interface IView | |
{ | |
void SetActive(bool active); | |
void SetName(string name); | |
void Link(IEntity entity, IContext context); | |
void Unlink(); | |
void SetParent(IView parent); | |
void RemoveParent(); | |
void DestroyView(); | |
} | |
public interface IGraphics2D | |
{ | |
void SetImage(string name); | |
void SetImageColor(ColorVector color); | |
void SetImageAlpha(float a); | |
void SetImageRenderOrder(int order); | |
void RemoveImage(); | |
} | |
public interface IPhysics2D | |
{ | |
Vector2D Position { get; set; } | |
Vector2D Velocity { get; set; } | |
void AddForce(Vector2D force); | |
void SetDrag(float drag); | |
void SetBounciness(float bounciness); | |
void SetMass(float mass); | |
void SetKinematic(bool isKinematic); | |
void SetSimulated(bool isSimulated); | |
void CreateRigidbody(); | |
void CreateCollider(); | |
void SetColliderAsTrigger(bool isTrigger); | |
void RemoveRigidbody(); | |
void RemoveCollider(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment