Assigning userData to entity properties


#1

Hi Folks,
I’m trying (and failing) to add a new property to the entity userData object, can you tell me where I’m going wrong?

here’s the script, the first call to editEntity is just there to visually reassure me the click has happened (the colour does change when clicked):

(function(){

this.clickDownOnEntity = function(entityID, mouseEvent) { 

Entities.editEntity(entityID, { color: { red: Math.random()*255, green: Math.random()*255, blue: Math.random()*255} });
Entities.editEntity(entityID, { userData:{myValue: 0}});

var newItemProperties = Entities.getEntityProperties(entityID);

print("new props: ", JSON.stringify(newItemProperties));

print("new value ",newItemProperties.userData.myValue);
};
})

and this is the log output, note userData is empty in the new properties:

[05/11 20:39:11] [DEBUG] Done downloading script at: “atp:/rbscrip/udtest.js?v=3”
[05/11 20:39:14] [DEBUG] script:print()<< new props: {“id”:"{4d9b16d9-79b6-4ed7-8d31-9e56aae24ee9}",“type”:“Box”,“created”:“2016-05-11T18:37:27Z”,“age”:3652.2841796875,“ageAsText”:“1 hours 0 minutes 52 seconds”,“position”:{“x”:1105.3372802734375,“y”:447.2249450683594,“z”:-48.50132369995117},“dimensions”:{“x”:0.20000000298023224,“y”:0.20000000298023224,“z”:0.20000000298023224},“naturalDimensions”:{“x”:1,“y”:1,“z”:1},“naturalPosition”:{“x”:0,“y”:0,“z”:0},“rotation”:{“x”:0,“y”:0,“z”:0,“w”:1},“velocity”:{“x”:0,“y”:0,“z”:0},“gravity”:{“x”:0,“y”:0,“z”:0},“acceleration”:{“x”:0,“y”:0,“z”:0},“damping”:0.39346998929977417,“restitution”:0.5,“friction”:0.5,“density”:1000,“lifetime”:-1,“script”:“atp:/rbscrip/udtest.js?v=3”,“scriptTimestamp”:0,“registrationPoint”:{“x”:0.5,“y”:0.5,“z”:0.5},“angularVelocity”:{“x”:0,“y”:0,“z”:0},“angularDamping”:0.39346998929977417,“visible”:1,“collisionless”:0,“ignoreForCollisions”:0,“collisionMask”:31,“collidesWith”:“static,dynamic,kinematic,myAvatar,otherAvatar,”,“dynamic”:0,“collisionsWillMove”:0,“href”:"",“description”:"",“actionData”:"",“locked”:0,“userData”:"",“marketplaceID”:"",“name”:"",“collisionSoundURL”:"",“color”:{“red”:17,“green”:160,“blue”:82},“sittingPoints”:{“length”:0},“boundingBox”:{“brn”:{“x”:1105.2373046875,“y”:447.12493896484375,“z”:-48.601322174072266},“tfl”:{“x”:1105.437255859375,“y”:447.324951171875,“z”:-48.40132522583008},“center”:{“x”:1105.3372802734375,“y”:447.2249450683594,“z”:-48.50132369995117},“dimensions”:{“x”:0.199951171875,“y”:0.20001220703125,“z”:0.1999969482421875}},“originalTextures”:"{\n}\n",“parentID”:"{00000000-0000-0000-0000-000000000000}",“parentJointIndex”:65535,“queryAACube”:{“x”:1105.1640625,“y”:447.0517272949219,“z”:-48.674530029296875,“scale”:0.3464101552963257},“localPosition”:{“x”:1105.3372802734375,“y”:447.2249450683594,“z”:-48.50132369995117},“localRotation”:{“x”:0,“y”:0,“z”:0,“w”:1}}
[05/11 20:39:14] [DEBUG] script:print()<< new value undefined

What am I doing wrong here?

Cheers,
Robin.


#2

Heya,

userdata has to be set as string (it is very annoying) not as a JSON object.

so use JSON.stringify when converting the JS Object into string.
:slight_smile:

Entities.editEntity(entityID, { userData:JSON.stringify({myValue: 0})});


#3

Thank you!

Nearly there… I’m not able to access the new value though, and looking at the dump of properties, the property name seems to have ended up with literal quotes in it…

First the code again:

(function(){

this.clickDownOnEntity = function(entityID, mouseEvent) { 

Entities.editEntity(entityID, { color: { red: Math.random()*255, green: Math.random()*255, blue: Math.random()*255} }); //click indicator

Entities.editEntity(entityID, { userData:JSON.stringify({myValue: 0})});

var newItemProperties = Entities.getEntityProperties(entityID);

print("new props: ", JSON.stringify(newItemProperties));

print("new value ",newItemProperties.userData.myValue);
};
})

now a bit of the log:

0,“userData”:"{“myValue”:0}",

[05/11 21:47:05] [DEBUG] script:print()<< new value undefined

