Пример #1
0
        /// <summary>
        /// Generates a bullet hole decal.
        /// </summary>
        /// <param name="surface">The surface properties of the hit object.</param>
        /// <param name="hitInfo">The information about the projectile impact such as position and rotation.</param>
        public virtual void CreateBulletDecal(SurfaceIdentifier surface, RaycastHit hitInfo)
        {
            SurfaceType surfaceType = surface.GetSurfaceType(hitInfo.point, hitInfo.triangleIndex);

            if (surface && surfaceType)
            {
                if (surface.AllowDecals(hitInfo.triangleIndex) && m_MaxDecals > 0)
                {
                    Material material = surfaceType.GetRandomDecalMaterial();
                    if (material)
                    {
                        GameObject decal = new GameObject("BulletMark_Decal");
                        decal.transform.position = hitInfo.point;
                        decal.transform.rotation = Quaternion.FromToRotation(Vector3.back, hitInfo.normal);

                        decal.transform.Rotate(new Vector3(0, 0, Random.Range(0, 360)));

                        float scale = surfaceType.GetRandomDecalSize() / 5;
                        decal.transform.localScale = new Vector3(scale, scale, scale);

                        decal.transform.parent = hitInfo.transform;

                        DecalPresets decalPresets = new DecalPresets()
                        {
                            maxAngle     = 60,
                            pushDistance = 0.009f + RegisterDecal(decal, scale),
                            material     = material
                        };

                        Decal d = decal.AddComponent <Decal>();
                        d.Calculate(decalPresets, hitInfo.collider.gameObject);
                    }
                }

                GameObject particle = surfaceType.GetRandomImpactParticle();
                if (particle)
                {
                    Instantiate(particle, hitInfo.point, Quaternion.FromToRotation(Vector3.up, hitInfo.normal));
                }

                AudioClip clip = surfaceType.GetRandomImpactSound();
                if (clip)
                {
                    AudioManager.Instance.PlayClipAtPoint(clip, hitInfo.point, 1, 25, surfaceType.BulletImpactVolume);
                }
            }
        }
Пример #2
0
        protected virtual void Penetrate(RaycastHit lastHitInfo, Vector3 direction, SurfaceIdentifier surf, float range, float damage)
        {
            Ray ray = new Ray(lastHitInfo.point + direction * 0.1f, direction);

            int affectedObjectID = lastHitInfo.collider.GetInstanceID();

            if (Physics.Raycast(ray, out RaycastHit hitInfo, range, m_GunData.AffectedLayers, QueryTriggerInteraction.Collide))
            {
                // Get the surface type of the object.
                SurfaceIdentifier newSurf = hitInfo.collider.GetSurface();

                // Exit hole
                Ray exitRay = new Ray(hitInfo.point, direction * -1);

                if (Physics.Raycast(exitRay, out RaycastHit exitInfo, range, m_GunData.AffectedLayers, QueryTriggerInteraction.Collide))
                {
                    float distanceTraveled = Vector3.Distance(lastHitInfo.point, exitInfo.point) * surf.Density(lastHitInfo.triangleIndex);

                    // Does the bullet gets through?
                    if (m_GunData.PenetrationPower > distanceTraveled)
                    {
                        if (newSurf)
                        {
                            BulletDecalsManager.Instance.CreateBulletDecal(newSurf, hitInfo);
                        }

                        if (affectedObjectID == exitInfo.collider.GetInstanceID())
                        {
                            BulletDecalsManager.Instance.CreateBulletDecal(surf, exitInfo);
                        }

                        // If hit a rigid body applies force to push.
                        Rigidbody rigidBody = hitInfo.collider.GetComponent <Rigidbody>();
                        if (rigidBody)
                        {
                            rigidBody.AddForce(direction * m_GunData.Force, ForceMode.Impulse);
                        }

                        if (hitInfo.transform.root != transform.root)
                        {
                            IProjectileDamageable damageableTarget = hitInfo.collider.GetComponent <IProjectileDamageable>();
                            damageableTarget?.ProjectileDamage(damage * (distanceTraveled / m_GunData.PenetrationPower), transform.root.position, exitInfo.point, m_GunData.PenetrationPower - distanceTraveled);
                        }
                    }
                }
            }
Пример #3
0
        protected virtual void Shot()
        {
            Vector3 direction = m_CameraTransformReference.TransformDirection(m_NextShootDirection);
            Vector3 origin    = m_CameraTransformReference.transform.position;

            Ray ray = new Ray(origin, direction);

            float tracerDuration = m_GunEffects.TracerDuration;

            if (Physics.Raycast(ray, out RaycastHit hitInfo, m_GunData.Range, m_GunData.AffectedLayers, QueryTriggerInteraction.Collide))
            {
                SurfaceIdentifier surf   = hitInfo.collider.GetSurface();
                float             damage = m_GunData.DamageType == GunData.DamageMode.Constant ? m_GunData.Damage
                    : m_GunData.Damage * m_GunData.DamageFalloffCurve.Evaluate(hitInfo.distance / m_GunData.Range);

                if (surf)
                {
                    BulletDecalsManager.Instance.CreateBulletDecal(surf, hitInfo);

                    if (m_GunData.PenetrateObjects && surf.CanPenetrate(hitInfo.triangleIndex))
                    {
                        Penetrate(hitInfo, direction, surf, m_GunData.Range - hitInfo.distance, damage);
                    }
                }

                // If hit a rigid body applies force to push.
                Rigidbody rigidBody = hitInfo.collider.GetComponent <Rigidbody>();
                if (rigidBody)
                {
                    rigidBody.AddForce(direction * m_GunData.Force, ForceMode.Impulse);
                }

                if (hitInfo.transform.root != transform.root)
                {
                    IProjectileDamageable damageableTarget = hitInfo.collider.GetComponent <IProjectileDamageable>();
                    damageableTarget?.ProjectileDamage(damage, transform.root.position, hitInfo.point, m_GunData.PenetrationPower);
                }

                tracerDuration = hitInfo.distance / m_GunEffects.TracerSpeed;
            }

            if (tracerDuration > 0.05f)
            {
                m_GunEffects.CreateTracer(transform, direction, tracerDuration);
            }
        }
 private void OnEnable()
 {
     m_Target      = (target as SurfaceIdentifier);
     m_SurfaceList = serializedObject.FindProperty("m_SurfaceList");
 }
Пример #5
0
 private void Start()
 {
     m_SurfaceIdentifier = GetComponent <SurfaceIdentifier>();
 }