Ejemplo n.º 1
0
        void Hit(Collision col)
        {
            //播放爆炸特效
            Explode(col.contacts[0].point);

            //让被击中物受到伤害
            if (SelectedDamageType == DamageType.Direct)
            {
                ReactiveTarget target = col.collider.gameObject.GetComponent <ReactiveTarget>();
                if (target)
                {
                    //第二个参数设置为true,不分敌我进行伤害
                    target.OnHit(this.gameObject.name, true, Damage);
                }
                else
                {
                    target = col.collider.transform.root.GetComponent <ReactiveTarget>();
                    if (target)
                    {
                        //第二个参数设置为true,不分敌我进行伤害
                        target.OnHit(this.gameObject.name, false, Damage);
                    }
                }
            }
        }
Ejemplo n.º 2
0
        //射线武器,开火
        public void Fire()
        {
            //调用RPC函数
            if (IsLocalObject)
            {
                m_NetSyncController.RPC(this, "Fire");
            }


            //重置计时器
            FireTimer = 0.0f;

            //增加已射击的子弹数
            BurstCounter++;

            //半自动武器不能连续射击
            if (AutoMode == Auto.Semi)
            {
                m_CanFire = false;
            }

            //判断当前是否仍有弹药
            if (m_CurrentAmmo <= 0)
            {
                DryFire();
                return;
            }

            //能够开枪,发送开枪消息
            SendMessage("StartShooting", SendMessageOptions.DontRequireReceiver);

            //如果不是无线弹药模式,减少弹药量
            if (!InfiniteAmmo)
            {
                m_CurrentAmmo--;
            }

            //单次射击,射出shotPerRound颗子弹
            for (int i = 0; i < ShotPerRound; i++)
            {
                Vector3 direction = m_CurrentShootPoint.forward;

                //计算当前的精确度
                float accuracyVary = (100 - CurrentAccuracy) / 1000;

                //根据精确度确定散射范围
                direction.x     += UnityEngine.Random.Range(-accuracyVary, accuracyVary);
                direction.y     += UnityEngine.Random.Range(-accuracyVary, accuracyVary);
                direction.z     += UnityEngine.Random.Range(-accuracyVary, accuracyVary);
                CurrentAccuracy -= AccuracyDropPerShot;
                if (CurrentAccuracy <= 0.0f)
                {
                    CurrentAccuracy = 0.0f;
                }

                //创建射线
                Ray ray = new Ray(m_CurrentShootPoint.position, direction);

                bool       hitResult;
                RaycastHit hit;

                int layer = LayerMask.NameToLayer(LayerMaskName);
                if (layer != -1)
                {
                    //过滤LayerMaskName这一层
                    LayerMask mask = ~(1 << layer);
                    hitResult = Physics.Raycast(ray, out hit, Range, mask);
                }
                else
                {
                    hitResult = Physics.Raycast(ray, out hit, Range);
                }

                if (hitResult)
                {
                    //蓄力
                    float damage = Power;
                    if (Warmup)
                    {
                        damage *= m_Heat * PowerMultiplier;
                        m_Heat  = 0.0f;
                    }

                    //造成伤害
                    ReactiveTarget target = hit.collider.gameObject.GetComponent <ReactiveTarget>();
                    if (target)
                    {
                        target.OnHit(this.transform.root.name, false, Power);
                    }
                    else
                    {
                        target = hit.collider.transform.root.gameObject.GetComponent <ReactiveTarget>();
                        if (target)
                        {
                            target.OnHit(this.transform.root.name, false, Power);
                        }
                    }


                    //判断被击中物体是否满足不产生弹孔的条件
                    bool exception = false;
                    if (BHSystem == BulletHoleSystem.Tag)
                    {
                        foreach (SmartBulletHoleGroup bhg in BulletHoleExceptions)
                        {
                            if (hit.collider.gameObject.tag == bhg.Tag)
                            {
                                exception = true;
                                break;
                            }
                        }
                    }
                    else if (BHSystem == BulletHoleSystem.Material)
                    {
                        foreach (SmartBulletHoleGroup bhg in BulletHoleExceptions)
                        {
                            MeshRenderer mesh = FindMeshRenderer(hit.collider.gameObject);
                            if (mesh != null)
                            {
                                if (mesh.sharedMaterial == bhg.Material)
                                {
                                    exception = true;
                                    break;
                                }
                            }
                        }
                    }
                    else if (BHSystem == BulletHoleSystem.Physic_Material)
                    {
                        foreach (SmartBulletHoleGroup bhg in BulletHoleExceptions)
                        {
                            if (hit.collider.sharedMaterial == bhg.PhysicMaterial)
                            {
                                exception = true;
                                break;
                            }
                        }
                    }

                    //如果需要生成弹孔,且物体满足生成弹孔条件
                    if (MakeBulletHoles && !exception)
                    {
                        //保存所有符合条件的SmartBulletHoleGroup
                        List <SmartBulletHoleGroup> holes = new List <SmartBulletHoleGroup>();

                        if (BHSystem == BulletHoleSystem.Tag)
                        {
                            foreach (SmartBulletHoleGroup bhg in BulletHoleGroups)
                            {
                                if (hit.collider.gameObject.tag == bhg.Tag)
                                {
                                    holes.Add(bhg);
                                }
                            }
                        }
                        else if (BHSystem == BulletHoleSystem.Material)
                        {
                            MeshRenderer mesh = FindMeshRenderer(hit.collider.gameObject);

                            foreach (SmartBulletHoleGroup bhg in BulletHoleGroups)
                            {
                                if (mesh != null)
                                {
                                    if (mesh.sharedMaterial == bhg.Material)
                                    {
                                        holes.Add(bhg);
                                    }
                                }
                            }
                        }
                        else if (BHSystem == BulletHoleSystem.Physic_Material)
                        {
                            foreach (SmartBulletHoleGroup bhg in BulletHoleGroups)
                            {
                                if (hit.collider.sharedMaterial == bhg.PhysicMaterial)
                                {
                                    holes.Add(bhg);
                                }
                            }
                        }

                        //保存被选中的SmartBulletHoleGroup
                        SmartBulletHoleGroup sbhg = null;

                        //没有满足条件的弹孔,使用默认弹孔
                        if (holes.Count == 0)
                        {
                            List <SmartBulletHoleGroup> defaultsToUse = new List <SmartBulletHoleGroup>();
                            foreach (BulletHolePool h in DefaultBulletHoles)
                            {
                                defaultsToUse.Add(new SmartBulletHoleGroup("Default", null, null, h));
                            }

                            //随机选择一个SmartBulletHoleGroup
                            sbhg = defaultsToUse[Random.Range(0, defaultsToUse.Count)];
                        }
                        else
                        {
                            //随机选择一个SmartBulletHoleGroup
                            sbhg = holes[Random.Range(0, holes.Count)];
                        }

                        //在场景中生成弹孔
                        if (sbhg.BulletHole != null)
                        {
                            sbhg.BulletHole.PlaceBulletHole(hit.point, Quaternion.FromToRotation(Vector3.up, hit.normal));
                        }
                    }

                    //击中的特效
                    if (MakeHitEffects)
                    {
                        foreach (GameObject hitEffect in HitEffects)
                        {
                            if (hitEffect != null)
                            {
                                Instantiate(hitEffect, hit.point, Quaternion.FromToRotation(Vector3.up, hit.normal));
                            }
                        }
                    }

                    //给被射中的物体加上一个击退的力
                    if (UseForce && hit.rigidbody)
                    {
                        hit.rigidbody.AddForce(ray.direction * Power * ForceMultiplier);
                    }
                }
            }

            //如果使用后坐力,调用后坐力函数
            if (UseRecoil)
            {
                Recoil();
            }

            //如果使用枪口火焰效果,就显示枪口火焰
            if (MakeMuzzleEffects)
            {
                GameObject muzfx = MuzzleEffects[Random.Range(0, MuzzleEffects.Length)];
                if (muzfx != null)
                {
                    Instantiate(muzfx, MuzzleEffectsPosition.position, MuzzleEffectsPosition.rotation);
                }
            }

            //创建弹壳
            if (UseSpitShells)
            {
                GameObject shellGO = Instantiate(Shell, ShellSpitPosition.position, ShellSpitPosition.rotation) as GameObject;
                shellGO.GetComponent <Rigidbody>().AddRelativeForce(new Vector3(ShellSpitForce + Random.Range(0, ShellForceRandom), 0, 0), ForceMode.Impulse);
                shellGO.GetComponent <Rigidbody>().AddRelativeTorque(new Vector3(ShellSpitTorqueX + Random.Range(-ShellTorqueRandom, ShellTorqueRandom), ShellSpitTorqueY + Random.Range(-ShellTorqueRandom, ShellTorqueRandom), 0), ForceMode.Impulse);
            }

            //播放射击音效
            GetComponent <AudioSource>().PlayOneShot(FireSound);
        }
