Using userData as a global JSON Object accessible from multiple Entity Scripts


#1

Hello everyone,

What I’m trying to do is use the userData property on a specific entity as a global JSON Object which I can use as a simple Key Value store, so here’s what I do

function getDataStore(){
        var storageEntity = Entities.findEntities({x:0, y:-1000, z:0}, 100.0);
        // print(storageEntity);
        var userData = Entities.getEntityProperties(storageEntity, ['userData']);
        // print(JSON.stringify(userData));
        return userData;
    }




function writeToDataStore(entityData){
        var storageEntity = Entities.findEntities({x:0, y:-1000, z:0}, 100.0);

       Entities.editEntity(storageEntity, { userData: entityData });

       print("Writing: " + JSON.stringify(entityData) + " to " + storageEntity);
    }

An the way i use this is:

updateTransform: function(entityName, position, rotation, scale){
             var ENTITY_DATA = getDataStore();
             print("Updating "+ entityName);
            if( ENTITY_DATA[entityName] ){
                print("Transform Updated");
                //Cache previous
                var currPos = ENTITY_DATA[entityName].position;

                //Calculate deltas
                var deltaPos = Vec3.subtract(position, currPos);

                //Update delta's'
                ENTITY_DATA[entityName].positionDelta.x = deltaPos.x;
                ENTITY_DATA[entityName].positionDelta.y = deltaPos.z; //Flipping y and Z
                ENTITY_DATA[entityName].positionDelta.z = deltaPos.y;

                ENTITY_DATA[entityName].rotation.x = rotation.x;
                ENTITY_DATA[entityName].rotation.y = rotation.y;
                ENTITY_DATA[entityName].rotation.z = rotation.z;
    
                //Centimetres to metres conversion
                ENTITY_DATA[entityName].scale.x = scale.x/100;
                ENTITY_DATA[entityName].scale.y = scale.y/100;
                ENTITY_DATA[entityName].scale.z = scale.z/100;

                 writeToDataStore(ENTITY_DATA);

            }else{
                print("WARNING : Trying to update property that is not registerd");
                EntityDeltaTracker.registerEntity(myEntityID);
            }
            
        }

I’m basically keeping track on how much an object has moved since it was first spawned in a structure as follows

{
entityName : {
positionDelta: { x, y ,z},
rotation : {x, y ,z},
scale: {x, y, z}
}
}  

SO I grab a specific entity ( I position it in a Unique location) in the world and try to mutate its userData, however the userData is not being updated at all.

I’d appreciate some help doing this, I just need a global JSON Object that I can access from multiple Entity Scripts really, if theres a better way than userData I’d love to know it.

Thanks!


#2

Heya,

As a reminder, I have a few notes you should probably take notice of:

  1. The userData field actually is a string, so if you want to manipulate as json, make sure to convert it from string and store it as a string using the JSON.parse (string to json) / JSON.stringify (json to string). So for getDataStore, you should as JSON.parse(userData) for the return, and for the writeToDataStore, JSON.stringify when editing the entity
  2. As a caution: Entity scripts are ‘global’ client scripts: so each client that loads the script will also edit and manipulate the same object

Hopefully that helps :slight_smile: