Code Monkey home page Code Monkey logo

Comments (9)

cgarciae avatar cgarciae commented on July 30, 2024

@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.

JenkinJoe avatar JenkinJoe commented on July 30, 2024

@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.

cgarciae avatar cgarciae commented on July 30, 2024

@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.

JenkinJoe avatar JenkinJoe commented on July 30, 2024

@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.

JenkinJoe avatar JenkinJoe commented on July 30, 2024

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.

cgarciae avatar cgarciae commented on July 30, 2024

@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.

cgarciae avatar cgarciae commented on July 30, 2024

@JenkinJoe Check the videos here: https://github.com/cgarciae/karma/blob/master/README.md#videos

from karma.

JenkinJoe avatar JenkinJoe commented on July 30, 2024

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.

cgarciae avatar cgarciae commented on July 30, 2024

@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's innerUI.
  • The parent of the Presenter's root3D will be set to the Layout's inner3D.

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.