Reputation: 57
I have a very strange issue where class B
and C
both inherits from class A
.
Basically, class A
handles life points and damage taking when B
handles enemy and C
handles destroyable objects.
I have my player that uses a Raycast
to check if it hit one of these B
or C
classes by checking if GetComponent<A>()
does return null or not. Then, it can use the A
class to apply damage.
It works well, until class B
(the enemy) throws an attack. Then GetComponent<A>()
starts returning null.
My script is pretty messy and complex so I wanted to know if it doesn't come from the GetComponent<A>()
. I mean, doesn't C# has polymorphism?
So here's the method TakeDamage()
in my main class (class A):
public void TakeDamage(float dmg, RaycastHit hit)
{
Hit(hit);
currentHp -= dmg;
if (currentHp <= 0)
{
currentHp = 0;
Die();
}
}
Here's the attack mechanism of my Enemy
class (class 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);
}
}
Here's the script attached to the weapon that tries to get access to the parent method:
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);
}
Upvotes: 0
Views: 1450
Reputation: 36
I'm just thinking why you need to call A to execute the TakeDamage method, you can call B or C and call the TakeDamage method because it is inherited by B and C.
hit.transform.GetComponent<B>().TakeDamage(_damagePerHit, hit);
Upvotes: 0
Reputation: 1074
C# inheritance does not constitute a Unity Component
. If you want to access your inherited class, you will need to have the overridden method to be virtual
.
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);
}
}
If you would rather use Unity's built-in Component
system, see the following.
Given: there are multiple scripts on a single, same GameObject
public class A
{
public int TakeDamage(int damageTaken) { ... }
}
public class B
{
public int AnotherMethod(int damage)
{
gameObject.GetComponent<A>().TakeDamage(damage);
}
}
Upvotes: 2