Skip to content

Commit bd3d98f

Browse files
committed
Expose game mode base functionality
1 parent b57f803 commit bd3d98f

12 files changed

Lines changed: 121 additions & 5 deletions

API/Actor.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ Derived
1212
↳ [Brush](./Brush.md 'UnrealEngine.Framework.Brush')
1313
↳ [Camera](./Camera.md 'UnrealEngine.Framework.Camera')
1414
↳ [Controller](./Controller.md 'UnrealEngine.Framework.Controller')
15+
↳ [GameModeBase](./GameModeBase.md 'UnrealEngine.Framework.GameModeBase')
1516
↳ [LevelScript](./LevelScript.md 'UnrealEngine.Framework.LevelScript')
1617
↳ [Light](./Light.md 'UnrealEngine.Framework.Light')
1718
↳ [Pawn](./Pawn.md 'UnrealEngine.Framework.Pawn')
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
### [UnrealEngine.Framework](./UnrealEngine-Framework.md 'UnrealEngine.Framework').[GameModeBase](./GameModeBase.md 'UnrealEngine.Framework.GameModeBase')
2+
## GameModeBase.SwapPlayerControllers(UnrealEngine.Framework.PlayerController, UnrealEngine.Framework.PlayerController) Method
3+
Swaps player controllers
4+
```csharp
5+
public void SwapPlayerControllers(UnrealEngine.Framework.PlayerController playerController, UnrealEngine.Framework.PlayerController newPlayerController);
6+
```
7+
#### Parameters
8+
<a name='UnrealEngine-Framework-GameModeBase-SwapPlayerControllers(UnrealEngine-Framework-PlayerController_UnrealEngine-Framework-PlayerController)-playerController'></a>
9+
`playerController` [PlayerController](./PlayerController.md 'UnrealEngine.Framework.PlayerController')
10+
11+
<a name='UnrealEngine-Framework-GameModeBase-SwapPlayerControllers(UnrealEngine-Framework-PlayerController_UnrealEngine-Framework-PlayerController)-newPlayerController'></a>
12+
`newPlayerController` [PlayerController](./PlayerController.md 'UnrealEngine.Framework.PlayerController')
13+

