Mouse click not working (on my colleagues PCs')
Options
matte
✭
in Photon Bolt
Hello,
I'm experiencing a strange bug, occurring only on my colleagues machines, involving mouse clicks. On my machine everything works (!!?). It's not a hardware problem (I tried switching mouses, etc..).
When the user left-clicks, its character is supposed to fire a projectile (as you can see in ExecuteCommand). This is not working on the machines I tried it on except mine.
Also, mouse movement (yaw and pitch) is fluid on my PC, and very jittery and unsensible on other PCs (unsensible meaning that you have to move the mouse a lot to change the camera direction).
Every time I tried, I was using a local Bolt server (i.e. both client and server on the same machine).
This is the code controlling the player (pretty standard stuff, mostly copied from the advanced tutorial).
Any help is very, very appreciated.
Thanks!
matte
I'm experiencing a strange bug, occurring only on my colleagues machines, involving mouse clicks. On my machine everything works (!!?). It's not a hardware problem (I tried switching mouses, etc..).
When the user left-clicks, its character is supposed to fire a projectile (as you can see in ExecuteCommand). This is not working on the machines I tried it on except mine.
Also, mouse movement (yaw and pitch) is fluid on my PC, and very jittery and unsensible on other PCs (unsensible meaning that you have to move the mouse a lot to change the camera direction).
Every time I tried, I was using a local Bolt server (i.e. both client and server on the same machine).
This is the code controlling the player (pretty standard stuff, mostly copied from the advanced tutorial).
public class PlayerController : Bolt.EntityBehaviour<IPlayerState>
{
const float MOUSE_SENSITIVITY = 2.0f;
private bool _forward;
private bool _backward;
private bool _left;
private bool _right;
private bool _jump;
private bool _fire;
private float _yaw;
private float _pitch;
private PlayerMotor _motor;
void Awake()
{
_motor = GetComponent<PlayerMotor>();
}
public override void Attached()
{
state.Transform.SetTransforms(transform);
}
public override void SimulateController()
{
PollKeys(true);
IPlayerCommandInput input = PlayerCommand.Create();
input.Forward = _forward;
input.Backward = _backward;
input.Left = _left;
input.Right = _right;
input.Jump = _jump;
input.Fire = _fire;
input.Yaw = _yaw;
input.Pitch = _pitch;
entity.QueueInput(input);
}
public override void ExecuteCommand(Bolt.Command command, bool resetState)
{
PlayerCommand cmd = (PlayerCommand)command;
if (resetState)
{
_motor.SetState(cmd.Result.Position, cmd.Result.Velocity, cmd.Result.IsGrounded, cmd.Result.JumpFrames);
}
else
{
PlayerMotor.State motorState = _motor.Move(cmd.Input.Forward, cmd.Input.Backward, cmd.Input.Left, cmd.Input.Right, cmd.Input.Jump, cmd.Input.Yaw);
cmd.Result.Position = motorState.position;
cmd.Result.Velocity = motorState.velocity;
cmd.Result.IsGrounded = motorState.isGrounded;
cmd.Result.JumpFrames = motorState.jumpFrames;
}
if (entity.isOwner && cmd.IsFirstExecution && cmd.Input.Fire)
{
Transform caster = this.gameObject.transform;
BoltEntity projectile = BoltNetwork.Instantiate(BoltPrefabs.Projectile, caster.position + caster.forward + caster.up, Quaternion.identity);
projectile.GetComponent<RigidBody>.AddForce(caster.forward * 5f, ForceMode.Impulse);
}
}
private void PollKeys(bool mouse)
{
_forward = Input.GetKey(KeyCode.W);
_backward = Input.GetKey(KeyCode.S);
_left = Input.GetKey(KeyCode.A);
_right = Input.GetKey(KeyCode.D);
_jump = Input.GetKey(KeyCode.Space);
_fire = Input.GetMouseButtonDown(0);
if (mouse)
{
_yaw += (Input.GetAxisRaw("Mouse X") * MOUSE_SENSITIVITY);
_yaw %= 360f;
_pitch += (-Input.GetAxisRaw("Mouse Y") * MOUSE_SENSITIVITY);
_pitch = Mathf.Clamp(_pitch, -85f, +85f);
}
}
}
Any help is very, very appreciated.
Thanks!
matte
0
Best Answer
-
ExecuteCommand is called at a fixed time interval, based on the simulation-rate in your bolt settings. At default 60 calls per second.
@kittyLLLL
I am guessing that the problem you are having is with Input.GetMouseButtonDown (and the same goes for Input.GetKeyDown).
The problem is that these functions only return true at the exact frame at which the button or key was pressed.
When polling these inputs during a function which is called at a fixed time interval such as such as SimulateController(), ExecuteCommand() or FixedUpdate(), (and not at each frame as Update()), you risk not hitting the exact frame and the Input will have already been true and false again.
And as you are experiencing, this is more noticeable at low frame-rates.
Anyway, on to a solution, which is simple. Just poll the inputs at each frame in Update() and save the result in a variable when its true.
Then in SimulateController() or where you need to use it, set it to false when you have used/read the variable.
5
Answers
-
Not sure if this helps, but I'll notice that the lower the framerate of the game that I'm running, (i.e. the more lag I have) a lot of my Input's fail to send true. With a normal framerate, all of my clicks and button inputs are detected and work fine, but if the framerate is lower and choppy, it takes me clicking more than once for it to do what I asked.
also when does this function get called?
public override void ExecuteCommand(Bolt.Command command, bool resetState)
Is it called every frame, or called every time your server is available to receive inputs, etc???0 -
ExecuteCommand is called at a fixed time interval, based on the simulation-rate in your bolt settings. At default 60 calls per second.
@kittyLLLL
I am guessing that the problem you are having is with Input.GetMouseButtonDown (and the same goes for Input.GetKeyDown).
The problem is that these functions only return true at the exact frame at which the button or key was pressed.
When polling these inputs during a function which is called at a fixed time interval such as such as SimulateController(), ExecuteCommand() or FixedUpdate(), (and not at each frame as Update()), you risk not hitting the exact frame and the Input will have already been true and false again.
And as you are experiencing, this is more noticeable at low frame-rates.
Anyway, on to a solution, which is simple. Just poll the inputs at each frame in Update() and save the result in a variable when its true.
Then in SimulateController() or where you need to use it, set it to false when you have used/read the variable.
5 -
@Symptom Thank you very much, that solved the problem
@Symptom @kittyLLLL
I'm not sure about the lower frame rate reasoning though... If FixedUpdate, SimulateController and ExecuteCommand are called at fixed time frames, then aren't them more likely to miss inputs if the framerate is higher?
For example, if they are called 60 times per second, but the framerate is 120 (i.e. Update is called 120 times per second, together with OnMouseButtonDown, etc.), shoudn't they be missing around half the inputs?
matte0