尝试使用getComponent访问基类

时间:2019-02-21 11:30:32

标签: c# unity3d

我遇到一个非常奇怪的问题,类BC都继承自类A

基本上,当A处理敌人而B处理可摧毁物体时,类别C处理生命点和承受的伤害。

我有一个使用Raycast的播放器,通过检查B是否返回null来检查它是否击中了这些CGetComponent<A>()类之一。然后,它可以使用A类施加伤害。

效果很好,直到B类(敌人)发起攻击为止。然后GetComponent<A>()开始返回null。

我的脚本非常混乱和复杂,因此我想知道它是否不是来自GetComponent<A>()。我的意思是C#不具有多态性吗?


添加的代码

这是我的主类(类A)中的方法TakeDamage()

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 :(得分:2)

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系统,请参阅以下内容。

给出:同一单个GameObject上有多个脚本

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

public class B
{
    public int AnotherMethod(int damage)
    {
        gameObject.GetComponent<A>().TakeDamage(damage);
    }
}

答案 1 :(得分:0)

我只是在想为什么您需要调用A来执行TakeDamage方法,您可以调用B或C并调用TakeDamage方法,因为它是B和C继承的。

hit.transform.GetComponent<B>().TakeDamage(_damagePerHit, hit);