Ejemplo n.º 3
0
        //激光武器,发射激光
        public void Beam()
        {
            //调用RPC函数
            if (IsLocalObject)
            {
                m_NetSyncController.RPC(this, "Beam");
            }

            //能够开枪,发送开枪消息
            SendMessage("StartShooting", SendMessageOptions.DontRequireReceiver);

            //当前正在发射激光
            m_IsBeaming = true;

            //如果不是无限激光,开始计时
            if (!InfiniteBeam)
            {
                m_BeamHeat += Time.deltaTime;
            }

            //如果没有设置激光Object,创建一个带有line renderer的GameObject
            if (m_BeamGO == null)
            {
                m_BeamGO = new GameObject(BeamTypeName, typeof(LineRenderer));
                //设置为Weapon的子对象
                m_BeamGO.transform.parent = transform;
            }
            //设置线渲染器属性
            LineRenderer beamLR = m_BeamGO.GetComponent <LineRenderer>();

            beamLR.material = BeamMaterial;
            beamLR.material.SetColor("_TintColor", BeamColor);
            beamLR.startWidth = StartBeamWidth;
            beamLR.endWidth   = EndBeamWidth;

            //反射次数
            int reflections = 0;

            //保存激光的所有反射点
            List <Vector3> reflectionPoints = new List <Vector3>();

            //添加第一个反射点
            reflectionPoints.Add(RaycastStartSpot.position);

            //保存上一个反射点
            Vector3 lastPoint = RaycastStartSpot.position;

            //用于保存激光的入射方向和反射方向
            Vector3 incomingDirection;
            Vector3 reflectDirection;

            //激光是否需要继续进行反射
            bool keepReflecting = true;

            //投射射线
            Ray        ray = new Ray(lastPoint, RaycastStartSpot.forward);
            RaycastHit hit;

            do
            {
                //如果没有检测到任何物体,那么下一个点为终点
                Vector3 nextPoint = ray.direction * Range;

                if (Physics.Raycast(ray, out hit, Range))
                {
                    //保存碰撞点
                    nextPoint = hit.point;

                    //计算反射方向
                    incomingDirection = nextPoint - lastPoint;
                    reflectDirection  = Vector3.Reflect(incomingDirection, hit.normal);
                    ray = new Ray(nextPoint, reflectDirection);

                    //更新上一次的反射点
                    lastPoint = hit.point;

                    //创建击中特效
                    if (MakeHitEffects)
                    {
                        foreach (GameObject hitEffect in HitEffects)
                        {
                            if (hitEffect != null)
                            {
                                Instantiate(hitEffect, hit.point, Quaternion.FromToRotation(Vector3.up, hit.normal));
                            }
                        }
                    }

                    //造成伤害
                    ReactiveTarget target = hit.collider.gameObject.GetComponent <ReactiveTarget>();
                    if (target)
                    {
                        target.OnHit(this.transform.root.name, false, Power);
                    }


                    // 增加反射次数
                    reflections++;
                }
                else
                {
                    //不再进行反射
                    keepReflecting = false;
                }

                //添加反射点
                reflectionPoints.Add(nextPoint);
            } while (keepReflecting && reflections < MaxReflections && Reflect && (ReflectionMaterial == null || (FindMeshRenderer(hit.collider.gameObject) != null && FindMeshRenderer(hit.collider.gameObject).sharedMaterial == ReflectionMaterial)));

            //设置线渲染器的顶点
            beamLR.positionCount = reflectionPoints.Count;

            for (int i = 0; i < reflectionPoints.Count; i++)
            {
                beamLR.SetPosition(i, reflectionPoints[i]);

                //枪口反射特效
                // Doesn't make the FX on the first iteration since that is handled later.  This is so that the FX at the muzzle point can be parented to the weapon
                if (MakeMuzzleEffects && i > 0)
                {
                    GameObject muzfx = MuzzleEffects[Random.Range(0, MuzzleEffects.Length)];
                    if (muzfx != null)
                    {
                        Instantiate(muzfx, reflectionPoints[i], MuzzleEffectsPosition.rotation);
                    }
                }
            }

            //枪口闪烁特效
            if (MakeMuzzleEffects)
            {
                GameObject muzfx = MuzzleEffects[Random.Range(0, MuzzleEffects.Length)];
                if (muzfx != null)
                {
                    GameObject mfxGO = Instantiate(muzfx, MuzzleEffectsPosition.position, MuzzleEffectsPosition.rotation) as GameObject;
                    mfxGO.transform.parent = RaycastStartSpot;
                }
            }

            //播放激光音效
            if (!GetComponent <AudioSource>().isPlaying)
            {
                GetComponent <AudioSource>().clip = FireSound;
                GetComponent <AudioSource>().Play();
            }
        }
