Ejemplo n.º 1
0
        //~ IEnumerator ShootRoutine(RaycastHit hit=default(RaycastHit)){
        IEnumerator ShootRoutine(ShootObject.AimInfo aimInfo=null)
        {
            if(uAnimation!=null) uAnimation.AttackRange();

            AttackStats aStats=ModifyAttackStatsToExistingEffect(weaponList[weaponID].CloneStats());
            AttackInstance aInstance=new AttackInstance(this, aStats);

            int weapID=weaponID;	//to prevent weapon switch and state change while delay and firing multiple so

            int spread=weaponList[weapID].spread;
            if(spread>1){
                aInstance.aStats.damageMin/=spread;
                aInstance.aStats.damageMax/=spread;
            }

            float startAngle=spread>1 ? -weaponList[weapID].spreadAngle/2f : 0 ;
            float angleDelta=spread>1 ? weaponList[weapID].spreadAngle/(spread-1) : 0 ;

            List<Collider> soColliderList=new List<Collider>();	//colliders of all the so fired, used to tell each so to ignore each other

            for(int i=0; i<weaponList[weapID].shootPointList.Count; i++){
                Transform shootPoint=weaponList[weapID].shootPointList[i];

                float recoilSign=(Random.value<recoilSignTH ? -1 : 1);
                recoilSignTH=Mathf.Clamp(recoilSignTH+(recoilSign>0 ? 0.25f : -0.25f), 0, 1);
                float recoilValue=recoilSign*Random.Range(0.1f, 1f)*GetRecoil();
                Quaternion baseShootRot=shootPoint.rotation*Quaternion.Euler(0, recoilValue, 0);

                for(int m=0; m<Mathf.Max(1, spread); m++){
                    Vector3 shootPos=shootPoint.position;
                    if(spread>1) shootPos=shootPoint.TransformPoint(new Vector3(0, 0, Random.Range(-1.5f, 1.5f)));
                    Quaternion shootRot=baseShootRot*Quaternion.Euler(0, startAngle+(m*angleDelta), 0);

                    //GameObject soObj=(GameObject)Instantiate(weaponList[weapID].shootObject, shootPos, shootRot);
                    GameObject soObj=ObjectPoolManager.Spawn(weaponList[weapID].shootObject, shootPos, shootRot);
                    ShootObject soInstance=soObj.GetComponent<ShootObject>();

                    soInstance.IgnoreCollider(GetCollider());
                    for(int n=0; n<soColliderList.Count; n++) soInstance.IgnoreCollider(soColliderList[n]);
                    if(soInstance.GetCollider()!=null) soColliderList.Add(soInstance.GetCollider());

                    soInstance.Shoot(thisObj.layer, GetRange(), shootPoint, aInstance.Clone(), aimInfo);
                    //soInstance.Shoot(thisObj.layer, GetRange(), shootPoint, aInstance.Clone(), hit);
                }

                TDS.CameraShake(weaponList[weapID].recoilCamShake);

                if(weaponList[weapID].shootPointDelay>0) yield return new WaitForSeconds(weaponList[weapID].shootPointDelay);

                if(weapID>=weaponList.Count) break;
            }
        }
Ejemplo n.º 2
0
        IEnumerator ShootRoutine(ShootObject.AimInfo aimInfo = null)
        {
            if (uAnimation != null)
            {
                uAnimation.AttackRange();
            }

            AttackStats aStats = ModifyAttackStatsToLevel(weaponList[weaponID].GetRuntimeAttackStats());

            aStats = ModifyAttackStatsToExistingEffect(aStats);
            //aStats=ModifyAttackStatsToExistingEffect(weaponList[weaponID].GetRuntimeAttackStats());
            AttackInstance aInstance = new AttackInstance(this, aStats);

            int weapID = weaponID;              //to prevent weapon switch and state change while delay and firing multiple so

            int spread = weaponList[weapID].spread;

            if (spread > 1)
            {
                aInstance.aStats.damageMin /= spread;
                aInstance.aStats.damageMax /= spread;
            }

            float startAngle = spread > 1 ? -weaponList[weapID].spreadAngle / 2f : 0;
            float angleDelta = spread > 1 ? weaponList[weapID].spreadAngle / (spread - 1) : 0;

            List <Collider> soColliderList = new List <Collider>();             //colliders of all the so fired, used to tell each so to ignore each other

            for (int i = 0; i < weaponList[weapID].shootPointList.Count; i++)
            {
                Transform shootPoint = weaponList[weapID].shootPointList[i];

                float recoilSign = (Random.value < recoilSignTH ? -1 : 1);
                recoilSignTH = Mathf.Clamp(recoilSignTH + (recoilSign > 0 ? 0.25f : -0.25f), 0, 1);
                float      recoilValue  = recoilSign * Random.Range(0.1f, 1f) * GetRecoil();
                Quaternion baseShootRot = shootPoint.rotation * Quaternion.Euler(0, recoilValue, 0);

                for (int m = 0; m < Mathf.Max(1, spread); m++)
                {
                    Vector3 shootPos = shootPoint.position;
                    if (spread > 1)
                    {
                        shootPos = shootPoint.TransformPoint(new Vector3(0, 0, Random.Range(-1.5f, 1.5f)));
                    }
                    Quaternion shootRot = baseShootRot * Quaternion.Euler(0, startAngle + (m * angleDelta), 0);

                    //GameObject soObj=(GameObject)Instantiate(weaponList[weapID].shootObject, shootPos, shootRot);
                    GameObject  soObj      = ObjectPoolManager.Spawn(weaponList[weapID].shootObject, shootPos, shootRot);
                    ShootObject soInstance = soObj.GetComponent <ShootObject>();

                    soInstance.IgnoreCollider(GetCollider());
                    for (int n = 0; n < soColliderList.Count; n++)
                    {
                        soInstance.IgnoreCollider(soColliderList[n]);
                    }
                    if (soInstance.GetCollider() != null)
                    {
                        soColliderList.Add(soInstance.GetCollider());
                    }

                    soInstance.Shoot(thisObj.layer, GetRange(), shootPoint, aInstance.Clone(), aimInfo);
                    //soInstance.Shoot(thisObj.layer, GetRange(), shootPoint, aInstance.Clone(), hit);
                }

                TDS.CameraShake(weaponList[weapID].recoilCamShake);

                if (weaponList[weapID].shootPointDelay > 0)
                {
                    yield return(new WaitForSeconds(weaponList[weapID].shootPointDelay));
                }

                if (weapID >= weaponList.Count)
                {
                    break;
                }
            }
        }
