Fps游戏常用功能

镜头拉远拉近,类似狙的镜头缩放;枪口特效;角色的移动和镜头旋转

镜头拉远拉近

  1. 在main camera中添加一个脚本 CameraZoom
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
using UnityEngine;

public class CameraZoom : MonoBehaviour
{
    private Camera mainCamera;

    public int[] zoomLevel = {60, 40, 20};

    private int currentLevel;


    private void Start()
    {
        mainCamera = GetComponent<Camera>();
    }


    private void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            currentLevel += 1;
            if (currentLevel >= zoomLevel.Length)
            {
                currentLevel = 0;
            }
        }

        int currentFieldOfView = zoomLevel[currentLevel];

        mainCamera.fieldOfView = Mathf.Lerp(mainCamera.fieldOfView, currentFieldOfView, 0.1f);
    }
}
  1. 此脚本的功能是可以在编辑器中自定义缩放等级,不设置的话默认是60,40,20共3个等级。当按下鼠标左键的时候缩放等级+1,到了最大缩放等级回到0

fps角色组成部分

  • player是个空物体,是放角色模型的容器
  • player/main camera是player的子物体,我们控制player移动时camera跟着一起移动
  • player/guns 是枪的容器,放所有的枪
  • player/guns/HandGun是手枪的容器,里面放手枪的模型,枪口
  • player/guns/handGun/firePoint/fireEffect 是枪口开火特效,默认隐藏,开火时显示
  1. 新建一个脚本FireEffectController挂在firePoint空物体上,当点击鼠标左键时开火显示特效,使用Invoke方法延迟0.3秒隐藏
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
using UnityEngine;

public class GunFireEffect : MonoBehaviour
{
    private GameObject fireEffect;

    void Start()
    {
        fireEffect = transform.Find("Effect").gameObject;
    }

    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            fireEffect.SetActive(true);
            Invoke("HideEffect", 0.3f);
        }
    }


    private void HideEffect()
    {
        fireEffect.SetActive(false);
    }
}

角色控制

  1. 移动,这个方法因为乘了Time.deltaTime,所以它是在Update方法中调用的,h或者v要有其一大于0
1
2
3
4
5
6
7
8
9
       /// 在update中调用
       /// </summary>
       /// <param name="h"></param>
       /// <param name="v"></param>
       public void Move(float h, float v)
       {
           Vector3 dir = new Vector3(h * speed * Time.deltaTime, 0, v * speed * Time.deltaTime);
           player.Translate(dir);
       }
  1. 旋转视野,这个方法只能在FixedUpdate中调用,如果要放在Update中,x、y要乘于Time.deltaTime
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
    /// <summary>
    /// 在fixUpdate中调用
    /// </summary>
    /// <param name="x"></param>
    /// <param name="y"></param>
    public void RotateView(float x, float y)
    {
        x *= rotateSpeed;
        y *= rotateSpeed;
        // 左右沿自身旋转
        transform.Rotate(-y, 0, 0);

        // 上下旋转沿世界坐标
        transform.Rotate(0, x, 0, Space.World);
    }
  1. 角色控制器脚本FpsPlayerController方法
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
public class FpsPlayerController : MonoBehaviour
{
    [Range(2, 4)] public int speed = 2;

    private Transform player;

    public float rotateSpeed = 3;


    private void Awake()
    {
        player = GameObject.Find("Player").transform;
    }

    private void Update()
    {
        // 键盘
        float h = Input.GetAxisRaw("Horizontal");
        float v = Input.GetAxisRaw("Vertical");

        if (h >= 0.1f || v >= 0.1f)
        {
            Move(h, v);
        }
    }

    private void FixedUpdate()
    {
        // 鼠标
        float x = Input.GetAxisRaw("Mouse X");
        float y = Input.GetAxisRaw("Mouse Y");

        if (x > 0.1f || y > 0.1f)
        {
            RotateView(x, y);
        }
    }
}

效果

署名 - 非商业性使用 - 禁止演绎 4.0