API/GameModeBase.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
### [UnrealEngine.Framework](./UnrealEngine-Framework.md 'UnrealEngine.Framework')
2+
## GameModeBase Class
3+
Defines the game being played, instantiated only on the server
4+
```csharp
5+
public class GameModeBase : UnrealEngine.Framework.Actor
6+
```
7+
Inheritance [System.Object](https://docs.microsoft.com/en-us/dotnet/api/System.Object 'System.Object') &#129106; [Actor](./Actor.md 'UnrealEngine.Framework.Actor') &#129106; GameModeBase
8+
### Methods
9+
- [SwapPlayerControllers(UnrealEngine.Framework.PlayerController, UnrealEngine.Framework.PlayerController)](./GameModeBase-SwapPlayerControllers(PlayerController_PlayerController).md 'UnrealEngine.Framework.GameModeBase.SwapPlayerControllers(UnrealEngine.Framework.PlayerController, UnrealEngine.Framework.PlayerController)')

API/UnrealEngine-Framework.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
- [DirectionalLightComponent](./DirectionalLightComponent.md 'UnrealEngine.Framework.DirectionalLightComponent')
3333
- [Engine](./Engine.md 'UnrealEngine.Framework.Engine')
3434
- [Font](./Font.md 'UnrealEngine.Framework.Font')
35+
- [GameModeBase](./GameModeBase.md 'UnrealEngine.Framework.GameModeBase')
3536
- [HeadMountedDisplay](./HeadMountedDisplay.md 'UnrealEngine.Framework.HeadMountedDisplay')
3637
- [HierarchicalInstancedStaticMeshComponent](./HierarchicalInstancedStaticMeshComponent.md 'UnrealEngine.Framework.HierarchicalInstancedStaticMeshComponent')
3738
- [InputComponent](./InputComponent.md 'UnrealEngine.Framework.InputComponent')

API/World-GetGameMode().md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
### [UnrealEngine.Framework](./UnrealEngine-Framework.md 'UnrealEngine.Framework').[World](./World.md 'UnrealEngine.Framework.World')
2+
## World.GetGameMode() Method
3+
Returns the current game mode instance which is always valid during gameplay on the server
4+
```csharp
5+
public static UnrealEngine.Framework.GameModeBase GetGameMode();
6+
```
7+
#### Returns
8+
[GameModeBase](./GameModeBase.md 'UnrealEngine.Framework.GameModeBase')
9+
A game mode or `null` on failure

API/World.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ Inheritance [System.Object](https://docs.microsoft.com/en-us/dotnet/api/System.O
1818
- [GetActorByID&lt;T&gt;(uint)](./World-GetActorByID-T-(uint).md 'UnrealEngine.Framework.World.GetActorByID&lt;T&gt;(uint)')
1919
- [GetActorByTag&lt;T&gt;(string)](./World-GetActorByTag-T-(string).md 'UnrealEngine.Framework.World.GetActorByTag&lt;T&gt;(string)')
2020
- [GetFirstPlayerController()](./World-GetFirstPlayerController().md 'UnrealEngine.Framework.World.GetFirstPlayerController()')
21+
- [GetGameMode()](./World-GetGameMode().md 'UnrealEngine.Framework.World.GetGameMode()')
2122
- [GetWorldOrigin()](./World-GetWorldOrigin().md 'UnrealEngine.Framework.World.GetWorldOrigin()')
2223
- [GetWorldOrigin(System.Numerics.Vector3)](./World-GetWorldOrigin(Vector3).md 'UnrealEngine.Framework.World.GetWorldOrigin(System.Numerics.Vector3)')
2324
- [LineTraceSingleByChannel(System.Numerics.Vector3, System.Numerics.Vector3, UnrealEngine.Framework.CollisionChannel, UnrealEngine.Framework.Hit, bool, UnrealEngine.Framework.Actor, UnrealEngine.Framework.PrimitiveComponent)](./World-LineTraceSingleByChannel(Vector3_Vector3_CollisionChannel_Hit_bool_Actor_PrimitiveComponent).md 'UnrealEngine.Framework.World.LineTraceSingleByChannel(System.Numerics.Vector3, System.Numerics.Vector3, UnrealEngine.Framework.CollisionChannel, UnrealEngine.Framework.Hit, bool, UnrealEngine.Framework.Actor, UnrealEngine.Framework.PrimitiveComponent)')

Source/Managed/Framework/Codegen.cs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ namespace UnrealEngine.Framework {
3535
// Automatically generated
3636

3737
internal static class Shared {
38-
internal const int checksum = 0x2C8;
38+
internal const int checksum = 0x2CB;
3939
internal static Dictionary<int, IntPtr> userFunctions = new();
4040
private const string dynamicTypesAssemblyName = "UnrealEngine.DynamicTypes";
4141
private static readonly ModuleBuilder moduleBuilder = AssemblyBuilder.DefineDynamicAssembly(new(dynamicTypesAssemblyName), AssemblyBuilderAccess.RunAndCollect).DefineDynamicModule(dynamicTypesAssemblyName);
@@ -48,7 +48,7 @@ internal static class Shared {
4848
private const TypeAttributes delegateTypeAttributes = TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.Sealed | TypeAttributes.AnsiClass | TypeAttributes.AutoClass;
4949

5050
internal static unsafe Dictionary<int, IntPtr> Load(IntPtr* events, IntPtr functions, Assembly pluginAssembly) {
51-
int position = 0;
51+
int position = 0;
5252
IntPtr* buffer = (IntPtr*)functions;
5353

5454
unchecked {
@@ -205,6 +205,7 @@ internal static unsafe Dictionary<int, IntPtr> Load(IntPtr* events, IntPtr funct
205205
World.getActorByTag = (delegate* unmanaged[Cdecl]<string, ActorType, IntPtr>)worldFunctions[head++];
206206
World.getActorByID = (delegate* unmanaged[Cdecl]<uint, ActorType, IntPtr>)worldFunctions[head++];
207207
World.getFirstPlayerController = (delegate* unmanaged[Cdecl]<IntPtr>)worldFunctions[head++];
208+
World.getGameMode = (delegate* unmanaged[Cdecl]<IntPtr>)worldFunctions[head++];
208209
World.setOnActorBeginOverlapCallback = (delegate* unmanaged[Cdecl]<IntPtr, void>)worldFunctions[head++];
209210
World.setOnActorBeginCursorOverCallback = (delegate* unmanaged[Cdecl]<IntPtr, void>)worldFunctions[head++];
210211
World.setOnActorEndCursorOverCallback = (delegate* unmanaged[Cdecl]<IntPtr, void>)worldFunctions[head++];
@@ -329,6 +330,13 @@ internal static unsafe Dictionary<int, IntPtr> Load(IntPtr* events, IntPtr funct
329330
Actor.unregisterEvent = (delegate* unmanaged[Cdecl]<IntPtr, ActorEventType, void>)actorFunctions[head++];
330331
}
331332

333+
unchecked {
334+
int head = 0;
335+
IntPtr* gameModeBaseFunctions = (IntPtr*)buffer[position++];
336+
337+
GameModeBase.swapPlayerControllers = (delegate* unmanaged[Cdecl]<IntPtr, IntPtr, IntPtr, void>)gameModeBaseFunctions[head++];
338+
}
339+
332340
unchecked {
333341
int head = 0;
334342
IntPtr* pawnFunctions = (IntPtr*)buffer[position++];
@@ -1315,7 +1323,8 @@ internal enum ActorType : int {
13151323
SpotLight,
13161324
TriggerVolume,
13171325
PostProcessVolume,
1318-
LevelScript
1326+
LevelScript,
1327+
GameModeBase
13191328
}
13201329

13211330
internal enum ComponentType : int {
@@ -1471,6 +1480,7 @@ static unsafe partial class World {
14711480
internal static delegate* unmanaged[Cdecl]<string, ActorType, IntPtr> getActorByTag;
14721481
internal static delegate* unmanaged[Cdecl]<uint, ActorType, IntPtr> getActorByID;
14731482
internal static delegate* unmanaged[Cdecl]<IntPtr> getFirstPlayerController;
1483+
internal static delegate* unmanaged[Cdecl]<IntPtr> getGameMode;
14741484
internal static delegate* unmanaged[Cdecl]<IntPtr, void> setOnActorBeginOverlapCallback;
14751485
internal static delegate* unmanaged[Cdecl]<IntPtr, void> setOnActorEndOverlapCallback;
14761486
internal static delegate* unmanaged[Cdecl]<IntPtr, void> setOnActorHitCallback;
@@ -1577,6 +1587,10 @@ unsafe partial class Actor {
15771587
internal static delegate* unmanaged[Cdecl]<IntPtr, ActorEventType, void> unregisterEvent;
15781588
}
15791589

1590+
unsafe partial class GameModeBase {
1591+
internal static delegate* unmanaged[Cdecl]<IntPtr, IntPtr, IntPtr, void> swapPlayerControllers;
1592+
}
1593+
15801594
unsafe partial class TriggerBase { }
15811595

15821596
unsafe partial class TriggerBox { }

Source/Managed/Framework/Framework.cs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4046,6 +4046,19 @@ public static PlayerController GetFirstPlayerController() {
40464046
return null;
40474047
}
40484048

4049+
/// <summary>
4050+
/// Returns the current game mode instance which is always valid during gameplay on the server
4051+
/// </summary>
4052+
/// <returns>A game mode or <c>null</c> on failure</returns>
4053+
public static GameModeBase GetGameMode() {
4054+
IntPtr pointer = getGameMode();
4055+
4056+
if (pointer != IntPtr.Zero)
4057+
return new(pointer);
4058+
4059+
return null;
4060+
}
4061+
40494062
/// <summary>
40504063
/// Retrieves the current location of the <a href="https://docs.unrealengine.com/en-US/Engine/LevelStreaming/WorldBrowser/index.html">world origin</a> to a reference
40514064
/// </summary>
@@ -5442,6 +5455,30 @@ public TriggerCapsule(string name = null, Blueprint blueprint = null) {
54425455
}
54435456
}
54445457

5458+
/// <summary>
5459+
/// Defines the game being played, instantiated only on the server
5460+
/// </summary>
5461+
public unsafe partial class GameModeBase : Actor {
5462+
internal override ActorType Type => ActorType.GameModeBase;
5463+
5464+
private protected GameModeBase() { }
5465+
5466+
internal GameModeBase(IntPtr pointer) => Pointer = pointer;
5467+
5468+
/// <summary>
5469+
/// Swaps player controllers
5470+
/// </summary>
5471+
public void SwapPlayerControllers(PlayerController playerController, PlayerController newPlayerController) {
5472+
if (playerController == null)
5473+
throw new ArgumentNullException(nameof(playerController));
5474+
5475+
if (newPlayerController == null)
5476+
throw new ArgumentNullException(nameof(newPlayerController));
5477+
5478+
swapPlayerControllers(Pointer, playerController.Pointer, newPlayerController.Pointer);
5479+
}
5480+
}
5481+
54455482
/// <summary>
54465483
/// The base class of actors that can be possessed by players or AI
54475484
/// </summary>

Source/Native/Source/UnrealCLR/Private/UnrealCLR.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Unreal Engine 4 .NET 5 integration
2+
* Unreal Engine 4 .NET 5 integration
33
* Copyright (c) 2021 Stanislav Denisov
44
*
55
* Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -322,6 +322,7 @@ void UnrealCLR::Module::StartupModule() {
322322
Shared::WorldFunctions[head++] = (void*)&UnrealCLRFramework::World::GetActorByTag;
323323
Shared::WorldFunctions[head++] = (void*)&UnrealCLRFramework::World::GetActorByID;
324324
Shared::WorldFunctions[head++] = (void*)&UnrealCLRFramework::World::GetFirstPlayerController;
325+
Shared::WorldFunctions[head++] = (void*)&UnrealCLRFramework::World::GetGameMode;
325326
Shared::WorldFunctions[head++] = (void*)&UnrealCLRFramework::World::SetOnActorBeginOverlapCallback;
326327
Shared::WorldFunctions[head++] = (void*)&UnrealCLRFramework::World::SetOnActorBeginCursorOverCallback;
327328
Shared::WorldFunctions[head++] = (void*)&UnrealCLRFramework::World::SetOnActorEndCursorOverCallback;
@@ -460,6 +461,15 @@ void UnrealCLR::Module::StartupModule() {
460461
checksum += head;
461462
}
462463

464+
{
465+
int32 head = 0;
466+
Shared::Functions[position++] = Shared::GameModeBaseFunctions;
467+
468+
Shared::GameModeBaseFunctions[head++] = (void*)&UnrealCLRFramework::GameModeBase::SwapPlayerControllers;
469+
470+
checksum += head;
471+
}
472+
463473
{
464474
int32 head = 0;
465475
Shared::Functions[position++] = Shared::PawnFunctions;

Source/Native/Source/UnrealCLR/Private/UnrealCLRFramework.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,9 @@ namespace UnrealCLRFramework {
114114
case ActorType::LevelScript:\
115115
Result = Head ALevelScriptActor Tail;\
116116
break;\
117+
case ActorType::GameModeBase:\
118+
Result = Head AGameModeBase Tail;\
119+
break;\
117120
default:\
118121
break;\
119122
}\
@@ -1137,6 +1140,10 @@ namespace UnrealCLRFramework {
11371140
return UnrealCLR::Engine::World->GetFirstPlayerController();
11381141
}
11391142

1143+
AGameModeBase* GetGameMode() {
1144+
return UnrealCLR::Engine::World->GetAuthGameMode();
1145+
}
1146+
11401147
void SetOnActorBeginOverlapCallback(ActorOverlapDelegate Callback) {
11411148
UnrealCLR::Shared::Events[UnrealCLR::OnActorBeginOverlap] = (void*)Callback;
11421149
}
@@ -1675,6 +1682,12 @@ namespace UnrealCLRFramework {
16751682
}
16761683
}
16771684

1685+
namespace GameModeBase {
1686+
void SwapPlayerControllers(AGameModeBase* GameModeBase, APlayerController* PlayerController, APlayerController* NewPlayerController) {
1687+
GameModeBase->SwapPlayerControllers(PlayerController, NewPlayerController);
1688+
}
1689+
}
1690+
16781691
namespace Pawn {
16791692
bool IsControlled(APawn* Pawn) {
16801693
return Pawn->IsPawnControlled();

0 commit comments

Comments
 (0)