Originally posted by Emaer
View Post
Announcement
Collapse
No announcement yet.
How to override a parent component in UE4 C++?
Collapse
X
-
Emaer repliedOriginally posted by Tomza View Post
//This doesn't work for B
Code:child1->Box (the component is inherited from A, not created in B)->AttachToComponent(GetMesh(), FAttachmentTransformRules::SnapToTargetNotIncludingScale, SocketName);
Code:child2->Box (the component is inherited from A, not created in B)->AttachToComponent(GetMesh(), FAttachmentTransformRules::SnapToTargetNotIncludingScale, SocketName);
Code:parent->Box (the component is created in A)->AttachToComponent(GetMesh(), FAttachmentTransformRules::SnapToTargetNotIncludingScale, SocketName);
And if `Box` is member of class `A`, then you don't need downcasting to B1/B2/B3, etc. to access this var.
Leave a comment:
-
Tomza repliedIn general, the problem is simple. Usually, you use a component created in a class to attach the object based on the class to a player. But in my case, the component is not created in the class, but is inherited from its parent. Two important things:
1/ Inheriting components
2/ Using components to attach an object to another object
Leave a comment:
-
Tomza repliedOriginally posted by Jorhoto View PostI am searching for this for a while, and the best way I found by now (which is not inheritance at all):
1. So you create your component "MyHealth" that includes a function named "Kill" and you create an EventDispatcher: OnKill which is called at the end of your Kill function.
2. Create your classes (or blueprint) that implements MyHealth. (can be anything with health in your game)
3. You want to kill your char... So you call MyHealth-Kill()
This will call the Kill function in the MyHealth (only in the component blueprint and where you do your default implementation) and then the event.
If you want to do something else in your actor implementing MyHealth, add the event OnKill.
Leave a comment:
-
Tomza repliedOriginally posted by henryLiu View Post
Probably there are some mistake in B, if you have no problem with A and those BP from A. Normally it would be more helpful with some code.
Class A. We create components in the parent class:
A.h
Code:UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "UsableMesh") class UBoxComponent* Box; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "UsableMesh") class UStaticMeshComponent* PickupMesh;
Code:Box = CreateDefaultSubobject<UBoxComponent>(TEXT("Box")); RootComponent = Box; PickupMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("PickupMesh")); PickupMesh->SetRelativeLocation(FVector(0.0f, 0.0f, 0.0f)); PickupMesh->SetupAttachment(RootComponent);
We create a child B from the class A:
B.h
//Nothing to do - the component is inherited from A
//Other stuff specific for B
...
B.cpp
//Nothing to do - the component is inherited from A
//Other stuff specific for B
...
However, we create blueprints based on the class B and put them in the level. There are various children of the class B (B1, B2, etc.), but all are based on the class A and all inherit their components from the class A. So all children B have the same components (Box and PickupMesh).
------------------------------------------------------------------------------------------------------------------------------------
Controller.h
//Declare a raycast function
Controller.cpp
//the raycast function detects all B classes based on A and returns A
Code:bool bIsHitSomething = GetWorld()->LineTraceSingleByObjectType(HitData, Start, End, FCollisionObjectQueryParams::AllObjects, RV_TraceParams); if(bIsHitSomething){ A* parent = Cast<A>(HitTarget); } return parent;
------------------------------------------------------------------------------------------------------------------------------------
Player.cpp
//Now we use the object (of type A) detected by the raycast and stored in the variable (above mentioned), so:
//Get reference to the controller (Controller.cpp)
//Get the detected object in the variable from the controller, so in reality we have A and we must cast to B (to know if it is B1, B2, etc.)
Code:B1* child1 = Cast<B1>(A); B2* child2 = Cast<B2>(A);
//Get the the inherited component from B to attach the object (a blueprint based on B) to the player
//This doesn't work for B
Code:child1->Box (the component is inherited from A, not created in B)->AttachToComponent(GetMesh(), FAttachmentTransformRules::SnapToTargetNotIncludingScale, SocketName);
Code:child2->Box (the component is inherited from A, not created in B)->AttachToComponent(GetMesh(), FAttachmentTransformRules::SnapToTargetNotIncludingScale, SocketName);
Code:parent->Box (the component is created in A)->AttachToComponent(GetMesh(), FAttachmentTransformRules::SnapToTargetNotIncludingScale, SocketName);
Last edited by Tomza; 04-27-2019, 03:52 AM.
Leave a comment:
-
henryLiu repliedOriginally posted by Tomza View Post
A -> B1
A -> B2
A -> B3
I just have a base class A with some components. And then I create a child B based on the base class, inheriting all the components. There are a few types of children B based on that parent class A and my raycast detect them by their base class A that is the same for all the children B. My player should attach the children to the socket in its mesh. The problem is that I can attach only the parent class A (by using its components), not its children B that inheriting the components from their base class A. How can I attach any of the children B by using the inherited components from the parent class?
AttachToComponent(GetMesh(), FAttachmentTransformRules::SnapToTargetNotIncludingScale, SocketName); needs a valid component to attach to a mesh socket. It works ony for the base class A, not for its children B.
A(Component1, Component2) ->B1 (Component1[inherited], Component2[inherited])
A(Component1, Component2) ->B2(Component1[inherited], Component2[inherited])
IN MY PLAYER CLASS:-----------
B1
Component1[inherited]->AttachToComponent(GetMesh(), FAttachmentTransformRules::SnapToTargetNotIncludingScale, SocketName);
B2
Component1[inherited]->AttachToComponent(GetMesh(), FAttachmentTransformRules::SnapToTargetNotIncludingScale, SocketName);
I'm interesting in the process of inheriting of the Actor components. I wish to attach a child B by using its inherited from A component. I can attach only A, where the component is created, but I cannot do the same with B. Do I need to create the components separately for each children? Not inherit them from their parent?
Instead of creating components directly in children to use them for attaching, I created in their parent. And I wish to use them to attach children to the player.
Those children are just items that can be attached to the player. All the items are based on the same parent class, but their mesh can be different. Raycast detects the items and each of them can be attached/detached by pressing a key. They are detected by using their parent class that has the components created. Then, I cast the found parent class to see what item is and attach it to the player with using the inherited component. The problem is I cannot attach an item, only its parent class.
Question is: Can I use the inherited component to attach an object to a socket in a mesh? If so, how can I do that?
Probably there are some mistake in B, if you have no problem with A and those BP from A. Normally it would be more helpful with some code.
Leave a comment:
-
Jorhoto repliedOriginally posted by Tomza View PostDoes somebody know how to inherit components properly in Unreal? I know the topic is rather complex and i have not found any good example how to do that.
1. So you create your component "MyHealth" that includes a function named "Kill" and you create an EventDispatcher: OnKill which is called at the end of your Kill function.
2. Create your classes (or blueprint) that implements MyHealth. (can be anything with health in your game)
3. You want to kill your char... So you call MyHealth-Kill()
This will call the Kill function in the MyHealth (only in the component blueprint and where you do your default implementation) and then the event.
If you want to do something else in your actor implementing MyHealth, add the event OnKill.
Leave a comment:
-
Tomza repliedOriginally posted by OptimisticMonkey View PostSlightly confused about what exactly you are asking.... If it is not working as expected paste code
A -> B2
A -> B3
I just have a base class A with some components. And then I create a child B based on the base class, inheriting all the components. There are a few types of children B based on that parent class A and my raycast detect them by their base class A that is the same for all the children B. My player should attach the children to the socket in its mesh. The problem is that I can attach only the parent class A (by using its components), not its children B that inheriting the components from their base class A. How can I attach any of the children B by using the inherited components from the parent class?
AttachToComponent(GetMesh(), FAttachmentTransformRules::SnapToTargetNotIncludingScale, SocketName); needs a valid component to attach to a mesh socket. It works ony for the base class A, not for its children B.
A(Component1, Component2) ->B1 (Component1[inherited], Component2[inherited])
A(Component1, Component2) ->B2(Component1[inherited], Component2[inherited])
IN MY PLAYER CLASS:-----------
B1
Component1[inherited]->AttachToComponent(GetMesh(), FAttachmentTransformRules::SnapToTargetNotIncludingScale, SocketName);
B2
Component1[inherited]->AttachToComponent(GetMesh(), FAttachmentTransformRules::SnapToTargetNotIncludingScale, SocketName);
I'm interesting in the process of inheriting of the Actor components. I wish to attach a child B by using its inherited from A component. I can attach only A, where the component is created, but I cannot do the same with B. Do I need to create the components separately for each children? Not inherit them from their parent?
Instead of creating components directly in children to use them for attaching, I created in their parent. And I wish to use them to attach children to the player.
Those children are just items that can be attached to the player. All the items are based on the same parent class, but their mesh can be different. Raycast detects the items and each of them can be attached/detached by pressing a key. They are detected by using their parent class that has the components created. Then, I cast the found parent class to see what item is and attach it to the player with using the inherited component. The problem is I cannot attach an item, only its parent class.
Question is: Can I use the inherited component to attach an object to a socket in a mesh? If so, how can I do that?Last edited by Tomza; 04-23-2019, 01:18 PM.
Leave a comment:
-
OptimisticMonkey repliedSlightly confused about what exactly you are asking.... If it is not working as expected paste code
Leave a comment:
-
Tomza repliedOriginally posted by OptimisticMonkey View PostDefine your property as :
UPROPERTY(EditAnywhere, Category=Foo) TSubclassOf<AMyBaseClass> MyProperty;
Leave a comment:
-
OptimisticMonkey repliedDefine your property as :
UPROPERTY(EditAnywhere, Category=Foo) TSubclassOf<AMyBaseClass> MyProperty;
Leave a comment:
-
Tomza started a topic How to override a parent component in UE4 C++?How to override a parent component in UE4 C++?
I have for example UStaticMeshComponent in a parent class and I wish to override it with another mesh in a child class. I made blueprints for both the parent class and the child class. I'm asking because I cannot attach the child class object to a socket (in my player class). I can only do that with the parent class. How to properly get child components inherited from the parent class and attach to a socket in the player.
ShapeClass -> CubeClass
ShapeClass->SphereClass
I can attach the ShapeClass, but not the CubeClass or SphereClass.
ChildComponentTakenFromTheChildClass(Created in the Parent Class)->AttachToComponent(GetMesh(), FAttachmentTransformRules::SnapToTargetNotIncludingScale, SocketName);Last edited by Tomza; 04-23-2019, 08:27 AM.
Leave a comment: