Попытка получить доступ к базовому классу с помощью getcomponent - PullRequest
0 голосов
/ 21 февраля 2019

У меня очень странная проблема, когда класс B и C оба наследуют от класса A.

В основном, класс A обрабатывает очки жизни и получает урон, когда B обращается с врагоми C обрабатывает разрушаемые объекты.

У меня есть игрок, который использует Raycast, чтобы проверить, попал ли он в один из этих классов B или C, проверив, возвращает ли GetComponent<A>() ноль илине.Затем он может использовать класс A для нанесения урона.

Работает хорошо, пока класс B (враг) не бросит атаку.Затем GetComponent<A>() начинает возвращать ноль.

Мой сценарий довольно грязный и сложный, поэтому я хотел узнать, не исходит ли он от GetComponent<A>().Я имею в виду, разве у C # нет полиморфизма?


Добавлен код

Итак, вот метод TakeDamage() в моем основном классе (класс A):

public void TakeDamage(float dmg, RaycastHit hit)
{
    Hit(hit);
    currentHp -= dmg;
    if (currentHp <= 0)
    {
        currentHp = 0;
        Die();
    }
}

Вот механизм атаки моего Enemy класса (класс B):

void Update()
{
    attackCounter -= Time.deltaTime;

    if ((Vector3.Distance(player.transform.position, transform.position) <= detectionDiam) && (isAlive == true))
    {
        _navAgent.SetDestination(player.transform.position);
        _anim.SetFloat("speed", 1f);

        if (Vector3.Distance(player.transform.position, transform.position) <= attackDiam && attackCounter <= 0)
        {
            audiosrc.PlayOneShot(attackSound);
            _anim.SetTrigger("attack");
            attackCounter = attackDelay;
            Invoke("attackRoutine",attackDelay);
        }
    }
    else
    {
        _anim.SetFloat("speed", 0);
    }
}

private void attackRoutine()
{
    if (Vector3.Distance(player.transform.position, transform.position) <= attackDiam && alive==true)
    {
        Player pl = player.GetComponent<Player>();
        pl.TakeDamage(damagePerHit);
    }
}

Вот скрипт, прикрепленный к оружию, который пытается получить доступ к родительскому методу:

void Fire()
{
    if(_actualBulletCount > 0 && _shotCounter < 0 && !isRunning && !isReloading)
    {
        flash.Play();
        _audioSource.Play();
        _anim.SetTrigger("fire");
        _actualBulletCount--;
        _shotCounter = _delayBetweenTwoShots;

        RaycastHit hit;
        Debug.DrawRay(_bulletSpawn.position, _bulletSpawn.TransformDirection(Vector3.forward) * 50f, Color.yellow);
        if (Physics.Raycast(_bulletSpawn.position, _bulletSpawn.TransformDirection(Vector3.forward), out hit, Mathf.Infinity))
        {
            Debug.Log("Did Hit");
            HandleHit(hit);
        }
    }
    printUI();
}

void HandleHit(RaycastHit hit)
{
    Debug.Log(hit.transform.GetComponent<HittableEntity>());
    hit.transform.GetComponent<HittableEntity>().TakeDamage(_damagePerHit,hit);
}

Ответы [ 2 ]

0 голосов
/ 21 февраля 2019

Я просто думаю, почему вам нужно вызвать A для выполнения метода TakeDamage, вы можете вызвать B или C и вызвать метод TakeDamage, потому что он наследуется B и C.

hit.transform.GetComponent<B>().TakeDamage(_damagePerHit, hit);
0 голосов
/ 21 февраля 2019

C # наследование не составляет Unity Component.Если вы хотите получить доступ к вашему унаследованному классу, вам понадобится переопределенный метод: virtual.

C # Полиморфизм

public class A
{
    public virtual int TakeDamage(int damageTaken) { ... }
}

public class B : A
{
    public override int TakeDamage(int damageTaken)
    {
        // Non-base stuff

        // Base stuff
        base(damageTaken);
    }
}

Unity Component

Если выпредпочел бы использовать встроенную систему Unity Component, см. следующее.

Учитывая: существует несколько сценариев на одном и том же GameObject

public class A
{
    public int TakeDamage(int damageTaken) { ... }
}

public class B
{
    public int AnotherMethod(int damage)
    {
        gameObject.GetComponent<A>().TakeDamage(damage);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...