Monday, November 29, 2021

Send Event from Normcore Realtime component string to Playmaker FSM

This may look complicated but it's not as bad as it looks, let me break down the pieces it consists of.

1. The realtime Component model script (That contains a string we want to sync to all players)

2.The "sync" script that reads the model string value, updates the realtime model if you or the other player updates it and then communicates that change to the other players.

3.A FSM event script that contains the event we will send to playmaker. We will activate that FROM the sync script.

Let's get started!

We are going to create a way to send an event to a playmaker FSM to tell it when a realtime component string has changed. Normcore sends it's own events but currently I don't know how to get them to talk to playmaker FSM's.

First make the script that will be the model called SelectedResourceModel for the realtime component string. our string is called "selectedResource"

  using System.Collections;

using System.Collections.Generic;
using UnityEngine;

using Normal.Realtime.Serialization;
using Normal.Realtime;

[RealtimeModel]
public partial class SelectedResourceModel

{

    [RealtimeProperty(1, reliable: true, createDidChangeEvent: true)]
    private string _selectedResource;
}

Once that is created, you can compile that model script in the right of the inspector when you select that model script.


 

Now when that is compiled you can create the sync script that will talk to the model to sync the realtime component string. selectedResource. The script is called SelectedResourceScript

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using Normal.Realtime;
using TMPro;


public class SelectedResourceScript : RealtimeComponent
{

    private SelectedResourceModel _model;
    //public RealtimeAvatarManager _avatarManager;
    private TextMeshProUGUI _selectedResourceText;
    public string selectedResourceCustom;

   

    //public ResourceStringUpdatedScript resourceStringUpdatedScript;
   

    private void Awake()
    {
            //get the reference to the selectedResource textygame object
        _selectedResourceText = GetComponent <TextMeshProUGUI>();
    }

    private SelectedResourceModel model
    {
        set
        {

            if (_model != null)
            {
                //unregister from events
                _model.selectedResourceDidChange -= SelectedResourceDidChange;
            }
        //store the model
            _model = value;

            if (_model != null)
            {
                //Update the selectedResource to match new value
               UpdateSelectedResourceText();
                // register for events so we'll nkow if the selectedResource chagnes later
                _model.selectedResourceDidChange += SelectedResourceDidChange;
            }
           
        }

    }

     private void SelectedResourceDidChange(SelectedResourceModel model, string value )
     {
            UpdateSelectedResourceText();
         

     }

     private void UpdateSelectedResourceText()
     {
         _selectedResourceText.text = "" + _model.selectedResource;
     }

     public string GetSelectedResource()
     {
         return _model.selectedResource;
     }

 

        public void SetSelectedResource(string selectedResourceCustom)
    {
        _model.selectedResource = _model.selectedResource = selectedResourceCustom;


    }    

   
}

So in this script you can see the method  private void SelectedResourceDidChange

Inside this method where we can run a method in another script to send the FSM event when it detects that the realtime component did change.

Now we need to create the textmeshproUI text for this script to go onto. The script above will sync the value of the realtime string model and update the text to the value of the model. This will let both players see the same string. 

So create a textmeshUI pro gameobect (if it's not UI then you will have to modify the script above for NOT UI textmeshpro)

Now drop the SelectedResourceScript.cs onto that textmeshproUI.

Now we need to create a little script that will actually send an FSM event WHEN the script we just made updates the text. Called ResourceStringUpdatedScript.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using PlayMaker;

public class ResourceStringUpdatedScript : MonoBehaviour
{




     public PlayMakerFSM myFSM;

    // Start is called before the first frame update
    void Start()
    {
       
    }

    // Update is called once per frame
    public void ResourceUpdateString()
    {
          myFSM.SendEvent("ResourceStringUpdated");
    }
}

This will send an event to the FSM called ResourceStringUpdated. Now drop this script onto the text mesh pro game object as well. 

We created a method called ResourceUpdateString

We can now RUN this method in the SelectedResourceScript when the text is updated, and it will ALSO send our FSM event upon updating.

Add a playmaker FSM to the textmeshpro object also. What you have should look kind of like this.

MAKE SURE YOU ALSO HAVE A REALTIME VIEW on that textmeshproUI as well or the realtime component WILL NOT WORK PROPERLY.


Drag the FSM into the FSM field on your ResourceStringUpdatedScript slot for MyFSM

Now all that is left is to add the Method called ResourceUpdateString from our ResourceStringUpdatedScript. To get to the method in the other script we just add this line of code.

GetComponent<ResourceStringUpdatedScript>().ResourceUpdateString();

This shows how we add it to the DidChange Method

   private void SelectedResourceDidChange(SelectedResourceModel model, string value )
     {
            UpdateSelectedResourceText();
            GetComponent<ResourceStringUpdatedScript>().ResourceUpdateString();

     }

Now in the FSM that is on that TextmeshProUI game object. You can create and event that will fire.

Add an event with the same name as the event in the script ResourceStringUpdated


That's it! Now when your realtime changes it will automatically also fire the event in your playmaker FSM!