Как обернуть эти повторяющиеся строки кода в Unity простым способом? - PullRequest
1 голос
/ 18 января 2020

Я сделал этот беспорядок, который отлично работает, но его трудно читать и изменять.

private void OnTriggerEnter(Collider other)
{
    if (gunController.isGrabbed)
    {
        if (other.gameObject.CompareTag("PlayerBullet") && gameObject.CompareTag("Enemy1")) //Player to Enemy fire
        {
            enemy1.enemyHealth -= gunController.gunDamage;
            Destroy(other.gameObject);

        }
        else if (other.gameObject.CompareTag("Enemy1Bullet") && gameObject.CompareTag("Player")) //Enemy to player fire
        {
            player.playerHealth -= gunController.gunDamage;
            Destroy(other.gameObject);
        }

    }
    else if(shotgunController.isGrabbed)
    {
        if (other.gameObject.CompareTag("PlayerBullet") && gameObject.CompareTag("Enemy1")) //Player to Enemy fire
        {
            enemy1.enemyHealth -= shotgunController.gunDamage;
            Destroy(other.gameObject);

        }
        else if (other.gameObject.CompareTag("Enemy1Bullet") && gameObject.CompareTag("Player")) //Enemy to player fire
        {
            player.playerHealth -= shotgunController.gunDamage;
            Destroy(other.gameObject);
        }

    } else if (uziController.isGrabbed)
    {
        if (other.gameObject.CompareTag("PlayerBullet") && gameObject.CompareTag("Enemy1")) //Player to Enemy fire
        {
            enemy1.enemyHealth -= uziController.gunDamage;
            Destroy(other.gameObject);

        }
        else if (other.gameObject.CompareTag("Enemy1Bullet") && gameObject.CompareTag("Player")) //Enemy to player fire
        {
            player.playerHealth -= uziController.gunDamage;
            Destroy(other.gameObject);
        }
    }

В основном, есть один контроллер для каждого оружия (пистолет, дробовик, узи) и код тот же для все они, единственное, что меняется, - это имя контроллера.

Поэтому моя идея состояла в том, чтобы создать метод и передать в качестве параметра список <> контроллеров и трижды повторить итерацию в одном и том же коде , Но я не могу передать список, поскольку типы контроллеров уникальны, я не могу хранить в списке различные типы контроллеров.

Я не знаю, есть ли более элегантный способ сделать это .

Ответы [ 2 ]

2 голосов
/ 18 января 2020

Подумайте о настройке базового класса, например, WeaponController или Controller. Теперь поместите в него все общие элементы c. Затем создайте отдельный класс для каждого типа оружия (если это действительно необходимо; использование префабов также может быть осуществимо, попробуйте изучить их). Пусть эти классы унаследованы от WeaponController, а затем добавьте свои собственные вещи, специфичные для типа оружия c сверху. Для вашего общего управления c, как и для игрока с оружием, вам теперь нужно использовать только класс WeaponController (GetComponent<WeaponController>()) - чтобы эти части кода не заботились о специфике, но позволяли обрабатывать специфику внутри указанного класса c как ShotgunController. Например,

using UnityEngine;

public class WeaponController : MonoBehaviour
{
    [SerializeField] AudioSource dropSound = null;
    protected Rigidbody body = null;
    protected int bullets = 10;
    protected float reloadSeconds = 0.5f;

    protected virtual void Fire()
    {
        if (bullets > 0)
        {
            bullets--;
            FireBullet();
        }
    }

    // etc.
}

и

using UnityEngine;

public class ShotgunController : WeaponController
{
    [SerializeField] GameObject bulletShellPrefab = null;

    protected override void Fire()
    {
        base.Fire();
        EmitBulletShell();
    }

    void EmitBulletShell()
    {
        // Maybe you only want shotguns to emit bullet shells,
        // so that code goes here.
    }

    // etc.
}

Удачи!

2 голосов
/ 18 января 2020

Если контроллеры не имеют общего базового класса или интерфейса,

private void doDamage(bool isGrabbed, int damage)
{
    if (isGrabbed)
    {
        if (other.gameObject.CompareTag("PlayerBullet") && gameObject.CompareTag("Enemy1")) //Player to Enemy fire
        {
            enemy1.enemyHealth -= damage;
            Destroy(other.gameObject);

        }
        else if (other.gameObject.CompareTag("Enemy1Bullet") && gameObject.CompareTag("Player")) //Enemy to player fire
        {
            player.playerHealth -= damage;
            Destroy(other.gameObject);
        }

    }

}
private void OnTriggerEnter(Collider other)
{
    doDamage(gunController.isGrabbed, gunController.gunDamage);
    doDamage(shotgunController.isGrabbed, shotgunController.gunDamage);
    doDamage(uziController.isGrabbed,uziController.gunDamage);
}

Если контроллеры имеют общий базовый класс (или являются экземплярами одного и того же класса), вы можете просто

private void doDamage(Controller controller)
{
    if (controller.isGrabbed)
    {
        if (other.gameObject.CompareTag("PlayerBullet") && gameObject.CompareTag("Enemy1")) //Player to Enemy fire
        {
            enemy1.enemyHealth -= controller.damage;
            Destroy(other.gameObject);

        }
        else if (other.gameObject.CompareTag("Enemy1Bullet") && gameObject.CompareTag("Player")) //Enemy to player fire
        {
            player.playerHealth -= controller.damage;
            Destroy(other.gameObject);
        }
    }           
}
private void OnTriggerEnter(Collider other)
{
    doDamage(gunController);
    doDamage(shotgunController);
    doDamage(uziController);
}

Если Controller является компонентом, вы можете просто GetComponents получить все их, а затем l oop через коллекцию, вызывая doDamage для каждого из них.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...