190 lines
4.4 KiB
C#
190 lines
4.4 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
[RequireComponent(typeof(AudioSource))]
|
|
public class vp_HitscanBullet : MonoBehaviour
|
|
{
|
|
public float Range = 100f;
|
|
|
|
public float Force = 100f;
|
|
|
|
public float Damage = 1f;
|
|
|
|
public string DamageMethodName = "Damage";
|
|
|
|
public bool RequireDamageHandler = true;
|
|
|
|
protected Transform m_Source;
|
|
|
|
public float m_SparkFactor = 0.5f;
|
|
|
|
public GameObject m_ImpactPrefab;
|
|
|
|
public GameObject m_DustPrefab;
|
|
|
|
public GameObject m_SparkPrefab;
|
|
|
|
public GameObject m_DebrisPrefab;
|
|
|
|
protected AudioSource m_Audio;
|
|
|
|
public List<AudioClip> m_ImpactSounds = new List<AudioClip>();
|
|
|
|
public Vector2 SoundImpactPitch = new Vector2(1f, 1.5f);
|
|
|
|
public int[] NoDecalOnTheseLayers;
|
|
|
|
protected Transform m_Transform;
|
|
|
|
protected Renderer m_Renderer;
|
|
|
|
protected bool m_Initialized;
|
|
|
|
protected int LayerMask = vp_Layer.Mask.IgnoreWalkThru;
|
|
|
|
protected static vp_DamageHandler m_TargetDHandler;
|
|
|
|
private RaycastHit m_Hit;
|
|
|
|
private void Awake()
|
|
{
|
|
m_Transform = base.transform;
|
|
m_Renderer = GetComponent<Renderer>();
|
|
m_Audio = GetComponent<AudioSource>();
|
|
}
|
|
|
|
private void Start()
|
|
{
|
|
m_Initialized = true;
|
|
DoHit();
|
|
}
|
|
|
|
private void OnEnable()
|
|
{
|
|
if (m_Initialized)
|
|
{
|
|
DoHit();
|
|
}
|
|
}
|
|
|
|
private void DoHit()
|
|
{
|
|
Ray ray = new Ray(m_Transform.position, m_Transform.forward);
|
|
if (m_Source != null && m_Source.gameObject.layer == 30)
|
|
{
|
|
LayerMask = vp_Layer.Mask.BulletBlockers;
|
|
}
|
|
if (Physics.Raycast(ray, out m_Hit, Range, LayerMask))
|
|
{
|
|
Vector3 localScale = m_Transform.localScale;
|
|
m_Transform.parent = m_Hit.transform;
|
|
m_Transform.localPosition = m_Hit.transform.InverseTransformPoint(m_Hit.point);
|
|
m_Transform.rotation = Quaternion.LookRotation(m_Hit.normal);
|
|
if (m_Hit.transform.lossyScale == Vector3.one)
|
|
{
|
|
m_Transform.Rotate(Vector3.forward, UnityEngine.Random.Range(0, 360), Space.Self);
|
|
}
|
|
else
|
|
{
|
|
m_Transform.parent = null;
|
|
m_Transform.localScale = localScale;
|
|
m_Transform.parent = m_Hit.transform;
|
|
}
|
|
Rigidbody attachedRigidbody = m_Hit.collider.attachedRigidbody;
|
|
if (attachedRigidbody != null && !attachedRigidbody.isKinematic)
|
|
{
|
|
attachedRigidbody.AddForceAtPosition(ray.direction * Force / Time.timeScale / vp_TimeUtility.AdjustedTimeScale, m_Hit.point);
|
|
}
|
|
if (m_ImpactPrefab != null)
|
|
{
|
|
vp_Utility.Instantiate(m_ImpactPrefab, m_Transform.position, m_Transform.rotation);
|
|
}
|
|
if (m_DustPrefab != null)
|
|
{
|
|
vp_Utility.Instantiate(m_DustPrefab, m_Transform.position, m_Transform.rotation);
|
|
}
|
|
if (m_SparkPrefab != null && UnityEngine.Random.value < m_SparkFactor)
|
|
{
|
|
vp_Utility.Instantiate(m_SparkPrefab, m_Transform.position, m_Transform.rotation);
|
|
}
|
|
if (m_DebrisPrefab != null)
|
|
{
|
|
vp_Utility.Instantiate(m_DebrisPrefab, m_Transform.position, m_Transform.rotation);
|
|
}
|
|
if (m_ImpactSounds.Count > 0)
|
|
{
|
|
m_Audio.pitch = UnityEngine.Random.Range(SoundImpactPitch.x, SoundImpactPitch.y) * Time.timeScale;
|
|
m_Audio.clip = m_ImpactSounds[UnityEngine.Random.Range(0, m_ImpactSounds.Count)];
|
|
m_Audio.Stop();
|
|
m_Audio.Play();
|
|
}
|
|
m_TargetDHandler = vp_DamageHandler.GetDamageHandlerOfCollider(m_Hit.collider);
|
|
if (m_TargetDHandler != null && m_Source != null)
|
|
{
|
|
m_TargetDHandler.Damage(new vp_DamageInfo(Damage, m_Source, vp_DamageInfo.DamageType.Bullet));
|
|
}
|
|
else if (!RequireDamageHandler)
|
|
{
|
|
m_Hit.collider.SendMessage(DamageMethodName, Damage, SendMessageOptions.DontRequireReceiver);
|
|
}
|
|
if (m_Renderer != null && NoDecalOnTheseLayers.Length > 0)
|
|
{
|
|
int[] noDecalOnTheseLayers = NoDecalOnTheseLayers;
|
|
foreach (int num in noDecalOnTheseLayers)
|
|
{
|
|
if (m_Hit.transform.gameObject.layer == num)
|
|
{
|
|
m_Renderer.enabled = false;
|
|
TryDestroy();
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
if (m_Renderer != null)
|
|
{
|
|
vp_DecalManager.Add(base.gameObject);
|
|
}
|
|
else
|
|
{
|
|
vp_Timer.In(1f, TryDestroy);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
vp_Utility.Destroy(base.gameObject);
|
|
}
|
|
}
|
|
|
|
public void SetSource(Transform source)
|
|
{
|
|
m_Source = source;
|
|
}
|
|
|
|
[Obsolete("Please use 'SetSource' instead.")]
|
|
public void SetSender(Transform sender)
|
|
{
|
|
SetSource(sender);
|
|
}
|
|
|
|
private void TryDestroy()
|
|
{
|
|
if (this == null)
|
|
{
|
|
return;
|
|
}
|
|
if (!m_Audio.isPlaying)
|
|
{
|
|
if (m_Renderer != null)
|
|
{
|
|
m_Renderer.enabled = true;
|
|
}
|
|
vp_Utility.Destroy(base.gameObject);
|
|
}
|
|
else
|
|
{
|
|
vp_Timer.In(1f, TryDestroy);
|
|
}
|
|
}
|
|
}
|