Comments (9)
@JenkinJoe The models are normal C# classes. Depending on how/what you are doing you wont need them, maybe your presenter or controller just defines those fields. I use them mostly to parse json that comes from the server.
from karma.
@cgarciae Assuming that we have a Player Controller & Presenter. How do you handle several different logic behaviors like Player's Camera, Movement, Physics or Animations if you are doing it the "karmic" way? - Placing everything into the controller seems confusing for me especially if you intend to separate Settings per behavior.
from karma.
@JenkinJoe The philosophy is to use composition. You create other presenters for e.g. the camera, the characters, ect, and request them via dependency injection. You can create special presenters called elements which are intented to appear in view but they themselves are not views, that is, you cant request them through the router. I'll post 2 videos today about this.
from karma.
@cgarciae Yes that's true. But what I intended to achieve is having lossless coupled scripts fullfilling different tasks like those described above. And i did already use Elements for other things such as a Screen Fader or Audio Sources. But doing the same on the player's scripts would result in having redundant instantiated prefabs that do not perform a task. What i really want is a player controller that uses all of those scripts and combines them into one action e.g. walking with animations and physics.
So what i was thinking about is more zenject related. By defining something like this in the App\startup.cs:
public class Startup : App, ICApp
{
[SerializeField]
Settings _settings = null;
public DiContainer container { get; private set; }
public override void Configure(IApplication app, DiContainer container)
{
this.container = container;
container.Bind<ICApp>().ToInstance(this);
InstallSettings();
}
public override void Init(IRouter router, DiContainer container)
{
router.GoTo(MenuPresenter.view);
}
public override void OnPresenterDestroy()
{
}
public void InstallSettings()
{
container.Bind<PlayerPresenter.Camera.Settings>().ToSingleInstance(_settings.Player.Camera);
}
}
[Serializable]
public class Settings
{
public PlayerSettings Player;
[Serializable]
public class PlayerSettings
{
public PlayerPresenter.Camera.Settings Camera;
}
}
public interface ICApp{}
And in the PlayerPresenter:
public PlayerPresenter.Camera.Settings settings { get; private set; }
public void PostConstructor(ICApp _app, DiContainer container, PlayerController controller, PlayerPresenter.Camera.Settings settings)
{
this.app = (MVCPresenter)_app;
this.container = container;
this.controller = controller;
this.settings = settings;
controller.PostConstructor(this);
}
public class Camera
{
public Settings settings;
public Camera(Settings settings)
{
this.settings = settings;
}
[Serializable]
public class Settings
{
public int zoomRate = 200;
public float
playerHeight = 2.0f,
playerDistance = 3.0f,
minDistance = 2.0f,
maxDistance = 10.0f,
zoomDampening = 5.0f,
xSpeed = 200.0f,
ySpeed = 200.0f,
rotationDampening = 3.0f,
offsetFromWall = 0.1f,
fpsCamDist = -0.15f;
public bool canControl = true;
public LayerMask collisionLayers = -1;
public enum CameraState
{
FirstPerson,
ThirdPerson,
Orbit
}
public CameraState camState = CameraState.FirstPerson;
public Transform cam = null;
public Transform headBone = null;
}
}
So I can use it in the PlayerController, like this:
internal void Init()
{
Debug.Log(presenter.settings.fpsCamDist);
}
The script above does only use settings passed by startup.cs : Settings to the PlayerPresenter.
Another thing that came up to my mind is to handle camera,animation,movement and physics as services (singleton therefore) in the Player Presenter, which is an element itself and only use the methods/settings in those service classes. That way you can still decide how the Presenter (Player in this case) will handle its movement by either use components of those services or not.
Doing this it's possible to have whole movement covering services for different types of enemies/players.
A more convenient way would be to nest different elements (Camera, Physics,...) inside one main element (Player Presenter). But then there would be the already mentioned problem with redundant game objects in the scene. Is it somehow possible to use different elements on the same gameObject?
edit
I found a good solution for this.
See https://github.com/modesttree/Zenject#sub-containers-and-facades
from karma.
Could you please make a usage example for layouts in Karma?
I don't like to use Facades if there's already a mvpc pattern that could handle this.
from karma.
@JenkinJoe Sorry about the delay.
I am uploading 2 videos about doing general stuff. I'll try to record a third about layouts tomorrow and update this repo.
from karma.
@JenkinJoe Check the videos here: https://github.com/cgarciae/karma/blob/master/README.md#videos
from karma.
Alright pal, thanks. I'm glad that you actually respond finally ;)
What I'm really missing is the tree structure of dependencies you have in angularjs 2.
It's possible to reconstruct that behavior with Zenject's Facades and Sub-Container. But i thought that karma's layouts could do something near. From what I've understood layouts in karma do only parenting children presenters. Do they also provide the same instance of dependencies for them?
Also for some reason i couldn't get those layouts to work for me. What I've tried was:
using UnityEngine;
using UnityEngine.Events;
using System.Collections;
using Karma;
using System;
using Karma.Metadata;
using Zenject;
[Layout(view)]
public class StartPresenter : MVCPresenter
{
public const string view = "start";
public Settings settings { get; private set; }
public MVCPresenter app { get; private set; }
public DiContainer container { get; private set; }
private StartController controller;
public StartEnvironmentPresenter environmentPresenter;
public IRouter router { get; private set; }
[PostInject]
public void PostConstructor(IRouter router, ICApp _app, DiContainer container, StartController controller, Settings settings, StartEnvironmentPresenter environment)
{
this.router = router;
this.app = (MVCPresenter)_app;
this.container = container;
this.controller = controller;
this.settings = settings;
this.environmentPresenter = environment;
controller.PostConstructor(this);
}
public override void OnPresenterDestroy()
{
}
}
from karma.
@JenkinJoe
Here is the skeleton of a layout
[Layout(view)]
public class MyLayoutPresenter : MVCPresenter
{
public const string view = "my-layout";
public Transform _root3D;
public Transform _inner3D;
public RectTransform _innerUI;
public RectTransform _rootUI;
public override RectTransform rootUI { get { return _rootUI; } }
public override Transform inner3D { get { return _inner3D; } }
public override Transform root3D { get { return _root3D; } }
public override RectTransform innerUI { get { return _innerUI; }}
[PostInject]
public void Constructor(....)
{
//code
}
public override void OnPresenterDestroy()
{
//code
}
rootUI
, inner3D
, root3D
and innerUI
are optional overrides of every MVCPresenter, they dictate how nesting will be done. The behavoiur is as follows:
- The parent of the Presenter's
rootUI
will be set to the Layout'sinnerUI
. - The parent of the Presenter's
root3D
will be set to the Layout'sinner3D
.
If your view is simple enough you might only need to override innerUI
on the Layout. By default all these properties are set to this.transform
.
You will also need to enable the use of layouts for your app on the Configure method:
public override void Configure(IApplication app, DiContainer container)
{
...
app.UseLayout(true);
...
}
Finally, the prefab of your layout will need to exist under App/Prefabs/Resources/layouts
as my-layout
.
from karma.
Related Issues (10)
- Scene Loading HOT 1
- Prevent child objects from being applied to a prefab HOT 6
- Transitions HOT 2
- Karma & ZenjectSceneLoader HOT 1
- Support for NUnit 3
- How can i update zenject to the latest? HOT 2
- Error in Example App HOT 8
- All compile errors have to be fixed before you can enter playmode! HOT 1
- videos are private
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from karma.