I am trying to implement drone flight, which in a basic sense is fine, except the flying mode in the CharacterMovementComponent isnt really up to the task. It will do for a while i guess, but it doesnt seem to be freely customisable.
The issue is mostly that the flying directions do not seem to be symmetric, it won’t ascend or descend as fast as it will fly horizontally, which for a drone doesnt reallly make sense, it can descend faster, at least as far as accelleration is concerned. Ideally i want to be able to simulate realistic drone movement in the long term, which probably involves quite an in depth movement class, so i need to get some pointers on how to start this. I can’t find why the current movement class treats Vertical movement differently to horizontal in flight. Anyone know?
I considered using the Cosys Airsim plugin to handle the movement but initially that seems like importing a lot of other simulation code, and it doesn’t respond directly to the unreal engine, but to a flight controller i think. All i want is the movement, and id probably like some customisation for the movement as i am making a game not a sim, and i think implementing a Character movement class would be easier than deciphering a science sim.
Is this perhaps just the gravity affecting your drone, have you tried adjusting UCharacterMovementComponent::GravityScale (exposed to BP)? On a quick glance at UCharacterMovementComponent::PhysFlying (and the related functions), I don’t see any other reason why vertical movement would be treated differently to horizontal movement.
I dont think so, i believe gravity is ignored in flying mode. And if flying down that should make down faster right? The issue i am trying to debug with it right now, is trying to get the drone to fly down to a target, it always misses because it cant descend quick enough. I am starting to second guess myself as i cant find something favouring the directions in the cpp files either. so I will do some further testing. There is still an issue in changing acceleration properties for the different directions, im still not sure on the best approach to this even if the directions are in fact symmetric
Not sure if you mentioned or not how exactly you control the drone, but is there a chance someone (you or UE) applies input scaling depending on the input axis? Maybe try to debug APawn::AddMovementInput (if that function is even relevant for your use case) and see if different values are used for vertical vs horizontal input?
Okay, so the asymmetry is my end, i am sorry for ever doubting unreal, i think i am getting closer to understanding the issue though, basically as the drone gains forward momentum, this takes up all the allowed top speed of the drone, and so when it tries to go down it cant add to its top speed particularly, so if the forwards outstrips the down, then it limits its ability to move down. Which is a complicated problem, but at least i understand it a bit better.
So i think i need to measure the horizontal speed, and create a specifically horizontal speed limit, so the character rejects horizontal input that would make it exceed a horizontal speed, so that it will leave room so that vertical speed can be influenced independent of horizontal speed.
Yeah the top speed is going to be based off your 3D velocity, so you’ll need custom logic either way. If your idea turns out fiddly (which it might seeing as you’re trying to approximately leave some “room” for the vertical component), I’d suggest deriving the movement component, adding separate max speeds for horizontal and vertical movement, and overriding the few relevant functions (possibly just CalcVelocity()).
Yeah so my quick throw together of that code did the trick, the drone will now move down quickly, but you are right it is not very elegant, but I should be able to implement max vertical speeds the same way i just limited the horizontal speeds (just reject input at a certain velocity which would mean i could set the max speed to a billion and it would never reach it.). but it would certainly be tidier to implement this in the movement component. My code just now is probably a bit fried because it is late where i am.
Id like to do it the way you are suggesting, but i must confess my C++ experience isnt strong, ive done plenty of text coding just not in C++ or unreal, so if you have further guidance on how to do this i would be extremely grateful. I probably wont be able to get through it today as its getting late, but i will be on it tomorrow.
Well if you’re not experienced with C++ you can probably also stick to your current solution and it’ll be fine assuming you can tune it properly, because overriding it in C++ is definitely more involved and unless your solution stops working there’s no real incentive to invest a bunch of time to make it in C++.
If you decide to try it out, I’d suggest you to (same as for analyzing any unfamiliar C++ system) set a breakpoint in PhysFlying/CalcVelocity/ApplyRequestedMove and see what exactly happens to the velocity and what you want it to do instead. Once you have it figured out, you just derive a new component UDroneMovementComponent : public UCharacterMovementComponent, add the speed limit members float MaxHorizontalSpeed and float MaxVerticalSpeed, and override whichever subset of the above functions you need to override (unable to guess, maybe all 3).
Thank you for the help, i think i will at least give it a try because i am retented like that sometimes, and want to be able to do it if i need to as much as i want to solve the issue at hand.
I will give that a try, i am mostly concerned about migrating my drone class to use a custom movement component, arent character classes locked into using the default movement component? i will have to reparent the drone to a pawn? Which will break my drones children?
Again thank you for the help, has been very useful
Yes, learning something new is the intention, and if i want to be in a position to use sim quality movement, i think i am going to need to understand how to override movement at least a little.
And that looks like it should solve my issue of swapping out the movement component, if that works then it should be simple, which is an extremely useful pointer.
Ok, i gave this a try and i ran into two issues. So i created a DroneCharacterMovementComponent class, and then in order to do your code, i figured i need to my Drone class (that is a blueprint that inherits from character) to inherit from an intermediary class that I have written, so I can pull your trick. So i created DroneCharacter so that the structure can be Character->DroneCharacter-> Drone
Unfortunately after reparenting the Drone file will not save in the editor, presumably due to some of the blueprint code that depends on the Character parent no longer working with DroneCharacter and silently failing after the Reparent. (It compiles fine in editor, but my research led me to believe this is why the save fails)
The other issue, is that my DroneCharacter class wont accept any variation of this constructor that i can write, there will always be an error line under the : on the second line “expected {”, I tried a few imports that i thought might be related but that didnt work, and I am a bit at a loss as at the moment i still dont understand the line fully so its hard to debug.
Its not super urgent that i fix this, as a blueprint only solution will work but as you know its a good opportunity to learn. Do you think its worth trying to make this reparent work so that i can at least add some c++ when needed ? Do you know any way to do it successfully? Am i going about it in the wrong way entirely?
This is the attempt at the line, just in case i have put it in the wrong place or something, i didnt finish the line, but if i understand it anyway there shouldn’t be an error as it is the line just wont change anything. Same error if i finish the line as you have written
Edit: Nevermind, was being a little dumb, the header file declaration of ADroneCharacter needed to match the one given here, so i need to add const FOBjectInitializer& … inside the brackets in the .h file.
Obvious in a way, but i am not used to using header files.
Now i just need to figure out if it is possible to reparent my largish drone file to this file to allow me to override Movement component methods, or if I need to make a new drone class that inherits from this and migrate functionality across more slowly. At the moment i think the second option is the way i will need to go, but if you have any insight on how i can reparent the original class so i dont need to painfully migrate things that would be awesome
There is a little more i need to fix, i think, So the new Character class DroneCharacter isnt showing up in the Editor, and i believe this is because it is incorrectly set up, The header file needed both constructors so needed to look like this
i had left out the default constructor, which apparently unreal expects, which means i need to add that back to the C++ file. I asked copilot and it suggested the following -
This builds in visual studio, but the class doesnt appear in the editor to be extended (it did when the file was left as it was generated)
Edit: Ok now if i return the class to its original state it still doesnt want to show up in the editor, Feels like i should never have crawled out of my hole haha
I only have a few minutes to reply rn, will come back later if this doesn’t fix it:
Make sure your derived Character class has UCLASS(Blueprintable) (should be inherited through the hierarchy anyway, but just in case; maybe you were missing UCLASS as well?)
You shouldn’t need the empty default constructor, I’d actually remove it and see what the compile error is (copy it here if you can’t figure it out)
Migrating things manually will definitely work, but it shouldn’t be necessary because reparenting this (through the BP buttons for reparenting under Class Settings) should work as well, but I’ve definitely seen reparenting issues in the past so this isn’t a guarantee
Edit:
Also, add X_API to your class declaration, something like: class DRONEGAME_API ADroneCharacter
but with the name of your project, and not “DroneGame” (unless that’s the actual name).
Thank you for taking the time to help me, this is the error shown when the default constructor isn’t there, however the project builds fine, as you can hopefully see at the bottom of the image. (This is the .h file, it’s essentially the boilerplate class with the cpp file declaring the constructor like you showed me.
this is the current state of my DroneCharacter.h file, so it has the Blueprintable keyword, and i think it has the X_API already added by the engine on line 8 (project is called darwinswar) but correct me if this is not what you mean
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "DroneCharacter.generated.h"
UCLASS(Blueprintable)
class DARWINSWAR_API ADroneCharacter : public ACharacter
{
GENERATED_BODY()
public:
// Sets default values for this character's properties
ADroneCharacter(const FObjectInitializer& ObjectInitializer);
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
// Called to bind functionality to input
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
};
Ive not finished exploring this, so i may have some progress in the next 10 mins or so
Your first screenshot has no error, the squiggly line is just VS getting confused a bit, the build passed with no errors. Your second screenshot is just Intellisense errors I believe, which is also just VS being VS.
This class seems perfectly fine and should show in the editor, could you try just creating a new blueprint class and see if (A)DroneCharacter is in the list of available parent classes?
unfortunately it is not showing in the editor and i am confused. It showed up when i had made no changes, but if i return it to what (i think) it was, it still doesnt seem to show