305 lines
6.7 KiB
C#
305 lines
6.7 KiB
C#
using DragonLi.Core;
|
|
using DragonLi.Frame;
|
|
using Mirror;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.AI;
|
|
|
|
// IAgent
|
|
public class Agent : Entity, IDamagable
|
|
{
|
|
/// <summary>
|
|
/// Default value of spawnable
|
|
/// </summary>
|
|
public class AgentDefault : Default
|
|
{
|
|
public static readonly int AnimtorSpeedKeyHash = Animator.StringToHash("speed");
|
|
|
|
public static readonly int AnimtorSpeedFkeyHash = Animator.StringToHash("speedf");
|
|
|
|
public static readonly int AnimtorSpeedRkeyHash = Animator.StringToHash("speedr");
|
|
}
|
|
|
|
/// <summary>
|
|
/// All DamageParts belong to this agent
|
|
/// </summary>
|
|
protected DragonLiDamagePart[] DamageProxies;
|
|
|
|
private bool updateAniamtorSpeedvalue = false;
|
|
|
|
private bool updateAniamtorSpeedFvalue = false;
|
|
|
|
private bool updateAniamtorSpeedRvalue = false;
|
|
|
|
#if UNITY_EDITOR
|
|
[DisplayOnly]
|
|
#endif
|
|
[SyncVar]
|
|
public float health = 0f;
|
|
|
|
/// <summary>
|
|
/// Health of this entity
|
|
/// </summary>
|
|
///
|
|
public float Health
|
|
{
|
|
get
|
|
{
|
|
return health;
|
|
}
|
|
set
|
|
{
|
|
health = value;
|
|
health = Mathf.Clamp(health, 0f, OriginHealth);
|
|
OnHeathChanged(health);
|
|
}
|
|
}
|
|
|
|
[NonSerialized]
|
|
[SyncVar]
|
|
public float OriginHealth = 0f;
|
|
|
|
/// <summary>
|
|
/// Is agent alive?
|
|
/// </summary>
|
|
public bool IsAlive => Health > 0f;
|
|
|
|
/// <summary>
|
|
/// Is agent full health?
|
|
/// </summary>
|
|
public bool IsHealthy => Health == OriginHealth;
|
|
|
|
private NavMeshAgent agent;
|
|
|
|
/// <summary>
|
|
/// NavMesh Agent of this Agent
|
|
/// </summary>
|
|
public NavMeshAgent NavAgent
|
|
{
|
|
get
|
|
{
|
|
if (agent == null)
|
|
{
|
|
agent = GetComponent<NavMeshAgent>();
|
|
}
|
|
return agent;
|
|
}
|
|
}
|
|
|
|
public bool isUserSkill;
|
|
public bool isUserHpSkill;
|
|
public int userHpSkillIndex;
|
|
public float waitSkillTime = 30;
|
|
public float curWaitSkillTime = 0;
|
|
public List<int> skillList = new List<int>();
|
|
public Transform skillPos;
|
|
public float skillHpInterval;
|
|
|
|
public int campId;
|
|
|
|
/// <summary>
|
|
/// Add damage
|
|
/// </summary>
|
|
/// <param name="value">How much</param>
|
|
/// <param name="info">Some information about this damage you want to tell damage receiver</param>
|
|
/// <param name="_sender">Who take this damage</param>
|
|
[Server]
|
|
public virtual void ApplyDamage(float value, object info, Transform _sender)
|
|
{
|
|
// Debug.Log("造成伤害1" + IsAlive + " " + !Data["partdamage"].BooleanValue + " " + IsProxyDamage(info));
|
|
if (IsAlive && (!Data["partdamage"].BooleanValue || IsProxyDamage(info)))
|
|
{
|
|
Health -= OnReceiveDamage(value, info, _sender);
|
|
if (!IsAlive)
|
|
{
|
|
Die(info, _sender);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Let this entity die, and tell task system.
|
|
/// </summary>
|
|
public virtual void Die(object info, Transform _sender)
|
|
{
|
|
OnDeath(info, _sender);
|
|
}
|
|
|
|
[Server]
|
|
/// <summary>
|
|
/// On entity enable, this will be called when entity was being spawned.
|
|
/// </summary>
|
|
public virtual void OnSpawn()
|
|
{
|
|
ResetDamageProxies();
|
|
OnBorn();
|
|
}
|
|
|
|
/// <summary>
|
|
/// On entity die, this will be called, you can write despawn functions here.
|
|
/// </summary>
|
|
public virtual void OnDeath(object info, Transform _sender) { }
|
|
|
|
/// <summary>
|
|
/// When agent receives damage this function will be called
|
|
/// If you want to re calculate damage you can do it here.
|
|
/// </summary>
|
|
/// <param name="value">How much</param>
|
|
/// <param name="info">Some information about this damage you want to tell damage receiver</param>
|
|
/// <param name="_sender">Who take this damage</param>
|
|
/// <returns></returns>
|
|
public virtual float OnReceiveDamage(float value, object info, Transform _sender)
|
|
{
|
|
return value;
|
|
}
|
|
|
|
/// <summary>
|
|
/// When health changed this function will be called
|
|
/// </summary>
|
|
/// <param name="currentHealth">current health</param>
|
|
[Server]
|
|
public virtual void OnHeathChanged(float currentHealth) { }
|
|
|
|
/// <summary>
|
|
/// When this entity has been born
|
|
/// </summary>
|
|
public virtual void OnBorn() { }
|
|
|
|
public override void InitData()
|
|
{
|
|
Data.Add("entity_type", new DataRow(SupportDataType.String)
|
|
{
|
|
Name = "entity_type"
|
|
});
|
|
Data.Add("speed", new DataRow(SupportDataType.Float)
|
|
{
|
|
Name = "speed",
|
|
FloatValue = 10f
|
|
});
|
|
Data.Add("acc", new DataRow(SupportDataType.Float)
|
|
{
|
|
Name = "acc",
|
|
FloatValue = 30f
|
|
});
|
|
Data.Add("health", new DataRow(SupportDataType.Float)
|
|
{
|
|
Name = "health",
|
|
FloatValue = 100f
|
|
});
|
|
Data.Add("partdamage", new DataRow(SupportDataType.Boolean)
|
|
{
|
|
Name = "partdamage",
|
|
BooleanValue = false
|
|
});
|
|
}
|
|
|
|
public override void Update()
|
|
{
|
|
if (isServer && IsAlive)
|
|
{
|
|
if (NavAgent != null & NavAgent.enabled)
|
|
{
|
|
UpdateAniamtorValues(NavAgent.velocity);
|
|
}
|
|
else if (RigidbodyComponent)
|
|
{
|
|
UpdateAniamtorValues(RigidbodyComponent.velocity);
|
|
}
|
|
OnUpdate();
|
|
}
|
|
}
|
|
|
|
public override void OnEnable()
|
|
{
|
|
DamageProxies = GetComponentsInChildren<DragonLiDamagePart>();
|
|
base.OnEnable();
|
|
}
|
|
|
|
public override void Awake()
|
|
{
|
|
base.Awake();
|
|
InitAnimator();
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// Update animator value for you.
|
|
/// </summary>
|
|
/// <param name="vel">Velocity of this entity</param>
|
|
[Server]
|
|
protected void UpdateAniamtorValues(Vector3 vel)
|
|
{
|
|
if (AnimatorComponent != null)
|
|
{
|
|
if (updateAniamtorSpeedvalue)
|
|
{
|
|
AnimatorComponent.SetFloat(AgentDefault.AnimtorSpeedKeyHash, vel.magnitude);
|
|
}
|
|
Vector3 val;
|
|
if (updateAniamtorSpeedFvalue)
|
|
{
|
|
val = Vector3.Project(vel, transform.forward);
|
|
float num = (val.magnitude / (vel.magnitude * (float)((!(Vector3.Angle(vel, transform.forward) > 90f)) ? 1 : (-1))));
|
|
AnimatorComponent.SetFloat(AgentDefault.AnimtorSpeedFkeyHash, num);
|
|
}
|
|
if (updateAniamtorSpeedRvalue)
|
|
{
|
|
val = Vector3.Project(vel, transform.right);
|
|
float num2 = (val.magnitude / (vel.magnitude * (float)((!(Vector3.Angle(vel, transform.right) > 90f)) ? 1 : (-1))));
|
|
AnimatorComponent.SetFloat(AgentDefault.AnimtorSpeedRkeyHash, num2);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Init animator
|
|
/// </summary>
|
|
private void InitAnimator()
|
|
{
|
|
if (AnimatorComponent == null)
|
|
{
|
|
return;
|
|
}
|
|
AnimatorControllerParameter[] parameters = AnimatorComponent.parameters;
|
|
foreach (AnimatorControllerParameter val in parameters)
|
|
{
|
|
if ((int)val.type == 1)
|
|
{
|
|
switch (val.name)
|
|
{
|
|
case "speed":
|
|
updateAniamtorSpeedvalue = true;
|
|
break;
|
|
case "speedr":
|
|
updateAniamtorSpeedRvalue = true;
|
|
break;
|
|
case "speedf":
|
|
updateAniamtorSpeedFvalue = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void ResetDamageProxies()
|
|
{
|
|
if (DamageProxies != null)
|
|
{
|
|
DragonLiDamagePart[] damageProxies = DamageProxies;
|
|
foreach (DragonLiDamagePart dragonLiDamagePart in damageProxies)
|
|
{
|
|
dragonLiDamagePart.ResetDamagePart();
|
|
}
|
|
}
|
|
}
|
|
|
|
private bool IsProxyDamage(object info)
|
|
{
|
|
DragonLiDamagePart dragonLiDamagePart = info as DragonLiDamagePart;
|
|
return dragonLiDamagePart == null;
|
|
}
|
|
|
|
|
|
}
|