243 lines
5.9 KiB
C#
243 lines
5.9 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using DarkTonic.MasterAudio;
|
|
using DragonLi.Core;
|
|
using Mirror;
|
|
using UnityEngine;
|
|
using UnityEngine.XR;
|
|
|
|
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;
|
|
|
|
[SyncVar]
|
|
public float bullet_attack = 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("开枪音效")]
|
|
[SoundGroup]
|
|
public string shotSound;
|
|
|
|
[Header("弹壳创建位置")]
|
|
public Transform shellPoint;
|
|
[Header("弹壳预制体")]
|
|
public GameObject shell_prefab;
|
|
[Header("弹壳朝向")]
|
|
public float shell_outforce;
|
|
[Header("弹壳销毁时间")]
|
|
public float shell_despawn_delay;
|
|
|
|
|
|
[NonSerialized]
|
|
public InputDevice leftHandDevice;
|
|
[NonSerialized]
|
|
public InputDevice rightHandDevice;
|
|
/// <summary>
|
|
/// If time.time is bigger than this value, so the gun can shoot
|
|
/// </summary>
|
|
[NonSerialized]
|
|
[SyncVar]
|
|
public float nextShootTime = 0f;
|
|
|
|
private float _shootInterval = 0f;
|
|
|
|
public int curOwnerIndex;
|
|
|
|
public void Awake()
|
|
{
|
|
_shootInterval = 1f / shootRate;
|
|
bullet_amount = -999;
|
|
}
|
|
|
|
public virtual void Start()
|
|
{
|
|
|
|
#if !UNITY_EDITOR
|
|
leftHandDevice = InputDevices.GetDeviceAtXRNode(XRNode.LeftHand);
|
|
rightHandDevice = InputDevices.GetDeviceAtXRNode(XRNode.RightHand);
|
|
#endif
|
|
}
|
|
|
|
[Server]
|
|
public void Shoot()
|
|
{
|
|
Shoot(curOwnerIndex);
|
|
}
|
|
|
|
[Server]
|
|
public bool Shoot(int ownerIndex)
|
|
{
|
|
return Shoot(bulletPoint.position + bulletPoint.forward * 1f, ownerIndex);
|
|
}
|
|
|
|
[Server]
|
|
public virtual bool Shoot(Vector3 target, int ownerIndex)
|
|
{
|
|
// 弹量不够
|
|
if (bullet_amount <= 0 && bullet_amount != -999)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// 未冷却
|
|
if (nextShootTime > Time.time)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (bullet_amount > 0&& GameManager.Ins.gameState==GameState.Playing)
|
|
{
|
|
bullet_amount--;
|
|
EventDispatcher.TriggerEvent("UserGun", bullet_amount);
|
|
}
|
|
if (bullet_amount <= 0 && bullet_amount != -999)
|
|
{
|
|
LauncherEmpty();
|
|
}
|
|
|
|
for (int i = 0; i < bullet_per_shoot; i++)
|
|
{
|
|
SpawnBullet(ownerIndex, target - bulletPoint.position);
|
|
}
|
|
//GameManager.Ins.PlaySound3DRPC(shotSound,transform,false);
|
|
SpawnShell();
|
|
SpawnMuzzle();
|
|
nextShootTime = Time.time + _shootInterval;
|
|
return true;
|
|
}
|
|
|
|
[TargetRpc]
|
|
public void LauncherEmpty()
|
|
{
|
|
GameLocal.Ins.self.DelWeapon();
|
|
}
|
|
|
|
[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, recoil);
|
|
return val;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 填充子弹
|
|
/// </summary>
|
|
public void StuffBullet(int amount)
|
|
{
|
|
if (amount < 0 && amount != -999)
|
|
{
|
|
return;
|
|
}
|
|
bullet_amount = amount;
|
|
}
|
|
|
|
public void SetBulletAmount(int amount,int ownerIndex)
|
|
{
|
|
if (amount < 0 && amount != -999)
|
|
{
|
|
return;
|
|
}
|
|
curOwnerIndex = ownerIndex;
|
|
GunInfo gunInfo = GameManager.Ins.GunInfos[type];
|
|
shootRate = gunInfo.ShootRate;
|
|
recoil = gunInfo.Recoil;
|
|
_shootInterval = 1f / shootRate;
|
|
bullet_amount = amount;
|
|
}
|
|
|
|
[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);
|
|
}
|
|
}
|
|
|
|
|
|
}
|