- Home /
How to use the protected override void function(T component) function
I am using the following two functions after following the Unity Roguelike tutorial and I am trying to modify it so that the player can attack the enemies. The problem comes in because im unfamiliar with the function(T component) function and im unsure of how to call it.
The AttemptMove() function checks if the player collides with anything and if its a wall, then the second function, OnCantMove() is called. How can I check what the 'hitComponent' is that is being passed into the OnCantMove() function so that I can create if statements for different objects.
Thanks guys.
protected virtual void AttemptMove<T> (int xDir, int yDir)
where T: Component
{
RaycastHit2D hit;
bool canMove= Move (xDir, yDir, out hit);
if (hit.transform == null)
return;
T hitComponent = hit.transform.GetComponent<T> ();
if (!canMove && hitComponent != null)
OnCantMove (hitComponent);
}
and `
protected override void OnCantMove<T>(T component)
{
Wall hitWall = component as Wall;
hitWall.DamageWall (wallDamage);
animator.SetTrigger ("PlayerChop");
}`
Answer by Kyle_WG · Mar 14, 2017 at 09:59 AM
Like the keyword as
, there is also is
which can be used in if statements like below.
protected override void OnCantMove<T>(T component) : where T : Component
{
if (component is Wall)
{
Wall hitWall = component as Wall;
hitWall.DamageWall (wallDamage);
animator.SetTrigger ("PlayerChop");
}
else if (component is Barrel)
{
// do barrel related stuff
}
}
Or you can check if the hitWall == null
as the component as Wall
statement will fail silently if not the right type.
Roughly:
<T>(T component)
is a way of allowing any specified type in that function.
: where T : Component
is a way of restricting that type of only types inheriting from Component.
You are calling it correct. Just think of the parameter as a dummy for any component passed through. Then in that function you can check that dummy to see if it is of type 'Wall'. Although, that function needs to be decalred virtual in a super class if you're overriding it. (or remove that keyword if not needed)
If you're unsure of virtual functions / overriding then it will be wise to look into it more. Especially understanding Objet Oriented design will help greatly, especially in this object / component heavy engine.
While this is all true it's actually a bad choice to use a generic parameter here. I had a quick look at the tutorial and they actually expect the player to call Attempt$$anonymous$$ove<Wall>(x,y)
while the enemy would call Attempt$$anonymous$$ove<Player>(x,y)
. This makes no sense if you want to hit several different objects. It's actually pointless to use a generic parameter because neither "Attempt$$anonymous$$ove" nor "OnCant$$anonymous$$ove" actually does anything "generic". Attempt$$anonymous$$ove only pass the type on. OnCant$$anonymous$$ove on the other hand treats the parameter as "Component" and manually casts it into a wall. They omitted a type check because they know they only call Attempt$$anonymous$$ove<Wall>(x,y)
. However that's not possible when you want to hit multiple objects.
So the whole design is flawed and not very flexible. "OnCant$$anonymous$$ove" doesn't need to be generic at all. If you remove the generic parameter and turn the "T component" parameter into a "Component component" parameter everything would still be the same.
To be able to check for multiple things at once the components you want to hit either have to derive from a base class or implement a common interface. The interface would be the best solution. GetComponent would simply use the base class / interface and just pass the component to OnCant$$anonymous$$ove where you would do a type check if necessary. In that case the generic parameter of Attempt$$anonymous$$ove is completely obsolete.
To sum up: This tutorial has a bad concept that is not flexible. I would even call that "misusing" of generic parameters. Generics are mainly useful when the method returns that generic type. So the caller specifies the type and he gets back what he has requested. Even for the way it's designed in the tutorial OnCant$$anonymous$$ove doesn't need to be generic. And to actually allow to hit multiple different objects the concept has to be changed all together.
Aye, agreed, totally misused! Unity isn't an engine that enforces good program$$anonymous$$g practices so I would definitely re-advise OP to look into different OO design patterns and learn the pros and cons of using templates / generics etc. if wanting to go further. Shame the tutorials are mal-designed. Especially when Unity attracts new-to-program$$anonymous$$g developers that want to get coding and are introduced to it with this. Wouldn't be so bad if the code was wrote in a simple way, but this is just unnecessary. Always $$anonymous$$ISS.