1.前言

       在我们个人开发自己的游戏的Demo的时候肯定会遇到这种情况,如果在一个Player类中实现的功能过多,就会使得整个代码的耦合性大幅度上升,其他地方需要某个功能,而这个功能在Player类中已经实现过时,代码的依赖关系就会不断变强,且后续开发其他功能时难以拓展。我们来根据一个实际情况看看这种写法带来的糟糕情况。

        现在有一个2D射击游戏,直观的逻辑来看,我们需要使得player类能执行我们的移动,射击(需要武器)等功能。那如果我们这些功能全部都写在player类这个脚本时会发生什么情况呢?当我们需要制造这个游戏中的敌人时,而敌人也需要射击这个功能时,我们就会遇到非常尴尬的情况了,这就是代码没有模块化的原因,我们没有履行好单一职责原则。

        那我们该如何根据现在的情景去编写一个Player类呢,先来看下面这张图

          

unity 代码创建AudioSource unity怎么创建player_射击游戏

       我们无需在player中实现所有我们想要的功能,我们创建PlayerController类与GunController将Player类中的多数功能下放给两个组件类去完善,我们只需要在Player类中去实现,这就好比乐高积木,我们只需要拿到我们想要的零件,然后将零件拼装成我们想要的模型。

[RequireComponent(typeof(GunController))]
[RequireComponent(typeof(PlayerController))]
public class Player : LivingEntity
{

    
    //[控制器] 组件类
    public GunController gunController;
    public PlayerController Controller;
    

    //[输入参数]
    private float moveH, MoveV;
    public Vector2 mousePos;

    [Header("PlayMoveSpeed")]
     public  float moveSpeed = 5f;

    public float ClearRange = 2f;


    public override void Start()//获取到我们的组件类
    {
        base.Start();
        Controller = GetComponent<PlayerController>();
        gunController = GetComponent<GunController>();
    }
    void Update()//通过拿到的输入直接去调用组件类的方法
    {
        mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
        moveH = Input.GetAxisRaw("Horizontal")*moveSpeed;
        MoveV = Input.GetAxisRaw("Vertical") * moveSpeed;
        if (Input.GetMouseButton(0))
        {
            gunController.Shoot();
        }
        if (Input.GetKeyDown(KeyCode.R))
        {
            gunController.Reload();
        }
        if (Input.GetKeyDown(KeyCode.Q))
        {
            gunController.ChangeGun();
        }
        if (Input.GetKeyDown(KeyCode.Space))
        {
            Controller.Roll();
        }      
    }
    void FixedUpdate()//通过拿到的输入直接去调用组件类的方法
    {
        Controller.Move(moveH, MoveV);
        gunController.GunPointTo(mousePos);
        Controller.Look(mousePos);
    }
}

          上述代码是我从我的个人项目中删减出来的一部分代码,我们不需要关注太多代码本身的问题,只需要关注思路,我们在Player类中只负责拿到玩家的输入(键盘鼠标操控)然后将具体的实现下放给PlayerController和GunController。这样我们Player类的职责就比较单一了,在后续我们需要实现我们的Enemy类时,也可以直接将GunController类当成自己的组件类来使用了。