HFFWS Object Instantiation and Setting Their Node Values

August 13, 2019

Human Fall Flat Workshop

Instantiating Objects with Nodes

Youtube – Moving Platform Tutorial in Unity for Human Fall Flat

By: Gotcha McFee

I just wanted to reference this tutorial again as this is how I got the moving platform in the first place for HFFWS. This also shows why I am interested in the specific components and their values when instantiating the object. This object also has a lot of node graph involvement, which is a big part of HFFWS in general, so it shows why being able to control their values in script is so necessary.

Creating Object Spawner

I wanted to create a script that could take some of these HFFWS prefabs and start spawning them with various values for their variables to see if I could produce varied objects in real time in the game.

This script needs to be able to:

  • Take a prefab reference
  • Access certain components (or children’s components)
  • Access the parameters of the components(s)
  • Randomly set them (within a given threshold)
  • Create instances of the prefab with these given values

The components for MovingPlatformVertical that we need access to are:

    Parent

  • Mesh Renderer
  • Mesh Filter
  • Mesh Collider
  • Signal Math Mul (Script): In 2
    Children (Axis)

  • Transform (Rotation)
  • Linear Joint
    • Max Value
    • Max Speed
    • Max Acceleration

It turns out SignalMathMul and LinearJoint are both part of the HFFWS .dll file. You can gain access to these classes in script however with the namespace “HumanAPI”. So at the top of your Unity C# script, you just need to add “using HumanAPI” to reference this namespace to create variable references for these classes.

The next issue I ran into however was attempting to set node values within script. SignalMathMul uses the node system, and I wanted to change the In 2 value of this component in script. By creating a variable reference for a SignalMathMul object, I saw there was simply a variable I could access within it called “in2”, which seemed like the variable I was looking for. Trying to set this as a float, I got an error telling me this was actually of type NodeInput. After creating this object, I looked at the methods and variables available and found one simply called “value”. So I tried setting the value of my number NodeInput to 0.5f, and then setting this signalMathMul.in2 to number (in an attempt to set the input 2 value of the signalMathMul component to 0.5f) but this just resulted in 0 at run time.

TESTING

I think that something with the whole Net Body setup may be causing issues, as this may not like values of these components being set at run time. This may be causing some value discrepancy for a very brief moment that when the networking system sees it it just defaults values to zero.

Initially, I was trying to instantiate a new moving platform with the given SignalMathMul values. I then tried to just alter the values of an existing in scene platform with the script. This also appeared to fail at first, as the inspector showed a value of 0 again. With further testing, this setup does appear to actually set the internal input node value. This change is not reflected in the Unity editor, but when play testing it did change the behavior of the platform. Upon further inspection in the node graph, it could also be seen here that the value was actually being set to that given in the script. I then went back to use the exact same setup but with instantiation again, and this did not work still. Again, this just set the input to zero. I checked in play mode in the updating node graph, and this confirmed it was actually set to a value of zero.

I then tried instantiating the object, and then changing its input values. This created an instance of the prefab with its default values just fine. The platform was moving properly. This however did not update the platform values with the scripted values.

SOLUTION

Since none of these approaches with setting in2.value to a number were working, I checked the methods and variables available again and saw there was also an initialValue variable for the Node Input class. I then tried setting in2.initialValue instead with my instantiated platform and this worked as intended. The value was properly set (in editor as well as in the node graph) and the platform’s moving behavior changed accordingly. The resulting script looks as follows:
public GameObject movingPlatformPrefab;
private SignalMathMul signalMathMul;
private LinearJoint linearJoint;

private void Awake()
{
GOInstantiatePlatform();
}

private void GOInstantiatePlatform()
{
GameObject newPlatform = (GameObject)Instantiate(movingPlatformPrefab);

newPlatform.GetComponent().in2.initialValue = 1.2f;
}

I left the extra component references in for later if I need them, and I was doing the instantiation in Awake through testing in case spawning it “later” was doing something weird with the networking scripts. I tested running it in Start instead and this also worked just fine.