123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436 |
- using System.Collections;
- using UnityEngine;
- using Spine.Unity;
- using Spine.Unity.Examples;
- using Mirror;
- public class enemyScript : NetworkBehaviour
- {
- public const int HEALTH_INC = 2;
- public const float DAMAGE_INC = 1.2f;
- public const float XP_GAIN = 1.5f;
- public const int XP_GAIN_Base = 5;
- [SyncVar(hook = nameof(OnHealthChange))]
- public int health;
- [SyncVar(hook = nameof(OnMagicalHealthChange))]
- public int magicalHealth;
- public SpriteHealthBar healthBar;
- public SpriteHealthBar MagicalhealthBar;
- public float speed;
- public float chaseRadius;
- public float attackRadius;
- public bool rotate;
- //public LayerMask layerMask;
- public playerNetwork target;
- private Rigidbody2D rb2;
- public SkeletonAnimation animator;
- private Vector2 movement;
- public Vector3 dir;
- public TextMesh enemyName;
- public TextMesh enemyLevel;
- public bool isInChaseRange;
- public bool isInAttackRange;
- public Transform uiEnemy;
- public int enemyAttackDamage = 10;
- MeshRenderer meshRenderer;
- public GameObject hitVfx;
- void Awake(){
- meshRenderer = GetComponent<MeshRenderer>();
- scanCooldown = Random.Range(0.5f, 1.5f);
- }
- private void Start(){
- rb2 = GetComponent<Rigidbody2D>();
- //target = GameObject.FindWithTag("Player").transform;
- UpdateAnimation(directionString,animationString);
- defaultPos = transform.position;
- }
- [SyncVar(hook =nameof(OnLevelChanged))]
- public int level;
- void OnLevelChanged(int oldVal, int newVal){
- if(isServer){return;}
- SetLevel(newVal);
- }
- public void SetLevel(int _level){
- if(enemyLevel != null){
- enemyLevel.text = _level.ToString();
- }
-
- level = _level;
- int healthIncrement =level * HEALTH_INC;
- maxHealth = 100 + healthIncrement;
- health = (int)maxHealth;
- magicalHealth = (int)maxHealth;
- enemyAttackDamage += (int)(level * DAMAGE_INC);
- // Debug.Log($"{health}/{maxHealth}");
-
- }
- public Vector3 defScale;
- Vector3 defaultPos;
- float playerDistCheckTimer=0f;
- void LateUpdate(){
- LOD();
- }
- public const float disappearDistFromPlayer = 15f;
- void LOD(){
- if(playerDistCheckTimer > 0){playerDistCheckTimer -= Time.deltaTime;return;}
- playerDistCheckTimer = Random.Range(1.5f,2.5f);
- if(playerNetwork.localPlayerTransform == null){return;}
- float distToPlayer = Vector3.Distance(playerNetwork.localPlayerTransform.position, transform.position);
- meshRenderer.enabled = distToPlayer < disappearDistFromPlayer;
- }
- #if UNITY_SERVER || UNITY_EDITOR
- [Server]
- private void Update(){
- // animator.skeleton.SetSkin
- // set animation state to running if in chase Range
- //isInChaseRange = true
- // isInChaseRange = Physics2D.OverlapCircle(transform.position, chaseRadius , layerMask);
- // isInAttackRange = Physics2D.OverlapCircle(transform.position, attackRadius, layerMask);
- if (health <= 0 ){
- return;
- }
- if(target != null){
- isInChaseRange = Vector3.Distance(transform.position, target.transform.position) < chaseRadius;
- isInAttackRange = Vector3.Distance(transform.position, target.transform.position) < attackRadius;
- }else{
- isInChaseRange = false;
- isInAttackRange = false;
- }
-
- ScanPlayers();
- if(target !=null){
- enemyFollow();
- }
- }
- #endif
- float scanTimer =0;
- float scanCooldown;
- public void ScanPlayers(){
-
- if(scanTimer >0){scanTimer-=Time.deltaTime; return;}
- scanTimer = scanCooldown;
- playerNetwork[] playersinNetwork = FindObjectsOfType<playerNetwork>();
- float closestDist = float.MaxValue;
- playerNetwork closestPlayer = null;
- foreach(playerNetwork player in playersinNetwork ){
- if(player.health <= 0 ){continue;}
- float dist = Vector3.Distance(transform.position, player.transform.position);
- if(dist < closestDist){
- closestPlayer = player;
- closestDist = dist;
- }
- }
- if(closestDist < chaseRadius){
- target = closestPlayer ;
- }
- else {
- target = null;
- }
-
- //if(target == null) {return;}
- }
- // [ClientRpc]
- // void RpcUpdateAnim(string animDir , string animName, bool isLoop){
- // UpdateAnimation(animDir , animName, isLoop);
- // }
- [SyncVar(hook =nameof(OnFlipped))]
- bool isFlipped= false;
- void OnFlipped(bool oldVal, bool newVal){
- if(isServer){return;}
- transform.localScale = new Vector3(defScale.x * (newVal ? -1 : 1),defScale.y,defScale.z);
- HandleFlip();
- }
- void HandleFlip(){
- if(uiEnemy == null){
- return;
- }
- if(transform.localScale.x < 0 ){
- uiEnemy.localScale = new Vector3(-1,1,1);
- }
- else{
- uiEnemy.localScale = new Vector3(1,1,1);
- }
- }
- private void enemyFollow(){
-
- if(Mathf.Abs(dir.y) > Mathf.Abs(dir.x)){
- if(dir.y < 0){
- directionString = "Back";
- }else{
- directionString = "Front";
- }
- }else{
- directionString = "Side";
- if(dir.x < 0){
- transform.localScale = new Vector3(defScale.x,defScale.y,0);
- isFlipped=false;
- }else{
- transform.localScale = new Vector3(-defScale.x,defScale.y,0);
- isFlipped = true;
- }
- HandleFlip();
- }
- if(animationHistory != directionString + animationString){
- UpdateAnimation(directionString, animationString);
- // RpcUpdateAnim(directionString, animationString,true);
- }
- animationHistory=directionString + animationString;
- if(target != null){
- dir = transform.position - target.transform.position;
- }
-
- float angle = Mathf.Atan2(dir.y , dir.x ) * Mathf.Rad2Deg;
- dir.Normalize();
- movement = dir;
- if(rotate){
- //set anim direction x, y dir
- }
- }
- string animationHistory ="";
- [SyncVar(hook =nameof(OnAnimationDirectionChanged))]
- public string directionString = "Side";
- [SyncVar(hook =nameof(OnAnimationNameChanged))]
- public string animationString = "Idle";
- void OnAnimationDirectionChanged(string oldVal, string newVal){
- UpdateAnimation(newVal, animationString);
- }
- void OnAnimationNameChanged(string oldVal, string newVal){
- UpdateAnimation(directionString, newVal);
- }
- float attackTimer = 0f;
- float attackDuration = 1.4f;
- [SyncVar]
- public float maxHealth;
-
- #if UNITY_SERVER || UNITY_EDITOR
- [Server]
- private void FixedUpdate() {
- if (health <= 0 || magicalHealth <= 0){
- return;
- }
- healthBar.SetHealth(health, maxHealth);
- MagicalhealthBar.SetHealth(magicalHealth, maxHealth); //magical health maxout err
- if(isInChaseRange && !isInAttackRange ){
- MoveEnemy(movement);
- //Set animation to moving
- animationString = "Walk";
- }
- if(isInAttackRange){
- rb2.velocity = Vector2.zero;
- //Set animation to attack
- animationString = "Attack";
- if(attackTimer < attackDuration){
- attackTimer += Time.deltaTime;
- }else{
- attackTimer = 0 ;
- Attack();
- }
-
- //TODO: ATTACK HERE
- }
- if(!isInAttackRange && !isInChaseRange){
- //SetAnimation to idle
- animationString = "Idle";
- }
- }
- #endif
- public void Attack(){
- target.TakeDamage(enemyAttackDamage);
- }
- private void MoveEnemy(Vector2 dir){
- rb2.MovePosition((Vector2)transform.position + (dir * speed * Time.deltaTime));
- }
- void UpdateAnimation(string direction, string animationName){
- // try{
- StartCoroutine(CoroutineUpdateAnim(direction, animationName));
- }
- IEnumerator CoroutineUpdateAnim(string direction, string animationName){
- while(animator == null){
- yield return new WaitForSeconds(0.1f);
- Debug.LogError("animator is null!");
- }
- while(animator.skeleton == null){
- yield return new WaitForSeconds(0.1f);
- Debug.LogError("animator skelton is null!");
- }
- while(animator.AnimationState == null){
- yield return new WaitForSeconds(0.1f);
- Debug.LogError("animator state is null!");
- }
- animator.skeleton.SetSkin(direction);
- animator.skeleton.SetSlotsToSetupPose();
- animator.AnimationState.SetAnimation(0, $"{direction}_{animationName}", !animationName.ToLower().Contains("death"));
- // }catch(Exception e){
- // Debug.LogError(e.ToString());
- // }
- Debug.Log($"Updating enemy animation {direction}_{animationName}");
- }
- [Command(requiresAuthority =false)]
- void CmdTakeDamage(int damage,uint id){
- takedmg(damage,id);
- Debug.Log("Enemy Attack Recieved ");
- }
- public void TakeDamage(int damage, uint id){
- if(isServer){
- takedmg(damage,id);
- }
- else{
- CmdTakeDamage(damage,id);
- }
- }
- void takedmg(int damage,uint id){
- if(health<=0){return;}
- health -= damage;
- //hit vfx
- // GameObject newObject = Instantiate(hitVfx , transform.position , Quaternion.identity );
- // newObject.transform.localPosition = Vector3.zero;
- // newObject.transform.parent = transform;
- if(health<= 0 ){
- StartCoroutine(couroutineDeath());
- foreach(playerNetwork player in FindObjectsOfType<playerNetwork>()){
- if(player.netId == id){
- //This one attacked me
- player.OnEnemyKilled(level);
- }
- }
- }
- Debug.Log("Enemy Takes Damage ***");
-
- }
- [Command(requiresAuthority =false)]
- void CmdTakeMagicalDamage(int damage,uint id){
- takeMagicalDmg(damage,id);
- Debug.Log("Enemy Attack Recieved ");
- }
- public void TakeMagicalDamage(int damage, uint id){
- if(isServer){
- takeMagicalDmg(damage,id);
- }
- else{
- CmdTakeMagicalDamage(damage,id);
- }
- }
- void takeMagicalDmg(int damage,uint id){
- if(magicalHealth<=0){return;}
- magicalHealth -= damage;
- if(magicalHealth<= 0 ){
- StartCoroutine(couroutineDeath());
- foreach(playerNetwork player in FindObjectsOfType<playerNetwork>()){
- if(player.netId == id){
- //This one attacked me
- player.OnEnemyKilled(level);
- }
- }
- }
- Debug.Log("Enemy Takes Damage ***");
-
- }
- IEnumerator couroutineDeath(){
-
- animationString = "Death";
- UpdateAnimation(directionString , animationString);
- // RpcUpdateAnim(directionString, animationString,false);
- Vector3 lootSpawnPos = transform.position;
- lootSpawnPos.z = GameManager.instance.LootSpawnPointsParent.GetChild(0).position.z;
- //instantiate loot item
- GameObject newLoot = Instantiate(GameManager.instance.GetRandomLoot(), lootSpawnPos, Quaternion.identity);
- NetworkServer.Spawn(newLoot);
- yield return new WaitForSecondsRealtime(5);
- if (!isServer)
- {
- CmdDie();
- }
- else
- {
- GameManager.OnEnemyDeath(this, defaultPos);
- }
-
- /* transform.position = defaultPos;
- health = (int)maxHealth;
- magicalHealth = (int)maxHealth;*/
- //animationString = "Idle";
- }
- [Command]
- void CmdDie()
- {
- GameManager.OnEnemyDeath(this,defaultPos);
- }
- public void OnHealthChange(int oldVlaue, int newValue){
- healthBar.SetHealth(newValue,maxHealth);
- }
- public void OnMagicalHealthChange(int oldVlaue, int newValue){
- MagicalhealthBar.SetHealth(newValue,maxHealth);
- }
- }
|