I'm working on game elements and looking to implement a lock-picking system. The user will hold the left stick in position and then rotate the right stick to a particular angle. Repeat three times for the three stages of lock. Nothing particularly groundbreaking, we have all played a game that does this, but I'm doing this to learn.
So far, I have it working, but I would like to add vibration. The vibration should be weak to start and get stronger as you close in on the target 'X' and 'Y' positions. Probably with a small "click" vibrate once the stage is complete. What do you think the best way is to achieve this?
Here is a little bit of code to show the basics of what's going on, I'm using,
Vector2 stickR = Gamepad.current.rightStick.ReadValue();
to allow me to check positions with my goalXmin
, goalYmin
and goalYmax
. I'm using max and min values to give the user a little wiggle room, as its nearly impossible to get the exact float position, eg:
if ((stickR.x > goalXmin) && (stickR.y > goalYmin && stickR.y < goalYmax))
{
Lock is solved.
I assume stop rumble will then be used, or the 'click' rumble will be played
Gamepad.current.SetMotorSpeeds(0f, 0f);
}
So, with that said, I assume I need to use goalYmin
and goalYmax
values and somehow feed them into Gamepad.current.SetMotorSpeeds()
after some form of adjustment?
Any help would be amazing.
Thanks in advance,
CodePudding user response:
You can do so by getting the distance between the point that the user is inputting and the 2 points that define the goal. Taking the shortest one, scaling it accordingly and giving that to the SetMotorSpeeds() function.
We need to scale it because the function SetMotorSpeeds() needs values between 0 and 1, while the input from a controller is in the range -1, 1 on both axis.
Supposing that the goals x and y positions are between -1 and 1, stickR is a Vector2 and the goals are Vector2 you can do something like this:
float distance = Mathf.Min(Vector2.Distance(stickR, goal1), Vector2.Distance(stickR, goal2);
float convertedDistance = distance / 2;
Gamepad.current.SetMotorSpeeds(1 - convertedDistance, 1 - convertedDistance);
The first line takes the smallest distance between the stick position and the goals.
Then we convert the distance using the formula z = (x - min) / (max - min)
, where x is the value we want to convert, z is the value in the range [0,1], min is the minimum of the interval our x lies in, and max is the maximum, in our case [0, 2], since the max distance the points can be is 2, and the minimum is 0. Simplifying the expression we get x / 2.
The last line we use the converted value to vibrate the controller.
Note: we use 1 - convertedDistance
because we want the rumble to be less strong as the distance increases, if you want the opposite just remove the 1 -
.
Let me know if something's not clear :)