Announcement

Collapse
No announcement yet.

How to override a parent component in UE4 C++?

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

    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.

    #2
    https://docs.unrealengine.com/en-US/...re/TSubclassOf
    https://www.casualdistractiongames.com

    Comment


      #3
      Thank you! So how to use it in my code?

      Comment


        #4
        Define your property as :
        UPROPERTY(EditAnywhere, Category=Foo) TSubclassOf<AMyBaseClass> MyProperty;
        https://www.casualdistractiongames.com

        Comment


          #5
          Originally posted by OptimisticMonkey View Post
          Define your property as :
          UPROPERTY(EditAnywhere, Category=Foo) TSubclassOf<AMyBaseClass> MyProperty;
          And for example, I can get my child's UStaticMeshComponent , not the parent's one? Can the components be used with TSubclassOf<>? I did not know that.

          Comment


            #6
            Slightly confused about what exactly you are asking.... If it is not working as expected paste code
            https://www.casualdistractiongames.com

            Comment


              #7
              Originally posted by OptimisticMonkey View Post
              Slightly confused about what exactly you are asking.... If it is not working as expected paste code
              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?
              Last edited by Tomza; 04-23-2019, 01:18 PM.

              Comment


                #8
                Does 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.
                Last edited by Tomza; 04-25-2019, 03:53 AM.

                Comment


                  #9
                  Originally posted by Tomza View Post
                  Does 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.
                  I 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.
                  Attached Files

                  Comment


                    #10
                    Originally 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.

                    Comment


                      #11
                      Originally 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.
                      Thank you for you help.

                      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;
                      A.cpp

                      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;
                      Because there are various blueprints B (B1, B2, etc.), the raycast search for their common parent (A) and when detected, it is stored in the variable of type A. So all B are detected by their parent A. For example, if raycast hits the B3, it is stored in the variable as A. Or if raycast detects B1, it is stored in the variable as A. So we always get A.
                      ------------------------------------------------------------------------------------------------------------------------------------

                      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);
                      etc.


                      //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);
                      , but it works for A:

                      Code:
                      parent->Box (the component is created in A)->AttachToComponent(GetMesh(), FAttachmentTransformRules::SnapToTargetNotIncludingScale, SocketName);
                      Last edited by Tomza; 04-27-2019, 03:52 AM.

                      Comment


                        #12
                        Originally posted by Jorhoto View Post
                        I 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.
                        Thank you for your help, but I don't see how it can solve my problem. I need to attach an object to a player using an inherited component.

                        Comment


                          #13
                          In 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

                          Comment


                            #14
                            Originally 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);
                            , but it works for A:

                            Code:
                            parent->Box (the component is created in A)->AttachToComponent(GetMesh(), FAttachmentTransformRules::SnapToTargetNotIncludingScale, SocketName);
                            What do you mean saying "doesn't work"?
                            And if `Box` is member of class `A`, then you don't need downcasting to B1/B2/B3, etc. to access this var.

                            Comment


                              #15
                              Originally posted by Emaer View Post

                              What do you mean saying "doesn't work"?
                              And if `Box` is member of class `A`, then you don't need downcasting to B1/B2/B3, etc. to access this var.
                              I cannot attach the B1/B2/B3 by using the inherited from A component (box).

                              Comment

                              Working...
                              X