[Unity learning notes: FPS game production] character movement, rotation, promotion and rise -- (learning notes on June 13, 2021)

1, What is FPS game

First person shooting game, FPS (first person shooting game), strictly speaking, first person shooting game belongs to a branch of ACT games, but like RTS games, it has developed into a separate type due to its rapid popularity in the world.
FPS (first person shooting game) first person shooting game, as its name implies, is to play shooting games from the subjective perspective of players. Players no longer manipulate the virtual characters in the screen to play the game like other games, but experience the visual impact brought by the game, which greatly enhances the initiative and realism of the game. Early first person games generally brought players the stimulation of screen light and simple and fast game rhythm. With the continuous improvement of various games and the gradual combination of hardware. The first person shooting games provide richer plots, exquisite pictures and vivid sound effects.

2, Function realization idea and process

(1) New role

Create a new project, load or create a new character model and gun model. In addition, since the perspective of the project is the first person, it is recommended to set the gun as a sub object of the camera. For the development of future combat functions, it is also recommended to save the completed character model set in a pre-made way. The effect picture after completion is as follows

(2) Thinking of realizing mobile function

In order to realize the function of keyboard input controlling movement, we must first obtain the keyboard input in real time. The method of obtaining is to obtain the input of the user in the Update() of the script (PS: Update(): when the game is running and the script is available, this method will be called when refreshing each frame), Obtain the modulus of the user's motion vector (the modulus of the motion vector is the moving distance).

/**The code for obtaining the modulus of the user's motion vector is as follows**/
float _xMov = Input.GetAxisRaw("Horizontal");//Get horizontal input
float _zMov = Input.GetAxisRaw("Vertical");//Get vertical input

Then multiply by the standard vector of the user's motion vector (PS: transform.right,transform.forward is a standard vector in essence, and according to the concept of vector, a non-zero vector can be divided by its modulus to obtain the required standard vector. Thus, the standard vector of the motion vector can be obtained by multiplying the standard vector of the motion vector by the modulus of the motion vector), Considering that the player's movement is affected by the vertical and horizontal movement vectors, the simple model of player's movement is shown in the figure below

According to the vector triangle rule, the player's movement vector is equal to the horizontal vector + vertical vector (the sketch of the rule is as follows)

  /**The calculation codes of horizontal vector, vertical vector and player movement vector are as follows**/
Vector3 _moveHoruzontal = transform.right * _xMov;//Horizontal movement vector = horizontal standard vector * modulus of horizontal movement vector (keyboard horizontal input)
Vector3 _moveVertical = transform.forward * _zMov;//Vertical movement vector = standard vector in vertical direction * modulus of vertical movement vector (keyboard vertical input)
Vector3 _velocity = (_moveHoruzontal + _moveVertical).normalized * speed;//Normalize the player's movement vector to the standard vector and multiply it by

Then normalize the player's movement vector into a standard vector. Multiply the normalized standard vector by the modulus of the velocity vector to obtain the player's velocity vector. Finally, multiply the velocity vector by time and add the position of the current player's rigid body to get the position to which the player should move at last.

(3) Idea of realizing rotation function

Similarly, the user's mouse input is obtained in the Update() of the script, and the obtained movement angle of the X and Y axes of the mouse is multiplied by the rotation speed of the user's field of view to obtain the rotation angle between the camera and the player's rigid body

(4) Thoughts on realizing the function of promoting rising

Similarly, get the user's keyboard input in the Update() of the script. When you hear the user enter a space, make the character rigid body move directly above.

(5) Specific code

PlayerMoter. CS (code below)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerMoter : MonoBehaviour
{
    [SerializeField]
    private Camera cam;//camera
    private Vector3 velocity = Vector3.zero;
    private Vector3 rotation = Vector3.zero;
    private float cameraRotationX = 0f;
    private float currentCamerRotationX = 0f;
    private Vector3 thrusterForce = Vector3.zero;
    [SerializeField]
    private float cameraRotationLimit = 85f;
    private Rigidbody rb;
    void Start()
    {
        rb = GetComponent<Rigidbody>();//Get rigid body
    }
    public void Move(Vector3 _velocity)//move
    {
        velocity = _velocity;
    }
    public void Rotate(Vector3 _rotation)//rotate
    {
        rotation = _rotation;
    }
    // Update is called once per frame
    void Update()
    {
        
    }
    private void FixedUpdate()
    {
        PerformMovement();
        PeformRotation();
    }
    public void RotarCamera(float _cameraRotation)//Camera rotation
    {
        cameraRotationX = _cameraRotation;
    }
    public void ApplyThruster(Vector3 _thrusterForce)//Applied propulsion
    {
        thrusterForce = _thrusterForce;
    }
    void PerformMovement()//move
    {
        if(velocity!=Vector3.zero)
        {
            rb.MovePosition(rb.position + velocity * Time.fixedDeltaTime);//
        }
        if(thrusterForce!=Vector3.zero)
        {
            rb.AddForce(thrusterForce * Time.fixedDeltaTime,ForceMode.Acceleration);
        }
    }
    void PeformRotation()//rotate
    {
        rb.MoveRotation(rb.rotation * Quaternion.Euler(rotation));
        if(cam!=null)
        {
           
            currentCamerRotationX -= cameraRotationX;
            currentCamerRotationX = Mathf.Clamp(currentCamerRotationX,-cameraRotationLimit,cameraRotationLimit);
            cam.transform.localEulerAngles = new Vector3(currentCamerRotationX, 0f, 0f);
        }
    }
}

