Hi,
Forgive me if this question is previously asked - I have an effect that I’m going for, but I don’t know what I don’t know, so I can only think to bluntly throw up a forum post with my ask.
I’m working on a fighting game, but the perspective is top-down, so ability direction is indicated with mouse position. The animations happen about the player’s model as a reference point, and the animations might be rotating about an axis through that point, so I want to program the ability to initiliate the animation going in either direction. I’ll share a gif below to demonstrate this.
Refering to the gif:
- the ball in the center of the screen is the “player”
- the little white boxes appearing near the players are hitboxes created by the character’s ability.
- In the gif, I think all but the first hitbox are generated from the same cast, so the white box that you see are all the same hitbox and they have the same dimensions, but they appear at different positions about the player because the mouse is positioned differently.
- It may be hard to tell in the gif, but - the hitbox trajectory is sometimes clockwise, and sometimes counterclockwise, as desired.
So, here is the crux of my post: I want to program the input such that the direction of movement of the hitbox is clockwise or counterclockwise, as determined by the movement of the player’s mouse when they initiate the cast.
The current implementation is as follows:
- initialization of hitbox animation, with respect to boolean
rotatingClockwise
Hit h = Instantiate(hitEvent.hit);
h.Initialize(caster, caster.transform, !rotatingClockwise);
hits.Add(h);
- Update of the boolean
rotatingClockwise
var direction = new Vector3(cursorWorldPosition.x-playerPosition.x, 0, cursorWorldPosition.z-playerPosition.z).normalized;
Quaternion newRotation = Quaternion.FromToRotation(Vector3.forward, direction);
float yRotationDiff = newRotation.y - transform.rotation.y;
if (yRotationDiff != 0) {
RotatingClockwise = (yRotationDiff>0);
}
So those are the snippets relevant to this question. In brief - the player’s look direction is directly at the mouse (and to be more specific, it’s the intersection of the mouse’s raycast through a horizontal plane through the center of the player). Each frame, I look at the of the player from the previous frame to the next frame, check the difference in the angle, and update rotatingClockwise
accordingly.
I think this implementation works perfectly, barring one thing - given that the degree of rotation is calculated between two game logic frames (@60Hz), the rotation angle is subject to any sort of jittering of the mouse position. So, I might feel that my mouse cursor is spinning my character clockwise, but if my hand movement isn’t smooth and the mouse position twitches in the opposite direction during a frame, the direction of rotation will be opposite to what might be the user’s “percieved” direction of rotation.
So, how can I reflect the model rotation direction to more closely mirror a user’s percieved rotation direction, as determined by their real mouse position? I have some conjectures as to what might work, but maybe there are some standard approaches to this sort of problem.
Approach off the top of my head:
- create a stack of
n
previous mouse positions or mouse rotations, and calculate the direction of rotation as the average rotation - though, then, what should n be? maybe that would just be determined by the player?
- Would the performance of this be okay? Maybe I could do some sort of moving/decaying averaging to speed it up?
and, a bonus adjacent question, if I may - while working on this, I came across the following issue: The object rotation angle is calculated in radians. Given that the value is periodic, there’s a point in the object’s rotation where the rotation angle skips from the top of the range to the bottom of the range. I still haven’t written out the logic to account for this because, while I was working on it, I found the following:
- the rotation of
Vector3.forward
seems to be 0u - gorgeous, makes sense - rotation of
Vector3.back
seems to be 1u - great - rotating clockwise from
Vector3.forward
toVector3.back
increases the angle from 0 to 1 - as expected - rotating counterclockwise from
Vector3.forward
toVector3.back
starts decreasing from 0 to negative numbers, but somewhere in Q3 (around -.86), the values are suddenly positive!
What the heck is that about? I would expect the jump to happen from 1 to -1, but the values in the range I’d expect to be ~[-.86, -1] are all positive. I see that the .86 value seems to be about sqrt(3)/2
, and it visually looks as if the jump happens at 45deg from the axes. Also, to be clear - the angle of rotation isn’t something that I’m calculating - I’m pulling the value directly from transform.rotation
, so I don’t think the wonky value has anything to do with the logic in my project.