У меня базовая c система повреждений / брони, и я хочу уменьшить входящий урон на величину брони. - PullRequest
0 голосов
/ 12 июля 2020

Как я сказал в названии, я хочу, чтобы входящий урон был уменьшен на то, сколько у меня брони (например, урон равен 30, поэтому если я сделаю 1/3 * броня = какое-то число), но я не могу понять, где мне следует Поместите это. Должен ли он быть внутри моего вражеского скрипта, где формируется сумма урона? Или в моем скрипте PlayerStats, где входящий урон снимается с моего здоровья? Скрипт моего игрока:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using UnityEngine.UI;
public class PlayerStats : MonoBehaviour
{

    public int armor = 5;
    public int currentLevel;
    public int currentXP;
    public int MaxLevel;

    public int[] ExpToNextLevel;


    public void SavePlayer(){
        SaveSystem.SavePlayer(this);
    }
    public void LoadPlayer(){
        PlayerData data = SaveSystem.loadPlayer();
        currentLevel = data.level;
        healthMax = data.MaxHealth;
        attackDamage = data.Damage;
    }
    void Awake(){
        currentLevel = 1;
        currentXP = 0;
    }
    void Start(){
        health = healthMax;
        healthBar.SetMaxHealth(healthMax);
        
        ExpToNextLevel = new int [MaxLevel+1];
        ExpToNextLevel[1] = 15;
        for(int i =2;i<MaxLevel;i++){
            ExpToNextLevel[i] = Mathf.RoundToInt(ExpToNextLevel[i-1]*1.2f);
        }
    }
    void Update(){
        if(Time.time >= nextAttackTime){

        
        if(Input.GetKeyDown(KeyCode.Mouse0)){
            Attack();
            nextAttackTime = Time.time +1f/attackRate;
        }
        }
        FindObjectOfType<StatsUI>().UpdatePlayerStatus();
        
    }
     public void AddExp(int amount){
        currentXP += amount;
        if(currentXP >= ExpToNextLevel[currentLevel]){
            LevelUp();
        }
        }

        private void LevelUp(){
            currentLevel++;
            healthMax = Mathf.RoundToInt(healthMax * 1.2f);
            attackDamage = Mathf.CeilToInt(attackDamage * 1.2f);

            
        }

        //HEALTH SYSTEM

         public HealthBarSystem healthBar;
    public event EventHandler OnHealthChanged;
    public int health;
    public int healthMax;

    
    public void Damage(int damageAmount){
        health -= damageAmount-1/3*armor;
        healthBar.SetHealth(health);
        if(health < 0) health =0;
        if(OnHealthChanged != null) OnHealthChanged(this,EventArgs.Empty);
    }
    public void Heal(int healAmount){
        health += healAmount;
        healthBar.SetHealth(health);
        if (health > healthMax)health = healthMax;
        if(OnHealthChanged != null) OnHealthChanged(this,EventArgs.Empty);
    }
    void OnTriggerEnter2D(Collider2D collider){
        if(collider.transform.tag=="Potion"){
            Debug.Log("Your Halth has risen");
            Heal(20);
        }
    }
    public Transform AttackPoint;
    public float AttackRange = 0.5f;
    public LayerMask enemyLayers;
    public Animator animator;
    public int attackDamage = 10;
    public float attackRate =2f;
    float nextAttackTime = 0f;

    
    void Attack(){
        animator.SetTrigger("Attack");

        Collider2D[] hitEnemies = Physics2D.OverlapCircleAll(AttackPoint.position, AttackRange, enemyLayers);

        foreach(Collider2D  enemy in hitEnemies){
            enemy.GetComponent<EnemyHealth>().TakeDamage(attackDamage);
            Debug.Log("We hit"+ enemy.name);  
        }
    }
    

    void OnDrawGizmosSelected(){
        Gizmos.DrawWireSphere(AttackPoint.position, AttackRange);
    }

  
}

Здесь скрипт врага:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class EnemySlime : MonoBehaviour
{

    private int armor;
    bool IsDead = false;
    private PlayerStats playerLevelSystem;
    public int expToGive = 15;
    public int damage;
    public Animator animator;
    public int speed;
    [SerializeField]
    Transform player;
    [SerializeField]
    float agroRange;
   Rigidbody2D rb2d;

    private int health;

    void Awake(){
      
    }
   void Start(){
    armor = GetComponent<PlayerStats>().armor;
    health = GetComponent<EnemyHealth>().health;
    playerLevelSystem = FindObjectOfType<PlayerStats>();
    rb2d = GetComponent<Rigidbody2D>();
      
     
   }

  
    void Update(){
        health = GetComponent<EnemyHealth>().health;
          float distToPlayer = Vector2.Distance(transform.position, player.position);

        if (transform.position.y > 0) {
      transform.position = new Vector3(transform.position.x, 0, transform.position.z);
   }
        if(distToPlayer < agroRange && health > 0){
            transform.position = Vector2.MoveTowards(transform.position,player.position,speed*Time.deltaTime);
        }
        if (health <= 0){
          rb2d.velocity = Vector3.zero;          
        }
        if (health <= 0 && IsDead == false){
          ExpToPlayer();
        }
        
        
        
}

    private void ExpToPlayer(){
      playerLevelSystem.AddExp(expToGive);
      Debug.Log("Xp Given");
      IsDead = true;
    }

    void OnCollisionEnter2D(Collision2D col){
      if(col.gameObject.tag == ("Player")){
        col.gameObject.GetComponent<PlayerStats>().Damage(damage-((1/3)*armor));
      }
    }

    
    
   
}

1 Ответ

1 голос
/ 12 июля 2020

Я предпочитаю разделить этот logi c на три разных интерфейса:

public interface IWeapon {} //deals damage
public interface IArmor {} //reduces damage
public interface IBuff {} //modifies entire plot into something else, for example, swapping armor/damage, or identifiyng damage type, or deal/heal damage, or make some special effect like burning, frozen, chilled, etc. Or just specifying you fighting on EXTREME HARDCORE, thus reducing your armor to nothing.

Затем я бы определил интерфейс, который вычисляет, что происходит при ударе:

public interface IDamage {} //identifies what happens, it can deal zero damage and flip player upside down, froze him, or whatever.
public inteface IDamageSystem
{
    IDamage Calculate(IWeapon weapon, IArmor armor, params IBuff[] buffs);
}

В идеале, IWeapon / IArmor сам по себе является баффом, поэтому его можно опустить, вы просто передаете кучу условий и соответственно рассчитываете урон.

Тогда что-то вроде apply должно присутствовать на ваших "здоровых" объектах, что в конечном итоге просто изменяет состояние сущность и ничего больше:

public interface ILivingBeing
{
    void ApplyDamage(IDamage damage);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...