This commit is contained in:
2025-05-14 10:51:59 +02:00
parent 62d340853d
commit c3e9f8abe8
110 changed files with 10605 additions and 3849 deletions

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 2eebc735c0624eadb3b5fc5a7cc611d7
timeCreated: 1746878778

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 408f07fbb2a14c019e5fc3324a24454c
timeCreated: 1746878783

View File

@@ -0,0 +1,59 @@
using System;
using System.Threading;
using Cysharp.Threading.Tasks;
using RealityReboot.jelycho.Player;
using RebootKit.Engine.Foundation;
using RebootKit.Engine.Main;
using RebootKit.Engine.Services.GameMode;
using RebootKit.Engine.Services.Simulation;
using UnityEngine.AddressableAssets;
namespace RealityReboot.jelycho.GameMode.Standard {
public class StandardGameMode : IGameMode {
[Serializable]
public class Config {
public PlayerControllerAsset playerControllerAsset;
public AssetReferenceGameObject playerPrefab;
public WorldConfigAsset worldConfig;
}
Config m_Config;
[Inject] DIContext m_DIContext;
CancellationTokenSource m_DisposeCancellationTokenSource = new();
ControllersManager<IController> m_ControllersManager;
PlayerController m_PlayerController;
public StandardGameMode(Config config) {
m_Config = config;
m_ControllersManager = new ControllersManager<IController>(m_DisposeCancellationTokenSource.Token);
}
public async UniTask OnInit(CancellationToken cancellationToken) {
await RR.World.LoadAsync(m_Config.worldConfig.Config, cancellationToken);
m_ControllersManager.Add(m_Config.playerControllerAsset, m_DIContext);
m_PlayerController = m_ControllersManager.Get<PlayerController>();
}
public void OnStart() {
m_ControllersManager.Start(m_DisposeCancellationTokenSource.Token).Forget();
}
public void OnStop() {
m_ControllersManager.Stop();
}
public void Dispose() {
m_DisposeCancellationTokenSource.Cancel();
}
public void OnTick() {
m_ControllersManager.Tick();
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 83af58c3064e420687c37222c18c472e
timeCreated: 1746878772

View File

@@ -0,0 +1,15 @@
using RebootKit.Engine.Foundation;
using RebootKit.Engine.Main;
using RebootKit.Engine.Services.GameMode;
using UnityEngine;
namespace RealityReboot.jelycho.GameMode.Standard {
[CreateAssetMenu(menuName = GameConsts.k_AddComponentMenu + "Game Modes/Standard")]
public class StandardGameModeAsset : GameModeAsset {
[SerializeField] StandardGameMode.Config m_Config;
public override IGameMode Create(DIContext context) {
return RR.DIContext.Create<StandardGameMode>(m_Config);
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 1a6162ffd783458ba697dcc1e1c40bea
timeCreated: 1746879123

View File

@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using Unity.Collections;
using Unity.Mathematics;
using UnityEngine;
@@ -13,9 +14,9 @@ namespace RealityReboot.jelycho {
[SerializeField] float3[] m_Positions;
[SerializeField] float m_Radius = 0.2f;
[SerializeField, Range(3, 128)] int m_Resolution = 16;
[SerializeField] Mesh m_Mesh;
void Update() {
@@ -26,7 +27,7 @@ namespace RealityReboot.jelycho {
};
m_Mesh.MarkDynamic();
}
if (m_Positions.Length < 2) {
return;
}
@@ -35,22 +36,77 @@ namespace RealityReboot.jelycho {
int vertexCount = m_Resolution * segmentCount;
int triangleCount = (segmentCount - 1) * m_Resolution * 2;
NativeArray<float3> positions = new(vertexCount, Allocator.Temp);
NativeArray<float3> normals = new(vertexCount, Allocator.Temp);
NativeArray<float2> uvs = new(vertexCount, Allocator.Temp);
NativeArray<int> indices = new(triangleCount * 3, Allocator.Temp);
NativeList<float3> positions = new(vertexCount, Allocator.Temp);
NativeList<float3> normals = new(vertexCount, Allocator.Temp);
NativeList<float2> uvs = new(vertexCount, Allocator.Temp);
NativeList<int> indices = new(triangleCount * 3, Allocator.Temp);
for (int i = 0; i < m_Positions.Length - 1; i++) {
float3 pos0 = m_Positions[i];
float3 pos1 = m_Positions[i + 1];
float startV0 = (float)i / (m_Positions.Length - 1);
float startV1 = (float)(i + 1) / (m_Positions.Length - 1);
for (int j = 0; j < m_Resolution - 1; j++) {
float t0 = (float)j / (m_Resolution - 1);
float t1 = (float)(j + 1) / (m_Resolution - 1);
float angle0 = math.lerp(0, math.PI * 2, t0);
float angle1 = math.lerp(0, math.PI * 2, t1);
float3 offset0 = new float3(math.cos(angle0), 0.0f, math.sin(angle0)) * m_Radius;
float3 offset1 = new float3(math.cos(angle1), 0.0f, math.sin(angle1)) * m_Radius;
int startIndex = positions.Length;
positions.Add(pos0 + offset0);
positions.Add(pos0 + offset1);
positions.Add(pos1 + offset0);
positions.Add(pos1 + offset1);
uvs.Add(new float2(t0, startV0));
uvs.Add(new float2(t0, startV1));
uvs.Add(new float2(t1, startV0));
uvs.Add(new float2(t1, startV1));
normals.Add(math.normalize(offset0));
normals.Add(math.normalize(offset1));
normals.Add(math.normalize(offset0));
normals.Add(math.normalize(offset1));
indices.Add(startIndex + 0);
indices.Add(startIndex + 1);
indices.Add(startIndex + 2);
indices.Add(startIndex + 3);
indices.Add(startIndex + 2);
indices.Add(startIndex + 1);
}
}
m_Mesh.Clear();
m_Mesh.SetVertices(positions);
m_Mesh.SetNormals(normals);
m_Mesh.SetUVs(0, uvs);
m_Mesh.SetIndices(indices, MeshTopology.Triangles, 0, false);
m_Mesh.SetVertices(positions.AsArray());
m_Mesh.SetNormals(normals.AsArray());
m_Mesh.SetUVs(0, uvs.AsArray());
m_Mesh.SetIndices(indices.AsArray(), MeshTopology.Triangles, 0, false);
Graphics.DrawMesh(m_Mesh, Matrix4x4.identity, m_Material, 0);
}
void OnDrawGizmos() {
if (m_Positions.Length < 2) {
return;
}
for (int i = 0; i < m_Positions.Length - 1; i++) {
Gizmos.color = Color.white;
Gizmos.DrawLine(m_Positions[i], m_Positions[i + 1]);
Gizmos.color = Color.yellow;
Gizmos.DrawSphere(m_Positions[i], 0.1f);
}
Gizmos.DrawSphere(m_Positions[m_Positions.Length - 1], 0.1f);
}
}
}

View File

@@ -1,18 +0,0 @@
using UnityEngine;
namespace RealityReboot.jelycho {
[AddComponentMenu(GameConsts.k_AddComponentMenu + "Active Ragdoll/Humanoid Ragdoll")]
public class HumanoidActiveRagdoll : MonoBehaviour {
[SerializeField] ActiveRagdollBone m_Head;
[SerializeField] ActiveRagdollBone m_Hips;
[SerializeField] float m_UpRightTorque = 400.0f;
void Start() {
}
void FixedUpdate() {
m_Hips.Rigidbody.AddTorque(m_Hips.transform.up * m_UpRightTorque, ForceMode.VelocityChange);
}
}
}

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 1f84d5c83dbd42549a41ca5df5a46632
timeCreated: 1743803454

View File

@@ -0,0 +1,108 @@
using System;
using System.Linq;
using System.Threading;
using Cysharp.Threading.Tasks;
using R3;
using RebootKit.Engine.Extensions;
using RebootKit.Engine.Main;
using RebootKit.Engine.Services.Console;
using RebootKit.Engine.Services.Crosshair;
using RebootKit.Engine.Services.GameMode;
using RebootKit.Engine.Services.Simulation;
namespace RealityReboot.jelycho {
public static class JelychoConsoleCommands {
[RCCMD("start", "Starts game mode with given name. Usage: start <game_mode_name> <world_name>")]
public static void StartGameMode(string[] args) {
if (args.Length != 3) {
RR.Console.WriteToOutput($"Usage: {args[0]} <game_mode_name> <world_name>");
return;
}
string worldName = args[2];
WorldConfigAsset worldConfig = RR.WorldConfigsAssets.FirstOrDefault(t => t.Config.name.Equals(worldName));
if (worldConfig is null) {
RR.Console.WriteToOutput($"World '{worldName}' not found");
return;
}
foreach (GameModeAsset gameModeAsset in RR.GameModesAssets) {
if (gameModeAsset.name == args[1]) {
RR.Console.WriteToOutput($"Starting game mode '{gameModeAsset.name}'");
RR.StartGameMode(gameModeAsset, worldConfig.Config);
return;
}
}
RR.Console.WriteToOutput($"Game mode '{args[1]}' not found");
}
[RCCMD("gamemodes", "Lists all game modes")]
public static void GameModes(string[] args) {
if (args.Length != 1) {
RR.Console.WriteToOutput($"Usage: {args[0]}");
return;
}
RR.Console.WriteToOutput("Game modes:");
foreach (GameModeAsset gameModeAsset in RR.GameModesAssets) {
RR.Console.WriteToOutput($" {gameModeAsset.name}");
}
}
[RCCMD("worlds", "Lists all worlds")]
public static void Worlds(string[] args) {
if (args.Length != 1) {
RR.Console.WriteToOutput($"Usage: {args[0]}");
return;
}
RR.Console.WriteToOutput("Worlds:");
foreach (WorldConfigAsset worldConfigAsset in RR.WorldConfigsAssets) {
RR.Console.WriteToOutput($" {worldConfigAsset.Config.name}");
}
}
}
public class JelychoGame : IGame {
[Serializable]
public class Config {
public WorldConfigAsset mainMenuWorldConfig;
public GameModeAsset standardGameMode;
public WorldConfigAsset worldAstek;
}
readonly Config m_Config;
DisposableBag m_DisposableBag;
public JelychoGame(Config config) {
m_Config = config;
m_DisposableBag = new DisposableBag();
}
public async UniTask InitAsync(CancellationToken cancellationToken) {
RR.CreateService<CrosshairService>();
await UniTask.Yield();
}
public void Run() {
RR.GameModes.ActiveGameMode.Subscribe(gameMode => {
if (gameMode == null) {
RR.Console.WriteToOutput("Game mode stopped, loading main menu world");
RR.World.LoadAsync(m_Config.mainMenuWorldConfig.Config, CancellationToken.None).Forget();
}
})
.AddTo(ref m_DisposableBag);
}
public void Dispose() {
m_DisposableBag.Dispose();
}
public void NewGame() {
RR.StartGameMode(m_Config.standardGameMode, m_Config.worldAstek.Config);
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 1b48aaf4fa4f43cc866687a188087c90
timeCreated: 1746665900

View File

@@ -0,0 +1,13 @@
using RebootKit.Engine.Main;
using UnityEngine;
namespace RealityReboot.jelycho {
[CreateAssetMenu(menuName = GameConsts.k_AddComponentMenu + "Jelycho Game")]
public class JelychoGameAsset : GameAsset {
[SerializeField] JelychoGame.Config m_Config;
public override IGame CreateGame() {
return RR.DIContext.Create<JelychoGame>(m_Config);
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 6db6aab28280422f92077cf32c409b0f
timeCreated: 1746666083

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 27478c81c5844c9aa11b08b86e0390d9
timeCreated: 1745347382

View File

@@ -0,0 +1,45 @@
using System;
using RebootKit.Engine;
using RebootKit.Engine.Main;
using RebootKit.Engine.UI;
using UnityEngine;
using UnityEngine.UIElements;
namespace RealityReboot.jelycho.MainMenu {
public class MainMenuController : MonoBehaviour {
const string k_ButtonPlay = "btn-play";
const string k_ButtonSettings = "btn-settings";
const string k_ButtonQuit = "btn-quit";
const string k_PanelMain = "panel-main";
const string k_PanelSettings = "panel-settings";
[SerializeField] UIDocument m_Document;
void OnEnable() {
VisualElement root = m_Document.rootVisualElement;
Button playButton = root.Q<Button>(k_ButtonPlay);
Button settingsButton = root.Q<Button>(k_ButtonSettings);
Button quitButton = root.Q<Button>(k_ButtonQuit);
playButton.RegisterCallback<ClickEvent>(e => {
RR.Game<JelychoGame>().NewGame();
});
settingsButton.RegisterCallback<ClickEvent>(e => OpenSettings());
quitButton.RegisterCallback<ClickEvent>(e => Application.Quit());
OpenMain();
}
void OpenMain() {
m_Document.rootVisualElement.Q<VisualElement>(k_PanelMain).style.display = DisplayStyle.Flex;
m_Document.rootVisualElement.Q<VisualElement>(k_PanelSettings).style.display = DisplayStyle.None;
}
void OpenSettings() {
m_Document.rootVisualElement.Q<VisualElement>(k_PanelMain).style.display = DisplayStyle.None;
m_Document.rootVisualElement.Q<VisualElement>(k_PanelSettings).style.display = DisplayStyle.Flex;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 9cf18c015c2646ad8f96e367a57a4f89
timeCreated: 1745347401

View File

@@ -0,0 +1,7 @@
using UnityEngine;
namespace RealityReboot.jelycho {
public class MapContext : MonoBehaviour {
[field: SerializeField] public Transform PlayerSpawnPoint { get; private set; }
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 6a274076a9874532802be870bb3fcd19
timeCreated: 1746878240

View File

@@ -6,12 +6,13 @@ using Unity.Mathematics;
using UnityEngine;
using Logger = RebootKit.Engine.Foundation.Logger;
namespace RealityReboot.jelycho {
namespace RealityReboot.jelycho.Player {
public class PlayerActor : Actor {
static readonly Logger s_logger = new(nameof(PlayerActor));
[SerializeField] FPPLocomotion m_Locomotion;
[SerializeField] PlayerFPPLocomotion m_Locomotion;
[SerializeField] FPPCamera m_Camera;
[SerializeField] Animator m_Animator;
[SerializeField] Transform m_DragGutStartPosition;
@@ -25,11 +26,13 @@ namespace RealityReboot.jelycho {
if (m_PhysicsDragger.Current.OrNull() != null) {
m_LineRenderer.enabled = true;
m_LineRenderer.SetPosition(0, m_DragGutStartPosition.position);
m_LineRenderer.SetPosition(1, m_PhysicsDragger.Current.position);
m_LineRenderer.SetPosition(0, m_LineRenderer.transform.InverseTransformPoint(m_DragGutStartPosition.position));
m_LineRenderer.SetPosition(1, m_LineRenderer.transform.InverseTransformPoint(m_PhysicsDragger.Current.position));
} else {
m_LineRenderer.enabled = false;
}
UpdateAnimator();
}
public void Jump() {
@@ -60,5 +63,19 @@ namespace RealityReboot.jelycho {
public void StopDrag() {
m_PhysicsDragger.Drop();
}
struct AnimatorParamHashes {
public static readonly int s_VelocityForwardNormalized = Animator.StringToHash("VelocityForwardNormalized");
public static readonly int s_VelocityRightNormalized = Animator.StringToHash("VelocityRightNormalized");
public static readonly int s_IsGrounded = Animator.StringToHash("IsGrounded");
}
void UpdateAnimator() {
float forwardNormalized = m_Locomotion.LocalVelocity.z / m_Locomotion.maxMovementSpeed;
m_Animator.SetFloat(AnimatorParamHashes.s_VelocityForwardNormalized, forwardNormalized);
m_Animator.SetFloat(AnimatorParamHashes.s_VelocityRightNormalized, 0.0f);
m_Animator.SetBool(AnimatorParamHashes.s_IsGrounded, true);
}
}
}

View File

@@ -3,6 +3,7 @@ using System.Threading;
using Cysharp.Threading.Tasks;
using RebootKit.Engine;
using RebootKit.Engine.Foundation;
using RebootKit.Engine.Main;
using RebootKit.Engine.Services.Input;
using RebootKit.FPPKit;
using UnityEngine;

View File

@@ -0,0 +1,68 @@
using System;
using RebootKit.Engine.Extensions;
using Unity.Mathematics;
using UnityEngine;
namespace RealityReboot.jelycho.Player {
[RequireComponent(typeof(Rigidbody), typeof(CapsuleCollider))]
public class PlayerFPPLocomotion : MonoBehaviour {
[SerializeField] Rigidbody m_Rigidbody;
public float acceleration = 10.0f;
public float accelerationBackwards = 2.0f;
public float accelerationStrafe = 2.0f;
public float maxMovementSpeed = 8.0f;
public float maxMovementSpeedBackwards = 2.0f;
public float maxStrafeSpeed = 2.0f;
public float3 Velocity => m_Rigidbody.linearVelocity;
public float3 LocalVelocity => m_Rigidbody.transform.InverseTransformDirection(m_Rigidbody.linearVelocity);
float3 m_PendingInputValue;
bool m_IsJumpRequested;
void Awake() {
}
void FixedUpdate() {
if (m_PendingInputValue.IsZero()) {
return;
}
float3 localVelocity = LocalVelocity;
m_PendingInputValue = math.normalize(m_PendingInputValue);
float3 localInput = m_Rigidbody.transform.InverseTransformDirection(m_PendingInputValue);
float3 velocityToAdd = float3.zero;
if (localInput.z > 0.0f) {
if (localVelocity.z < maxMovementSpeed) {
velocityToAdd.z += localInput.z * acceleration * Time.fixedDeltaTime;
}
} else {
velocityToAdd.z += localInput.z * accelerationBackwards * Time.fixedDeltaTime;
}
velocityToAdd.x += localInput.x * accelerationStrafe * Time.fixedDeltaTime;
float3 velocityToAddWorldSpace = m_Rigidbody.transform.TransformDirection(velocityToAdd);
m_Rigidbody.AddForce(velocityToAddWorldSpace, ForceMode.VelocityChange);
m_PendingInputValue = float3.zero;
}
void OnValidate() {
if (m_Rigidbody == null) {
m_Rigidbody = GetComponent<Rigidbody>();
}
}
public void AddMovementInput(float3 input, float scale) {
m_PendingInputValue += input * scale;
}
public void Jump() {
m_IsJumpRequested = true;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: ee4e0741b71b4e0e81f8109748ea961d
timeCreated: 1746663547

View File

@@ -27,10 +27,10 @@ namespace RealityReboot.jelycho {
Clear();
}
void OnDrawGizmos() {
Gizmos.color = Color.yellow;
Gizmos.DrawSphere(transform.position, 0.075f);
}
// void OnDrawGizmos() {
// Gizmos.color = Color.yellow;
// Gizmos.DrawSphere(transform.position, 0.075f);
// }
public void GetWorldPositions(List<Vector3> outList) {
outList.Clear();

View File

@@ -1,11 +1,11 @@
using RebootKit.Engine.Services.Simulation;
using UnityEngine;
using UnityEngine.AI;
namespace RealityReboot.jelycho {
[AddComponentMenu(GameConsts.k_AddComponentMenu + "Zombie Actor")]
public class ZombieActor : Actor {
[SerializeField] HumanoidActiveRagdoll m_ActiveRagdoll;
[SerializeField] NavMeshAgent m_NavMeshAgent;
[SerializeField] Animator m_Animator;
void OnEnable() {