Announcement

Collapse
No announcement yet.

Training Stream - Tanks vs. Zombies, p.3 - May 17th

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

    [TWITCH] Training Stream - Tanks vs. Zombies, p.3 - May 17th



    WHAT

    Continuing the "Tanks" C++ stream, Richard and Lauren will be making tanks to fight a zombie onslaught, using Paper2D. This time, we're adding the ability to aim our tank's turret with the mouse and fire a projectile from it.

    WHEN
    Tuesday, May 17th @ 2:00PM-3:00PM ET - Countdown

    WHERE
    www.twitch.tv/unrealengine

    WHO
    Lauren Ridge - Training Content Creator - @LRRidge
    Richard Hinckley - Sr Learning Resource Engineer

    Feel free to ask any questions on the topic in the thread below, and remember, while we try to give attention to all inquiries, it's not always possible to answer everyone's questions as they come up. This is especially true for off-topic requests, as it's rather likely that we don't have the appropriate person around to answer. Thanks for understanding!

    ASSETS HERE!


    Archive:

    Attached Files
    Last edited by Alexander Paschall; 05-26-2016, 10:17 AM. Reason: Adding image
    Twitch /unrealalexander| Twitter @UnrealAlexander
    How to report a bug? | Installation & Setup issues?
    Call me to a thread by posting this: [MENTION]Alexander Paschall[/MENTION]

    #2
    Great stuff again! Any chance for the code? The very last part spawning the missile isn't working for me and I'm getting an error that the AMissile isn't an AActor in the if statement:

    if(AMissile*NewProjectile = World->SpawnActor(Projectile))

    I tried changing the header file to make it an actor but that didn't work either. Im still pretty new to c++.

    Thank you!

    PS Im still not able to use the Player Start in the editor to spawn the tank in so let us know how you fixed that too!

    Comment


      #3
      Originally posted by TheDuke View Post
      Great stuff again! Any chance for the code? The very last part spawning the missile isn't working for me and I'm getting an error that the AMissile isn't an AActor in the if statement:

      if(AMissile*NewProjectile = World->SpawnActor(Projectile))

      I tried changing the header file to make it an actor but that didn't work either. Im still pretty new to c++.
      What error are you getting? Also, did you remember to add the AMissile code to your project? And yes, we will be posting the code soon.

      Originally posted by TheDuke View Post
      PS Im still not able to use the Player Start in the editor to spawn the tank in so let us know how you fixed that too!
      Most likely it was just setting the default pawn class and game mode and all of that stuff I showed in the Project Settings page. It's really more of a question of what I forgot to do last time, as this is usually very straightforward. I just missed something, and I have forgotten exactly what it was. When the project is posted, it should work fine, I just don't remember what I missed the first time around.

      Comment


        #4
        The project is now available for download in our Asset Sharing forum. The post is here:
        https://forums.unrealengine.com/show...484#post536484

        Comment


          #5
          Hey Richard

          Below is the error I'm still getting (I had added the AMissile to the project). Its this line that its not happy about...if(AMissile*NewProjectile = World->SpawnActor(Projectile))

          EDIT: I get error C2440: initialising: Cannot convert from AActor * to AMissile *
          Note: Cast from base to derived requires dynamic cast or static cast

          The download project you linked doesnt seem to have the code folder that you had before in pervious downloads which i found the most useful to compare etc. Would it be possible to add that?

          D

          Comment


            #6
            Hi Richard,

            First of all, thank you for doing this stream series. You and Lauren have done a fantastic job explaining Unreal's C++ API.

            A couple of things I've noticed:

            1)
            In your ATank::Tick method, in the part that handles the tank's rotation there is a small problem.


            if (AdjustedDeltaYaw < -90.0f)
            {
            AdjustedDeltaYaw += 180.0f;
            bReverse = true;
            }

            else if (AdjustedDeltaYaw > 90.0f)
            {
            AdjustedDeltaYaw -= 180.0f;
            bReverse = true;
            }


            Float point precision errors make these comparisons fragile. For example, when the AdjustedDeltaYaw is 90, but the float representation is slightly off (90.0000001) the tank will move in the opposite direction. We need tolerance bounds to solve the issue.

            2)
            To fix the issue with TankBP not spawning at PlayerStart, I had to change the "Spawn Collision Handling Method" of TankBP to "Try To Adjust Location, But Always Spawn". But I couldn't figure out what I was colliding with. Do you know what is happening?

            Comment


              #7
              Originally posted by gseben View Post
              First of all, thank you for doing this stream series. You and Lauren have done a fantastic job explaining Unreal's C++ API.
              Thanks! Glad to know it's helpful.

              Originally posted by gseben View Post
              1)
              In your ATank::Tick method, in the part that handles the tank's rotation there is a small problem.
              ...
              Float point precision errors make these comparisons fragile. For example, when the AdjustedDeltaYaw is 90, but the float representation is slightly off (90.0000001) the tank will move in the opposite direction. We need tolerance bounds to solve the issue.
              Do you mean that the tank will actually move the wrong direction, or that it will turn suboptimally when it's right on the line between turning right and turning left? Depending on what the effect is, there are cases in gameplay programming where I'm OK with fragility. Usually, in engine-level programming, I would be more strict about things like that, but if it's at a gameplay level and doesn't lead to a bad player experience, it's usually considered acceptable. So, the tank turning an extra 0.0000001 degrees by rotating the wrong way is OK, but the tank moving left when I press right or vibrating in place is not.

              Originally posted by gseben View Post
              2)
              To fix the issue with TankBP not spawning at PlayerStart, I had to change the "Spawn Collision Handling Method" of TankBP to "Try To Adjust Location, But Always Spawn". But I couldn't figure out what I was colliding with. Do you know what is happening?
              I would probably have gone with "always spawn" without the location adjustment, but the fact that it's moving you around is interesting, because that means it's detecting a collision, as you said, and we don't deliberately have any collision geometry on the tank, or the land, for that matter. Maybe we need to go through the sprite components that we used to make the tank/turret/terrain and double-check that collision is turned off. That seems like it is the most probable cause of an issue like that.

              Comment


                #8
                Originally posted by TheDuke View Post
                Below is the error I'm still getting (I had added the AMissile to the project). Its this line that its not happy about...if(AMissile*NewProjectile = World->SpawnActor(Projectile))
                Hello! I just answered your post in the other forum, but the short version is that we've updated the zip file with tested code, so hopefully that will fix it.

                Comment


                  #9
                  Hopefully I do not come off the wrong way, because I do not mean this in a rushing or negative way, but I was wondering if their happens to be an estimated time of Part 4 of the stream? In my Game Prototyping Class, along with my group assignment, I am following a long a tutorial series and have to turn that in, in two weeks. Doesn't have to be completed, just have to do as much as I can, so I am just curious as to when the next part is Sorry if I am not allowed to ask this!

                  Comment


                    #10
                    Hi UchihaKite! Right now, we're scheduled for 6/14 - hope to see you then!

                    Comment


                      #11
                      Originally posted by Lauren Ridge View Post
                      Hi UchihaKite! Right now, we're scheduled for 6/14 - hope to see you then!
                      Typically I wait until it is on Youtube, because I am usually busying doing my C++ homework, but this will defiantly be my first Stream. Looking forward to it, thank you very much for the reply!

                      Comment


                        #12
                        Originally posted by Richard Hinckley View Post
                        Do you mean that the tank will actually move the wrong direction, or that it will turn suboptimally when it's right on the line between turning right and turning left? Depending on what the effect is, there are cases in gameplay programming where I'm OK with fragility. Usually, in engine-level programming, I would be more strict about things like that, but if it's at a gameplay level and doesn't lead to a bad player experience, it's usually considered acceptable. So, the tank turning an extra 0.0000001 degrees by rotating the wrong way is OK, but the tank moving left when I press right or vibrating in place is not.
                        The problem that I see is not that the tank is turning sub-optimally or incorrectly by a very small degree, it actually reverses direction. For example, when turning the tank clockwise, and logging the Yaw values as they change, the tank's direction never gets to 90 degrees:
                        LogTemp:Warning: TankDirection->GetComponentRotation().Yaw, DesiredMovementDirection.Rotation().Yaw: (89.999992, 90.000000)
                        LogTemp:Warning: DeltaYaw, AdjustedDeltaYaw: (0.000008, 0.000008)
                        LogTemp:Warning: TankDirection->GetComponentRotation().Yaw, DesiredMovementDirection.Rotation().Yaw: (89.999992, 90.000000)
                        LogTemp:Warning: DeltaYaw, AdjustedDeltaYaw: (0.000008, 0.000008)
                        LogTemp:Warning: TankDirection->GetComponentRotation().Yaw, DesiredMovementDirection.Rotation().Yaw: (89.999992, 90.000000)
                        LogTemp:Warning: DeltaYaw, AdjustedDeltaYaw: (0.000008, 0.000008)


                        Trying to turn the tank by an additional 90 degrees results in:
                        LogTemp:Warning: TankDirection->GetComponentRotation().Yaw, DesiredMovementDirection.Rotation().Yaw: (89.999992, 180.000000)
                        LogTemp:Warning: DeltaYaw, AdjustedDeltaYaw: (90.000008, -89.999992)


                        Note how AdjustedDeltaYaw becomes negative since the difference between the tank direction and the desired direction is slightly greater than 90 degrees. I'm not sure where this small error is coming from, and how reproducible it is, but it happens consistently for me.

                        Originally posted by Richard Hinckley View Post
                        I would probably have gone with "always spawn" without the location adjustment, but the fact that it's moving you around is interesting, because that means it's detecting a collision, as you said, and we don't deliberately have any collision geometry on the tank, or the land, for that matter. Maybe we need to go through the sprite components that we used to make the tank/turret/terrain and double-check that collision is turned off. That seems like it is the most probable cause of an issue like that.
                        Thanks, disabling collision on the tank, turret and terrain fixed the spawning issue.

                        Comment


                          #13
                          Hello Everyone.I have updated my engine to 4.11 .I have an error in Turret.cpp file that ParentComponentActor is not declared.Also the page for ParentComponentActor has been removed from documentation.Any help?

                          Comment


                            #14
                            Originally posted by Freedom911 View Post
                            Hello Everyone.I have updated my engine to 4.11 .I have an error in Turret.cpp file that ParentComponentActor is not declared.Also the page for ParentComponentActor has been removed from documentation.Any help?
                            Hello, Freedom911. You're right, that won't work in 4.11 because it has been deprecated. Here's the relevant piece of code from Actor.h:

                            Code:
                            private:
                            	/** The Actor that owns the UChildActorComponent that owns this Actor. */
                            	UPROPERTY()
                            	TWeakObjectPtr<AActor> ParentComponentActor_DEPRECATED;	
                            
                            	/** The UChildActorComponent that owns this Actor. */
                            	UPROPERTY()
                            	TWeakObjectPtr<UChildActorComponent> ParentComponent;
                            Although this change takes away your ability to get your parent actor directly, you can now get the actual component that spawned you by calling GetParentComponent(). From there, you can find the actor that owns the component as usual, and that's what we need in this turret function. Overall, this is an improvement, because you could have an actor with multiple child actor components, and you'd have to search through them if you wanted to know which one spawned you. Now, you can go directly to that component and then quickly and easily trace it back up to the parent from there. On our next stream, it is likely that we'll go up to 4.12, in which case the next code drop will address this and any other API breaks that have happened since 4.10. Thanks for your question!

                            Comment


                              #15
                              Thanks, gseben, I understand what you mean now. Yes, there's some imprecision there, so checking the absolute value of delta against an epsilon would be a good idea to stop redundant rotator usage. To fix that, we'll use KINDA_SMALL_NUMBER as our epsilon. We'll also need to check if DeltaYaw is 180. To do this, we should replace this check:

                              Code:
                              			if (DeltaYaw != 0.0f)
                              with this:

                              Code:
                              			if (FMath::IsNearlyZero(DeltaYaw - 180.0f, KINDA_SMALL_NUMBER))
                              			{
                              				bReverse = true;
                              			}
                              			else if (!FMath::IsNearlyZero(DeltaYaw, KINDA_SMALL_NUMBER))
                              I hope this clears up the issue you were seeing. On my end, there was no visible defect coming from this, but rotators were being set constantly at times when it wasn't needed and this prevents that.

                              Comment

                              Working...
                              X