Unity 消灭病毒(98K)—2

Posted CZandQZ

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity 消灭病毒(98K)—2相关的知识,希望对你有一定的参考价值。

写完玩家的移动,接下来就开始写玩家的射击。玩家是一直射击的,然后射击有个间隔。所以在Update里面就只是一个时间一直减,定义这个类为VirusPlayerShoot。

 public void OnUpdate()
 
        if (_isStartShoot)
        
            _totalTime += Time.deltaTime;
            if (_totalTime > _shootDuration)
            
                _totalTime -= _shootDuration;
                Shoot();
            
        
  

我们这里用OnUpdate替代Update,因为我们需要将这个OnUpdate放到一个管理类里面去做一个Update分流。然后先把几个变量填充进去。

 [SerializeField] private Transform _shootPos;

    private float _shootDuration;
    private float _interval;
    private float _totalTime;
    private bool _isStartShoot;


    public bool IsStartShoot
    
        set  _isStartShoot = value;  
        get  return _isStartShoot; 
    

接下来就是写Shoot方法了。

private void Shoot()

        int shootNum = VirusPlayerDataAdapter.GetShootNum();
        float originX = 0;
        int v = shootNum % 2;
        int vv = shootNum / 2;
        originX = v == 1 ? -vv * _interval : -(vv - 0.5f) * _interval;
        for (int i = 0; i < shootNum; i++)
        
            float x = originX + i * _interval + _shootPos.position.x;
            SpawnBullet(_shootPos.position, Vector3.zero, x, true);
        
 

首先获取飞机一次发射多少颗子弹,然后根据子弹数目计算子弹最终的X偏移所以 float x = originX + i * _interval + _shootPos.position.x;这样一句代码就是来计算子弹的最终X偏移。

SpawnBullet(_shootPos.position, Vector3.zero, x, true);根据射击的位置,子弹的角度,子弹的最终X偏移,是否成扇形。最后就是生成子弹方法了。

 private void SpawnBullet(Vector3 pos, Vector3 euler, float boderX, bool isSector)
 
        string bulletName = "BulletBlue";
        bool coin = VirusPlayerDataAdapter.GetShootCoin();
        bool power = VirusPlayerDataAdapter.GetPower();
        if (coin && power)
            bulletName = "BulletCoinPower";
        if (coin && !power)
            bulletName = "BulletCoin";
        if (!coin && power)
            bulletName = "BulletPower";

        int damage = VirusPlayerDataAdapter.GetShootPower();
        var obj = BulletPools.Instance.Spawn(bulletName);
        obj.transform.position = pos;
        obj.transform.eulerAngles = euler;
        obj.GetComponent<VirusPlayerBulletMove>().InitiDir(boderX, isSector);
        obj.GetComponent<VirusBulletDamage>().Initi(damage);
  

子弹总共有四种类型,第一种是最普通的,第二种是火力加强,第三种是打病毒会产生金币的,第四种是火力加强并且打病毒会产生金币的,所以首先判断子弹的类型。然后生成对应的子弹,给子弹赋值它的伤害,玩家的射击讲完了接下来就是讲解玩家吃道具之后,我们将这个类定义为:VirusPlayerPropMrg,然后吃道具之后我们采用消息处理的机制来实现,就是这个类之负责处理吃到了道具之后 玩家做出相应的反应的。

    private void OnEnable()
    
        EventRegister.EventStartListening<VirusPropAddEvent>(this);
    

    private void OnDisable()
    
        EventRegister.EventStopListening<VirusPropAddEvent>(this);
    

    public void OnEvent(VirusPropAddEvent eventType)
    
        switch (eventType.PropEnum)
        
            case VirusPropEnum.Big:
                AddBigProp(eventType.Duration);
                break;
            case VirusPropEnum.Active:
                AddActiveProp(eventType.Duration);
                break;
            case VirusPropEnum.Weaken:
                AddWeakenProp(eventType.Duration);
                break;
            case VirusPropEnum.ReinforceShootSpeed:
                AddShootNumProp(eventType.Duration);
                break;
            case VirusPropEnum.ReinforceShootPower:
                AddShootPowerProp(eventType.Duration);
                break;
            case VirusPropEnum.CallFriend:
                AddCallFriendProp(eventType.Duration);
                break;
            case VirusPropEnum.LimitMove:
                AddLimitMoveProp(eventType.Duration);
                break;
            case VirusPropEnum.ShootCoin:
                AddShootCoinProp(eventType.Duration);
                break;
            case VirusPropEnum.ShootRepulse:
                AddShootRepulseProp(eventType.Duration);
                break;
        
    

游戏中总共有9种这里有个Switch其实是一种错误的写法。正确的写法应该是在吃到道具的时候然后再写 AddLimitMoveProp(eventType.Duration);这样类似的方法。

具体如下:

public class ActiveProp : VirusBaseProp


    [SerializeField] private float _duration;

    public override void Excute(Transform target)
    
        EventManager.TriggerEvent(new VirusPropAddEvent(_duration, VirusPropEnum.Active));
        PropPools.Instance.DeSpawn(gameObject);
    

所以这个AddLimitMoveProp(eventType.Duration)应该放到Excute里面,所以这里就应该把EventManager去掉。为什么说我这里写法错了呢 因为在需求变了之后比如我们策划又想了一个道具那么这里岂不是要重新添加一个枚举同时又要在这里添加一个方法么? 所以我这里写法其实是错的。我也不建议写成我这样的。接下啦就是填充一下每种道具的具体方法。首先填写变大道具。

 private void AddBigProp(float duration)
 
        string str = VirusPropEnum.Big.ToString();
        Action<float> updateAction = t =>
        
            _player.UpdatePropItem(VirusPropEnum.Big, t, duration);
        ;
        Action callAction = () =>
        
            VirusMrg.Instance.RecoverBiggerVirus();
            _player.RemovePropItem(VirusPropEnum.Big);
            TimerManager.Instance.RemoveTimer(str);
        ;
        Action initiAction = () =>
        
            VirusMrg.Instance.StartBiggerVirus();
        ;

        Timer timer = new Timer(duration, updateAction, callAction, initiAction, () =>  _player.AddPropItem(VirusPropEnum.Big); );
        TimerManager.Instance.AddTimer(str, timer);
 

这个计时器也是之前写的,所以这个计时器就定义3个Action,一个初始化,一个更新的,一个时间结束后的。依次写完后面几个的。如果有什么问题qq联系:1850761495,源文件的地址:链接: https://pan.baidu.com/s/1tTXv-9s1BaTh6s_-3MFrhw 提取码: ri31 后期有些项目就可能放到github上去了,到时候我也会及时更新。

以上是关于Unity 消灭病毒(98K)—2的主要内容,如果未能解决你的问题,请参考以下文章

Ruby‘s Adventrue游戏制作笔记(十六)Unity子弹数量及其UI

Ruby‘s Adventrue游戏制作笔记(十六)Unity子弹数量及其UI

Ruby‘s Adventrue游戏制作笔记(十六)Unity子弹数量及其UI

Ruby‘s Adventrue游戏制作笔记(十六)Unity子弹数量及其UI

Unity3D制作简易坦克旋转发射子弹

unity怎么用C#写个发射子弹的脚本?