Third-Person Camera Control in Unity for Android

Share the Post

In this tutorial, we will port the third-person camera types to Android. This tutorial is an extension of what we have implemented in our previous tutorial. Here we will port the 5 different types, viz.,

  • Track
  • Follow
  • Follow and Track Rotation
  • Follow and Independent Rotation
  • Top-Down 

of third-person camera controls to a touch sensitive device (we will export to Android phone).

If you have not read the previous tutorial then I strongly suggest that you read that tutorial first before going through this.


Section 1 – Scene and Character Setup

Section 2 – Implement Third-person Camera Controls


Section 3 – Porting the 5 Camera Controls to Android

To implement the movement and camera control we will use a virtual joystick package. You can directly go to https://assetstore.unity.com/packages/tools/input-management/joystick-pack-107631#content or go to Unity Asset Store and search for “Joystick Pack”.

Download and import the package.

You will also need the FixedTouchField.cs script. Download and put in your scripts folder. This allows you to create a touch field. We will see the usage later in our tutorials.

Create a Canvas and Add the Joystick

Right click on the Hierarchy click on UI -> Canvas.

Now browse to Joystick Pack->Prefabs and drag and drop the Fixed Joystick.prefab into the Canvas.

You can configure the Joystick parameters including the images. But we will leave it as it is now.

Port the Player movement script

For Player movement, we use the PlayerMovement.cs script file. In our original tutorial, we took inputs from the GetAxis Unity functions. Now we will take inputs from our virtual joystick controls. We will add a public variable called mJoystick. Then we will associate the Fixed Joystick in the canvass with this variable.

We will use platform dependent conditional compilation.

#if UNITY_ANDROID
    public FixedJoystick mJoystick;
#endif

Change the Build Settings to Android.

Modify the Move function

#if UNITY_STANDALONE
        float h = Input.GetAxis("Horizontal");
        float v = Input.GetAxis("Vertical");
#endif

#if UNITY_ANDROID
        float h = mJoystick.Horizontal;
        float v = mJoystick.Vertical;
#endif

This means that for Android build the h and v values will be taken from the virtual joystick.

Click Play and drag the virtual joystick for the player to move.

https://faramira.com/wp-content/uploads/2020/06/ThirdPersonShooterCamera-SampleScene-Android-Unity-2019.3.8f1-Personal-_DX11_-2020-06-27-14-05-19.mp4

Now open the ThirdPersonCamera.cs. There will be no changes to 4 of the 5 camera modes. Changes are only required for the Follow_IndependentRotation camera type.

This is because all except Follow_IndependentRotation requires no input. They passively follow the player. Whereas, Follow_IndependentRotation uses mouse to orient the camera. We will replace mouse with FixedTouchFiled input.

Create a Touch Field

Right click on the Canvas and create an UI->Image.

Attached the FixedTouchFiled.cs script to the image. Resize and position the image to your liking (this is where the user will touch and drag to orient the camera). Change the transparency to 50 for now so that it is slightly visible. Later we will make the image to be completely transparent.

ThirdPersonCamera.cs

Add a new public variable using platform specific conditional check.

#if UNITY_ANDROID
    public FixedTouchField mTouchField;
#endif

Drag and drop the Image from the Canvas and associate with this field.

Now we amend the Follow_IndependentRotation() function to use the touch field’s x and y changes rather than mouse’s x and y changes.

#if UNITY_STANDALONE
        float mx, my;
        mx = Input.GetAxis("Mouse X");
        my = Input.GetAxis("Mouse Y");
#endif
#if UNITY_ANDROID
        float mx, my;
        mx = mTouchField.TouchDist.x * Time.deltaTime;
        my = mTouchField.TouchDist.y * Time.deltaTime;
#endif

Click Play and see the behavior on your screen.

https://faramira.com/wp-content/uploads/2020/06/ThirdPersonShooterCamera-SampleScene-Android-Unity-2019.3.8f1-Personal-_DX11_-2020-06-27-14-41-33.mp4

We will make one last change to make our Player move left and right while using the virtual joystick. We will also remove the use of Left Shift key to move to run and instead we will use the pull extent of your joystick button.

So open up PlayerMovement.cs and make the following changes.

    public void Move()
    {
#if UNITY_STANDALONE
        float h = Input.GetAxis("Horizontal");
        float v = Input.GetAxis("Vertical");
#endif

#if UNITY_ANDROID
        float h = mJoystick.Horizontal;
        float v = mJoystick.Vertical;
#endif
#if UNITY_STANDALONE
        float speed = mWalkSpeed;
        if (Input.GetKey(KeyCode.LeftShift))
        {
            speed = mRunSpeed;
        }
#endif

#if UNITY_ANDROID
        float speed = mRunSpeed;
#endif

        if (mFollowCameraForward)
        {
            // Only allow aligning of player's direction when there is a movement.
            if (v > 0.1 || v < -0.1 || h > 0.1 || h < -0.1)
            {
                // rotate player towards the camera forward.
                Vector3 eu = Camera.main.transform.rotation.eulerAngles;
                transform.rotation = Quaternion.RotateTowards(
                    transform.rotation,
                    Quaternion.Euler(0.0f, eu.y, 0.0f),
                    mTurnRate * Time.deltaTime);
            }
        }
        else
        {
            transform.Rotate(0.0f, h * mRotationSpeed * Time.deltaTime, 0.0f);
        }

        mCharacterController.Move(transform.forward * v * speed * Time.deltaTime);

        // Move forward / backward
        Vector3 forward = transform.TransformDirection(Vector3.forward).normalized;
        forward.y = 0.0f;
        Vector3 right = transform.TransformDirection(Vector3.right).normalized;
        right.y = 0.0f;
        if (mAnimator != null)
        {
            if (mFollowCameraForward)
            {
                mCharacterController.Move(forward * v * speed * Time.deltaTime + right * h * speed * Time.deltaTime);
                mAnimator.SetFloat("PosX", h * speed / mRunSpeed);
                mAnimator.SetFloat("PosZ", v * speed / mRunSpeed);
            }
            else
            {
                mCharacterController.Move(forward * v * speed * Time.deltaTime);
                mAnimator.SetFloat("PosX", 0);
                mAnimator.SetFloat("PosZ", v * speed / mRunSpeed);
            }
        }

        // apply gravity.
        mVelocity.y += mGravity * Time.deltaTime;
        mCharacterController.Move(mVelocity * Time.deltaTime);

        if (mCharacterController.isGrounded &amp;&amp; mVelocity.y < 0)
            mVelocity.y = 0f;
    }

Now, lets export to an Android phone. Before exporting double confirm that you have selected M Follow Camera Forward in PlayerMovement and you have selected Follow_IndependentRotation from the drop-down in your ThirdPersonCamera.

https://faramira.com/wp-content/uploads/2020/06/WhatsApp-Video-2020-06-27-at-15.24.31.mp4
Recorded from a Redmi Note 8 Pro Phone in Landscape mode

Note that after you have tested and find everything is working as desired you may want to change the transparency for the Fixed Touch Field image to be 0 so that there is no white image seen on the screen.

Download Unity Package


Read Also

Solving 8 puzzle problem using A* star search in C++


Implementing a Finite State Machine Using C# in Unity


Implementing a Command Design Pattern in Unity

View all tutorials

Leave a Reply

Your email address will not be published. Required fields are marked *