I’ve tried various ways if incorporating the literal quotes in the retrieval but get “illegal character” errors if I try stunts like : x = newItemProperties.userData.“myValue” or similar

Have I found a bug?

Cheers,
Robin.


#4

Since the userData is string, when you are retrieving the data, make sure to convert it back to a JSON Object.

so that

JSON.parse(newItemProperties.userData).myValue

Hopefully that helps :slight_smile:


#5

Ah, ok, got it, now that I look at the stacking of quotes in the log dump properly!

Thanks again! I’d never have picked that up from the docs and there seem to be no examples of using userData in the entity script examples on github.

Also this page: http://jsref.docs.highfidelity.com/v1.0/docs/entity-properties#section-common-properties shows userData’s type as object when it clearly isn’t :wink:

As a corollary, does this mean we have to be careful when adding userData if other scripts also use it on the same entity? i.e. do we have to do a string merge with existing userData then pass that to editEntity() or does editEntity() take care of that for us? I’d experiment but I’ve shut down my VR rig for the night now.

Cheers,
Robin.


#6

Yes. Good practise would be to get the current userData is one exists (check length) and add to it :slight_smile: unless you are creating a brand new object.


#7

For me it works, when i run this script from inside entity.

(function()
{     
    this.clickDownOnEntity = function(entityID, mouseEvent) 
    { 
        var Ent = entityID;
        var copyEnt = Entities.getEntityProperties(Ent);
        var jsonEnt = JSON.stringify(copyEnt);
        
        print(jsonEnt);
    
        var newProperties = 
        {
            userData: 'Test'
        };    
        
        Entities.editEntity(Ent, newProperties);    
    }; 
}
)

#8

just the kind of article for the wiki


#9

I dont know if I trust the user data yet, I have had several scripts fail to correctly update and read the user data string.

I have had to resort to using the name field as a data field because its reliable. Didnt have time to report the bug at the time I just had to make my scripts work. It might be fixed I havent checked.

Keep an eye on the data field while you run the scripts and ensure that its being updated according to the script.


#10

Are you seeing update delay? That is, if you write the field then read it back it has not updated?


#11

Yes in fact the delay can sometimes be until I relog.
Also it was glitching to a point where I would click a new entity and its user data showed what was in the last entity I clicked.


#12

This is a bug in edit.js, not in the userData transfer.

userData is treated no different than name and would be just as reliable. The thing you might have experienced is that our entity properties are still limited by the packet size.
Meaning a single property has to fit in the MTU (i.e. let’s say ~1000 Bytes to be safe). So if you were putting more than that in the userData, your client was never able to send that to the server and it probably got overwritten by the server on the next userData change by another user or loaded the previous one on restart/domain change.


#13

Real responses from the engineers. A more frequent occurrence in beta. :slight_smile: not that alpha phase was completely devoid of dev input, but it seems you guys have a bit more breathing room to check in on stuff here. I like it!


#14

Yes, I used to check the forum only every week, couple weeks personally.
But recently I’ve been trying to check it everyday and go through every post even if I don’t read everything, just to get a feeling of what’s going on in the forum and answer question that won’t take too much of my time.
Seeing how the daily post count increases lately, I’m not sure how long I’m gonna be able to do that, but it works out for now.


#15

one catch about userData is that it’s not guaranteed to be available in an entity’s preload method. a click callback like this is a good way to go since the data will generally be there by the time you try to click!


[Scripts] How to deny user B from click access on object user A use?
#16

Ouch, so if a script needs the user data ASAP after entity instantiation, how would one determine when it is available? Is there a properties-available (or some similar) event?

Looked through the docs and I could not find something like an IsRezzed() event method, where presumably all the properties have settled down to be accessible.


#17

‘properties-available’ would be sweet, but alas it isn’t there yet. if i have to include some data like that when an entity gets loaded, i usually write an initializer function that checks regularly on an invterval to see if the userData that we’re looking for is actually there, and then clears the interval and sets up the object once this data has arrived. hacky but it works. needs improvement


#18

Yes, unfortunately, that was my sinking conclusion too. OK, something clean is needed. IsRezzed() or something. What’s the best way to get this request in, through GitHub?


#19

Ouch, i hit the same problem. The userdate is not the same between users. and that gives big problems.

https://forums.highfidelity.com/t/scripts-how-to-deny-user-b-from-click-access-on-object-user-a-use/10878/1

Did someone posted a bug on github ?


#20

I know it’s a bit of a topic resurrection, but I’ve been having terrible trouble editing an entity’s animation URL via script. It’s a similar question due to the fact that both properties (userData and animation) are JSONs.

Part of the problem is that two places in the docs say that the animation URL property is handled in two different ways (though I’d have to say I haven’t got either one of them to work.)

Without showing 10000 versions of how I tried to go about this, I thought it would be just simpler to ask…

Has anyone successfully done this, and how did that end up looking?