337 lines
8.8 KiB
C#
337 lines
8.8 KiB
C#
using DragonLi.Frame;
|
|
using UnityEngine;
|
|
using DragonLi.Core;
|
|
using DG.Tweening;
|
|
using BehaviorDesigner.Runtime;
|
|
using Mirror;
|
|
|
|
public class RobotMech : XAgent
|
|
{
|
|
private const float kRotationDuring = 1.1f;
|
|
private static readonly int kShootHash = Animator.StringToHash("shoot");
|
|
private static readonly int kRotationHash = Animator.StringToHash("rotation");
|
|
private static readonly int kNeedRotationHash = Animator.StringToHash("needRotate");
|
|
|
|
private Transform player;
|
|
private Vector3 faceTarget;
|
|
private bool Shooting = false;
|
|
|
|
public BloodSlider BloodSlider;
|
|
public RobotGun[] launchers;
|
|
public GameObject zadi;
|
|
public float height = 10f;
|
|
public GameObject speak;
|
|
|
|
public Animator gunAnimator;
|
|
public Animator gunAnimator2;
|
|
|
|
|
|
public BehaviorTree behavior;
|
|
|
|
public GameObject explosion_prefab;
|
|
|
|
public float explosion_despawn_time = 4f;
|
|
|
|
public float xSpeed = 10f;
|
|
|
|
public float xAcc = 30f;
|
|
|
|
public float xHealth = 50000f;
|
|
|
|
public float xAtk = 10;
|
|
|
|
public Vector3 XPatrol_position = new Vector3(0, 0, 0);
|
|
|
|
|
|
//public int Id;
|
|
|
|
/// <summary>
|
|
/// 落地
|
|
/// </summary>
|
|
public AudioClip lanOn;
|
|
|
|
/// <summary>
|
|
/// 架枪
|
|
/// </summary>
|
|
public AudioClip stackArms;
|
|
|
|
/// <summary>
|
|
/// 说话
|
|
/// </summary>
|
|
public AudioClip speack;
|
|
///
|
|
|
|
public AudioSource audioSource;
|
|
[SyncVar]
|
|
public float blood;
|
|
|
|
|
|
[Server]
|
|
public void StackArms()
|
|
{
|
|
audioSource.PlayOneShot(stackArms, 0.8f);
|
|
}
|
|
|
|
public override void InitData()
|
|
{
|
|
base.InitData();
|
|
type = (int)EnemyType.RobotMech;
|
|
EnemyInfo enemyInfo = GameManager.Ins.EnemyDescInfos[(int)EnemyType.RobotMech];
|
|
DifficultyInfo difficultyInfo = GameManager.Ins.DifficultyescInfos[StoryManager.Ins.gameDifficulty];
|
|
BloodSlider.SetName(enemyInfo.NameCN);
|
|
xHealth = enemyInfo.Hp * difficultyInfo.enemyHpCoefficient * MRNetworkManager.Ins.roomSlots.Count * 0.7f;
|
|
xAtk = enemyInfo.Atk * difficultyInfo.damageCoefficient;
|
|
Data["health"].FloatValue = xHealth;
|
|
blood = xHealth;
|
|
Data["acc"].FloatValue = xAcc;
|
|
Data["speed"].FloatValue = xSpeed;
|
|
Data["atk"].FloatValue = xAtk;
|
|
Data["patrol_position"].Vector3Value = XPatrol_position;
|
|
|
|
Data.Add("explosion_despawn_time", new DataRow(SupportDataType.Float)
|
|
{
|
|
Name = "explosion_despawn_time",
|
|
FloatValue = explosion_despawn_time
|
|
});
|
|
|
|
Data.Add("nature_recoil", new DataRow(SupportDataType.Boolean)
|
|
{
|
|
Name = "nature_recoil",
|
|
BooleanValue = true
|
|
}); ;
|
|
}
|
|
|
|
[Server]
|
|
public override void OnSpawn()
|
|
{
|
|
base.OnSpawn();
|
|
Data["nature_recoil"].BooleanValue = true;
|
|
EventDispatcher.TriggerEvent("SpwanPoint", transform);
|
|
player = GameManager.Ins.GetPlayer1();
|
|
NavAgent.enabled = false;
|
|
behavior.enabled = true;
|
|
ColliderComponent.enabled = true;
|
|
Data["attackmode"].BooleanValue = false;
|
|
Data["rotating"].BooleanValue = false;
|
|
behavior.RegisterEvent("RotateToPlayer", RotateToPlayer);
|
|
behavior.RegisterEvent("Attack", Attack);
|
|
behavior.RegisterEvent("StopAttack", StopAttack);
|
|
behavior.RegisterEvent("RotateToNext", RotateToNext);
|
|
|
|
Vector3 nowPos = transform.position;
|
|
transform.position = new Vector3(nowPos.x, height, nowPos.z);
|
|
transform.DOMove(nowPos, 0.5f).SetEase(Ease.InBack).OnComplete(() =>
|
|
{
|
|
Debug.Log("移动结束");
|
|
audioSource.PlayOneShot(speack, 1f);
|
|
zadi.SetActive(true);
|
|
ZadiOpen();
|
|
audioSource.PlayOneShot(lanOn);
|
|
NavAgent.enabled = transform;
|
|
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
|
|
{
|
|
NavAgent.enabled = true;
|
|
speak.SetActive(true);
|
|
}, 1.5f);
|
|
});
|
|
|
|
}
|
|
|
|
|
|
[ClientRpc]
|
|
public void ZadiOpen()
|
|
{
|
|
zadi.SetActive(true);
|
|
}
|
|
|
|
public void RotateToPlayer()
|
|
{
|
|
RotateToTarget(player.position);
|
|
}
|
|
|
|
public void RotateToNext()
|
|
{
|
|
Debug.Log("RotateToNext");
|
|
RotateToTarget(player.position);
|
|
}
|
|
|
|
|
|
protected override void OnUpdate()
|
|
{
|
|
if (!IsAlive)
|
|
return;
|
|
Shoot();
|
|
}
|
|
//protected override void OnReceiveMessage(string msg, object info)
|
|
//{
|
|
// switch (msg)
|
|
// {
|
|
// case "Attack":
|
|
// Attack();
|
|
// break;
|
|
// case "StopAttack":
|
|
// StopAttack();
|
|
// break;
|
|
// case "RotateToPlayer":
|
|
// RotateToTarget(player.position);
|
|
// break;
|
|
// case "RotateToNext":
|
|
// RotateToTarget(Data["patrol_position"].Vector3Value);
|
|
// break;
|
|
// }
|
|
//}
|
|
|
|
[Server]
|
|
public override void OnHeathChanged(float currentHealth)
|
|
{
|
|
base.OnHeathChanged(currentHealth);
|
|
HealthChange(currentHealth);
|
|
}
|
|
|
|
[ClientRpc]
|
|
public void HealthChange(float currentHealth)
|
|
{
|
|
if (BloodSlider != null)
|
|
{
|
|
|
|
BloodSlider.SetValue2(currentHealth, blood);
|
|
}
|
|
}
|
|
|
|
[Server]
|
|
public override void ApplyDamage(float value, object info, Transform _sender)
|
|
{
|
|
base.ApplyDamage(value, info, _sender);
|
|
|
|
if (_sender != null)
|
|
{
|
|
int ownerIndx = _sender.GetComponent<Bullet>().ownerIndex;
|
|
|
|
RpcDamage(value, (bool)info, ownerIndx);
|
|
}
|
|
}
|
|
|
|
[ClientRpc]
|
|
public void RpcDamage(float value, bool info, int ownerIndx)
|
|
{
|
|
if (GameInit.Ins.self.index == ownerIndx)
|
|
{
|
|
BloodSlider.CreateDamagePre(value, info);
|
|
Debug.Log("收到伤害 ClientRpc:");
|
|
}
|
|
}
|
|
|
|
|
|
[Server]
|
|
public override void OnDeath(object info, Transform _sender)
|
|
{
|
|
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
|
|
{
|
|
NetworkServer.Destroy(transform.gameObject);
|
|
SpawnExplosion();
|
|
GameManager.Ins.CreateItemDrop(index, transform.position);
|
|
|
|
if (GameManager.Ins.EnemyDie())
|
|
{
|
|
StoryManager.Ins.CreateStoryItem();
|
|
GameManager.Ins.ShowLandmark(8, 9);
|
|
}
|
|
|
|
}, 0.5f);
|
|
}
|
|
|
|
[Server]
|
|
public void SpawnExplosion()
|
|
{
|
|
if (explosion_prefab != null)
|
|
{
|
|
GameObject explosion = Instantiate(explosion_prefab);
|
|
explosion.transform.position = transform.position;
|
|
NetworkServer.Spawn(explosion);
|
|
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
|
|
{
|
|
NetworkServer.Destroy(explosion);
|
|
}, Data["explosion_despawn_time"].FloatValue);
|
|
}
|
|
}
|
|
|
|
public void RotateToTarget(Vector3 target)
|
|
{
|
|
faceTarget = target;
|
|
SetRotateState(GetAngleStep());
|
|
}
|
|
|
|
private void RotateToPlayerIfShooting()
|
|
{
|
|
if (Shooting)
|
|
RotateToTarget(player.transform.position);
|
|
}
|
|
[Server]
|
|
private void Shoot()
|
|
{
|
|
gunAnimator.SetBool("shoot",Shooting);
|
|
gunAnimator2.SetBool("shoot",Shooting);
|
|
if (!Shooting)
|
|
return;
|
|
Shot();
|
|
}
|
|
private void Shot()
|
|
{
|
|
launchers[0].Shoot(launchers[0].LaunchPoint.position + launchers[0].LaunchPoint.forward * 1.0f, -1);
|
|
launchers[1].Shoot(launchers[1].LaunchPoint.position + launchers[0].LaunchPoint.forward * 1.0f, -1);
|
|
}
|
|
|
|
private void Attack()
|
|
{
|
|
AnimatorComponent.SetBool(kShootHash, true);
|
|
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
|
|
{
|
|
Shooting = true;
|
|
}, 2.0f);
|
|
}
|
|
private void StopAttack()
|
|
{
|
|
// set animator
|
|
AnimatorComponent.SetBool(kShootHash, false);
|
|
// stop shooting
|
|
Shooting = false;
|
|
}
|
|
private void SetRotateState(float angle)
|
|
{
|
|
bool state = Mathf.Abs(angle) > 5.0f;
|
|
AnimatorComponent.SetBool(kNeedRotationHash, state);
|
|
AnimatorComponent.SetFloat(kRotationHash, angle);
|
|
}
|
|
private void OnRotateFinishedCallback()
|
|
{
|
|
// start to rotate
|
|
SetRotateState(GetAngleStep());
|
|
|
|
}
|
|
private float GetAngleStep()
|
|
{
|
|
//Debug.Log("faceTarget" + faceTarget);
|
|
// get target direction
|
|
Vector3 direction = (faceTarget - transform.position).ReflectVectorXOZ();
|
|
|
|
// get angle (0, 180]
|
|
float angle = Vector3.Angle(transform.forward.ReflectVectorXOZ(), direction);
|
|
|
|
// angle
|
|
if (Mathf.Abs(angle) > 90.0f)
|
|
angle /= 2.0f;
|
|
|
|
// left or right?
|
|
if (Vector3.Cross(transform.forward.ReflectVectorXOZ(), direction).y < 0)
|
|
angle *= -1;
|
|
|
|
return angle;
|
|
}
|
|
private bool IsRotating()
|
|
{
|
|
return Data["rotating"].BooleanValue;
|
|
}
|
|
}
|
|
|
|
|