Skip to content

Commit e07add6

Browse files
committed
Add internal data structure to replace GameTickPacket
1 parent 6d023b2 commit e07add6

File tree

13 files changed

+265
-46
lines changed

13 files changed

+265
-46
lines changed

RLBotCSharpExample/RLBotCSharpExample/DataConversion.cs

Lines changed: 0 additions & 15 deletions
This file was deleted.
Lines changed: 25 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,44 @@
1-
using System;
1+
using System.Numerics;
22
using RLBotDotNet;
3-
using rlbot.flat;
3+
using RLBotCSharpExample.Utilities.Packet;
44

55
namespace RLBotCSharpExample
66
{
77
// We want to our bot to derive from Bot, and then implement its abstract methods.
88
class ExampleBot : Bot
99
{
1010
// We want the constructor for ExampleBot to extend from Bot, but we don't want to add anything to it.
11+
// You might want to add logging initialisation or other types of setup up here before the bot starts.
1112
public ExampleBot(string botName, int botTeam, int botIndex) : base(botName, botTeam, botIndex) { }
1213

13-
public override Controller GetOutput(GameTickPacket gameTickPacket)
14+
public override Controller GetOutput(rlbot.flat.GameTickPacket gameTickPacket)
1415
{
15-
// This controller object will be returned at the end of the method.
16-
// This controller will contain all the inputs that we want the bot to perform.
17-
Controller controller = new Controller();
16+
// We process the gameTickPacket and convert it to our own internal data structure.
17+
Packet packet = new Packet(gameTickPacket);
1818

19-
// Store the required data from the gameTickPacket.
20-
// The GameTickPacket's attributes are nullables, so you must use .Value.
21-
// It is recommended to create your own internal data structure to avoid the displeasing .Value syntax.
22-
Vector3 ballLocation = gameTickPacket.Ball.Value.Physics.Value.Location.Value;
23-
Vector3 carLocation = gameTickPacket.Players(this.index).Value.Physics.Value.Location.Value;
24-
Rotator carRotation = gameTickPacket.Players(this.index).Value.Physics.Value.Rotation.Value;
19+
// Get the data required to drive to the ball.
20+
Vector3 ballLocation = packet.Ball.Physics.Location;
21+
Vector3 carLocation = packet.Players[index].Physics.Location;
22+
Orientation carRotation = packet.Players[index].Physics.Rotation;
2523

26-
// Calculate to get the angle from the front of the bot's car to the ball.
27-
double botToTargetAngle = Math.Atan2(ballLocation.Y - carLocation.Y, ballLocation.X - carLocation.X);
28-
double botFrontToTargetAngle = botToTargetAngle - carRotation.Yaw;
29-
// Correct the angle
30-
if (botFrontToTargetAngle < -Math.PI)
31-
botFrontToTargetAngle += 2 * Math.PI;
32-
if (botFrontToTargetAngle > Math.PI)
33-
botFrontToTargetAngle -= 2 * Math.PI;
24+
// Find where the ball is relative to us.
25+
Vector3 ballRelativeLocation = Orientation.RelativeLocation(carLocation, ballLocation, carRotation);
3426

3527
// Decide which way to steer in order to get to the ball.
36-
if (botFrontToTargetAngle > 0)
37-
controller.Steer = 1;
28+
// If the ball is to our left, we steer left. Otherwise we steer right.
29+
float steer;
30+
if (ballRelativeLocation.Y > 0)
31+
steer = 1;
3832
else
39-
controller.Steer = -1;
40-
41-
// Set the throttle to 1 so the bot can move.
42-
controller.Throttle = 1;
33+
steer = -1;
4334

44-
return controller;
35+
// This controller will contain all the inputs that we want the bot to perform.
36+
return new Controller
37+
{
38+
// Set the throttle to 1 so the bot can move.
39+
Throttle = 1,
40+
Steer = steer
41+
};
4542
}
4643
}
47-
}
44+
}

RLBotCSharpExample/RLBotCSharpExample/Properties/AssemblyInfo.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using System.Reflection;
2-
using System.Runtime.CompilerServices;
32
using System.Runtime.InteropServices;
43

