Search Unity

Just Logic - visual programming extension for Unity [SPECIAL PRICE 60% OFF!]

Discussion in 'Assets and Asset Store' started by WVlad, Nov 11, 2013.

  1. EmeralLotus

    EmeralLotus

    Joined:
    Aug 10, 2012
    Posts:
    1,462
    Both, confused with the large number of castings and would be very nice to be able to access the sequences/conditions parts more conveniently.

    For now, can you give some examples of how the helper functions are written.
     
  2. WVlad

    WVlad

    Joined:
    Apr 5, 2013
    Posts:
    68
    Add this class to your project:
    Code (csharp):
    1.  
    2. using JustLogic.Core;
    3. using System.Collections.Generic;
    4.  
    5. public static class JustLogicExecutionEngineExtensions
    6. {
    7.     public static JLAction[] GetActions(this ExecutionEngine engine)
    8.     {
    9.         return ((JLSequence)((JLIf)engine.Tree).Then).Actions;
    10.     }
    11.  
    12.     public static void SetActions(this ExecutionEngine engine, params JLAction[] actions)
    13.     {
    14.         ((JLSequence)((JLIf)engine.Tree).Then).Actions = actions;
    15.     }
    16.  
    17.     public static void AddActions(this ExecutionEngine engine, params JLAction[] actions)
    18.     {
    19.         var lst = new List<JLAction>(GetActions(engine));
    20.         lst.AddRange(actions);
    21.         SetActions(engine, lst.ToArray());
    22.     }
    23.  
    24.     public static void InsertActions(this ExecutionEngine engine, int index, params JLAction[] actions)
    25.     {
    26.         var lst = new List<JLAction>(GetActions(engine));
    27.         lst.InsertRange(index, actions);
    28.         SetActions(engine, lst.ToArray());
    29.     }
    30.  
    31.     public static JLExpression[] GetConditions(this ExecutionEngine engine)
    32.     {
    33.         return ((JLAnd)(((JLIf)engine.Tree).Value)).Operands;
    34.     }
    35.  
    36.     public static void SetConditions(this ExecutionEngine engine, params JLExpression[] boolExpressions)
    37.     {
    38.         ((JLAnd)(((JLIf)engine.Tree).Value)).Operands = boolExpressions;
    39.     }
    40.  
    41.     public static void AddConditions(this ExecutionEngine engine, params JLExpression[] boolExpressions)
    42.     {
    43.         var lst = new List<JLExpression>(GetConditions(engine));
    44.         lst.AddRange(boolExpressions);
    45.         SetConditions(engine, lst.ToArray());
    46.     }
    47.  
    48.     public static void InsertConditions(this ExecutionEngine engine, int index, params JLExpression[] boolExpressions)
    49.     {
    50.         var lst = new List<JLExpression>(GetConditions(engine));
    51.         lst.InsertRange(index, boolExpressions);
    52.         SetConditions(engine, lst.ToArray());
    53.     }
    54. }
    55.  
    Usage:
    Code (csharp):
    1.  
    2.         var script = gameObject.AddComponent<JustLogicScript>();
    3.         UnityEngine.Object ptLight = null;
    4.         script.Engine.SetActions(
    5.             JLAction.Build<JLToggle>(t => t.Object = JLExpression.Build<JLObjectValue>(v => v.Value = ptLight)),
    6.             JLAction.Build<JLEvalute>(t => t.Expression = JLExpression.Build<JLPrintRet>(v => v.Value = JLExpression.Build<JLStringValue>(w => w.Value = "test"))),
    7.             JLAction.Build<JLEvalute>(t => t.Expression = JLExpression.Build<JLPrintRet>(v => v.Value = JLExpression.Build<JLStringValue>(w => w.Value = "test2")))
    8.             );
    9.  
    You can Get, Set, Add, Insert actions and conditions.

    Be careful: your arrays are references so if you pass an array to the SetActions, you should use a new array instance afterwise, of course if you don't want to change the content of just assigned units.
     
    Last edited: Feb 17, 2014
  3. EmeralLotus

    EmeralLotus

    Joined:
    Aug 10, 2012
    Posts:
    1,462
    Does this mean that once the asset is built, it can be used during run-time ?

    If this is the case, then you have to change your forum footer text from "JustLogic - make your games without coding!"
    to JustLogic - make your games without coding! Change game logic during run-time "
     
  4. EmeralLotus

    EmeralLotus

    Joined:
    Aug 10, 2012
    Posts:
    1,462
    Fantastic ! big thanks for this. Will test it out.

    Edit: Just tried out the script with the following code. I commented out the JLToggle because I thought the problem was that it could not find ptLight1. After commenting I got the same error.


    UnityEngine.ObjectptLight = ptLight1;
    script.Engine.SetActions(
    //JLAction.Build<JLToggle>(t => t.Object = JLExpression.Build<JLObjectValue>(v => v.Value = ptLight)),
    JLAction.Build<JLEvalute>(t => t.Expression = JLExpression.Build<JLPrintRet>(v => v.Value = JLExpression.Build<JLStringValue>(w => w.Value = "test"))),
    JLAction.Build<JLEvalute>(t => t.Expression = JLExpression.Build<JLPrintRet>(v => v.Value = JLExpression.Build<JLStringValue>(w => w.Value = "test2")))
    );


    NullReferenceException: Object reference not set to an instance of an object
    JustLogicExecutionEngineExtensions.SetActions (JustLogic.Core.ExecutionEngine engine, .JLAction[] actions) (at Assets/JustLogic/Extension/JustLogicExecutionEngineExtensions.cs:13)
    test1.Start () (at Assets/JustLogic/Tutorials/test1.cs:37)


    Edit 1:

    Oops, my mistake, I commented out the code below, so it couldn't find the Tree. What I wanted to do is to start out with an empty Tree and be able to add actions. The question then is what is code for a totally empty Tree so that I can use JustLogicExecutionEngineExtensions to add actions. Perhaps to add CreateTree() and other useful convenient tree functions to the extension.



    engine.Tree = JLAction.Build<JLIf>(
    v =>
    {
    v.Value = JLExpression.Build<JLAnd>(a => a.Operands = newJLExpression[0]);
    v.Then = JLAction.Build<JLSequence>(
    b => b.Actions = newJLAction[]
    {
    JLAction.Build<JLEvalute>(
    ev => ev.Expression=JLExpression.Build<JLPrintRet>
    (p => p.Value =
    JLExpression.Build<JLStringValue>( s => s.Value = "Hello world2!")))
    });
    });
     
    Last edited: Feb 17, 2014
  5. WVlad

    WVlad

    Joined:
    Apr 5, 2013
    Posts:
    68
    You can empty a tree by calling Engine.Tree.SetActions() and Engine.Tree.SetConditions() without arguments.

    Yes. Unfortunately, I can't rename the forum thread, only change the first post title :)
     
    Last edited: Feb 18, 2014
  6. EmeralLotus

    EmeralLotus

    Joined:
    Aug 10, 2012
    Posts:
    1,462
    Very cool,

    I've been getting into trying to making a small game with only using the Editor functions of JustLogic.


    The blocks are great, however, I am running into an issue to how to structure the project. The more functionality that is added, I'm finding that I'm making more and more JL scripts, which is becoming a bit confusing. Perhaps you have a best practice in mind that you can share. Some sort of guideline to help manage the scripts.

    You mentioned on a previous comment that a state machine would be coming. This is a great idea as it will help to better structure the project.
     
  7. EmeralLotus

    EmeralLotus

    Joined:
    Aug 10, 2012
    Posts:
    1,462
    Vlad,

    I'm making good progress with JustLogic.

    One thing that will really help me to better understand is a Doxygen Documentation.
    I posted a link to a Free Unity Asset that can do this.

    This will really help tremendously.

    Cheers.
     
  8. EmeralLotus

    EmeralLotus

    Joined:
    Aug 10, 2012
    Posts:
    1,462
    How to create a prefab from a JLscript?

    For example: In tutorial_2_Completed, how to make a prefab from the CloseScript object that's in the Scene.
    When I try to make a prefab, I only get a default JLscript with a JLEvaluate string Hello World!

    Edit: Same goes for trying to make a prefab of the Door which has the CloseScript and OpenScript as children.
    The Door is stored in the prefab correctly, but the JLScripts are not correctly created.
     
    Last edited: Feb 20, 2014
  9. EmeralLotus

    EmeralLotus

    Joined:
    Aug 10, 2012
    Posts:
    1,462
    Sorry for so many questions because documentation is not yet complete.

    Hopefully the answers to these questions will be in the new docs.

    In the Settings option of the JLScript, there is "Initialization"

    Reentrance:
    1. Interrupt
    2. Queue
    3. Drop
    4. Parallel

    Can you give some explanation about the use cases for these various choices.

    Also in the OpenScript,

    JLScript.HasStartedCoroutines
    JLScript.HasQueueStarts

    Can you describe this a bit more.

    Edit: I've been following the examples and doing a lot of guess work, but in order to make something serious, definitely need better understand how things work. So either better docs or Open Source.
     
    Last edited: Feb 20, 2014
  10. WVlad

    WVlad

    Joined:
    Apr 5, 2013
    Posts:
    68
    Unfortunately there is an issue with placing your JL scripts on prefabs. I'm going to implement a workaround for it but.. until that you can only save a script seperately with "Assets/Create/JustLogic Script" and invoke it with your C# script placed on a prefab. Create a field of JLCustomScriptAsset type so you can drag and drop it to the inspector. In the script you can load the asset like this:
    Code (csharp):
    1.  
    2. var script = AddComponent<JustLogicScript>();
    3. script.Engine.Tree.SetActions(yourField.Value);
    4.  
    I understand that this is very awkward. I'll fix it in a high priority.


    Reentrance - basically it's about situations when a JL script is being invoking when it's already is in its execution process:
    Current execution will be cancelled.
    Will be enqueued to be executed later. Check it with JLScript.HasQueuedStarts.
    The invokation will be dropped and not executed at all.
    The invokation will be queued but in a seperate coroutine.

    These options has only effect when coroutine-related actions are used: "Wait...".


    Is this script currently paused as a coroutine?
     
    Last edited: Feb 20, 2014
  11. WVlad

    WVlad

    Joined:
    Apr 5, 2013
    Posts:
    68
    This is a generated API documentation: JustLogicApiDocs.chm. It does not contain any comments but it can show you usefull classes. May be helpful.
     
    Last edited: Feb 21, 2014
  12. EmeralLotus

    EmeralLotus

    Joined:
    Aug 10, 2012
    Posts:
    1,462
    "JLScript.HasStartedCoroutines" = Is this script currently paused as a coroutine?

    Not quite understanding, so in the script, we have.

    1. If
    2. JLScript.HasStartedCoroutines, value = CloseScript.
    3. Then Sequence
    4. Actions[2]
    5. JLScript.StopAllCoroutines.

    I dont' quite understand the "Paused as a coroutine"
     
  13. WVlad

    WVlad

    Joined:
    Apr 5, 2013
    Posts:
    68
    Your JL script execution can be paused until next frame or some specified time period. It can be done with units "Wait...". This is an equivalent of "yield return". If the specified JL Script has paused executions, HasStartedCoroutines returns true, otherwise false.
     
  14. WVlad

    WVlad

    Joined:
    Apr 5, 2013
    Posts:
    68
    Submitted:

    1.2 24-02-2014
    + main documentation updated
    + public API documantation
    + public API fixes
    + included C# scripting examples (see Tutorials/Scripting)
    + prefabs support
    + included the source code of the units
    + custom events support (see Tutorials/Scripting)
    + added new tutorial scenes
     
  15. EmeralLotus

    EmeralLotus

    Joined:
    Aug 10, 2012
    Posts:
    1,462
    Excellent Work. Cheers.
     
  16. WVlad

    WVlad

    Joined:
    Apr 5, 2013
    Posts:
    68
    Forgot to add this to update notes: Remove "JustLogic\Editor" folder before updating. If you've already updated remove it and reimport the package.
     
    Last edited: Feb 24, 2014
  17. WVlad

    WVlad

    Joined:
    Apr 5, 2013
    Posts:
    68
    Upgrade 1.2 was accepted to the store.
     
  18. WVlad

    WVlad

    Joined:
    Apr 5, 2013
    Posts:
    68
    Minor improvements and fixes are planned to the next version. For now the "dynamic" scripting tutorial doesn't work on iOS, you can fix it by adding "Library.Initialize(Application.isPlaying);" to the beginning of the Awake method of the JustLogic/Tutorials/Scripting/JustLogicDynamicScriptCreation.cs file:
    Code (csharp):
    1.  
    2. using JustLogic.Core;
    3. using UnityEngine;
    4.  
    5. public class JustLogicDynamicScriptCreation : MonoBehaviour
    6. {
    7.     public Light Target;
    8.  
    9.     void Awake()
    10.     {
    11.         Library.Initialize(Application.isPlaying);
    12.         // creating new JL Script dynamically
    13.         var script = gameObject.AddComponent<JustLogicScript>();
    14.         var engine = script.Engine;
    15.         if (engine.Tree)
    16.             Destroy(engine.Tree);
    17.  
    18.         // building actions fluently
    19.         script.Engine.SetActions
    20.         (
    21.           JLAction.Build<JLToggle>(t => t.Object = JLExpression.Build<JLObjectValue>(v => v.Value = Target)),
    22.           JLAction.Build<JLEvalute>(t => t.Expression = JLExpression.Build<JLPrintRet>(
    23.               v => v.Value = JLExpression.Build<JLStringValue>(w => w.Value = "text1"))),
    24.           JLAction.Build<JLEvalute>(t => t.Expression = JLExpression.Build<JLPrintRet>(
    25.               v => v.Value = JLExpression.Build<JLStringValue>(w => w.Value = "text2")))
    26.         );
    27.        
    28.         // launching the script from code
    29.         //script.StartExecution();
    30.         // or simulate event Awake
    31.         //script.StartExecutionByEvent(new EventData(eventInfo: new JustLogic.Core.Events.Awake(),
    32.         //    arguments: new object[0], handler: null, counter: 0));
    33.  
    34.         // or create event handler
    35.         var handler = gameObject.AddComponent<JustLogicEventHandlerLite>();
    36.         var data = handler.EventHandlerData;
    37.         // specify event FixedUpdate
    38.         data.EventDataClassFullName = typeof(JustLogic.Core.Events.FixedUpdate).FullName;
    39.         // specify target script
    40.         data.JLScriptsLookup = new[] { JLExpression.Build<JLObjectValue>(v => v.Value = script) };
    41.         // initialize conditions
    42.         data.Condition = JLExpression.Build<JLBoolValue>(v => v.Value = true);
    43.     }
    44. }
    45.  
     
  19. EmeralLotus

    EmeralLotus

    Joined:
    Aug 10, 2012
    Posts:
    1,462
    Out of curiosity,

    What does that line do ? What was the actual problem ?
     
  20. WVlad

    WVlad

    Joined:
    Apr 5, 2013
    Posts:
    68
    The Library class contains references to the unit types and other meta data. On PC the Library class is initialized by the editor but in a build it should be initialized manually. This line ensures that Library class is properly initialized. If you call it multiple times it will be initialized only once.

    It's also possible to initialize it in a seperate thread with Library.BeginInitialize but if you try to use any JL functionality until the initalization is completed your app will hang until it's completed. It may be suitable for "preloader" scenes to save a couple of seconds of the loading time.
     
    Last edited: Mar 3, 2014
  21. EmeralLotus

    EmeralLotus

    Joined:
    Aug 10, 2012
    Posts:
    1,462
    Do you have a rough ETA on when the next update will be coming.

    Cheers.
     
  22. WVlad

    WVlad

    Joined:
    Apr 5, 2013
    Posts:
    68
    Yes, I'm uploading the next minor update on March, 24th. There will be included some fixes and improvements.
     
  23. WVlad

    WVlad

    Joined:
    Apr 5, 2013
    Posts:
    68
    Version 1.2.1 is submitted to the store:
    + added "Navigate" button to the Unit Selector to open the selected unit menu, it is used automatically if all the categories are collapsed,
    + fixed default parameter types (e.g. Compare is a default unit for If value)
    + fixed some broken in the previous version functionality

    Price is temporarily reduced to $20!
     
    Last edited: Mar 24, 2014
  24. EmeralLotus

    EmeralLotus

    Joined:
    Aug 10, 2012
    Posts:
    1,462
    Cool, thanks for the update.

    Question: I asked this question via email, but it's good to ask it here so others can use the info.

    "C# events subscribing - it is not directly supported. You can use your custom event handler to subscribe to UIPopupList events on the current game object."

    it would be very nice if you could make a small example in code of how to setup JL to work with NGUI. Currently there is no examples or demos of how to actually work with an 3rd party package. In the documentation PDF, there is only a mention of the generator unit working with any 3rd party package like NGUI, but there isn't yet a working example.


    Cheers.
     
  25. EmeralLotus

    EmeralLotus

    Joined:
    Aug 10, 2012
    Posts:
    1,462
    If it takes time to do the example, for now, what would the custom event handler code look like for subscribing to C# events from NGUI.
     
  26. WVlad

    WVlad

    Joined:
    Apr 5, 2013
    Posts:
    68
    Sorry if it's not obvious: by design any custom events should be used with your custom event handler. No matter C# events or behavior messages.

    Let's see how you can modify the example of a custom event handler:
    Code (csharp):
    1.  
    2. [ExecuteInEditMode]
    3. public class JustLogicCustomEventHandleExample : JustLogicEventHandlerLite
    4. {
    5.     void MyCustomEvent1()
    6.     {
    7.         Trigger(new MyCustomEvent1());
    8.     }
    9.  
    10.     void MyCustomEvent2(int x)
    11.     {
    12.         Trigger(new MyCustomEvent2(), x);
    13.     }
    14. }
    What you need is 1) retrieve a reference to the instance to which event you want to subscribe and 2) Subcribe to it via standard C# way to call Trigger(...).
    Code (csharp):
    1.  
    2.  
    3. [ExecuteInEditMode]
    4. public class JustLogicCustomEventHandleExample : JustLogicEventHandlerLite
    5. {
    6.     protected override void Awake()
    7.     {
    8.         base.Awake();
    9.         if (Application.isPlaying)
    10.             GetComponent<UIPopupList>().OnChanged +=  List_OnChanged; // delegate { Trigger(new MyCustomEvent3(); }
    11.     }
    12.    
    13.     void List_OnChanged(object sender, object newValue (see declaration of OnChanged and use correct signature) )
    14.     {
    15.         Trigger(new MyCustomEvent3(), (Color)newValue);
    16.     }
    17.  
    18.     public override void OnDestroy()
    19.     {
    20.          base.OnDestroy();
    21.          if (Application.isPlaying) // unsubscribe
    22.             GetComponent<UIPopupList>().OnChanged -=  List_OnChanged;
    23.     }
    24.  
    25.     void MyCustomEvent1()
    26.     {
    27.         Trigger(new MyCustomEvent1());
    28.     }
    29.  
    30.     void MyCustomEvent2(int x)
    31.     {
    32.         Trigger(new MyCustomEvent2(), x);
    33.     }
    34. }
     
    Last edited: Mar 26, 2014
  27. EmeralLotus

    EmeralLotus

    Joined:
    Aug 10, 2012
    Posts:
    1,462
    Great, thanks for the tip Vlad.

    Much better to understand JL when there is examples.

    Question: NGUI popupList only returns a string, it cannot take a data structure.
    This brings up the question of how to create a simple data structure using JL.
     
  28. EmeralLotus

    EmeralLotus

    Joined:
    Aug 10, 2012
    Posts:
    1,462
    Have a question about "Trigger" , is this function coming from JustLogicEventHandlerLite ?

    Edit: Found it in JustLogicEventHandlerCoreBase


    I'm wondering about performance and speed.
    Which is better to use in JL. sendMessage or Invoke ?
     
    Last edited: Mar 26, 2014
  29. WVlad

    WVlad

    Joined:
    Apr 5, 2013
    Posts:
    68
    You can instantiate a simple data structure like Color with unit %StructureName%/New. It's automatically created for generated units.

    SendMessage and Invoke both use reflection and have the same bad performance but it's not so critical when you don't call them in a loop from Update.
     
  30. WVlad

    WVlad

    Joined:
    Apr 5, 2013
    Posts:
    68
    Update 1.2.1 has been accepted to the store.
     
  31. teeebor

    teeebor

    Joined:
    Mar 7, 2013
    Posts:
    3
    Does WebGL supported by Just Logic?
    I can't get it to work with WebGL
     
  32. WVlad

    WVlad

    Joined:
    Apr 5, 2013
    Posts:
    68
    I decided that there is no commerical sense for me to sell anything in asset store. So I'm going to make JustLogic open source and free. If you purchased JustLogic I want to thank you for your support. But unfortunately JL is not paying off for its commerical development.

    If you have any offers until its open source plese email me wvlad.dev@gmail.com

    teeebor, no, it's not supported. but I think it should be certainly possible to add such support.
     
  33. teeebor

    teeebor

    Joined:
    Mar 7, 2013
    Posts:
    3
    Thank you for your answer :)
     
  34. WVlad

    WVlad

    Joined:
    Apr 5, 2013
    Posts:
    68
    Version 1.3 beta with Unity 5 support. Free and open source. Contributions are welcome. Download on Github.
     
    Last edited: May 29, 2015
  35. WVlad

    WVlad

    Joined:
    Apr 5, 2013
    Posts:
    68
    Version 1.3.1 is freely available on the store.