PlayerControl. CS (code below)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(ConfigurableJoint))]
[RequireComponent(typeof(PlayerMoter))]
public class PlayerControl : MonoBehaviour
{
    [SerializeField]
    private float speed = 5f;
    private PlayerMoter moter;
    [SerializeField]
    private float lookSensitivity = 3f;//Viewing angle rotation speed

    [SerializeField]
    private float thrustserForce = 1000f;//Propulsion speed

    [Header("Spring setting")]
    [SerializeField]
    private JointDriveMode jointMode=JointDriveMode.Position;
    [SerializeField]
    private float jointSpring = 20f;
    [SerializeField]
    private float jointMaxForce = 40f;
    private PlayerMoter motor;
    private ConfigurableJoint joint;
    // Start is called before the first frame update
    void Start()
    {
        moter = GetComponent<PlayerMoter>();
        joint = GetComponent<ConfigurableJoint>();
    }

    // Update is called once per frame
    void Update()
    {
        float _xMov = Input.GetAxisRaw("Horizontal");//Get horizontal input
        float _zMov = Input.GetAxisRaw("Vertical");//Get vertical input

        //transform.right,transform.forward is essentially a standard vector, that is, a vector with direction and modulus 1
        Vector3 _moveHoruzontal = transform.right * _xMov;//Horizontal movement vector = horizontal standard vector * modulus of horizontal movement vector (keyboard horizontal input)
        Vector3 _moveVertical = transform.forward * _zMov;//Vertical movement vector = standard vector in vertical direction * modulus of vertical movement vector (keyboard vertical input)
        Vector3 _velocity = (_moveHoruzontal + _moveVertical).normalized * speed;//Normalize the player's movement vector to the standard vector and multiply it by
        moter.Move(_velocity);
        float _yRot = Input.GetAxisRaw("Mouse X");//Get the X-axis movement of the mouse
        Vector3 _rotation = new Vector3(0f, _yRot, 0f) * lookSensitivity;
        moter.Rotate(_rotation);
        float _xRot = Input.GetAxis("Mouse Y");//Get mouse Y-axis movement
        float _cameraRotation = _xRot * lookSensitivity;
        moter.RotarCamera(_cameraRotation);
        Vector3 _thrusterForce = Vector3.zero;
        if(Input.GetButton("Jump"))
        {
            _thrusterForce = Vector3.up * thrustserForce;//
            SetJointSettings(0f);
        }
        else
        {
            SetJointSettings(jointSpring);
        }
        moter.ApplyThruster(_thrusterForce);
    }
    private void SetJointSettings(float _jointSpring)
    {
        joint.yDrive = new JointDrive {
            mode = jointMode,
            positionSpring= _jointSpring,
            maximumForce=jointMaxForce
        };
    }
}

PlayerScript. CS (code below)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerScript : MonoBehaviour
{
    private const int Player_Up = 0;
    private const int Player_Right = 1;
    private const int Player_Down = 2;
    private const int Player_Left = 3;

    private int state = 0;
    public int moveSpeed = 2;

    void Awake()
    {
        state = Player_Up;
    }

    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        float KeyVertical = Input.GetAxis("Vertical");
        float KeyHorizontal = Input.GetAxis("Horizontal");
        if(KeyVertical==-1)
        {
            setPlayerState(Player_Down);
        }
        else if(KeyVertical==1)
        {
            setPlayerState(Player_Up);
        }
        if(KeyHorizontal==1)
        {
            setPlayerState(Player_Right);
        }
        else if(KeyHorizontal==-1)
        {
            setPlayerState(Player_Left);
        }

    }
    void setPlayerState(int NewState)
    {
        int rotateValue = (NewState - state) * 90;
        Vector3 transformValue = new Vector3();
        switch(NewState)
        {
            case Player_Up:
                transformValue = Vector3.forward * Time.deltaTime;
                break;
            case Player_Down:
                transformValue = (-Vector3.forward) * Time.deltaTime;
                break;
            case Player_Left:
                transformValue = Vector3.left * Time.deltaTime;
                break;
            case Player_Right:
                transformValue = (-Vector3.left) * Time.deltaTime;
                break;
        }
        transform.Rotate(Vector3.up, rotateValue);
        transform.Translate(transformValue * moveSpeed, Space.World);
        state = NewState;
    }
}

(5) How to use scripts

Add playerscript CS and PlayerControl CS is bound to the player character object, and the camera is bound to the PlayerControl script (as shown below)

(6) Final effect


[1] Reference tutorial https://www.bilibili.com/video/BV1Hz4y1R7ZY

Keywords: C# Unity Game Development

Added by unknownproto on Sun, 30 Jan 2022 05:07:13 +0200