54
// General Information about an assembly is controlled through the following
@@ -10,7 +9,7 @@
109
[assembly: AssemblyConfiguration("")]
1110
[assembly: AssemblyCompany("")]
1211
[assembly: AssemblyProduct("RLBotCSharpExample")]
13-
[assembly: AssemblyCopyright("Copyright © 2018")]
12+
[assembly: AssemblyCopyright("Copyright © 2020")]
1413
[assembly: AssemblyTrademark("")]
1514
[assembly: AssemblyCulture("")]
1615

RLBotCSharpExample/RLBotCSharpExample/RLBotCSharpExample.csproj

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,18 @@
7373
<Compile Include="ExampleBot.cs" />
7474
<Compile Include="Program.cs" />
7575
<Compile Include="Properties\AssemblyInfo.cs" />
76+
<Compile Include="Utilities\DataConversion.cs" />
77+
<Compile Include="Utilities\Packet\Ball.cs" />
78+
<Compile Include="Utilities\Packet\BoostPadState.cs" />
79+
<Compile Include="Utilities\Packet\GameInfo.cs" />
80+
<Compile Include="Utilities\Packet\Orientation.cs" />
81+
<Compile Include="Utilities\Packet\Physics.cs" />
82+
<Compile Include="Utilities\Packet\Player.cs" />
83+
<Compile Include="Utilities\Packet\Packet.cs" />
84+
<Compile Include="Utilities\Packet\TeamInfo.cs" />
7685
</ItemGroup>
7786
<ItemGroup>
7887
<None Include="App.config" />
79-
<Compile Include="DataConversion.cs" />
8088
<None Include="packages.config" />
8189
<None Include="port.cfg">
8290
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
namespace RLBotCSharpExample.Utilities
2+
{
3+
public static class DataConversion
4+
{
5+
public static System.Numerics.Vector3 ToVector3(this rlbot.flat.Vector3 vector)
6+
{
7+
return new System.Numerics.Vector3(vector.X, vector.Y, vector.Z);
8+
}
9+
10+
public static System.Numerics.Vector2 ToVector2(this rlbot.flat.Vector3 vector)
11+
{
12+
return new System.Numerics.Vector2(vector.X, vector.Y);
13+
}
14+
}
15+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
namespace RLBotCSharpExample.Utilities.Packet
2+
{
3+
public struct Ball
4+
{
5+
public Physics Physics;
6+
7+
public Ball(rlbot.flat.BallInfo ballInfo)
8+
{
9+
Physics = new Physics(ballInfo.Physics.Value);
10+
}
11+
}
12+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
namespace RLBotCSharpExample.Utilities.Packet
2+
{
3+
public struct BoostPadState
4+
{
5+
public float Timer;
6+
public bool IsActive;
7+
8+
public BoostPadState(rlbot.flat.BoostPadState boostPadState)
9+
{
10+
Timer = boostPadState.Timer;
11+
IsActive = boostPadState.IsActive;
12+
}
13+
}
14+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
namespace RLBotCSharpExample.Utilities.Packet
2+
{
3+
public struct GameInfo
4+
{
5+
public float SecondsElapsed;
6+
public float GameTimeRemaining;
7+
public bool IsKickoffPause;
8+
9+
public GameInfo(rlbot.flat.GameInfo gameInfo)
10+
{
11+
SecondsElapsed = gameInfo.SecondsElapsed;
12+
GameTimeRemaining = gameInfo.GameTimeRemaining;
13+
IsKickoffPause = gameInfo.IsKickoffPause;
14+
}
15+
}
16+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
using System;
2+
using System.Numerics;
3+
4+
namespace RLBotCSharpExample.Utilities.Packet
5+
{
6+
public struct Orientation
7+
{
8+
public float Pitch;
9+
public float Roll;
10+
public float Yaw;
11+
12+
public Vector3 Forward;
13+
public Vector3 Right;
14+
public Vector3 Up;
15+
16+
public Orientation(rlbot.flat.Rotator rotator)
17+
{
18+
Pitch = rotator.Pitch;
19+
Roll = rotator.Roll;
20+
Yaw = rotator.Yaw;
21+
22+
float cp = (float) Math.Cos(Pitch);
23+
float cy = (float) Math.Cos(Yaw);
24+
float cr = (float) Math.Cos(Roll);
25+
float sp = (float) Math.Sin(Pitch);
26+
float sy = (float) Math.Sin(Yaw);
27+
float sr = (float) Math.Sin(Roll);
28+
29+
Forward = new Vector3(cp * cy, cp * sy, sp);
30+
Right = new Vector3(cy * sp * sr - cr * sy, sy * sp * sr + cr * cy, -cp * sr);
31+
Up = new Vector3(-cr * cy * sp - sr * sy, -cr * sy * sp + sr * cy, cp * cr);
32+
}
33+
34+
/// <summary>
35+
/// Gets the <see cref="target"/> relative to an object at the given <see cref="start"/>
36+
/// location with the given <see cref="orientation"/>.<br/>
37+
/// For example, you can use this method to get the start of the ball relative to your car.
38+
/// </summary>
39+
/// <param name="start">
40+
/// The global location of the object you want to base the new target off of.
41+
/// This location will be the center of the world.
42+
/// </param>
43+
/// <param name="target">
44+
/// The global location of the target you want to get the relative location of.
45+
/// </param>
46+
/// <param name="orientation">The orientation of the current object.</param>
47+
/// <returns>
48+
/// Returns <see cref="target"/> as a relative location from <see cref="start"/> point of
49+
/// view using the given <see cref="orientation"/>.<br/>
50+
/// Rocket League's coordinate system might be different to what you're used to.
51+
/// The returned vector's components describe the following (relative to the start location
52+
/// and orientation):
53+
/// <list type="bullet">
54+
/// <item>X: How far in front the target is</item>
55+
/// <item>Y: How far right the target is</item>
56+
/// <item>Z: How far above the target is</item>
57+
/// </list>
58+
/// </returns>
59+
public static Vector3 RelativeLocation(Vector3 start, Vector3 target, Orientation orientation)
60+
{
61+
Vector3 startToTarget = target - start;
62+
float x = Vector3.Dot(startToTarget, orientation.Forward);
63+
float y = Vector3.Dot(startToTarget, orientation.Right);
64+
float z = Vector3.Dot(startToTarget, orientation.Up);
65+
66+
return new Vector3(x, y, z);
67+
}
68+
}
69+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
namespace RLBotCSharpExample.Utilities.Packet
2+
{
3+
/// <summary>
4+
/// Processed version of the <see cref="rlbot.flat.GameTickPacket"/> that uses sane data structures.
5+
/// </summary>
6+
// This struct is here for your convenience. It is NOT part of the framework and you can change it
7+
// as much as you want, or delete it entirely.
8+
// The benefits of using this instead of rlbot.flat.GameTickPacket are:
9+
// - You avoid the displeasing .Value syntax of nullables due to Flatbuffers.
10+
// - You end up with nice System.Numeric.Vector3 objects that you can call methods on.
11+
// - If the framework changes its data format, you can just update the code here and leave your
12+
// bot logic alone.
13+
// Note that this struct and the structs inside are NOT complete. For example, Dropshot data has NOT
14+
// been added.
15+
// If you require any data from rlbot.flat.GameTickPacket that is missing in any of these structs,
16+
// you can add them yourself. You can always use Intellisense on rlbot.flat.GameTickPacket to see
17+
// what data is supported by RLBot and add them to these structs.
18+
public struct Packet
19+
{
20+
public Player[] Players;
21+
public BoostPadState[] BoostPadStates;
22+
public Ball Ball;
23+
public GameInfo GameInfo;
24+
public TeamInfo[] Teams;
25+
26+
public Packet(rlbot.flat.GameTickPacket packet)
27+
{
28+
Players = new Player[packet.PlayersLength];
29+
for (int i = 0; i < packet.PlayersLength; i++)
30+
Players[i] = new Player(packet.Players(i).Value);
31+
32+
BoostPadStates = new BoostPadState[packet.BoostPadStatesLength];
33+
for (int i = 0; i < packet.BoostPadStatesLength; i++)
34+
BoostPadStates[i] = new BoostPadState(packet.BoostPadStates(i).Value);
35+
36+
Ball = new Ball(packet.Ball.Value);
37+
GameInfo = new GameInfo(packet.GameInfo.Value);
38+
39+
Teams = new TeamInfo[packet.TeamsLength];
40+
for (int i = 0; i < packet.TeamsLength; i++)
41+
Teams[i] = new TeamInfo(packet.Teams(i).Value);
42+
}
43+
}
44+
}

0 commit comments

Comments
 (0)