fix:修改敌人流程,添加敌人枚举
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using BehaviorDesigner.Runtime;
|
||||
using DarkTonic.MasterAudio;
|
||||
using DragonLi.Core;
|
||||
using Mirror;
|
||||
using Pathfinding;
|
||||
@@ -89,6 +90,9 @@ public class PlayerAI : Agent
|
||||
private bool introPlayed = false;
|
||||
private bool isAttacking = false;
|
||||
private bool isDead = false;
|
||||
|
||||
public float killEnemyTime = 10;
|
||||
public float curKillEnemyTime;
|
||||
void Awake()
|
||||
{
|
||||
InitAnimator();
|
||||
@@ -140,7 +144,8 @@ public class PlayerAI : Agent
|
||||
originHealth = 10;
|
||||
aiPath.enabled = true;
|
||||
aiPath.maxSpeed = speed;
|
||||
|
||||
killEnemyTime = 10;
|
||||
curKillEnemyTime = killEnemyTime;
|
||||
// 初始设置(server)
|
||||
if (isServer)
|
||||
{
|
||||
@@ -177,6 +182,17 @@ public class PlayerAI : Agent
|
||||
UpdateAnimatorValues(RigidbodyComponent.velocity);
|
||||
}
|
||||
UpdateRotation();
|
||||
|
||||
if (state == (PlayerAIState)3)
|
||||
{
|
||||
curKillEnemyTime-=Time.deltaTime;
|
||||
if (curKillEnemyTime <= 0)
|
||||
curKillEnemyTime = killEnemyTime;
|
||||
if (behaviorTree != null && behaviorTree.enabled)
|
||||
{
|
||||
behaviorTree.SetVariable("CountdownTime",(SharedFloat)curKillEnemyTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -208,10 +224,22 @@ public class PlayerAI : Agent
|
||||
|
||||
public virtual void UpdateRotation()
|
||||
{
|
||||
if (behaviorTree != null)
|
||||
{
|
||||
target=(GameObject)behaviorTree.GetVariable("target").GetValue();
|
||||
}
|
||||
if (target != null)
|
||||
{
|
||||
transform.rotation = Quaternion.Lerp(transform.rotation, Quaternion.LookRotation(target.transform.position.ReflectVectorXOZ() - transform.position), Time.deltaTime * 10f);
|
||||
}
|
||||
else
|
||||
{
|
||||
Vector3 targetPos = (Vector3)behaviorTree.GetVariable("targetPos").GetValue();
|
||||
if (targetPos != Vector3.zero)
|
||||
{
|
||||
transform.rotation = Quaternion.Lerp(transform.rotation, Quaternion.LookRotation(new Vector3(targetPos.x,transform.position.y,targetPos.z) - transform.position), Time.deltaTime * 10f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void LateUpdate()
|
||||
@@ -226,10 +254,28 @@ public class PlayerAI : Agent
|
||||
if (!isServer) return; // 攻击判定/伤害应由 Server 执行(Host 权威)
|
||||
AnimatorComponent.SetInteger("state",4);
|
||||
//调用枪械开枪脚本
|
||||
//gun.AiShoot();
|
||||
if (behaviorTree != null)
|
||||
{
|
||||
target=(GameObject)behaviorTree.GetVariable("target").GetValue();
|
||||
Vector3 targetPos = (Vector3)behaviorTree.GetVariable("targetPos").GetValue();
|
||||
if (target == null)
|
||||
{
|
||||
if (targetPos != Vector3.zero)
|
||||
{
|
||||
gun.EnemyShoot(targetPos);
|
||||
}
|
||||
else
|
||||
{
|
||||
gun.EnemyShoot(gun.showPos.forward);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gun.EnemyShoot(target.transform.position);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public virtual void StopAttack()
|
||||
{
|
||||
if (!isServer) return; // 攻击判定/伤害应由 Server 执行(Host 权威)
|
||||
@@ -243,11 +289,19 @@ public class PlayerAI : Agent
|
||||
|
||||
public void ChangeKillEnemyTime()
|
||||
{
|
||||
behaviorTree.SetVariable("CountdownTime",(SharedFloat)10f);
|
||||
curKillEnemyTime = killEnemyTime;
|
||||
}
|
||||
|
||||
public void KillEnemyEvent()
|
||||
{
|
||||
//gun.Shoot()
|
||||
}
|
||||
|
||||
[ClientRpc]
|
||||
public void PlaySound3DRPC(string sound,bool isStop)
|
||||
{
|
||||
if(isStop)
|
||||
MasterAudio.StopAllSoundsOfTransform(transform);
|
||||
MasterAudio.PlaySound3DAtTransform(sound, transform);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -174,10 +174,11 @@ public class Agent : NetworkBehaviour, IDamagable
|
||||
// Debug.Log("造成伤害" + value);
|
||||
if (IsAlive)
|
||||
{
|
||||
Die(info, _sender);
|
||||
Health -= OnReceiveDamage(value, info, _sender);
|
||||
if (!IsAlive)
|
||||
{
|
||||
Die(info, _sender);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,11 +110,16 @@ public class Actions
|
||||
|
||||
public class EnemyAttack : Action
|
||||
{
|
||||
public SharedVector3 targetPos;
|
||||
public SharedGameObject target;
|
||||
public override TaskStatus OnUpdate()
|
||||
{
|
||||
Enemy enemy = transform.GetComponent<Enemy>();
|
||||
if (enemy == null) return TaskStatus.Failure;
|
||||
enemy.DoAttack();
|
||||
Vector3 curTargetPos=targetPos.Value;
|
||||
if (target.Value != null)
|
||||
curTargetPos = target.Value.transform.position;
|
||||
enemy.DoAttack(curTargetPos);
|
||||
return TaskStatus.Success;
|
||||
}
|
||||
}
|
||||
@@ -248,7 +253,6 @@ public class Actions
|
||||
/// </summary>
|
||||
public class TeammateSupportKill : Action
|
||||
{
|
||||
public SharedFloat CountdownTime; // 倒计时秒数
|
||||
public SharedGameObject Target;
|
||||
public override TaskStatus OnUpdate()
|
||||
{
|
||||
@@ -257,17 +261,17 @@ public class Actions
|
||||
if (enemy != null)
|
||||
{
|
||||
var enemyComponent = enemy.GetComponent<Enemy>();
|
||||
Target.Value = enemyComponent.gameObject;
|
||||
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
|
||||
{
|
||||
if (enemyComponent != null && enemyComponent.state != EnemyState.Die)
|
||||
{
|
||||
enemyComponent.Die(transform.position,null);
|
||||
Debug.Log($"{gameObject.name} 倒计时结束,击杀一名敌人!");
|
||||
Debug.LogError($"{gameObject.name} 倒计时结束,击杀一名敌人!");
|
||||
}
|
||||
}, 3f);
|
||||
Target = enemy;
|
||||
Target.Value = enemy;
|
||||
}
|
||||
CountdownTime.Value=10;
|
||||
return TaskStatus.Success;
|
||||
}
|
||||
}
|
||||
|
||||
11
Assets/_DefendNJ/Scripts/Bullets/EnemyMortarBullet.cs
Normal file
11
Assets/_DefendNJ/Scripts/Bullets/EnemyMortarBullet.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class EnemyMortarBullet : MRNetworkManager
|
||||
{
|
||||
public void Init()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
11
Assets/_DefendNJ/Scripts/Bullets/EnemyMortarBullet.cs.meta
Normal file
11
Assets/_DefendNJ/Scripts/Bullets/EnemyMortarBullet.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: eef80bc3e97a5864a8f8ab7645864725
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -2,11 +2,15 @@ using static XPlugin.Data.JsonLiteDB.JsonLiteDB;
|
||||
|
||||
public enum EnemyType
|
||||
{
|
||||
ThinZombie=0,
|
||||
FatZombie=1,
|
||||
ExplosionDog=2,
|
||||
RunZombie=3,
|
||||
ZombieBoss = 4,
|
||||
Ordinary=3,//步兵
|
||||
Sniper=4,//狙击手
|
||||
Mortar=5,//迫击炮兵
|
||||
Riflemen=6,//机枪兵
|
||||
Charge = 7,//冲锋枪兵
|
||||
Grenade=8,//手雷兵
|
||||
Virus=9,//生化兵
|
||||
Tank=10,//坦克
|
||||
Commander,//指挥官
|
||||
}
|
||||
|
||||
public class EnemyInfo
|
||||
|
||||
@@ -11,6 +11,7 @@ using BehaviorDesigner.Runtime.Tasks;
|
||||
using Animancer; // Animancer 支持
|
||||
using DarkTonic.MasterAudio;
|
||||
using DragonLi.Frame;
|
||||
using EPOOutline;
|
||||
|
||||
public enum EnemyState
|
||||
{
|
||||
@@ -52,11 +53,7 @@ public class Enemy : Agent
|
||||
|
||||
public Transform weakness;
|
||||
|
||||
[Header("死亡音效")]
|
||||
[SoundGroup]
|
||||
public string dieSound;
|
||||
|
||||
public GameObject explosion_prefab;
|
||||
public Outlinable outline;
|
||||
|
||||
[Header("编号")]
|
||||
[SyncVar]
|
||||
@@ -138,21 +135,20 @@ public class Enemy : Agent
|
||||
}
|
||||
|
||||
[Server]
|
||||
public virtual void OnSpawn(int id, int type, int lvl,Vector3 targetPos)
|
||||
public virtual void OnSpawn(int id, int typeIndex, int lvl,Vector3 targetPos)
|
||||
{
|
||||
base.OnSpawn();
|
||||
this.id = id;
|
||||
//this.type = type;
|
||||
type = (EnemyType)typeIndex;
|
||||
state = EnemyState.Borning;
|
||||
this.lvl = lvl;
|
||||
AiInfo enemyInfo = GameManager.Ins.AiInfos[type];
|
||||
speed = 1;
|
||||
atk = 1;
|
||||
health = 1*GameManager.Ins.players.Count;
|
||||
originHealth = 1*GameManager.Ins.players.Count;
|
||||
aiPath.enabled = true;
|
||||
aiPath.maxSpeed = speed;
|
||||
|
||||
if(outline !=null)outline.enabled = false;
|
||||
GameManager.Ins.CreateEnemyUI(this);
|
||||
// 初始设置(server)
|
||||
if (isServer)
|
||||
@@ -222,10 +218,23 @@ public class Enemy : Agent
|
||||
|
||||
public virtual void UpdateRotation()
|
||||
{
|
||||
if (behaviorTree != null)
|
||||
{
|
||||
target=(GameObject)behaviorTree.GetVariable("target").GetValue();
|
||||
|
||||
}
|
||||
if (target != null)
|
||||
{
|
||||
transform.rotation = Quaternion.Lerp(transform.rotation, Quaternion.LookRotation(target.transform.position.ReflectVectorXOZ() - transform.position), Time.deltaTime * 10f);
|
||||
}
|
||||
else
|
||||
{
|
||||
Vector3 targetPos = (Vector3)behaviorTree.GetVariable("targetPos").GetValue();
|
||||
if (targetPos != Vector3.zero)
|
||||
{
|
||||
transform.rotation = Quaternion.Lerp(transform.rotation, Quaternion.LookRotation(new Vector3(targetPos.x,transform.position.y,targetPos.z) - transform.position), Time.deltaTime * 10f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void LateUpdate()
|
||||
@@ -337,7 +346,7 @@ public class Enemy : Agent
|
||||
if (behaviorTree != null) behaviorTree.enabled = false;
|
||||
if (aiPath != null) aiPath.enabled = false;
|
||||
if (rvoController != null) rvoController.enabled = false;
|
||||
|
||||
if(outline!=null) outline.enabled = false;
|
||||
// 在 server 上播放死亡并通知客户端
|
||||
Vector3 hitPoint = transform.position;
|
||||
if (info is Vector3) hitPoint = (Vector3)info;
|
||||
@@ -392,11 +401,10 @@ public class Enemy : Agent
|
||||
/// 发起一次攻击(播放攻击动画,Server 上触发伤害判定/事件)
|
||||
/// - BehaviorTree 在 host 上执行时应调用 DoAttack(),并在动画的事件帧调用真正的伤害函数(或在 DoAttackCoroutine 中等待到事件再次调用)
|
||||
/// </summary>
|
||||
public virtual void DoAttack()
|
||||
public virtual void DoAttack(Vector3 target)
|
||||
{
|
||||
if (!isServer) return; // 攻击判定/伤害应由 Server 执行(Host 权威)
|
||||
AnimatorComponent.SetInteger("state",1);
|
||||
//ApplyAttackDamage();
|
||||
}
|
||||
public virtual void StopAttack()
|
||||
{
|
||||
|
||||
@@ -4,8 +4,12 @@ using UnityEngine;
|
||||
|
||||
public class Enemy1 : Enemy
|
||||
{
|
||||
public override void DoAttack()
|
||||
public GunAiComponent gun;
|
||||
public EnemyAIAnimator enemyAIAnimator;
|
||||
|
||||
public override void DoAttack(Vector3 targetPos)
|
||||
{
|
||||
base.DoAttack();
|
||||
base.DoAttack(targetPos);
|
||||
gun.EnemyShoot(targetPos);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,14 +29,7 @@ public class EnemyUI : NetworkBehaviour
|
||||
// 0.2秒后展示ui,防止在原点出现
|
||||
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
|
||||
{
|
||||
if (_enemy.type == EnemyType.ZombieBoss)
|
||||
{
|
||||
UIStateChange(2);
|
||||
}
|
||||
else
|
||||
{
|
||||
UIStateChange(1);
|
||||
}
|
||||
UIStateChange(1);
|
||||
}, 0.2f);
|
||||
}
|
||||
|
||||
@@ -83,7 +76,7 @@ public class EnemyUI : NetworkBehaviour
|
||||
[ClientRpc]
|
||||
public void HpChange(EnemyType type, float currentBlood, float totalBlood)
|
||||
{
|
||||
float allLength = type == EnemyType.ZombieBoss ? 3f : 1.58f;
|
||||
float allLength = 1.58f;
|
||||
float lastValue = _lastHp / totalBlood;
|
||||
float value = currentBlood / totalBlood;
|
||||
blood2[0].size = new Vector2(value * allLength, 0.14f);
|
||||
|
||||
@@ -67,7 +67,9 @@ public class GameLocal : MonoBehaviour
|
||||
public Transform[] playerAiPos;
|
||||
public Transform[] playerAiEndPos;
|
||||
public Transform[] gunPropPos;
|
||||
|
||||
public Transform[] mortarPos;
|
||||
public Transform insMortarPos;
|
||||
|
||||
public Transform doorPos;
|
||||
void Start()
|
||||
{
|
||||
|
||||
@@ -1,19 +1,216 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using DragonLi.Core;
|
||||
using DragonLi.Frame;
|
||||
using EPOOutline;
|
||||
using Mirror;
|
||||
using UnityEngine;
|
||||
|
||||
public class GunAiComponent : Launcher
|
||||
public class GunAiComponent : MonoBehaviour
|
||||
{
|
||||
public override void Start()
|
||||
[Header("References")]
|
||||
public Transform showPos; // 子弹和火光生成位置
|
||||
public GameObject bulletPre; // 子弹预制体
|
||||
public GameObject firePre; // 火焰特效预制体 (Muzzle Flash)
|
||||
|
||||
[Header("Settings")]
|
||||
[Range(0f, 1f)]
|
||||
public float hpPercentage = 0.1f; // 本组件血量占父体总血量的比例
|
||||
public float fireInterval = 0.5f; // 射击间隔 (秒)
|
||||
public float bulletSpeed = 20f; // 子弹飞行速度
|
||||
public float aimRadius = 1.5f; // 以玩家为中心的随机子弹目标半径
|
||||
public bool isLookPlayer;
|
||||
|
||||
public bool isQteComponent;//是否是Qte组件
|
||||
|
||||
private bool _isStartLookPlayer;
|
||||
|
||||
public bool isDead;
|
||||
public bool isFire;
|
||||
|
||||
private float _nextShootTime;
|
||||
//private Outlinable outlinable;
|
||||
|
||||
public Transform target;
|
||||
|
||||
void Awake()
|
||||
{
|
||||
|
||||
// outlinable = GetComponent<Outlinable>();
|
||||
// if (outlinable != null) outlinable.enabled = false;
|
||||
}
|
||||
|
||||
public void AiShoot()
|
||||
void Start()
|
||||
{
|
||||
SpawnBullet(-1, (bulletPoint.position + bulletPoint.forward * 1f) - bulletPoint.position);
|
||||
SpawnShell();
|
||||
SpawnMuzzle();
|
||||
_nextShootTime = Time.time;
|
||||
isDead = false;
|
||||
isFire = false;
|
||||
_isStartLookPlayer = false;
|
||||
}
|
||||
|
||||
public void Play()
|
||||
{
|
||||
if (isDead) return;
|
||||
isFire = true;
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
isFire = false;
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
|
||||
if ( isDead||!isFire) return;
|
||||
// if (isLookPlayer || _isStartLookPlayer)
|
||||
// {
|
||||
// // 朝向玩家
|
||||
// Vector3 dir = (target.position - transform.position).normalized;
|
||||
// transform.rotation = Quaternion.LookRotation(dir);
|
||||
// }
|
||||
|
||||
// 射击控制
|
||||
// if (Time.time >= _nextShootTime)
|
||||
// {
|
||||
// // 计算子弹目标点:以玩家位置为中心的随机范围
|
||||
// Vector2 randCircle = Random.insideUnitCircle * aimRadius;
|
||||
// Vector3 targetPos = target.position + new Vector3(randCircle.x, 0, randCircle.y);
|
||||
// EnemyShoot(targetPos);
|
||||
// _nextShootTime = Time.time + fireInterval;
|
||||
// }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 外部调用射击
|
||||
/// </summary>
|
||||
public void EnemyShoot(Vector3 targetPos)
|
||||
{
|
||||
if (isDead) return;
|
||||
CmdFire(targetPos);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 执行射击逻辑
|
||||
/// </summary>
|
||||
private void CmdFire(Vector3 targetPos)
|
||||
{
|
||||
// 火光特效
|
||||
if (firePre != null && showPos != null)
|
||||
{
|
||||
GameObject fire=Instantiate(firePre, showPos.position, showPos.rotation, transform);
|
||||
NetworkServer.Spawn(fire);
|
||||
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
|
||||
{
|
||||
NetworkServer.Destroy(fire);
|
||||
}, 1f);
|
||||
}
|
||||
|
||||
if (bulletPre == null || showPos == null )
|
||||
return;
|
||||
|
||||
// 生成子弹
|
||||
GameObject bullet = Instantiate(bulletPre, showPos.position, Quaternion.identity);
|
||||
NetworkServer.Spawn(bullet);
|
||||
bullet.SetActive(true);
|
||||
if (bullet.GetComponent<Bullet>())
|
||||
{
|
||||
bullet.GetComponent<Bullet>().OnSpawn(-1,targetPos,20);
|
||||
}
|
||||
Rigidbody rb = bullet.GetComponent<Rigidbody>();
|
||||
if (rb != null)
|
||||
{
|
||||
// 忽略 Y 轴,只计算水平面方向
|
||||
Vector3 fixedTargetPos = new Vector3(targetPos.x, showPos.position.y, targetPos.z);
|
||||
Vector3 shootDir = (fixedTargetPos - showPos.position).normalized;
|
||||
|
||||
rb.velocity = shootDir * bulletSpeed;
|
||||
}
|
||||
|
||||
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
|
||||
{
|
||||
NetworkServer.Destroy(bullet);
|
||||
}, 5f);
|
||||
// 自动销毁子弹,避免泄漏
|
||||
//Destroy(bullet, 5f);
|
||||
}
|
||||
|
||||
|
||||
public void StatQteAttack()
|
||||
{
|
||||
_isStartLookPlayer = true;
|
||||
}
|
||||
|
||||
public void QteAttack(Vector3 targetPos)
|
||||
{
|
||||
EnemyShoot(targetPos);
|
||||
}
|
||||
|
||||
public void StopQteAttack()
|
||||
{
|
||||
_isStartLookPlayer = false;
|
||||
}
|
||||
|
||||
public float arcHeight = 2f; // 抛物线最高点高度
|
||||
public float flightTime = 1.2f; // 导弹飞行时长
|
||||
//抛物线攻击
|
||||
// public void ShootMissile(Vector3 from, Vector3 to, float flightTime = 1.2f)
|
||||
// {
|
||||
// GameObject m = Instantiate(bulletPre, from, Quaternion.identity);
|
||||
// LeviathanBullet arc = m.GetComponent<LeviathanBullet>();
|
||||
// arc.Initialize(from, to, flightTime);
|
||||
// }
|
||||
//
|
||||
// //弧度攻击
|
||||
// public void FireThreeMissiles(Vector3 from, Vector3 to)
|
||||
// {
|
||||
// var go = Instantiate(bulletPre, from, Quaternion.identity);
|
||||
// var sm = go.GetComponent<LeviathanBullet>();
|
||||
// sm.Initialize(
|
||||
// startPos: from,
|
||||
// targetPos: to,
|
||||
// flightTime: flightTime,
|
||||
// arcHeight: arcHeight
|
||||
// );
|
||||
// }
|
||||
//
|
||||
// //激光攻击
|
||||
// public IEnumerator FireQteMissiles()
|
||||
// {
|
||||
// Debug.LogError("显示激光");
|
||||
// var go = Instantiate(bulletPre, showPos.position, Quaternion.identity);
|
||||
// LineRenderer lr = go.GetComponent<LineRenderer>();
|
||||
// if (lr != null)
|
||||
// {
|
||||
// lr.SetPosition(0, showPos.position);
|
||||
// lr.SetPosition(1, GameManager.Ins.player.transform.position);
|
||||
// }
|
||||
// yield return new WaitForSeconds(1f);
|
||||
// GameManager.Ins.player.GetComponent<IDamagable>().ApplyDamage(GameManager.Ins.player.GetComponent<Player>().Health, null, null);
|
||||
// yield return new WaitForSeconds(1.5f);
|
||||
// Destroy(go);
|
||||
// }
|
||||
//
|
||||
//
|
||||
// public void CmdFire2(Vector3 targetPos)
|
||||
// {
|
||||
// // 火光特效
|
||||
// if (firePre != null && showPos != null)
|
||||
// Instantiate(firePre, showPos.position, showPos.rotation, transform);
|
||||
//
|
||||
// if (bulletPre == null || showPos == null || _player == null)
|
||||
// return;
|
||||
//
|
||||
// // 生成子弹
|
||||
// GameObject bullet = Instantiate(bulletPre, showPos.position, Quaternion.LookRotation(targetPos - showPos.position));
|
||||
// bullet.SetActive(true);
|
||||
//
|
||||
// // 设置飞行方向
|
||||
// if (bullet.TryGetComponent<BossBullet>(out var enemyBullet))
|
||||
// {
|
||||
// enemyBullet.SetTarget(targetPos, bulletSpeed);
|
||||
// }
|
||||
//
|
||||
// // 自动销毁子弹,避免泄漏
|
||||
// Destroy(bullet, 5f);
|
||||
// }
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ public class Pistol : Launcher
|
||||
type = GunType.Pistol;
|
||||
AiInfo gunInfo = GameManager.Ins.AiInfos[(int)type];
|
||||
shootRate = gunInfo.FiringRate;
|
||||
recoil = 100;
|
||||
recoil = 50;
|
||||
if (hand == HandType.Left)
|
||||
{
|
||||
MRInput.Ins.RegisterHoldPressLeftTrigger(ClickLeftTrigger);
|
||||
@@ -29,7 +29,7 @@ public class Pistol : Launcher
|
||||
type = GunType.Pistol;
|
||||
AiInfo gunInfo = GameManager.Ins.AiInfos[(int)type];
|
||||
shootRate = gunInfo.FiringRate;
|
||||
recoil = 100;
|
||||
recoil = 50;
|
||||
}
|
||||
// 从机自身
|
||||
else if (isClient && isOwned)
|
||||
|
||||
@@ -39,6 +39,23 @@ public enum GameState
|
||||
Wave=5,
|
||||
}
|
||||
|
||||
public enum GameEnemyEventType
|
||||
{
|
||||
None=0,//普通事件
|
||||
Snipe=1,//狙击事件
|
||||
Mortar=2,//迫击炮事件
|
||||
MachineGun=3,//机关枪事件
|
||||
SubmachineGun=4,//冲锋枪事件
|
||||
Grenade=5,//手榴弹事件
|
||||
Biochemical=6,//生化兵事件
|
||||
Tank=7,//坦克兵事件
|
||||
Bomber=8,//轰炸机事件
|
||||
HelpNpc=9,//拯救平民事件
|
||||
BulletUp=10,//子弹拾取事件
|
||||
CleanUp=11,//清场事件
|
||||
LastGame=12,//最终冲锋事件
|
||||
}
|
||||
|
||||
public enum GameMode
|
||||
{
|
||||
OnePlayer=0,
|
||||
@@ -54,6 +71,8 @@ public class GameManager : NetworkBehaviour
|
||||
public GameObject DoorPre;
|
||||
public GameObject gunPropPre;
|
||||
public GameObject itemPropPre;
|
||||
|
||||
public GameObject mortarBulletPre;
|
||||
// 炮塔预制体集合
|
||||
//public GameObject[] TowerPres;
|
||||
// 怪物预制集合
|
||||
@@ -118,7 +137,7 @@ public class GameManager : NetworkBehaviour
|
||||
|
||||
public Dictionary<string, SettleInfo> SettleInfos = new Dictionary<string, SettleInfo>();
|
||||
|
||||
public List<Enemy> curEnemyList = new List<Enemy>();
|
||||
//public List<Enemy> curEnemyList = new List<Enemy>();
|
||||
|
||||
[SyncVar]
|
||||
public bool isStart;
|
||||
@@ -279,6 +298,12 @@ public class GameManager : NetworkBehaviour
|
||||
}
|
||||
}
|
||||
|
||||
[Server]
|
||||
public void ChangePlayerAiKillTime()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
[ClientRpc]
|
||||
public void RpcShowWin(bool isBlue)
|
||||
{
|
||||
@@ -331,20 +356,35 @@ public class GameManager : NetworkBehaviour
|
||||
/// <summary>
|
||||
/// 创建敌方单位
|
||||
/// </summary>
|
||||
[Server]
|
||||
IEnumerator CreateEnemy(RoundInfo info)
|
||||
{
|
||||
curRoundEnemyCount = info.EnemyList.Count;
|
||||
for (int i = 0; i < info.EnemyList.Count; i++)
|
||||
{
|
||||
GameObject enemy = Instantiate(EnemyPres[info.EnemyList[i]-3]);
|
||||
int enemyId = info.EnemyList[i];
|
||||
bool isUerInfoAngles = (EnemyType)enemyId == EnemyType.Mortar;
|
||||
Transform[] targetPos = GameLocal.Ins.enemyEndPos;
|
||||
GameObject enemy = Instantiate(EnemyPres[enemyId-3]);
|
||||
NetworkServer.Spawn(enemy);
|
||||
int posId =i/3;
|
||||
int posX=i%3==0? 0: i%3==1 ? 1 : -1;
|
||||
if (isUerInfoAngles)
|
||||
posX = 0;
|
||||
switch ((EnemyType)enemyId)
|
||||
{
|
||||
case EnemyType.Ordinary:
|
||||
case EnemyType.Sniper:
|
||||
break;
|
||||
case EnemyType.Mortar:
|
||||
targetPos = GameLocal.Ins.mortarPos;
|
||||
break;
|
||||
}
|
||||
enemy.transform.position = GameLocal.Ins.enemyStartPos[posId].position;
|
||||
enemy.transform.eulerAngles = AiInfos[i+3].EulerAngles;
|
||||
enemy.transform.eulerAngles =isUerInfoAngles? AiInfos[i+3].EulerAngles: targetPos[posId].eulerAngles;
|
||||
enemyIndex++;
|
||||
Enemy enemyScript = enemy.GetComponent<Enemy>();
|
||||
enemyScript.OnSpawn(enemyIndex, info.EnemyList[i], 1,GameLocal.Ins.enemyEndPos[posId].position+new Vector3(0,0,posX));
|
||||
enemyScript.OnSpawn(enemyIndex, info.EnemyList[i], 1,targetPos[posId].position+new Vector3(0,0,posX));
|
||||
EnemyList.Add(enemyIndex, enemyScript);
|
||||
yield return new WaitForSeconds(0.5f);
|
||||
}
|
||||
@@ -459,20 +499,86 @@ public class GameManager : NetworkBehaviour
|
||||
public List<Enemy> GetRoundEnemy()
|
||||
{
|
||||
List<Enemy> curEnemyList = new List<Enemy>();
|
||||
if (roundIndex <= 2)
|
||||
{
|
||||
var combatUnitInfo= RoundInfos[0];
|
||||
StartCoroutine(CreateEnemy(combatUnitInfo));
|
||||
}
|
||||
else
|
||||
{
|
||||
int curRoundIndex=Random.Range(1,RoundInfos.Count);
|
||||
var roundInfo= RoundInfos[curRoundIndex];
|
||||
StartCoroutine(CreateEnemy(roundInfo));
|
||||
}
|
||||
int curRoundIndex=Random.Range(1,RoundInfos.Count);
|
||||
var roundInfo=roundIndex <= 2? RoundInfos[0]: RoundInfos[curRoundIndex];
|
||||
StartEvent(roundInfo);
|
||||
return curEnemyList;
|
||||
}
|
||||
|
||||
public GameEnemyEventType curEnemyEventType;
|
||||
public void StartEvent(RoundInfo info)
|
||||
{
|
||||
curEnemyEventType = (GameEnemyEventType)info.Belong;
|
||||
StartCoroutine(CreateEnemy(info));
|
||||
switch (curEnemyEventType)
|
||||
{
|
||||
case GameEnemyEventType.None:
|
||||
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
|
||||
{
|
||||
PlayerAiList[0].PlaySound3DRPC("1.10",true);
|
||||
}, 10);
|
||||
break;
|
||||
case GameEnemyEventType.Snipe:
|
||||
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
|
||||
{
|
||||
PlayerAiList[0].PlaySound3DRPC("1.14",true);
|
||||
}, 5);
|
||||
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
|
||||
{
|
||||
PlayerAiList[0].PlaySound3DRPC("1.15",true);
|
||||
EnemyShowOutline((EnemyType)4);
|
||||
}, 7);
|
||||
break;
|
||||
case GameEnemyEventType.Mortar:
|
||||
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
|
||||
{
|
||||
PlayerAiList[0].PlaySound3DRPC("1.20",true);
|
||||
StartCoroutine(CreateMortarBullet());
|
||||
}, 5);
|
||||
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
|
||||
{
|
||||
PlayerAiList[0].PlaySound3DRPC("1.21",true);
|
||||
}, 7);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerator CreateMortarBullet()
|
||||
{
|
||||
Transform insPos=GameLocal.Ins.insMortarPos;
|
||||
bool isHaveMortar = IsHaveTypeEnemy(EnemyType.Mortar);
|
||||
while (isHaveMortar)
|
||||
{
|
||||
var item= Instantiate(mortarBulletPre);
|
||||
NetworkServer.Spawn(item);
|
||||
item.transform.position=insPos.position;
|
||||
item.GetComponent<EnemyMortarBullet>().Init();
|
||||
yield return new WaitForSeconds(AiInfos[(int)EnemyType.Mortar].FiringRate);
|
||||
isHaveMortar = IsHaveTypeEnemy(EnemyType.Mortar);
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsHaveTypeEnemy(EnemyType curType)
|
||||
{
|
||||
foreach (var enemy in EnemyList.Values)
|
||||
{
|
||||
if (enemy.type == curType)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void EnemyShowOutline(EnemyType type)
|
||||
{
|
||||
foreach (var enemy in EnemyList.Values)
|
||||
{
|
||||
if (enemy.type == type)
|
||||
{
|
||||
enemy.outline.enabled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除敌方单位
|
||||
/// </summary>
|
||||
@@ -491,7 +597,7 @@ public class GameManager : NetworkBehaviour
|
||||
curRoundEnemyCount--;
|
||||
|
||||
NetworkServer.Destroy(enemy);
|
||||
|
||||
ChangePlayerAiCountdownTime();
|
||||
if (curRoundEnemyCount<=0)
|
||||
{
|
||||
//CreateGunProp();
|
||||
@@ -724,7 +830,7 @@ public class GameManager : NetworkBehaviour
|
||||
GameObject enemyUI = EnemyUIList[id].gameObject;
|
||||
EnemyUIList.Remove(id);
|
||||
NetworkServer.Destroy(enemyUI);
|
||||
ChangePlayerAiCountdownTime();
|
||||
|
||||
}
|
||||
|
||||
[ClientRpc]
|
||||
@@ -732,8 +838,7 @@ public class GameManager : NetworkBehaviour
|
||||
{
|
||||
HUDPanel.Show();
|
||||
}
|
||||
|
||||
|
||||
|
||||
#region 空投道具
|
||||
/// <summary>
|
||||
/// 修复炮塔
|
||||
@@ -824,7 +929,7 @@ public class GameManager : NetworkBehaviour
|
||||
|
||||
public bool IsHaveEnemy()
|
||||
{
|
||||
return curEnemyList.Count > 0;
|
||||
return EnemyList.Count > 0;
|
||||
}
|
||||
|
||||
#region 工具
|
||||
|
||||
@@ -5,11 +5,11 @@ using UnityEngine;
|
||||
public class Boss : Zombie
|
||||
{
|
||||
public GameObject touObj;
|
||||
public override void DoAttack()
|
||||
{
|
||||
float[] atkStates=new float[3]{0,0.5f,1};
|
||||
int atkStateId=Random.Range(0,3);
|
||||
AnimatorComponent.SetFloat("atkState",atkStates[atkStateId]);
|
||||
base.DoAttack();
|
||||
}
|
||||
// public override void DoAttack()
|
||||
// {
|
||||
// float[] atkStates=new float[3]{0,0.5f,1};
|
||||
// int atkStateId=Random.Range(0,3);
|
||||
// AnimatorComponent.SetFloat("atkState",atkStates[atkStateId]);
|
||||
// base.DoAttack();
|
||||
// }
|
||||
}
|
||||
|
||||
@@ -23,15 +23,15 @@ public class Zombie : Enemy
|
||||
base.OnUpdate();
|
||||
}
|
||||
|
||||
public override void DoAttack()
|
||||
{
|
||||
base.DoAttack();
|
||||
if(attackEffect==null)
|
||||
return;
|
||||
//attackEffect.SetActive(true);
|
||||
// CoroutineTaskManager.Instance.WaitSecondTodo(() =>
|
||||
// {
|
||||
// attackEffect.SetActive(false);
|
||||
// }, 0.5f);
|
||||
}
|
||||
// public override void DoAttack()
|
||||
// {
|
||||
// base.DoAttack();
|
||||
// if(attackEffect==null)
|
||||
// return;
|
||||
// //attackEffect.SetActive(true);
|
||||
// // CoroutineTaskManager.Instance.WaitSecondTodo(() =>
|
||||
// // {
|
||||
// // attackEffect.SetActive(false);
|
||||
// // }, 0.5f);
|
||||
// }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user