241 lines
5.8 KiB
C#
241 lines
5.8 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using DragonLi.Core;
|
|
using Mirror;
|
|
using UnityEngine;
|
|
|
|
public class Launcher : NetworkBehaviour
|
|
{
|
|
[Header("枪械类型")]
|
|
#if UNITY_EDITOR
|
|
[DisplayOnly]
|
|
#endif
|
|
[SyncVar]
|
|
public GunType type;
|
|
|
|
[Header("枪械射速(s)")]
|
|
#if UNITY_EDITOR
|
|
[DisplayOnly]
|
|
#endif
|
|
public float shootRate = 10f;
|
|
|
|
[Header("枪械后坐力")]
|
|
#if UNITY_EDITOR
|
|
[DisplayOnly]
|
|
#endif
|
|
public float recoil = 100f;
|
|
|
|
[Header("子弹创建位置")]
|
|
public Transform bulletPoint;
|
|
|
|
[Header("子弹预制体")]
|
|
public GameObject bullet_prefab;
|
|
|
|
[Header("子弹数量")]
|
|
#if UNITY_EDITOR
|
|
[DisplayOnly]
|
|
#endif
|
|
[SyncVar]
|
|
public float bullet_amount = 0f;
|
|
|
|
[Header("枪械持有位置")]
|
|
#if UNITY_EDITOR
|
|
[DisplayOnly]
|
|
#endif
|
|
[SyncVar]
|
|
public HandType hand = HandType.Right;
|
|
|
|
[Header("子弹每次射击量")]
|
|
#if UNITY_EDITOR
|
|
[DisplayOnly]
|
|
#endif
|
|
public int bullet_per_shoot = 1;
|
|
|
|
[Header("开火创建位置")]
|
|
public Transform muzzlePoint;
|
|
[Header("开火预制体")]
|
|
public GameObject muzzle_prefab;
|
|
[Header("开火销毁时间")]
|
|
public float muzzle_despawn_time = 1;
|
|
|
|
[Header("弹壳创建位置")]
|
|
public Transform shellPoint;
|
|
[Header("弹壳预制体")]
|
|
public GameObject shell_prefab;
|
|
[Header("弹壳朝向")]
|
|
public float shell_outforce;
|
|
[Header("弹壳销毁时间")]
|
|
public float shell_despawn_delay;
|
|
|
|
/// <summary>
|
|
/// If time.time is bigger than this value, so the gun can shoot
|
|
/// </summary>
|
|
[NonSerialized]
|
|
[SyncVar]
|
|
public float nextShootTime = 0f;
|
|
|
|
/// <summary>
|
|
/// 上子弹时间
|
|
/// </summary>
|
|
[NonSerialized] [SyncVar]
|
|
public float waitBulletTime;
|
|
|
|
/// <summary>
|
|
/// 持续时间
|
|
/// </summary>
|
|
public float userTime;
|
|
|
|
private float _curWaitBulletTime = 0f;
|
|
|
|
private bool _isWaiBulletting = false;
|
|
|
|
//private float _shootInterval = 0f;
|
|
|
|
public void Awake()
|
|
{
|
|
bullet_amount = 0;
|
|
}
|
|
|
|
[Server]
|
|
public bool Shoot()
|
|
{
|
|
return Shoot(-1);
|
|
}
|
|
|
|
[Server]
|
|
public bool Shoot(int ownerIndex)
|
|
{
|
|
return Shoot(bulletPoint.position + bulletPoint.forward * 1f, ownerIndex);
|
|
}
|
|
|
|
[Server]
|
|
public virtual bool Shoot(Vector3 target, int ownerIndex)
|
|
{
|
|
|
|
// 未冷却
|
|
if (nextShootTime > Time.time)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (bullet_amount > 0)
|
|
{
|
|
bullet_amount--;
|
|
}
|
|
// 弹量不够
|
|
if (bullet_amount <= 0&&!_isWaiBulletting&& waitBulletTime>0)
|
|
{
|
|
_isWaiBulletting = true;
|
|
PlayWaitBullet();
|
|
return false;
|
|
}
|
|
|
|
if (_isWaiBulletting)
|
|
{
|
|
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
|
|
{
|
|
_isWaiBulletting = false;
|
|
StopBullet();
|
|
SetBulletAmount(GameManager.Ins.GunInfos[type][1].BulletAmount);
|
|
},waitBulletTime);
|
|
return false;
|
|
}
|
|
|
|
if (bullet_amount <= 0 && bullet_amount != -999)
|
|
{
|
|
// LauncherEmpty();
|
|
}
|
|
|
|
for (int i = 0; i < bullet_per_shoot; i++)
|
|
{
|
|
SpawnBullet(ownerIndex, target - bulletPoint.position);
|
|
}
|
|
|
|
SpawnShell();
|
|
SpawnMuzzle();
|
|
nextShootTime = Time.time + shootRate;
|
|
return true;
|
|
}
|
|
|
|
// [TargetRpc]
|
|
// public void LauncherEmpty()
|
|
// {
|
|
// GameInit.Ins.self.DelWeapon();
|
|
// }
|
|
|
|
public int x = 5;
|
|
[Server]
|
|
public virtual Transform SpawnBullet(int ownerIndex, Vector3 direction)
|
|
{
|
|
GameObject bullet = Instantiate(bullet_prefab, bulletPoint.position, bulletPoint.rotation);
|
|
Transform val = bullet.transform;
|
|
NetworkServer.Spawn(val.gameObject);
|
|
Bullet component = val.GetComponent<Bullet>();
|
|
component.OnSpawn(ownerIndex, direction, shootRate,userTime);
|
|
return val;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 填充子弹
|
|
/// </summary>
|
|
public void StuffBullet(int amount)
|
|
{
|
|
if (amount < 0 && amount != -999)
|
|
{
|
|
return;
|
|
}
|
|
bullet_amount = amount;
|
|
GunInfo info = GameManager.Ins.GunInfos[type][1];
|
|
userTime = info.Time;
|
|
}
|
|
|
|
public void SetBulletAmount(int amount)
|
|
{
|
|
bullet_amount = amount;
|
|
}
|
|
|
|
public virtual void PlayWaitBullet(){}
|
|
|
|
public virtual void StopBullet(){}
|
|
|
|
[Server]
|
|
protected void SpawnMuzzle()
|
|
{
|
|
if (muzzle_prefab != null)
|
|
{
|
|
Transform val = Instantiate(muzzle_prefab, muzzlePoint.position, new Quaternion(0, 0, 0, 0)).transform;
|
|
val.forward = muzzlePoint.forward;
|
|
NetworkServer.Spawn(val.gameObject);
|
|
if (val == null)
|
|
{
|
|
this.LogEditorOnly("Failed to spawn muzzle");
|
|
return;
|
|
}
|
|
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
|
|
{
|
|
NetworkServer.Destroy(val.gameObject);
|
|
}, muzzle_despawn_time);
|
|
}
|
|
}
|
|
|
|
[Server]
|
|
protected void SpawnShell()
|
|
{
|
|
if (shell_prefab != null && shellPoint != null)
|
|
{
|
|
Transform val = Instantiate(shell_prefab, shellPoint.position, Quaternion.Euler(UnityEngine.Random.insideUnitSphere * 360f)).transform;
|
|
NetworkServer.Spawn(val.gameObject);
|
|
Rigidbody component = val.GetComponent<Rigidbody>();
|
|
if (component != null)
|
|
{
|
|
component.velocity = shellPoint.forward * shell_outforce;
|
|
}
|
|
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
|
|
{
|
|
NetworkServer.Destroy(val.gameObject);
|
|
}, shell_despawn_delay);
|
|
}
|
|
}
|
|
}
|