Ejemplo n.º 3
0
        //called when shootobject hit something
        void OnTriggerEnter(Collider col)
        {
            if (state == _State.Hit)
            {
                return;                                 //if the shootobject has hit something before this, return
            }
            //if the shootobject hits another shootobject from friendly unit
            if (!GameControl.SOHitFriendly() && col != null)
            {
                if (srcLayer == col.gameObject.layer)
                {
                    return;
                }
            }

            //register the state of the shootobject as hit
            state = _State.Hit;

            TDS.CameraShake(impactCamShake);


            //when hit a shootObject
            if (col != null && col.gameObject.layer == TDS.GetLayerShootObject())
            {
                //if this is a beam shootobject, inform the other shootobject that it has been hit (beam doesnt use a collider)
                if (type == _SOType.Beam)
                {
                    col.gameObject.GetComponent <ShootObject>().Hit();
                }
            }


            //when hit a collectible, destroy the collectible
            if (col != null && col.gameObject.layer == TDS.GetLayerCollectible())
            {
                ObjectPoolManager.Unspawn(col.gameObject);
                return;
            }


            //if there's a attack instance (means the shootobject has a valid attacking stats and all)
            if (attInstance != null)
            {
                float aoeRadius = attInstance.aStats.aoeRadius;

                //for area of effect hit
                if (aoeRadius > 0)
                {
                    Unit unitInstance = null;

                    //get all the potental target in range
                    Collider[] cols = Physics.OverlapSphere(thisT.position, aoeRadius);
                    for (int i = 0; i < cols.Length; i++)
                    {
                        //if the collider in question is the collider the shootobject hit in the first place, apply the full attack instance
                        if (cols[i] == col)
                        {
                            unitInstance = col.gameObject.GetComponent <Unit>();
                            if (unitInstance != null)
                            {
                                unitInstance.ApplyAttack(attInstance.Clone());
                            }
                            continue;
                        }

                        //no friendly fire, then skip if the target is a friendly unit
                        if (!GameControl.SOHitFriendly())
                        {
                            if (cols[i].gameObject.layer == srcLayer)
                            {
                                continue;
                            }
                        }

                        unitInstance = cols[i].gameObject.GetComponent <Unit>();

                        //create a new attack instance and mark it as aoe attack, so diminishing aoe can be applied if enabled
                        AttackInstance aInstance = attInstance.Clone();
                        aInstance.isAOE       = true;
                        aInstance.aoeDistance = Vector3.Distance(thisT.position, cols[i].transform.position);

                        //apply the attack
                        if (unitInstance != null)
                        {
                            unitInstance.ApplyAttack(aInstance);
                        }
                    }
                }
                else
                {
                    if (col != null)
                    {
                        //get the unit and apply the attack
                        Unit unitInstance = col.gameObject.GetComponent <Unit>();
                        if (unitInstance != null)
                        {
                            unitInstance.ApplyAttack(attInstance);
                        }
                    }
                }

                if (col != null)
                {
                    //apply impact force to the hit object
                    Vector3 impactDir = Quaternion.Euler(0, thisT.eulerAngles.y, 0) * Vector3.forward;
                    TDSPhysics.ApplyAttackForce(thisT.position, impactDir, col.gameObject, attInstance.aStats);
                }
            }

            //add collider to the condition so the shootobject wont split if the shootObject didnt hit anything (it could have just reach the range limit)
            if (splitUponHit && col != null)
            {
                Split(col);
            }

            Hit();
        }