I was able to solve my enemy forward vector to my pawn rotation angle after some help and its made me more confident in being able to code using UE4’s API.
For the past day I’ve been trying to get the next angle which is the rotation of the camera in world space (attached to my pawn) versus the world location of the enemy.
I’ve tried atan2, acos, vector math (dot products etc), rotator deltas, normalizing, clamping, ranges etc.
This is following clockwise 0-360 rotations with 0d world rotation being 0 (north I think)
So what I have in pseudo code is
float TrueTargetBearing::MyBPFuncLib(APawn* TargetShip, APawn* PlayerShip)
{
USceneComponent camera = PlayerShip()->GetComponentByTag("PeriscopeCamera");
FRotator TrueTargetBearing = [All the things above that I tried in blueprints I tried in code as well here to get the view of the camera]
return trueTargetBearing.Z; //Get camera yaw
}
Here is what I;m trying to emulate which is written in c++ edited with what I have gotten done in UE4’s API so far and bold what I;m trying to replace with right now && small font what I should be able to do since it uses less or no trig/vector maths.
// Simulation of the Torpedo Data Computer (TDC)
void tdc::simulate(double delta_t)
{
** // turn bearing dial to set bearing, with max. 2.5 degrees per second
double bearingturn = 2.5 * delta_t;
if (bearing_dial.diff(bearing) <= bearingturn) {
bearing_dial = bearing;
} else {
if (!bearing_dial.is_cw_nearer(bearing))
bearingturn = -bearingturn;
bearing_dial += angle(bearingturn);
} //I HAVE IS_CW_NEARER REPRODUCED IN UE4 C++**
// AoB tracker: updated by bearing
if (angleonthebow_tracking) {
compute_aob(bearing_dial);
}
// compute lead angle from data
double sinrelleadangle = target_speed * angleonthebow.sin() / torpedo_speed;
valid_solution = false;
if (fabs(sinrelleadangle) <= 1.0) {
// angle is relative to absolute bearing
angle relative_lead_angle = angle::from_rad(asin(sinrelleadangle));
if (target_bow_is_left) {
lead_angle = bearing_dial - relative_lead_angle;
} else {
lead_angle = bearing_dial + relative_lead_angle;
}
// compute run time from target distance
angle aob_on_hit = angle(180) - angleonthebow - relative_lead_angle;
torpedo_runtime = (angleonthebow.sin() * target_distance) / (torpedo_speed * aob_on_hit.sin());
// check if torpedo can hit target
if (torpedo_speed * torpedo_runtime <= torpedo_runlength) {
valid_solution = true;
}
Yes I’ve watched many trig and vector math courses. Youtube, KhanAcademy, Ebooks etc.
Basically I can only get it in blueprints, but it gives me 0-180 and 180-0 so I cant even verify if thats right.
I’d like to hire someone to convert this class for me :haha:
Thanks for any input: this is my biggest issue with ue4 is blueprint vs c++ rotations seem to be different and rotations just wont “work” without a ton of “aha” moments that arnt sticking/arnt clear.
Edit: Heres what I’m tryin to solve in picture form, I can link the whole 30 page manual with all teh equations if needed.
I have (~)A AngleOffBow which we solved a few days ago (thanks again!), Co (own course aka world rotation), C (Target course) and R (range), so I’m trying to solve Br (B actually but Br is just relative vs world) which will give me G I’m hoping fairly easily which will allow me to figure out the angle I need to fire an actor at to hit a moving target from a moving target.
Edit: I also have P (length) for both ships.
What has stuck so far is how to calculate an angle (~)x from the big yellow line R given as two points with a forward vector from R as one and a random vector as two.
Edit: Two. This is actually where I’m at also this shows B instead of Br (how they relatate is the following: just world rotation vs relative to pawn rotation…)
B :: The angle between the north and south line and the line of sight to the target, measured clockwise from north (0d to 360d)
Br :: The angle between the vertical plane of the fwd and aft axis of own ship and the vertical plane through the line of sight measured CW from the bow (0d to 360d)
After that I just have to find G (gyro angle) and a few others and I’m good to go.
http://www.maritime.org/doc/tdc/img/pg024.jpg
Edit3: Heres OpenSSN’s bearing code. It appears they have the same issue, is this a limitation of cpp AND ue4? I have latitude and longitude so I could make this work if the math would port fine to ue4
double Submarine::BearingToTarget(Submarine *Target){
double latdif=0, londif=0, bearing = 0; //atan() needs doubles
//LatLonDifference(observer, target, &latdif, &londif);
if (! Target)
return 0;
if (Lat_TotalYards > Target->Lat_TotalYards){
latdif = Lat_TotalYards - Target->Lat_TotalYards;
}
else{
latdif = Target->Lat_TotalYards - Lat_TotalYards;
}
if (Lon_TotalYards > Target->Lon_TotalYards){
londif = Lon_TotalYards - Target->Lon_TotalYards;
}
else{
londif = Target->Lon_TotalYards - Lon_TotalYards;
}
if ((Lon_TotalYards < Target->Lon_TotalYards) &&
(Lat_TotalYards < Target->Lat_TotalYards)){
bearing = (360 - ((atan(latdif / londif) * 360) / 6.28318530717958647692));
}
else if ((Lon_TotalYards < Target->Lon_TotalYards) &&
(Lat_TotalYards > Target->Lat_TotalYards)){
bearing = (0 + ((atan(latdif / londif) * 360) / 6.28318530717958647692));
}
else if ((Lon_TotalYards > Target->Lon_TotalYards) &&
(Lat_TotalYards < Target->Lat_TotalYards)){
bearing = (180 + ((atan(latdif / londif) * 360) / 6.28318530717958647692));
}
else if ((Lon_TotalYards > Target->Lon_TotalYards) &&
(Lat_TotalYards > Target->Lat_TotalYards)){
bearing = (180 - ((atan(latdif / londif) * 360) / 6.28318530717958647692));
}
if (londif == 0){
if (Lat_TotalYards > Target->Lat_TotalYards){
bearing = 90;
}else{
bearing = 270;
}
}
if (latdif == 0){
if (Lon_TotalYards > Target->Lon_TotalYards){
bearing = 180;
}else{
bearing = 0;
}
}
return bearing;
}