139 lines
3.9 KiB
C#
139 lines
3.9 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using Mirror;
|
|
|
|
public class AtkDummyExplosion : Explosion
|
|
{
|
|
public GameObject bulletPrefab; // 假人的子弹
|
|
public Transform shootPoint; // 发射点
|
|
public Transform roteTransform; // 炮台旋转节点(只旋转这个)
|
|
|
|
public MeshRenderer meshRenderer1;
|
|
public MeshRenderer meshRenderer2;
|
|
|
|
public Material redMaterial;
|
|
public Material blueMaterial;
|
|
|
|
private float shootTimer;
|
|
private float shootRate;
|
|
private float damage;
|
|
private float recoil;
|
|
private float userTime;
|
|
|
|
private GameObject target;
|
|
|
|
public override void OnSpawn(TeamType team, float curDurationTime, int id)
|
|
{
|
|
base.OnSpawn(team, curDurationTime, id);
|
|
|
|
transform.eulerAngles = Vector3.zero;
|
|
|
|
// 读取武器信息
|
|
GunInfo info = GameManager.Ins.GunInfos[(GunType)type][1];
|
|
shootRate = info.ShootRate * 2f; // 攻击速度减半
|
|
damage = info.Damage;
|
|
recoil = info.Recoil;
|
|
userTime = info.Time;
|
|
score = info.Score;
|
|
if (!isServer)
|
|
return;
|
|
Material mat = curTeam == TeamType.Red ? redMaterial : blueMaterial;
|
|
meshRenderer1.material = mat;
|
|
meshRenderer2.material = mat;
|
|
RpcSetTeamMaterial(curTeam);
|
|
StartCoroutine(AutoAttackRoutine());
|
|
}
|
|
|
|
[ClientRpc]
|
|
private void RpcSetTeamMaterial(TeamType team)
|
|
{
|
|
Material mat = team == TeamType.Red ? redMaterial : blueMaterial;
|
|
|
|
meshRenderer1.material = mat;
|
|
meshRenderer2.material = mat;
|
|
}
|
|
|
|
[Server]
|
|
private IEnumerator AutoAttackRoutine()
|
|
{
|
|
while (true)
|
|
{
|
|
if (target == null || IsDead(target))
|
|
{
|
|
target = FindNearestEnemy();
|
|
}
|
|
|
|
if (target != null)
|
|
{
|
|
// 🔥 只旋转炮台,不旋转整体物体
|
|
Vector3 dir = target.transform.position - roteTransform.position;
|
|
dir.y = 0;
|
|
|
|
if (dir.sqrMagnitude > 0.01f)
|
|
{
|
|
Quaternion targetRot = Quaternion.LookRotation(dir);
|
|
roteTransform.rotation = Quaternion.Lerp(roteTransform.rotation, targetRot, Time.deltaTime * 6f);
|
|
}
|
|
|
|
// 攻击计时
|
|
shootTimer += Time.deltaTime;
|
|
if (shootTimer >= shootRate)
|
|
{
|
|
shootTimer = 0;
|
|
Shoot();
|
|
}
|
|
}
|
|
|
|
yield return null;
|
|
}
|
|
}
|
|
|
|
[Server]
|
|
private void Shoot()
|
|
{
|
|
if (bulletPrefab == null || shootPoint == null) return;
|
|
|
|
// 子弹朝向 = 炮台方向
|
|
GameObject bullet = Instantiate(bulletPrefab, shootPoint.position, shootPoint.rotation);
|
|
|
|
if (bullet.TryGetComponent(out Bullet bulletComp))
|
|
{
|
|
Vector3 fireDir = roteTransform.forward; // 🔥 使用炮台的 forward
|
|
bulletComp.OnSpawn(playerId, fireDir, recoil, userTime);
|
|
}
|
|
|
|
if (NetworkServer.active)
|
|
{
|
|
NetworkServer.Spawn(bullet);
|
|
}
|
|
}
|
|
|
|
private GameObject FindNearestEnemy()
|
|
{
|
|
float minDist = float.MaxValue;
|
|
GameObject nearest = null;
|
|
|
|
foreach (var player in GameManager.Ins.allPlayers)
|
|
{
|
|
if (player == null) continue;
|
|
if (player.teamType == curTeam) continue;
|
|
if (IsDead(player.gameObject)) continue;
|
|
|
|
float dist = Vector3.Distance(transform.position, player.transform.position);
|
|
if (dist < minDist)
|
|
{
|
|
minDist = dist;
|
|
nearest = player.gameObject;
|
|
}
|
|
}
|
|
return nearest;
|
|
}
|
|
|
|
private bool IsDead(GameObject obj)
|
|
{
|
|
var player = obj.GetComponent<Player>();
|
|
return player != null && player.isDie;
|
|
}
|
|
}
|