Ejemplo n.º 4
0
        //将Start设置为协程,自动开始协程
        IEnumerator Start()
        {
            //暂停一帧,避免有碎片还没被创建
            yield return(null);

            //获取物理层
            int layer = LayerMask.NameToLayer(LayerMaskName);

            Collider[] cols;
            Collider[] colsWithoutMask;

            if (layer != -1)
            {
                //创建物理遮罩
                LayerMask mask = ~(1 << layer);
                //爆炸范围内的物体
                cols = Physics.OverlapSphere(transform.position, ExplosionRadius, mask);
            }
            else
            {
                Debug.LogWarning("Can not find the layer to create a layer mask");
                //爆炸范围内的物体
                cols = Physics.OverlapSphere(transform.position, ExplosionRadius);
            }

            colsWithoutMask = Physics.OverlapSphere(transform.position, ExplosionRadius);

            //造成伤害
            if (CauseDamage)
            {
                foreach (Collider col in cols)
                {
                    float damageAmount = Damage * (1 / Vector3.Distance(transform.position, col.transform.position));

                    //造成伤害
                    ReactiveTarget target = col.gameObject.GetComponent <ReactiveTarget>();
                    if (target)
                    {
                        //第二个参数为true,不分敌我进行伤害
                        target.OnHit(this.gameObject.name, true, Damage);
                    }
                }
            }

            //用来保存爆炸范围内所有Rigidbody信息
            List <Rigidbody> rigidbodies = new List <Rigidbody>();

            foreach (Collider col in cols)
            {
                //保存范围内所有Rigidbody信息
                if (col.attachedRigidbody != null && !rigidbodies.Contains(col.attachedRigidbody))
                {
                    rigidbodies.Add(col.attachedRigidbody);
                }
            }

            foreach (Rigidbody rb in rigidbodies)
            {
                rb.AddExplosionForce(ExplosionForce, transform.position, ExplosionRadius, 1, ForceMode.Impulse);
            }

            foreach (Collider col in colsWithoutMask)
            {
                //如果子对象包含Vibration脚本,就调用函数进行抖动
                if (ShakeCamera && col.transform.GetComponentInChildren <Vibration>() != null)
                {
                    float shakeViolence = 1 / (Vector3.Distance(transform.position, col.transform.position) * CameraShakeViolence);
                    col.transform.GetComponentInChildren <Vibration>().StartShakingRandom(-shakeViolence, shakeViolence, -shakeViolence, shakeViolence);
                }
            }
        }