Search Unity

CML Evolution: Progression tracking-, Dialogue-, Save-, Shop- and Inventory system

Discussion in 'Assets and Asset Store' started by MrDude, Oct 10, 2012.

  1. MrDude

    MrDude

    Joined:
    Sep 21, 2006
    Posts:
    2,569
    Unity Dialogue Engine Advanced (formerly known as CML Evolution) showcases some of the more useful things you can do with CML. This kit includes the Unity Dialogue Engine's features but adds a lot more functionality. The demo showcases game and progress tracking-, game save-, dialogue-, inventory- and even a shop system...


    The UDEA is built on top of my CML data storage class (XML replacement) and thus, by default, includes the following data handling features:

    * Allows you to store int, float, string, boolean, rect, vector and quaternion values
    * Separate data as nodes and store any number of information under each node
    * Access each node directly without having to navigate to it first
    * Filter nodes by parent node or type
    * Retrieve a single node or a list of nodes
    * Retrive full nodes or just the node ID for direct access later
    * Save all data with a single line of code
    * Fetch all data with a single line of code
    * Copy nodes between CML classes
    * Save data to PlayerPrefs or to a specified path
    * Load data from PlayerPrefs, to a specified path or from a Resources folder
    * 2 different styles of scripting (Normal and Shortform) can be mixed and matched
    * Very easy and intuitive scripting format to learn and use

    Included class: CMLGameKeys

    CMLGameKeys allows for easy progress tracking throughout your application and by it's very nature acts as an inventory system.

    The basic premise for use is:
    "For anything important that happens, mark it's occurrence by setting a key".
    Picked up ammo? Found the kidnapped princess? Found the key to unlock the door to king's throne room? Completed the level? Used up an arrow? Died? Set a key. Setting a key is one line of code, testing for a key is one line of code, saving all the keys for your entire game is one line of code...

    Due to the very nature of how the CMLGameKeys class works, you not only get an automatic inventory, you also get an automatic game save system. Simply by using the CMLGameKeys class you can save everything you want from player position and rotation to quests received or completed to inventory items or anything else you wish to save, all with one line of code...

    Add to this the fact that CMLGameKeys is built on top of CML it means you can even classify your save game data if you so wish. You could easily sort all quests as separate quest nodes and store all info pertaining to the quest under such a node if your game's quests contain lots of info. On the other hand, if your quests are as simple as having a name and a "done/not done" indicator then you could easily save all your quests under a single "Quest" node. Store all user profile information under a node called "profile" and all player options like audio volume and screen brightness under a node called "settings"... you can classify your data any way you feel like and still save all of it via 1 line of code, set the values via one line of code and test the field values via one line of code...

    Included class UDEA:

    The Unity Dialogue Engine Advanced is a custom version of the Unity Dialogue Engine that runs on CML, rather than the old UDE file format. This means you can now write your dialogues in the same scripting format as you do your game's data files and save data.

    Another major change this brings is the fact that you can now add any number of custom "tags" (now called nodes) per dialogue turn and thereby create entirely new functionality without having to modify the underlaying engine!

    What this dialogue engine allows you to do is to make any object in your game interactive by giving it a popup description.

    It also allows you to trigger custom code via interacting with any object in your scene. Some example uses would be to make a switch open a gate or to make a stone pillar plummet to the ground when you interact with it. Since you are calling custom code, you can do anything you want and are not limited to just one action. Play the "JumpForJoy" animation on your character while spawning the extra life prop, have the prop play the "Rise" animation for 3 seconds then destroy the prop and add 1 to the "Lives" key in the CMLGameKeys class you use to store your data in... All when you interact with the 3rd rock from the West gate in village 2... Trigger any custom code, by interacting with any object in your game.

    UDEA includes a prefab to simply this process for you. Just drag and drop onto any object in your scene and 90% of the works is done! Interaction in seconds!

    UDEA also makes use of the CMLGameKeys class to store keys and as such can remember any past interactions with objects or characters. Meaning you are able to create dialogue where characters appear to remember past interactions with you and change their dialogue accordingly. You cold have a farmer speak to you in all manner of friendly and then, next time you speak to the same farmer, you could have him attack you with a sickle when you start a conversation simply because you made a pass at his daughter 2 villages down the road, 3 days after you last spoke to that farmer... Since the dialogue has access to all keys set throughout the game, you can customise every bit of dialogue based on any event that took place (or didn't take place) at any point in the game... Your dialogues can thus be as simple or complex as you want it to be.

    Finally, you are able to modify your game keys (and thus your inventory) right inside the dialogue thus directly influencing the game outside the dialogues, and vice versa with dialogues changing based on what has or has not happened outside the dialogues. These keys can also be dynamically inserted into your dialogue and displayed on screen also.

    Since no two games will ever have exactly the same interface, the UDEA is not locked to a single display style. It allows you to easily build your own, custom displays by simply inheriting your display from the UDEA class and creating an OnGUI function. You need do no more than that. It is also easy to integrate with NGUI and EZGUI, for example, so this truly is a very useful piece of kit for your projects... (Also includes a sample NGUI demo scene)

    Shop system and inventory spawning system

    To further demonstrate the versatility of CML, UDEA also includes an example of a shop system. Some of the features included in the shop system are:
    * Item prices can differ based on the merchant
    * Item prices differ based on wether you are buying or selling the product
    * Purchases persist between game plays
    * Items are sorted by category, i.e. weapons, farming tools.
    (You can always include ArmorBody, ArmorLegs, Magic, Potions,Maps...)

    UDEA also includes a sample class to demonstrate how to display your inventory items on screen and mount your items (from inventory text) to specific nodes on your character.

    For more information regarding the Unity Dialogue Engine Advanced, have a look here...
    Asset Store link
     
    Last edited: Jun 25, 2013
  2. AntFitch

    AntFitch

    Joined:
    Jan 31, 2012
    Posts:
    243
    I think this sounds promising... especially for RPGs. Do you have any video tutorials so that we can see how to build dialog and use keys, using your product? Maybe there is also a video of a sample game?
     
  3. MrDude

    MrDude

    Joined:
    Sep 21, 2006
    Posts:
    2,569
    Video tutorials... People have been asking me for video tutorials for absolutely ages now. I finally decided to grace your all with the beauty that is my voice... but alas no... I have not yet made any video tutorials :(

    Included in the product is the mandatory example scene and then there is also the series of tutorials on how the new and improved dialogue system works so I don't think anyone will struggle to get to grips with how this works... :D I guess a series of video tutorials will have to be added sometime soon...

    As per tradition, the included demo will be available for play on my website soon enough, though. Who wants to watch a video of a game when they can play the game instead? :D
     
  4. MrDude

    MrDude

    Joined:
    Sep 21, 2006
    Posts:
    2,569

    Attached Files:

    Last edited: Oct 12, 2012
  5. MrDude

    MrDude

    Joined:
    Sep 21, 2006
    Posts:
    2,569
    As requested, some video tutorials:

    Tutorial 1 shows how to write dialogue in CML:
    http://www.youtube.com/watch?v=SKzgPir3di4&hd=1

    Tutorial 2 shows how to make an object interactive by adding dialogue to an NPC.
    1. Drag the prefab onto the object
    2. (Optionally) drag the collectibles script onto the object
    3. Complete the FileName field on the prefab
    4. If (2), mark the check boxes to indicate available actions (speak, interact, investigate, collect)
    5. If (4), complete the corresponding field by entering the turn id

    Done! Create your script and tweak it during the course of your project, adding new content or modifying existing. Either way, it still takes less than 1 minute to hook up an inanimate object to become an interactive object! See tutorial 2

    http://www.youtube.com/watch?v=hMmJCCNlDGU&hd=1

    Is it possible to embed video into this thread?
     
    Last edited: Oct 15, 2012
  6. runner

    runner

    Joined:
    Jul 10, 2010
    Posts:
    865
    Hey, I've been interested in the package since release

    Question: can the CML be extended to include something like gamobject.sendmessage as a function call within the dialogue?

    adding CMLGameKeys on OnTrigger() OnMouse() events is cool, By the way good work with the tutorials, Keep it up, It went along way at filling in gaps in understanding because the documentation is sort of weak.
     
    Last edited: Oct 16, 2012
  7. MrDude

    MrDude

    Joined:
    Sep 21, 2006
    Posts:
    2,569
    Hi runner. Thanks for the feedback :)

    In what ways do you find the documentation weak? Any tips on how to improve on it? I don't go into too much detail in the public pages but do include some actual step by step lessons in the final product to get customers up to speed, but if you are saying what I DO show is not very helpful, I'd be very interested to know how I could improve upon it! All feedback welcome :D

    Right... now the confusion starts... he he he... terminology...:
    1. CML is the Custom Markup Language and is basically the file format and functions relating to that
    2. CMLE is the short name of this kit : CML (E)volution
    3. CMLDE is the dialogue engine built on top of CML ...

    Right, now that we have our terminology sorted out, CML can't be extended to include sendmessage, no.
    CMLDE, on the other hand, has this built in already. You will have seen how you add fields to your dialogue scripts, but one of the fields I have not yet shown is the [keys] field. I'm not going to go into details on that here now but basically you can do this in your dialogue script:
    Code (csharp):
    1.  [keys] myKey SomeValue SomeArgument, Animation play dance
    This will then send those keys to a function called ProcessKeys from where you can split the string and then do whatever you want... Here is an example:
    Code (csharp):
    1. public class MYActions : MYDisplay {
    2.  
    3. public void ProcessKeys( string key ) {
    4.     string[] fields = key.Split(' ');
    5.  
    6.     switch(fields[0]) {
    7.         //key format: level load Level1
    8.         case "level":
    9.             switch(fields[1]) {
    10.                 case "load":
    11.                     Application.LoadLevel(fields[2]);
    12.                     break;
    13.             }
    14.             break;
    15.  
    16.         //key format: Animation action argument
    17.         case "Animation":
    18.             switch(fields[1]) {
    19.                 case "play":
    20.                     transform.parent.animation.Play(fields[2]);
    21.                     break;
    22.             }
    23.             break;
    24.         ...
    25.  
    Of course, you don't HAVE to split the key and use switch statements like I do, but I like doing it this way as it makes sense to me to do so. You could simply say:
    Code (csharp):
    1.  
    2. public void ProcessKeys(string key) {
    3.    if (key == "quit")
    4.       Application.Quit();
    5. }
    How you handle your custom code is entirely up to you. So, with that said, the short answer is: Yes, you are able to send custom messages and, by proxy, able to trigger any custom code you want. :cool:
     
    Last edited: Oct 16, 2012
  8. runner

    runner

    Joined:
    Jul 10, 2010
    Posts:
    865
    A more detailed explanation somewhere in the public pages is precisely what seems to be missing, As i like as much information as possible with a product's code practices, so that i can form a decision not based on guess's.

    I still have huge gaps in understanding, things like (lifted from the front page) some of this has been glossed over while other stuff seemed entirely missing.

    * Separate data as nodes and store any number of information under each node
    * Access each node directly without having to navigate to it first
    * Filter nodes by parent node or type
    * Retrieve a single node or a list of nodes
    * Retrieve full nodes or just the node ID for direct access later

    Tell me more about nodes are they only good for inventory and so much more (such as.)

    I probably envision some IDEA outside the scope of the products capabilities but I'm thinking text parser and the liberal use of grep kind of thing which it wasn't designed for but possible?

    Thanks for the code sample that opens the door a little wider to understanding.
     
    Last edited: Oct 16, 2012
  9. MrDude

    MrDude

    Joined:
    Sep 21, 2006
    Posts:
    2,569
    I can do you one better...
    You will notice those points are listed under "Current Features Of CML"

    I've released CML as a free product on the asset store. Instead of me trying to explain it, just go to the Asset Store, download CML and you can inspect that actual code itself and see EXACTLY what it can do :D
    Although, the version included in the kit has that one little bug fixed and has a bunch of extra stuff added.

    CML is a replacement for XML, basically. So you write CML data in a format that I think is much simpler than XML and then the CML class parses that data and offers a bunch of search functions into the data. So if you have a file with 245 pieces of data (nodes) and you happen to know that the piece you are after is has an internal id of 173, you can access it directly without having to navigate to a parent node or searching through a hierarchy .
    Code (csharp):
    1.  
    2. //mydata.txt
    3. <CML Header>Version=2.0
    4. <employee>name=John; surname=Black; employee_number=123123; age=30
    5. <employee>name=Joe; surname=Shmoe; employee_number=1323113; age=19
    6. <employee>name=Sally; surname=Peters; employee_number=122534; age=94; retired=true
    7.      <child>name=Peter; surname=Pan; employed_here=false; age=59
    8.      <child>name=Susan; surname=Jenkins; employed_here=false; age=62
    9. <employee>name=Foo; surname=Bar; employee_number=134524; age=23;
    10.  
    11. //myfile.cs
    12. CML employees = new CML("mydata");
    13.  
    14. //direct printing: Joe
    15. Debug.Log("Name: " + employees[2].String("name") + " Employee ID:" + employees[2].String("employee_number"));
    16.  
    17. //alternative: Sally
    18. cmlData Sally = employees[3];
    19. if (Sally.Bool("retired")) {
    20.    Debug.Log("--retired--");
    21.    if (Sally.Int("age") > 90)
    22.       SendFlowersOnBirthday();
    23. }
    24.  
    25. //Get a list of employees
    26. List<CMLData> Employees = employees.Children(0);
    27. foreach (CMLData E in Employees)
    28.     Debug.Log("Name: " + E.String("name") );
    29.  
    30. //or
    31. List<int> Employees = employees.Childreni(0);
    32. foreach (int ID in Employees)
    33.     Debug.Log("Name: " + employees[ID].String("name") );
    34.  
    35. //or
    36. List<CMLData> Employees = employees.AllDataOfType("employee");
    37. foreach (CMLData E in Employees)
    38.     Debug.Log("Name: " + E.String("name") );
    39.  
    As for the first point you mentioned, as you can see from Sally, nodes don't have to contain the same fields. They can contain some, none, all or completely new fields, as your needs require. If you don't include a field and test it as a boolean value, it returns false. If you use it as an int but it doesn't exist, it returns 0 etc etc etc so you don't need to store data you don't need.

    CML allows you a lot of freedom in how you store your data as well as how you retrieve it again afterwards. As you can see, it even converts your data to string, int, float, rect, vector, quaternion and boolean values for you for with correct handling of the data in case you try to use an invalid format like int a = myData.Int("name');

    Contact me via the contact page on my website and tell me what it is you are trying to do then I can be able to help you more directly, instead of me having to answer general purpose questions hoping to solve your particular issue eventually.
     
    Last edited: Oct 16, 2012
  10. runner

    runner

    Joined:
    Jul 10, 2010
    Posts:
    865
    Thanks so much for CML and open-sourcing and quite useful as tool as is evolution

    And the tips were great !!
    :eek:
     
  11. MrDude

    MrDude

    Joined:
    Sep 21, 2006
    Posts:
    2,569
    I'm dying to get some feedback on this. What are your thoughts ? :D
     
  12. runner

    runner

    Joined:
    Jul 10, 2010
    Posts:
    865
    Tutorial 1 shows how to write dialogue in CML:
    http://www.youtube.com/watch?v=SKzgPir3di4&hd=1

    can you also provide a detailed video or provide sample code practicum on using .cml with CMLGamekeys.

    http://www.mybadstudios.com/

    http://forum.unity3d.com/threads/15...ntory-system?p=1061668&viewfull=1#post1061668
    [keys] FeleciaQuest level, 1
    So in learning the gist of these thing's pulled reference snippits from a few url's and the forum just to get a idea what I/m dealing with here. so i assume saving "Save all data with a single line of code". CML Function list. http://cmlevolution.mybadstudios.com/

    It's alot to take in and a bullet list on CML functions sure could use documented samples of accessing nodes ect, After all if you want me to adopt this framework first i gotta feel cozy with the methodology.

    -peace-
     
    Last edited: Nov 5, 2012
  13. MrDude

    MrDude

    Joined:
    Sep 21, 2006
    Posts:
    2,569
    Hi all

    Just thought I'd let you know of my Christmas discount voucher. Simply use voucher XMAS2012 during checkout for 20% discount on all items on my website.

    Enjoy and merry Christmas
    http://www.mybadstudios.com
     
  14. TopThreat

    TopThreat

    Joined:
    Aug 7, 2012
    Posts:
    136
    Hi!

    Would you mind posting a quick example of how you would link this to NGUI?

    Thanks!

    Lee
     
  15. MrDude

    MrDude

    Joined:
    Sep 21, 2006
    Posts:
    2,569
    Hi there

    Since CML Evolution contains an inventory system, a save game system, a dialogue system, a shop system (and in the near future a custom keyboard editor) this question is a bit ambiguous. I am going to assume you mean how to link the CML dialogue Engine to NGUI...

    With that being te case, it would be very much similar to the way you did it with the UDE (over here):
    Code (csharp):
    1.  
    2. public class NGUISample : CMLDE {
    3.  
    4.     public UILabel NGUILabel;
    5.  
    6.     public void OnClick()
    7.     {
    8.         if (HasEnded) {
    9.             StartDialogue(2);
    10.         } else {
    11.             Speak();
    12.             if (HasEnded)
    13.                 NGUILabel.text = "Press start to\nbegin the dialogue";
    14.         }
    15.         if (!HasEnded)
    16.             NGUILabel.text = currentText;
    17.     }
    18.  
    19.     override public void HandleInput() {}
    20.  
    21. }
    By creating a class that you subclass from CMLDE, you will have a place in the inspector to select the filename of the script that contains your dialogue and from there you just use it as normal... sort of. In normal use case, you would create the subclass and then add an ONGUI function to handle the display. When using NGUI, you skip the OnGUI function and just add the OnClick handler and tell it to do what you would have had the ONGUI function do... which is just to start or continue the dialogue when you want to.

    Basically, the CMLDE will fetch die relevant text depending on where in the dialogue you are and that text will be stored in currentText. So all you need to do is assign that text to an NGUI label and that is all there is to it. In the above example I have a boolean value that tests wether the dialogue has completed or not and if it has, it will set the label to "press Start to begin". If you press the button while this is the case, it will start the dialogue from turn 2 (value I chose based on the dialogue I had loaded at the time). If the dialogue HAS already started but has NOT ended yet, then it will continue. That simple: StartDialogue(2) and Speak(). All you had to call.

    Load in avatars and assign them to NGUI elements or do whatever else you want to do from here. The CMLDE will keep track of whatever is relevant to the particular turn. What is new in CMLDE, as opposed to the UDE is that each turn can now hold any amount of extra data also so if you want to play audio, for example, you could also include the na me of the audio file to this turn by adding " [audio]SayHello " to the script file. Any other info you want to add, add it and it will be available to you after you started the dialogue. Your only limit is your imagination and NGUI skills :D

    Another example: especially for NGUI, I also added an event to trigger every time a letter is added to formattedText meaning, you could write an event handler that updates your label and have yourself a typewriter mode without having to update the NGUI Label every Update or OnGUI, but instead only when the text changes.
     
    Last edited: Jun 5, 2013
  16. MrDude

    MrDude

    Joined:
    Sep 21, 2006
    Posts:
    2,569
    Hi all

    The first update is now live with 2 new features: Localization and Dynamic Keys

    The big news is that CML Evolution now supports localization natively. Existing projects will continue to work undisturbed but, if you would like to add localization to your dialogues you can do so in 2 easy steps. First, add the translated text to your dialogue by adding a field with the name of the language. Secondly, set the static string variable CMLDE.Language to the language you want to use. Done...

    Example:
    Code (csharp):
    1.  
    2. <turn>id=0; next=-1
    3. [Afrikaans]Hallo daar.\nBly om jou te ontmoet.\nEk is MrDude van myBad Studios
    4. [Japanese]Konnichiwa\nHajimemashite\nWatashi wa myBad Studios no MrDude desu
    5. Hi there.
    6. Please to meet you.
    7. I am MrDude from myBad Studios
    8.  
    Secondly, in not so major news but possibly a little helpful non the ness, you are now able to use dynamic keys.

    Up to now you were able to display key values within your dialogue but now you can use the same method when specifying keys also. Before the keys are evaluated, it will first replace the dynamic text markers with the appropriate value and then continue to do it's thing. For example, you can now change the dialogue if, say, player's luck is lower than his skill... See example:
    Code (csharp):
    1. <turn>id=0; next =-1
    2. [require] + luck {:skill} 1
    3. Here you go, mister, please throw the dice for us...
    4.  
    5. <turn>id=1; next = -1
    6. Forget you! I'll throw my own dice..!
    7.  
    So, now, instead of working out your quests in advance and manually saying: "You must have 2000 Gold to meet this goal", you can now have a generic requirement and change it's criteria as the game progresses but still be able to use the same line in all cases... Example:
    Code (csharp):
    1. <turn>id=0; next=-1
    2. [require]+ {:currency} {:requirement} 1
    3. [keys] - {:currency} {:requirement}, + requirement {:requirement}, + rank 1
    4. Thank you for your contribution to our cause.
    5. You are now awarded a higher ranking in the order.
    6. Congratulations.
    7. Be advised, though, that your next contribution will require twice the dedication...
    8.  
    9. <turn>id=1; next =-1
    10. I am sorry but your 'dedication' to the order is not adequate...
    11. Please come back when your 'dedication' reaches <color=yellow>{:requirement} {:currency}</color>
    In this example, you could have different races who deal in different currencies use the same turn and still show / use the selected currency. In this example, using these two lines, you could now have a level up bribe system in your RPG. Each time you use the system, the bribe amount doubles and you gain an extra rank within your chosen guild. Your inventory is also depleted of the relevant amount in your relevant currency...

    All that work done in only 2 lines of dialogue... Clever, 'innit? :D

    So there you have it. Localized dialogue and dynamic keys. Simply download the updated package from the asset store and you are good to go.

    You can also get a free new dialogue GUI two posts down...

    See it in action here:
    $HostageNegLogo.jpg
    Enjoy.
     
    Last edited: Apr 14, 2013
  17. GregMeach

    GregMeach

    Joined:
    Dec 5, 2012
    Posts:
    249
    The free gui link didn't work for me, returned this error:
    Code (csharp):
    1. Incorrect password or file not found.
    2.  
     
  18. MrDude

    MrDude

    Joined:
    Sep 21, 2006
    Posts:
    2,569
    I've been getting complaints about all the files I've uploaded to box.com.

    I'm in the process of re-uploading everything elsewhere. In the mean time, I am including the GUI here.
    View attachment $IconicBottomDisplay.zip

    Sorry for the inconvenience...
     
  19. GregMeach

    GregMeach

    Joined:
    Dec 5, 2012
    Posts:
    249
    Thanks, ill check it out tomorrow. :)
     
  20. Burletech

    Burletech

    Joined:
    Jul 1, 2010
    Posts:
    73
    Okay so I found CML a pain to implement with NGUI. While I found the actual CML part to be amazing so far, I found the documentation to be difficult to understand and comprehend.

    Thank God for the post above from the author on how he implemented NGUI. Despite this help it wasn't enough to just plug things in and get going so it took me a few hours but I was finally able to implement NGUI. I thought perhaps I'm not the only one who was struggling to integrate this great asset so I'd share a little code snip for others.

    Good Luck!

    Note: I claim in no way, shape or form to be any good at programming. I still consider myself an intermediate at best so I'm sure there's better way's of doing this. I just am sharing because there was a lack (IMO) of examples on how to use CML in other systems.

    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4.  
    5. public class DialogueController : UDEA { // Inherit from UDEA or won't work
    6.    
    7.     // Note: Put this script on a empty gameobject named GameController with a tag of "GameController" so the ChoiceBtn scripts can find it easily.
    8.     // You can set it up however you want but that's how this script is used.
    9.    
    10.     // UI //
    11.     public UILabel dialogueLbl; // Main dialogue lbl
    12.     public UITable choiceTable; // Table player can make choices from
    13.    
    14.     // PreFabs //
    15.     public GameObject choiceBtnPreFab; // These are the buttons we'll fill our choiceTable with
    16.    
    17.    
    18.     // Starts the dialogue
    19.     void StartDialogue()
    20.     {
    21.         // Checks to see if the dialogue is already going
    22.         if( HasEnded )
    23.         {
    24.             //If not start it
    25.             StartDialogue( "Test" , 0 ); // StartDialogue( string "CML File Name" , int IndexToStartDialogueAt );
    26.         }
    27.         else
    28.         {
    29.             // If started continue it
    30.             Speak();
    31.         }
    32.        
    33.         // Checks to see if we need to show choices
    34.         if( CurrentIsChoice )
    35.         {
    36.             // If we need to make choices then fill the table with buttons
    37.             SetChoices();
    38.         }
    39.         else
    40.         {
    41.             // Otherwise just update the dialogue lbl
    42.             UpdateCurrentTextLbl();
    43.         }
    44.        
    45.     }
    46.    
    47.     // Updates visual GUI assets
    48.     void UpdateCurrentTextLbl()
    49.     {
    50.         // Just some string formatting
    51.         string txt = WhoIsSpeakingName + ":\n";
    52.         txt += CurrentText;
    53.        
    54.         // Update Main Dialogue Text
    55.         dialogueLbl.text = txt;
    56.     }
    57.    
    58.     // Sets up any choice btns for the player
    59.     void SetChoices()
    60.     {
    61.         // Double check to make sure it really is a choice node
    62.         if( CurrentIsChoice )
    63.         {
    64.             // Fill the table with the choice buttons
    65.             for( int i=0; i < CurrentOptionCount; i++ )
    66.             {
    67.                 // Add a button to the table
    68.                 var choiceBtn = NGUITools.AddChild( choiceTable.gameObject , choiceBtnPreFab );
    69.                 choiceBtn.GetComponent< ChoiceBtn >().choiceOption = CurrentOptions( i );
    70.                 choiceBtn.GetComponent< ChoiceBtn >().choiceIndex = i;
    71.                 choiceBtn.GetComponent< ChoiceBtn >().SetBtn();
    72.             }
    73.            
    74.             // Reposition Table
    75.             choiceTable.Reposition();
    76.         }
    77.        
    78.     }
    79.    
    80.     // This is called when a player presses a choice button
    81.     public void MakeChoice( string choice , int indx )
    82.     {
    83.         // Set the CML data from the choice that was made
    84.         OptionSelect( indx );
    85.         Speak();
    86.        
    87.         // Update to GUI
    88.         UpdateCurrentTextLbl();
    89.        
    90.         // Remove any choice btns
    91.         if( choiceTable.children.Count > 0 )
    92.         {
    93.             foreach( Transform btn in choiceTable.children )
    94.             {
    95.                 Destroy( btn.gameObject );
    96.             }
    97.         }
    98.        
    99.         // Disable start dialogue button if needed
    100.     }  
    101.    
    102. }
    103.  
    104. /*
    105.  * For this controller to work properlly you must go into the main
    106.  * CMLDE class file and comment or delete the Update() and HandleUnput()
    107.  * functions or it won't work
    108.  *
    109.  */

    Put this script on the UIButton prefab you use to fill your UITable
    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class ChoiceBtn : MonoBehaviour {
    5.    
    6.     // Dialogue Controller //
    7.     DialogueController dCon;
    8.    
    9.     // Public //
    10.     public UILabel btnLbl;
    11.    
    12.     // Setable Variables //
    13.     public string choiceOption;
    14.     public int choiceIndex;
    15.    
    16.     void Awake()
    17.     {
    18.         // Find out Dialogue Controller
    19.         dCon = GameObject.FindGameObjectWithTag( "GameController" ).GetComponent< DialogueController >();  
    20.     }
    21.    
    22.     public void OnClick()
    23.     {
    24.         // Tell the Dialogue controller the choice we've made
    25.         dCon.MakeChoice( choiceOption , choiceIndex );
    26.     }
    27.    
    28.     public void SetBtn()
    29.     {
    30.         // Set this btns choice variables
    31.         btnLbl.text = choiceIndex + ": " + choiceOption;   
    32.     }
    33. }

    Test.txt file in the "Resources" folder
    Code (csharp):
    1. <actors>
    2.     <actor>
    3.         [name] Burletech
    4.     <avatar>
    5.         UglyMugShot
    6.    
    7. <dialogue>
    8.     <turn>id=0
    9.     Man this CML thing is awesome!
    10.    
    11.     <turn>id=1
    12.     [next] 4
    13.     I want to use NGUI but I suck at reeding and cumpryhantion. Can you help?
    14.    
    15.     <turn>id=4
    16.     [choice] true
    17.     [next]5,6
    18.     Sure I'll help you out.
    19.     Go **** yourself Burletech!
    20.    
    21.     <turn>id=5
    22.     [next] -1
    23.     Oh thanks broseph. After you're done can you program an FPSMMORPGF2P for me real quick?
    24.    
    25.     <turn>id=6
    26.     [next] -1
    27.     Okay I'll be in the bathroom.
     
  21. MrDude

    MrDude

    Joined:
    Sep 21, 2006
    Posts:
    2,569
    Hi there

    Sorry to hear you had a hard time implementing this but it seems you managed to do it just fine. Congratulations. :) Thanks for sharing your code with others, here. :D

    Firstly, I guess here is as good a place as any to announce that CML Evolution is no more. The name has been a source of constant confusion for many people and it seems that, although it is capable of so much more, most of the people who look at it (and most of the people who visit my website) are after a dialogue system only. The fact that I don't CALL it a dialogue system has been the topic of many a support email so I decided to rebrand it. The product itself has remained 100% unchanged except for the name change and the update to a few classes to reflect this change. I.e. the CMLDE classes and references have now been renamed to UDEA to reflect the new name of Unity Dialogue Engine Advanced.

    For those of you who purchased the CML Evolution from the Asset Store, simply login and update your package toUnity Dialogue Engine Advanced. Be aware, there is a tiny bug in Unity that sometimes creeps up and might feature here. After you have updated the package, Unity might still open up the old package instead. Don't know why, but I have already notified Unity of this bug. You could try to close Unity and restarting Unity to see if it fixes the problem but I have found the problem to be that Unity stores this package as a duplicate package on your computer (same as with any other package that has had a name change i.e. changed the name v1.1 from v1.0). To guarantee that you use the right version of any of your products, I would actually recommend you go to your /Library/Unity/AssetStore/ folder and checking all your products to see if there are any duplicate packages in there. First off, they waste your hdd space and secondly, they might cause you to use older versions of a package, instead of the latest ones. Definitely directly after an update if there was a name change of any kind...

    No idea where these files are stored in Windows, though. Perhaps someone can chime in with some hep on that front? Please?

    Anyways, back on topic:

    @Burletech
    I just wanted to point out two mistakes I noticed above:
    1. In your first script you mentioned that you have to go modify the UDEA.cs script. This is incorrect. I tried real hard to make it so that that would never be the case. When I was first asked about NGUI support, this was the only thing I had to change to make it compatible. As you figured out yourself, by default, any mouse click continues the dialogue and this is not what you want to have happen when you use NGUI. For that reason I made the function virtual so that you can change it's behavior in your own scripts. As such, all you HAD to do was add this line to your DialogueController.cs file (I noticed I made a mistake in that NGUI example I posted above. Sorry about that):
    Code (csharp):
    1.     override public void HandleInput(){}
    2. You made a mistake with your avatar definition. the "<" starts a new node. With CML, you can add as many fields as you want after the opening "<"-node using key value pairs but if you want to add more fields on the following lines, you need to enclose them in "[" and "]". So in the example you posted, you now have two actors defined. One has a name and no avatar while the other has an avatar and no name. However, since theUDEA looks for <avatar> nodes, it will completely ignore the second actor. Here is how you are supposed to do it:
    Code (csharp):
    1. <actors>
    2.       <actor>name=BurleTech; avatar=myUglyMug; thanked=1; Hero = true
    3.       <actor>myBadStudios
    4.          [avatar] mrDude
    5.          [appreciation level] 79
    6.  
     
    Last edited: Jun 5, 2013
  22. Burletech

    Burletech

    Joined:
    Jul 1, 2010
    Posts:
    73
    MrDude,

    Thanks for such an in depth reply. I really appreciate your getting back so soon and taking the time to help out with the code.

    You're right on each count. I wasn't actually using the avatar image in NGUI so i never even tested it out. That was a oversight on my part oops. Also another oversight was commenting out the Update() and HandleInput() in UDEA. I did this because I didn't want an empty Update() running in the background (I'm using it for mobile development so I try and scrape every little piece out). My mistake I should have been more clear on both those in the code comments.

    I must say I'm really enjoying the data part of CML. Writing the .txt is so easy and clean. I'm currently using it in a turn based RPG and it's allowing me to completely contain all my story, inventory, level, and turn elements easily with no fuss. Fantastic asset once you can wrap your head around it. Left a 5 star review on the AS.

    Edit: Oh also had a quick request. Would you be able to post UDEA in a 3.5 compatible project format. It works just fine in 3.5 if you just drag the folders over into it but it's kinda a pain to have to open it in Unity 4 then collect the folders and export them into another 3.5 project. If not it's no biggy but would make things easier =) Thanks!
     
    Last edited: Jun 5, 2013
  23. MrDude

    MrDude

    Joined:
    Sep 21, 2006
    Posts:
    2,569
    Glad you are enjoying it :)

    From pre-sales support to aftercare service, this is indeed what I have found to be true in most cases. Either people don't know what this kit can do and just leave it, or they take a chance and come back to me with raves about how awesome it is... :)

    If you think about it, what CML allows you to do is to create and use runtime, typeless variables... Now explain that to an artist and see what kind of a response you get. i.e. measure the height of the shrug...

    Now tell that to a programmer and measure the size of the bulging eyes :p lol :)

    This was why I called it CML Evolution to begin with; because CML allows you to do a great many things. For instance, I created a runtime input manager (similar to C Input) but mapped with only joystick buttons so that you configure the number of buttons you have on a joypad (6 shoulder, 6 buttons, start, pause, home, d-pad) and each will accept 3 inputs so you can configure an actual joypad as well as keyboard input with an alternate button layout. From start to finish (minus the axis support) it took me under 2 hours to create. I am busy with a character customization system, also running on CML... The runtime variables sure make life easy when it comes to writing code now that will work with any future models I just so happen to add...

    But tell people the name is CML Evolution and they shrug and go "Whatever". Tell them it's called "Dialogue Engine" and suddenly they take notice... and then get a welcome surprise afterwards :p Sad but true.

    Anyways, I am available should you require anything else. Feel free to email me. Oh, and check your PM. I left you a little something in there.

    As to your request... Bugger... I completely overlooked 3.x support. As it is I just deleted 3.5 from my system last week as I said to myself: "Well, I don't see me using THAT again"... Will get a new copy and do so. Honestly never even THOUGHT to upload in 3.5. Silly me...
     
    Last edited: Jun 5, 2013
  24. Burletech

    Burletech

    Joined:
    Jul 1, 2010
    Posts:
    73
    Hey MrDude. Quick and probably easy question for you. Okay let's say for example I have a CML like this..


    Code (csharp):
    1.  
    2. <inventory>
    3. [BagSlots] 20
    4.  
    5.     <item>
    6.     [type] Chest
    7.     [name] Wizard's Robe
    8.    
    9.     <item>
    10.     [type] Sword
    11.     [name] Wooden Sword
    12.    
    13.     <item>
    14.     [type] Herb
    15.     [name] Grass Root
    16.     [Count] 2
    17.  
    Okay now let's say I want to add a new <item> to the <inventory>? So far when I try this...

    Code (csharp):
    1.  
    2. cmlData item = new cmlData();
    3. item.data_type = "item";
    4. item.Set( "type" , "Herb" );
    5. item.Set( "name" , "Grass" );
    6. invCon.inventoryCML[ 0 ].AddToData( item.ToString() );
    7.  
    I get back a CML that looks like it should work. It even assigns the ids and everything. The problem then is when I do this...

    Code (csharp):
    1.  
    2. List< cmlData > items = AllObjects.DataWithField( "type" , "Herb" );
    3.  
    The new <item> that was just added does not show up. Any chance I could get some guidance from you? Thanks!
     
  25. MrDude

    MrDude

    Joined:
    Sep 21, 2006
    Posts:
    2,569
    Hi Burletech

    If you look carefully at what you were doing there, you will notice that you were not working with the database itself; but rather with the first node.

    Each node (or "key" if you will) can hold an infinite number of fields + a collection of unordered data.
    The command AddToData, on node level, adds content to the node's unordered data.

    To add new nodes / keys to the database, there are a number of ways you could do that but, CML was meant to be simple and the way you were going at it, you were seriously overcomplicating it for yourself...

    Here, try this:
    Code (csharp):
    1.  
    2. invCon.inventoryCML.AddNode("item", "type=Herb; name=Grass");
    3.  
    ...or, if you prefer...
    Code (csharp):
    1.  
    2. invCon.inventoryCML.AddNode("item");
    3. invCon.inventoryCML.Last.Set("type", "Herb");
    4. invCon.inventoryCML.Last.Set("name", "Grass");
    5.  
    ...or if you already HAVE the node created like "item" above, try this:
    Code (csharp):
    1. invCon.inventoryCML.CopyNode(item);
    Also, what confuses me a tad is that you add to invCol.inventoryCML but you query AllObjects... What's that about?
     
    Last edited: Jun 11, 2013
  26. Burletech

    Burletech

    Joined:
    Jul 1, 2010
    Posts:
    73
    Lol ya sorry I just mashed that together copy pasting various parts of code I was trying out. That was meant to find out how many "Herbs" I had in my inventory after adding the new node.

    Your example works great and is much simpler than what I was trying. Thank you. I'm sure I'll have more questions to come ;) I really appreciate such prompt replies.
     
    Last edited: Jun 10, 2013
  27. MrDude

    MrDude

    Joined:
    Sep 21, 2006
    Posts:
    2,569
    I uploaded an update to the package about a week ago. Still waiting for Unity to accept the update. This new version is uploaded from Unity 3.5.7 so your request is met :D.

    I've also included the NGUI Distribution version in the kit and included the demo NGUI scene you created for me. Thanks again for that and to all who reads this, full credit to Burletech for this new demo scene. There were a few things in the coding that you could have done slightly differently but to give you all the credit I left "what works" alone :p

    But to correct you on something you stated in a previous post, you were wrong about dragging the folders over to Unity 3. Yes, you can use the UDEA for your own projects, yes, but all the prefabs get destroyed in the downgrade which means the demo scenes no longer work. Moreover, when I tried to open the demo scene (not run it, just open it) it caused Unity to hang. As such, I had to recreate the demo scene from scratch by re-importing the Unity asset, replacing the new scripts with the old ones and what not. the end result is a project that is 100% the same as it was but recreated to be compatible with 3.5.

    When Unity finally get around to looking at this update your request will be one download away from being answered... :)

    The kit also includes a new file that has nothing to do with the UDEA itself but DOES offer a nice little feature I am not yet at liberty to discuss... Let's just say that this new feature is dependent on another package and this package has been submitted also so if it gets accepted also I will make the announcement here... Unfortunately you will need Unity 4 for this to work... :(

    Anyways, just wanted to say thank again for the NGUI demo scene and to let you know the update has been laying in the Asset Store inbox for a week already so it should be available soon-ish :D
     
  28. Leslie-Young

    Leslie-Young

    Joined:
    Dec 24, 2008
    Posts:
    1,148
    hehe, you may ;)
    I only hope it gets accepted to AS.

    We are working on creating a plugin that will make it easy to use MrDude's kit with UniRPG (not the tile editor, the new tool ;).
     
  29. MrDude

    MrDude

    Joined:
    Sep 21, 2006
    Posts:
    2,569
    One of my customers recently asked me for an example of how to create a questing system so I thought I'd go and make one and post it here. The following is copied from the script comment block:

     

    Attached Files:

    Last edited: Jun 27, 2013
  30. MrDude

    MrDude

    Joined:
    Sep 21, 2006
    Posts:
    2,569
    Ahhh.... update number 1.

    in the QuestNew function, add this to the end of the function:
    Code (csharp):
    1.         Quests.Save("Quests");
    Currently I save the quests to disc when you complete one but I don't automatically save it when you receive a new one...
    You might also want to add that to the QuestUnlock(int ID) function also for the same reason; save the quests when the status of one changes...

    Edit:
    Above file updated...
     
    Last edited: Jun 27, 2013
  31. zisaMan

    zisaMan

    Joined:
    Jun 27, 2013
    Posts:
    25
    Please can you post some examples, how to use this script or how to call from another script.
    I'm definitely doing something wrong:

    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4.  
    5. public class myStart : MonoBehaviour
    6. {
    7.     void Start()
    8.     {
    9.         UDEAQuesting.QuestGenerate("questname", "a quick quest", "Gold = 200", "Gold= 2500", "crate01", false);
    10.         UDEAQuesting.QuestCompleteAll();
    11.     }
    12. }
     
  32. MrDude

    MrDude

    Joined:
    Sep 21, 2006
    Posts:
    2,569
    That looks okay... What problems are you having? Remember, you are saying that the quest requires gold to be completed so in order for the completeall to work, you need to have enough gold in UDEA.GameKeys

    QuestComplete tests wether the quest is still active and wether you now meet all criteria to close it off and get your rewards. QuestCompleteAll calls QuestComplete for all quests.
     
  33. zisaMan

    zisaMan

    Joined:
    Jun 27, 2013
    Posts:
    25
    i've got this errors:

    Assets/crRPGSystem/Demo/myStart.cs(9,22): error CS0122: `UDEAQuesting.QuestGenerate(string, string, string, string, string, bool)' is inaccessible due to its protection level

    Assets/crRPGSystem/Demo/myStart.cs(10,22): error CS0122: `UDEAQuesting.QuestCompleteAll()' is inaccessible due to its protection level

    in the demo i've attached myStart to Dude, it has 2000 gold (assigned via UDEA)
    only if i change in UDEAQuesting.cs QuestGenerate() to public static it works, is this correct?
     
    Last edited: Jun 27, 2013
  34. MrDude

    MrDude

    Joined:
    Sep 21, 2006
    Posts:
    2,569
    Yes, you are right. Sorry, my bad. I fixed the script and added all my little tweaks. Please download it again and you should be good to go :)
    Thanks for pointing that out to me :)
     
  35. zisaMan

    zisaMan

    Joined:
    Jun 27, 2013
    Posts:
    25
    ok.. errors cleared. Thank you.
    Everything works fine.
    The only thing i don't understand well is how works QuestEventHandler
     
  36. MrDude

    MrDude

    Joined:
    Sep 21, 2006
    Posts:
    2,569
    Google Blackwasp and event. That site is awesome for learning c#.

    Fortunately, you don't need it, I simply added the 3 events in case advanced users wanted it. You will notice that the events fire, as the names suggest, when you create a new quest, when you successfully complete a quest and for every reward you get. This is merely a notification for advanced users who want to do some additional stuff like playing a sound or sliding in a notification or making the player do a boogie or whatever. The events simply tell you: "You said to tell you when this happened, well it just did"

    Thats all it does so you don't technically NEED it. It's just there for convenience...
     
  37. zisaMan

    zisaMan

    Joined:
    Jun 27, 2013
    Posts:
    25
    thank you again :D
     
  38. Burletech

    Burletech

    Joined:
    Jul 1, 2010
    Posts:
    73
    I should've been more clear on that. I just draged the code folders into a 3.5 project and they worked fine. Thanks for updating that to 3.5 :D

    No problem at all. I know it's not the best but like you said it works.

    Excited to check out the Quest example and really looking forward to seeing what you and Leslie have coming.
     
  39. MrDude

    MrDude

    Joined:
    Sep 21, 2006
    Posts:
    2,569
    Still waiting for the update to get to reviewed but at least I can tell you what to expect. Leslie is working on an RPG system that does so bloody much and let's you make RPGs without a single line of code. I've seen this in action but don't know how to explain it in under 10,000 words so simply have a look at the official website and watch the YouTube trailer...

    Then factor in the fact that the UDEA will be the official dialogue plugin for this kit. First experience what his kit does, then get excited about this union... :D
    http://plyoung.com/unirpg
     
  40. TopThreat

    TopThreat

    Joined:
    Aug 7, 2012
    Posts:
    136
    Just when I had decided not to buy anymore assets for a while :) I already have your great product but can see some potential with using it alongside the RPG system!
     
  41. MrDude

    MrDude

    Joined:
    Sep 21, 2006
    Posts:
    2,569
    Okay, the uniRPG is live on the Asset Store here:
    https://www.assetstore.unity3d.com/#/content/9694

    My update has been laying on the asset store for 2 weeks now and still no review. No idea when they are finally going to get around to reviewing it but once they do, uniRPG will be "aware" of the UDEA if you include it in the same project. We are working on the communication between the two but that should be available in (hopefully) the next update of uniRPG.

    That is to say, if the Asset Store team has gotten around to reviewing the UDEA update by then... :(
    Some more finger crossing going on here... Last time they turned down one of my packages I had "typos" in an image that had no text in it... Big no-no that. If you are not going to write anything, make sure you spell it correctly... lol So, not really sure what to expect or when to expect it so even more finger crossing going on :D :p I'm quickly running out of fingers to cross now... :p

    I'm thinking of adding data encryption to the next package update but at this rate I have no idea when that update will see the light of day.
    Soon... hopefully...

    Just a quick question, though... At one point I worked on a project that dealt a lot with online data so I created some functions to fetch and store data online. The Unity Dialogue Engine Advanced is supposed to be about dialogues, not data storage but it is built on top of CML and CML is all about data storage and retrieval. Would you like me to add the functionality to store your data online to the UDEA or is this not something you think should be a default part of a dialogue engine?

    Adding it would be simplicity itself but it would require you to have a website, have a database setup, placing some scripts on your website and configuring your settings file with your database login details etc etc etc... So on my end it is simplicity itself but on your end it does require a little bit of work.

    I currently have a number of packages that deal with this stuff and can make it compatible to the point where anyone who has any of my other packages would be good to go without having to configure the login scripts but thus far, most of the support requests I get are from people who don't know how their web hosts deal with database access. Weather to use "localhost" or a URL, where to get their details, how their host's "mail" function is setup etc etc etc. This is obviously not something that is related to the UDEA so if I include this feature I would expect you to at least know something about php and mySQL...

    What do you think? Leave this feature to those who know about php and mySQL (and can add this feature themselves in 10 minutes flat) or add it in and spend 90% of all support requests for the dialogue engine explaining how to get passwords from web hosts and how to use phpmyadmin...?
     
    Last edited: Jul 2, 2013
  42. MrDude

    MrDude

    Joined:
    Sep 21, 2006
    Posts:
    2,569
    Cool. I now have some fingers available to start coding with again :)
    Update is up.

    All your "Does this support NGUI?" questions are now answered by means of a sample demo project.

    Enjoy :)
     
  43. zisaMan

    zisaMan

    Joined:
    Jun 27, 2013
    Posts:
    25
    You are asking for feature request? here are mine.
    Since i've purchased UDEA to make a game like hayday but with quest adventures, it would be great to have a system to save/load/parse all data to/from a server.
    I am implementing a crafting system and try to use/expand the quest system you wrote last time. So anything you could write more about questing system is extremely... extremely welcome :)
     
  44. MrDude

    MrDude

    Joined:
    Sep 21, 2006
    Posts:
    2,569
    I've been meaning to copy the encryption code back into the main project for ages now. I have finally done so and it will be included in the next update. To use, instead of saying:
    Code (csharp):
    1. Save("some_file_name");
    ...you now say:
    Code (csharp):
    1. Save("some_file_name", "some_secret_string");
    That simple. Obviously loading encrypted data is just as easy. This way your data will be protected and completely unreadable by anyone who doesn't have the encryption string you used in the second parameter. If you want to encrypt the data itself without saving it, the ToString() function can now be used as ToString("some_secret_string") on both CML and cmlData classes.

    I will release the next update when I've added the online saving feature. But please be aware that with the WWW class having a delay between requesting data and receiving data, fetching data needs to be done via a coroutine and is completely unusable for real time or time critical updates of data. If you want to do time critical or real time data transfer and saving etc you will still need to use networking and have a server up and running etc etc etc. The online features I will be including herein is to save the entire file online and fetch it back again. So you would be storing your library online and fetching the library back again each time you want to want info about a book or want to add a book to the library... This would be purely for storage.

    Be advised.
     
  45. zisaMan

    zisaMan

    Joined:
    Jun 27, 2013
    Posts:
    25
    i know i am doing something wrong, but...
    So, i have a NPC with a script UDEAdialogueGUI, you know it.
    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class UDEAdialogueGUI : UDEA
    5. {
    6.  ......
    7. }
    then i have the player, with his script, trying to receive events from NPC:
    Code (csharp):
    1. using UnityEngine;
    2. using System;
    3. using System.Collections;
    4. using System.Collections.Generic;
    5.  
    6. public class questTest : MonoBehaviour
    7. {
    8.     public GameObject myNPC;
    9.     private UDEAdialogueGUI npcUDEA_GUI;
    10.  
    11.     void Start()
    12.     {
    13.         npcUDEA_GUI = myNPC.GetComponent<UDEAdialogueGUI>();
    14.         npcUDEA_GUI.OnDialogueEnded += new  UDEA.UDEAEventHandler(nowDialogueEnded);
    15.     }
    16.  
    17.     void nowDialogueEnded(object source, UDEAEvent e)
    18.     {
    19.         Debug.Log("now dialogue ended");
    20.     }
    21. }
    but i receive this error:
    Code (csharp):
    1. Static member `UDEA.OnDialogueEnded' cannot be accessed with an instance reference, qualify it with a type name instead
    where am i doing wrong? Please.
     
  46. MrDude

    MrDude

    Joined:
    Sep 21, 2006
    Posts:
    2,569
    Hi there

    The events are static so you need to access them like so:
    Code (csharp):
    1.  
    2. UDEA.OnDialogueEnded += new  UDEA.UDEAEventHandler(nowDialogueEnded);
    3.  
    ...or simply...
    Code (csharp):
    1.  
    2. UDEA.OnDialogueEnded += nowDialogueEnded;
    3.  
     
    Last edited: Jul 6, 2013
  47. zisaMan

    zisaMan

    Joined:
    Jun 27, 2013
    Posts:
    25
    oops... :rolleyes:
    thank you
     
  48. MrDude

    MrDude

    Joined:
    Sep 21, 2006
    Posts:
    2,569
  49. MrDude

    MrDude

    Joined:
    Sep 21, 2006
    Posts:
    2,569
    @Steven Hart
    Just in case you are seeing this, the email address you used on my website returned with an "this email doesn't exist" error. Please see my original correspondence below:

     
    Last edited: Jul 11, 2013
  50. MrDude

    MrDude

    Joined:
    Sep 21, 2006
    Posts:
    2,569
    Some of you have mailed me asking why the UDEA was removed from the Madness Sale as you are now no longer able to get it at the discounted price.

    The simple answer is that the UDEA was not part of the madness sale. It was on a 24 hour sale as part of the summer promotions.

    For those of you who thought it was part of the madness sale and were thus holding off on buying it, note that I have temporarily dropped the price. For the duration of the Madness Sale you can now buy it at 50% off. After which the normal price will be restored.

    So there you have it. A second chance so to speak. If you missed it, at least you didn't completely miss out. :)
    Enjoy.

    ...and tell your friends :D