SanAndreasUnity/Assets/Scripts/Behaviours/Projectile.cs

153 lines
5 KiB
C#
Raw Normal View History

2020-12-20 20:51:59 +00:00
using SanAndreasUnity.Behaviours.Vehicles;
2020-12-21 00:50:31 +00:00
using SanAndreasUnity.Importing.Conversion;
2020-12-20 20:51:59 +00:00
using SanAndreasUnity.Net;
using SanAndreasUnity.Utilities;
using UnityEngine;
using UnityStandardAssets.Effects;
2020-12-20 20:51:59 +00:00
using Object = UnityEngine.Object;
2020-12-21 22:27:00 +00:00
using Random = UnityEngine.Random;
2020-12-20 20:51:59 +00:00
2020-12-20 20:53:55 +00:00
namespace SanAndreasUnity.Behaviours
2020-12-20 20:51:59 +00:00
{
2020-12-20 20:53:55 +00:00
public class Projectile : MonoBehaviour
{
public GameObject explosionPrefab;
public float explosionDamageAmount = 1000;
public float explosionDamageRadius = 5;
public float particleSystemMultiplier = 1;
2020-12-20 20:53:55 +00:00
public float speed = 10;
2020-12-26 19:07:05 +00:00
public float acceleration = 4;
public float maxSpeed = 50;
2020-12-21 22:27:00 +00:00
public float rotationSpeed = 180;
2020-12-20 20:53:55 +00:00
public float lifeTime = 30;
2020-12-21 01:10:26 +00:00
[SerializeField] private Transform m_modelAttachTransform = null;
2020-12-20 20:51:59 +00:00
2020-12-20 20:53:55 +00:00
private bool m_alreadyExploded = false;
2020-12-26 17:45:42 +00:00
public Rigidbody RigidBody { get; private set; }
public AudioSource AudioSource { get; private set; }
2020-12-20 20:51:59 +00:00
2021-02-19 21:08:37 +00:00
public Ped ShooterPed { get; private set; }
public Player ShooterPlayer { get; private set; }
2020-12-20 20:51:59 +00:00
2020-12-20 20:53:55 +00:00
public static Projectile Create(
GameObject prefab,
Vector3 position,
Quaternion rotation,
Ped shooterPed)
2020-12-20 20:53:55 +00:00
{
2020-12-26 17:45:42 +00:00
NetStatus.ThrowIfNotOnServer();
2020-12-20 20:53:55 +00:00
var go = Instantiate(prefab, position, rotation);
2020-12-20 20:51:59 +00:00
2020-12-20 20:53:55 +00:00
var projectile = go.GetComponentOrThrow<Projectile>();
2021-02-19 21:08:37 +00:00
projectile.ShooterPed = shooterPed;
projectile.ShooterPlayer = shooterPed != null ? shooterPed.PlayerOwner : null;
2020-12-20 20:51:59 +00:00
if (shooterPed != null)
{
2020-12-22 01:24:00 +00:00
var projectileCollider = projectile.GetComponentOrThrow<Collider>();
var pedColliders = shooterPed.GetComponentsInChildren<Collider>();
foreach (var pedCollider in pedColliders)
{
Physics.IgnoreCollision(pedCollider, projectileCollider);
}
}
2020-12-26 22:57:51 +00:00
NetManager.Spawn(go);
2020-12-20 20:53:55 +00:00
return projectile;
}
2020-12-20 20:51:59 +00:00
2020-12-20 20:53:55 +00:00
void Awake()
{
2020-12-26 17:45:42 +00:00
this.RigidBody = this.GetComponentOrThrow<Rigidbody>();
this.AudioSource = this.GetComponentOrThrow<AudioSource>();
2020-12-20 20:51:59 +00:00
2020-12-26 17:45:42 +00:00
if (NetStatus.IsServer)
Object.Destroy(this.gameObject, this.lifeTime);
if (Weapon.ProjectileSound != null)
{
this.AudioSource.clip = Weapon.ProjectileSound;
this.AudioSource.Play();
}
if (Weapon.ProjectileModel != null)
{
Weapon.ProjectileModel.AttachFrames(m_modelAttachTransform, MaterialFlags.Default);
}
2020-12-26 17:45:42 +00:00
this.RigidBody.velocity = this.transform.forward * this.speed;
if (!NetStatus.IsServer)
{
// disable all colliders
var colliders = this.gameObject.GetComponentsInChildren<Collider>();
foreach (var c in colliders)
{
c.enabled = false;
}
}
2020-12-20 20:53:55 +00:00
}
2020-12-20 20:51:59 +00:00
2020-12-21 22:27:00 +00:00
private void Update()
{
2020-12-26 19:07:05 +00:00
// rotate model
2020-12-21 22:27:00 +00:00
float delta = this.rotationSpeed * Time.deltaTime * Random.Range (0.75f, 1.25f);
m_modelAttachTransform.rotation *= Quaternion.AngleAxis (delta, Vector3.forward);
2020-12-26 19:07:05 +00:00
// accelerate projectile
Vector3 currentVectorSpeed = this.RigidBody.velocity;
float currentSpeed = currentVectorSpeed.magnitude;
if (currentSpeed < this.maxSpeed)
{
float newSpeed = currentSpeed + this.acceleration * Time.deltaTime;
this.RigidBody.velocity = currentVectorSpeed.normalized * newSpeed;
}
2020-12-21 22:27:00 +00:00
}
2020-12-20 20:53:55 +00:00
private void OnCollisionEnter(Collision other)
{
2020-12-26 17:45:42 +00:00
if (!NetStatus.IsServer)
return;
2020-12-20 20:53:55 +00:00
if (m_alreadyExploded)
return;
2020-12-20 20:51:59 +00:00
2020-12-20 20:53:55 +00:00
m_alreadyExploded = true;
2020-12-20 20:51:59 +00:00
2020-12-20 20:53:55 +00:00
Object.Destroy(this.gameObject);
2020-12-20 20:51:59 +00:00
2020-12-20 20:53:55 +00:00
Vector3 contactPoint = other.contacts[0].point;
2020-12-20 20:51:59 +00:00
2020-12-20 20:53:55 +00:00
// inflict damage to nearby objects
Damageable.InflictDamageToObjectsInArea(
contactPoint,
this.explosionDamageRadius,
this.explosionDamageAmount,
VehicleManager.Instance.explosionDamageOverDistanceCurve,
2021-02-19 21:08:37 +00:00
DamageType.Explosion,
this.ShooterPed,
this.ShooterPlayer);
2020-12-20 20:51:59 +00:00
2020-12-20 20:53:55 +00:00
// create explosion - this includes effects, physics force, sound
2020-12-20 20:51:59 +00:00
2020-12-20 20:53:55 +00:00
GameObject explosionGo = Object.Instantiate(
this.explosionPrefab,
contactPoint,
this.transform.rotation);
2020-12-20 20:51:59 +00:00
var psm = explosionGo.GetComponentOrThrow<ParticleSystemMultiplier>();
psm.multiplier = this.particleSystemMultiplier;
2020-12-26 17:45:42 +00:00
NetManager.Spawn(explosionGo);
2020-12-20 20:51:59 +00:00
2020-12-20 20:53:55 +00:00
// assign explosion sound
F.RunExceptionSafe(() => Vehicle.AssignExplosionSound(explosionGo));
2020-12-20 20:51:59 +00:00
2020-12-20 20:53:55 +00:00
}
2020-12-20 20:51:59 +00:00
}
}