Roll20 uses cookies to improve your experience on our site. Cookies enable you to enjoy certain features, social sharing functionality, and tailor message and display ads to your interests on our site and others. They also help us understand how our site is being used. By continuing to use our site, you consent to our use of cookies. Update your cookie preferences .
×
Create a free account

[Help] rotate tokens to facing direction slowly on move?

1417400977

Edited 1417405628
DXWarlock
Sheet Author
API Scripter
I have a script I found and modified from here, to make tokens face the direction they move so they are always facing the right way. it works wonderful but the sudden "snap" to a new direction is a bit jarring when they have limited directional light on dynamic light maps. So I was attempting to 'rotate' the token over a second until its facing the correct way, and seem to have hit a wall. First problem is token can have over 360 degrees of rotation(?). I think I solved it 'adding up over time" by checking to see if its over 360, if so subtract 360 which seems to fix it ever giving me like 410 as the angle. Next was rotating it the proper way, say they turned 10 degrees, make sure it doesn't do a 350 degree rotation making it look like the spun around backwards by comparing old angle to new, and picking the smaller distance of the 2 to reach it. (for example going from 5 to 355 I didn't want them doing a full spin to try to go to the right facing) My main problem now is actually doing a "while" or such. I tried using a 'setInterval' inside a 'while', dividing the new angle by 10, then doing a small rotate every 1/10th of a second until angle=needed angle. But that was messy, caused sandbox to sometime choke thinking it was hung, and sometimes not do anything. (think sometimes my math was off). This is what I have so far, anyone give me a push in the right direction of how to take the angle needed to face the new way, and turn it that way over a set period of time? Some of the variables arent used, they was the ones I was doing to calcuate the right direction to rotate it. on("change:graphic", function(obj, prev) { if(obj.get("name") == "NR" || state.Tokenface == 0) return; if(obj.get("left") != prev.left || obj.get("top") != prev.top) { if(obj.get("layer") == "objects") { var movex = obj.get("left") - prev.left; var movey = obj.get("top") - prev.top; var degs; var olddeg = obj.get("rotation"); var olddeg = olddeg - olddeg%1 if(movey != 0) { degs = Math.atan(movex/movey) * 57.29577; if(movey < 0) degs = 360-degs%360; else degs = 180-degs%360; } else if(movex < 0) degs = 270; else degs = 90; degs = degs - degs%1; if (degs > 360) degs = degs-360; if (olddeg > 360) olddeg = olddeg-360; turnmin = Math.min(degs, olddeg); turnmax = Math.max(degs, olddeg); turnang = turnmax-turnmin; if (olddeg > degs) turnang = 0-turnang; obj.set("rotation", degs); } } });
setInterval causes the supplied callback to be called multiple times already, so it should be called instead of the loop rather than in it. You could either set up one function running via setInterval constantly and set variables to tell it what you want rotated when, or you could grab the return value from the setInterval call and pass it to clearInterval when you're done.
1417721590
The Aaron
Roll20 Production Team
API Scripter
How are you doing with this, still need help?
1417722532

Edited 1417723215
DXWarlock
Sheet Author
API Scripter
Actually I forgot to reply back as I was fighting with it. sorry manveti. At one point I got it to where it was working as far as rotating over 1 second, but the whole thing of figuring out if it needs to be clockwise vs counterclockwise to go from old to new in the smallest angle kicked my butt. Like if they are at 5 to 355 its only 10 degrees backwards but counting up they would do a huge 350 degree spin that made no sense :P. but working out the math to make it do that, or the more confusing one to work out 355 to 5 ..I gave up on it..haha. If you want to take a stab at it, feel free. I fought with it for 2 days just making it overly complex and more broken by trying to section it off in 90 degree quadrants and comparing them to see how many quadrants the turn would go thru, if it was over 3 its the wrong direction...which was probably the rube goldburg way of doing it :)
1417727646

Edited 1417727744
If you subtract in each direction, one will be positive and the other negative (that tells you the direction of each rotation). Then you can add 360 to the negative one, so both numbers are in [0,360), and compare the numbers (this lets you pick the smallest rotation). Edit: An example might illustrate it better: Currently at 5, want to be at 355: 355-5 = 350 (positive) 5-355 = -350 => 10 (negative) 10 < 350, so we want to rotate 10 degrees in the negative direction
1417740068

Edited 1417740170
DXWarlock
Sheet Author
API Scripter
thats seems 10x easier than how I was trying to do it, thanks! That should solve which direction to turn for me, guess I can make 2 functions one for each direction, one that subtracts until it matches new angle, and one that adds until it does. Then figure out how to handle the 355 to 5 once I try to add and its over 360, make 360 0 and keep adding. (without it stopping on the first loop because the current angle will already be over 5..cant count 'up' to 5 from 355).
1417751313
The Aaron
Roll20 Production Team
API Scripter
If you figure the span, and you know positive/negative, you can divide by how many times you want to adjust (say 10) to get an increment and set it positive/negative, then successively apply it to the current angle until you get to the correct angle. Use: var newAngle = ((CurrentAngle+(Increment))+360)%360; This will keep it in the 0-360 range.
1417789627
DXWarlock
Sheet Author
API Scripter
Ah thanks guys, Ill give those a try. I think that should do it for me. I was WAY overcomplicating figure out direction and how to do the transition from high angle to low angle (or vice verse)