Camera rotation not rotating correctly on mobile

Viewed 119

I'm making a FPS and I want the player to rotate the camera, my code works for PC, but on mobile if I'm rotating the camera and I also touching the fire button (or anywhere else with my other finger) the camera rotates to right (here where my fire button is) and I don't know if I can do something about it, or I need to cancel the release for android and IOS and publish my game only for PC

Part of my code:

if (CanProcessInput())
        {

            // Check if this look input is coming from the mouse
            bool isGamepad = Input.GetAxis(stickInputName) != 0f;
            float i = isGamepad ? Input.GetAxis(stickInputName) : Input.GetAxisRaw(mouseInputName);

            // handle inverting vertical input
            if (InvertYAxis)
                i *= -1f;

            // apply sensitivity multiplier
            i *= LookSensitivity;

            if (isGamepad)
            {
                // since mouse input is already deltaTime-dependant, only scale input with frame time if it's coming from sticks
                i *= Time.deltaTime;
            }
            else
            {
                // reduce mouse input amount to be equivalent to stick movement
                i *= 0.01f;
#if UNITY_WEBGL
                    // Mouse tends to be even more sensitive in WebGL due to mouse acceleration, so reduce it even more
                    i *= WebglLookSensitivityMultiplier;
#endif
            }

            return i;
        }
2 Answers

Segment the touch input so you ignore values that are generated in the area of the fire button. You can do this by checking the Touch. position value:

Description

The position of the touch in screen space pixel coordinates.

Position returns the current position of a touch contact as it's dragged. If you need the original position of the touch see Touch.rawPosition.

The documentation hints at what you might be interested in, too - the original touch position. Your question body is asking about horizontal motion, but your code is referencing y values. The position coordinates are given in (width, height), so I just wanted to be clear up front that I'll use x values to answer your question about horizontal motion.

So if you know that the bottom-left corner of the screen is (0,0) and you can use Screen.width to get the width in pixels, then you could calculate the right 20% of the screen as reserved for the fire button. Anything less than that would be acceptable inputs for rotation, but the 80%-of-width pixel would be the maximum allowable input:

private int maxAllowablePixel;
void Start()
{
    maxAllowablePixel = 0.8f * Screen.width;
}

and then only process the touch as a rotation if the original touch was less than that value:

if(touch.rawPosition.x < maxAllowablePixel)
{
    DoRotation(touch.position);
}

and again here you are allowing the user to put their finger down in the middle of the screen, drag it over the fire button, and still rotate that much, but any touches that originate in the fire button "exclusion zone" are ignored for the purposes of doing rotations.

Also when you do the rotation, do it where the finger is now (Touch.position) and not where it started (Touch.rawPosition).

The way I always solve an issue like this is to not use the touch positions directly, but to have a "TouchReceiver" Object in the Canvas with a script that implements IDragHandler. So the class might look like this:

[RequireComponent(typeof(Image))]
public class TouchReceiver : MonoBehaviour, IDragHandler
{
    public void OnDrag(PointerEventData data)
    {
        Vector2 delta = data.delta;

        // do something with delta, like rotating the camera.
    }
}

Then set up your canvas like so:

enter image description here

Make sure to put the "TouchReceiver" behind the fire button, that way the OnDrag event will not occur when pressing the fire button, because the fire button blocks the "TouchReceiver" object itself. The "TouchReceiver" object needs to have an Image component, otherwise it won't be able to receive any touches. Of course the image should then be made totally transparent.

With this setup is pretty easy to move the fire button around without changing anything else. This might also come in handy when adapting to different screen resolutions.

Related