Нашёл причину утечки памяти

This commit is contained in:
ThomasCharester committed 2026-03-24 15:16:17 +03:00
1 parent 60c28f54f2
commit 320847af5b
229 files changed
+3094 -18282

No files matched your search

@@ -88,8 +88,8 @@ namespace Code.Example.Platformer.Entity
public void Dispose()
{
UnityEngine.Debug.LogWarning($"Enemies released");
_playerPrefabHandle.Release();
UnityEngine.Debug.LogWarning($"Player released");
if(_playerPrefabHandle.IsValid()) _playerPrefabHandle.Release();
_playerConfigHandle.Release();
}
@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: ab2cbe7f4c0142f980f9640c57d27030
timeCreated: 1774277361
@@ -76,11 +76,22 @@ namespace Code.Example.Platformer
Context.CameraFactory.ReleaseCinemachineCamera(CameraMode.Platformer);
Context.InputService.DisableMap(ActionMappings.Platformer);
_audioFactory.ReleaseAudios(AudioNames.Platformer);
Context.AudioService.ChangeGroupVolume(
AudioGroupType.Music,
0f,
0.5f,
ReleasePlatformerMusic);
EventBus.Unsubscribe(this);
}
private void ReleasePlatformerMusic()
{
Context.AudioService.CancelMusic(AudioNames.Platformer, 0);
Context.AudioService.CancelMusic(AudioNames.Platformer, 7);
_audioFactory.ReleaseAudios(AudioNames.Platformer);
}
private void StartInitialLoading()
{
@@ -259,6 +270,25 @@ namespace Code.Example.Platformer
}
public void PlayerDied()
{
_loading = new(2, EndGameLoading);
Context.AudioService.ChangeGroupVolume(
AudioGroupType.Music,
0f,
0.5f,
OffTheMusic);
Context.UIService.OpenPanel(UIPanelType.Loading);
}
private void OffTheMusic()
{
ReleasePlatformerMusic();
_loading.DoProgress();
}
private void EndGameLoading()
{
Context.StateMachine.SwitchState(AppStates.MainMenu)
.AllowStateTransition(AppStates.Platformer);
-3
View File
@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 28672941a49242ad95c4a99705410c30
timeCreated: 1769522077
@@ -1,65 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using Newtonsoft.Json;
using UnityEngine;
namespace Code.Example.Race
{
public class PlayerPrefsRacePoopshitter
{
private List<RaceData> _races = new();
public PlayerPrefsRacePoopshitter()
{
GetRaces();
}
public List<RaceData> GetRaces()
{
var path = Path.Combine(Application.persistentDataPath,"raceData.json");
using (StreamReader reader = new(path))
{
var json = reader.ReadToEnd();
_races = JsonConvert.DeserializeObject<List<RaceData>>(json);
}
// for (int i = 0; i < _raceCount; i++)
// races.Add(new(
// PlayerPrefs.GetFloat($"Race{i}"),
// PlayerPrefs.GetInt($"Place{i}")));
return _races;
}
public void AddRace(RaceData race)
{
// PlayerPrefs.SetFloat($"Race{_raceCount}", race.raceTimeSeconds);
// PlayerPrefs.SetInt($"Place{_raceCount}", race.place);
// PlayerPrefs.SetInt("RaceCount", ++_raceCount);
_races.Add(race);
var json = JsonConvert.SerializeObject(_races, Formatting.Indented);
var path = Path.Combine(Application.persistentDataPath,"raceData.json");
using (StreamWriter writer = new(path))
{
writer.Write(json);
}
}
}
[Serializable]
public struct RaceData
{
public float raceTimeSeconds;
public int place;
public RaceData(float raceTimeSeconds, int place)
{
this.raceTimeSeconds = raceTimeSeconds;
this.place = place;
}
}
}
@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: e984eddc1697449487c9a790345dfb0b
timeCreated: 1770653240
-108
View File
@@ -1,108 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Code.Example.Race.Racer;
using Code.Example.Race.Track;
using Code.Infrastructure.EventBus;
using Code.Infrastructure.Loadings;
using UnityEngine;
namespace Code.Example.Race
{
public class RaceGame : IRacerLoadedHandle, IDisposable
{
private RaceScores _scores;
private IRacerFactory _racerFactory;
private RaceTrackData _raceTrackData;
private EventBus _eventBus;
public RaceGame(EventBus eventBus, IRacerFactory racerFactory, RaceTrackData raceTrackData, RaceScores scores)
{
_eventBus = eventBus;
_racerFactory = racerFactory;
_raceTrackData = raceTrackData;
_eventBus.Subscribe(this);
_scores = scores;
RandomizeRacers(raceTrackData.trackData.RacerPoints.Count);
}
private float _timeStart;
public float RaceTime => Time.time - _timeStart;
public void StartRacers()
{
_timeStart = Time.time;
foreach (var racer in PlacedRacers)
{
racer.StartRacer();
}
}
// DEBUG
private List<RacerType> _randomizedTypes = new();
private void RandomizeRacers(int count)
{
_raceGameLoading = new Loading(count, RacersLoadCompleted);
_randomizedTypes.Add(RacerType.Player);
for (var i = 0; i < count - 1; i++)
_randomizedTypes.Add((RacerType)UnityEngine.Random.Range(1, 3));
foreach (var type in _randomizedTypes) _racerFactory.LoadRacer(type);
}
private void RacersLoadCompleted() =>
_eventBus.RaiseEvent<IRaceGameHandle>(x => x.RaceGameReady());
public List<Racer.Racer> PlacedRacers { get; } = new();
public void PlaceRacers()
{
for (var i = 0; i < _raceTrackData.trackData.RacerPoints.Count; i++)
{
PlacedRacers.Add(UnityEngine.Object.Instantiate(
_racerPrefabs[_randomizedTypes[i]],
_raceTrackData.trackData.RacerPoints[i].transform).GetComponent<Racer.Racer>());
PlacedRacers[^1].SetData(_racerPrefabs[_randomizedTypes[i]].Data);
PlacedRacers[^1].Id = i;
_scores.SubscribeRacer(PlacedRacers[^1]);
}
foreach (var racer in PlacedRacers)
{
racer.Initialize(_raceTrackData.trackData.Checkpoints.Select(x=> x.transform).ToList());
}
}
private Dictionary<RacerType, Racer.Racer> _racerPrefabs = new();
private Loading _raceGameLoading;
public void RacerLoaded(RacerType type, Racer.Racer racer)
{
if (racer)
_racerPrefabs.Add(type, racer);
_raceGameLoading.DoProgress();
}
public void Dispose()
{
foreach (var racer in PlacedRacers) _scores.UnsubscribeRacer(racer);
_eventBus.Unsubscribe(this);
_racerPrefabs.Clear();
}
}
public interface IRaceGameHandle : IGlobalSubscriber
{
void RaceGameReady();
void RaceGameEnded(RaceScores scores);
}
}
@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 0ffa5c181be7447cb1c41392018b193f
timeCreated: 1769692114
-80
View File
@@ -1,80 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Code.Example.Race.Racer.Player;
using Code.Example.Race.Track;
using Code.Infrastructure.EventBus;
using Reflex.Attributes;
namespace Code.Example.Race
{
public class RaceScores : IRacerPassedCheckpointHandler, IDisposable, IPlayerPassedCheckpointHandler
{
private Dictionary<Racer.Racer, ScoreData> _scores = new();
private EventBus _eventBus;
public RaceScores(EventBus eventBus)
{
_eventBus = eventBus;
_eventBus.Subscribe(this);
}
public void SubscribeRacer(Racer.Racer racer)
{
_scores.Add(racer, new ScoreData());
}
public void ChangeScore(Racer.Racer racer, int additionalScore)
{
_scores[racer].checkpointsPassed += additionalScore;
_eventBus.RaiseEvent<IScoreChangedHandle>(x=> x.ScoreChanged(racer,_scores[racer], GetScores()));
}
public void LapPassed(Racer.Racer racer)
{
_scores[racer].lapsPassed++;
_eventBus.RaiseEvent<IScoreChangedHandle>(x=> x.ScoreChanged(racer,_scores[racer], GetScores()));
if (_scores[racer].lapsPassed >= _raceTrackData.trackData.LapCount)
_eventBus.RaiseEvent<IRaceGameHandle>(x=> x.RaceGameEnded(this));
}
public void UnsubscribeRacer(Racer.Racer racer)
{
_scores.Remove(racer);
}
public List<KeyValuePair<Racer.Racer, ScoreData>> GetScores()
{
return _scores.OrderByDescending(x => x.Value.checkpointsPassed).ToList();
}
public void OnRacerPassedCheckpoint(Racer.Racer racer) => ChangeScore(racer,1);
public void Dispose()
{
_eventBus.Unsubscribe(this);
}
[Inject] private RaceTrackData _raceTrackData;
public void OnPlayerPassedCheckpoint(Racer.Racer racer)
{
var player = (PlayerRacer)racer;
_raceTrackData.trackData.Checkpoints[player.CurrentWaypointIndex].Show();
}
public void OnPlayerLapPassed(Racer.Racer racer)
{
}
}
public class ScoreData
{
public int checkpointsPassed;
public int lapsPassed;
}
public interface IScoreChangedHandle : IGlobalSubscriber
{
void ScoreChanged(Racer.Racer racer, ScoreData score, List<KeyValuePair<Racer.Racer, ScoreData>> scores);
}
}
@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: b45fb028abcf43129f5c8100e7215f1f
timeCreated: 1770051193
-3
View File
@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: db04851257b24d4698e8101ef2d54b2d
timeCreated: 1769522144
-3
View File
@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 391fdca5d5c94a86bcbd0f7cda609ee7
timeCreated: 1769522152
@@ -1,36 +0,0 @@
using UnityEngine;
namespace Code.Example.Race.Racer.AI
{
public class AICarDriver : CarControllerRB
{
public override void SetSteering(Vector2 steeringLinear)
{
SteeringInput = steeringLinear;
}
protected override void Brake()
{
if (CarRb.linearVelocity.magnitude > 10f && (SteeringInput.y > CarRb.linearVelocity.y || SteeringInput.x > CarRb.linearVelocity.x))
{
foreach (var wheel in wheels)
{
wheel.wheelCollider.brakeTorque = 100 * racer.Data.brakeAcceleration * Time.fixedDeltaTime;
}
// carLights.isBackLightOn = true;
// carLights.OperateBackLights();
}
else
{
foreach (var wheel in wheels)
{
wheel.wheelCollider.brakeTorque = 0;
}
// carLights.isBackLightOn = false;
// carLights.OperateBackLights();
}
}
}
}
@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: c82b0db1441e417098bccb9ca1575e3e
timeCreated: 1770639201
@@ -1,45 +0,0 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
namespace Code.Example.Race.Racer.AI
{
public class AIDebugRacer : Racer
{
[SerializeField] private NavMeshAgent navMeshAgent;
[SerializeField] private List<Transform> waypoints;
private int _currentWaypointIndex;
private void Awake()
{
navMeshAgent.destination = waypoints[_currentWaypointIndex].position;
_currentWaypointIndex++;
}
public override void NextWaypoint()
{
if(_currentWaypointIndex >= waypoints.Count) _currentWaypointIndex = 0;
navMeshAgent.destination = waypoints[_currentWaypointIndex++].position;
}
public override void StartRacer()
{
}
public override void StopRacer()
{
}
public override void SetData(RacerData data)
{
}
public override void Initialize(List<Transform> waypoints)
{
}
}
}
@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 6644b39029d14164961d83a37749e6cc
timeCreated: 1769522190
@@ -1,36 +0,0 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
namespace Code.Example.Race.Racer.AI
{
public class AIRacer : Racer
{
[SerializeField] private NavMeshAgent navMeshAgent;
public override void SetData(RacerData data)
{
Data = data;
navMeshAgent.angularSpeed = data.angularSpeed;
navMeshAgent.speed = data.speed;
}
public override void Initialize(List<Transform> waypoints)
{
navMeshAgent.isStopped = true;
Waypoints = waypoints;
navMeshAgent.destination = Waypoints[CurrentWaypointIndex].position;
CurrentWaypointIndex++;
}
public override void StartRacer() => navMeshAgent.isStopped = false;
public override void StopRacer() => navMeshAgent.isStopped = true;
public override void NextWaypoint()
{
if(CurrentWaypointIndex >= Waypoints.Count) CurrentWaypointIndex = 0;
navMeshAgent.destination = Waypoints[CurrentWaypointIndex++].position;
}
}
}
@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 05f30660967e40209aa88719fa498c78
timeCreated: 1769694590
@@ -1,110 +0,0 @@
using System.Collections.Generic;
using Code.Example.Race.Racer.AI.ID;
using Code.Example.Race.Track;
using Code.Infrastructure.EventBus;
using Reflex.Attributes;
using UnityEngine;
namespace Code.Example.Race.Racer.AI
{
public class AIRacerID : Racer
{
[Inject] private EventBus _eventBus;
[SerializeField] private CarControllerRB carController;
public override void SetData(RacerData data)
{
Data = data;
_velocity = Vector3.zero;
_steering = new Steering();
}
public override void Initialize(List<Transform> waypoints)
{
Waypoints = waypoints;
}
public override void NextWaypoint()
{
if (++CurrentWaypointIndex < Waypoints.Count) return;
CurrentWaypointIndex = 0;
_eventBus.RaiseEvent<IRacerPassedCheckpointHandler>(x=> x.LapPassed(this));
}
public override void StartRacer()
{
_running = true;
}
public override void StopRacer()
{
_running = false;
}
[SerializeField] private AgentBehaviour agent;
private float _orientation;
private float _rotation;
private Vector3 _velocity;
private Steering _steering;
private bool _running;
private float NormalizeAngle(float angle)
{
switch (angle)
{
case > 360.0f:
{
while (angle > 360.0f) angle -= 360.0f;
break;
}
case < 0.0f:
{
while (angle < 0.0f) angle += 360.0f;
break;
}
}
return angle;
}
public virtual void Update()
{
if (!_running) return;
var steering =
transform.InverseTransformDirection(
agent.GetSteering(Waypoints[CurrentWaypointIndex]).linear);
carController.SetSteering(new Vector2(steering.x, steering.z));
// var displacement = _velocity * Time.deltaTime;
// _orientation += _rotation * Time.deltaTime;
// _orientation = NormalizeAngle(_orientation);
//
// transform.Translate(displacement, Space.World);
// transform.Rotate(Vector3.up, _orientation);
}
public virtual void LateUpdate()
{
if (!_running) return;
//
// _steering = agent.GetSteering(Waypoints[CurrentWaypointIndex]);
//
// _velocity += _steering.linear * Time.deltaTime;
// _rotation += _steering.angular * Time.deltaTime;
// if (_velocity.magnitude > Data.speed)
// {
// _velocity = _velocity.normalized * Data.speed;
// }
// if (_steering.angular == 0.0f)
// {
// _rotation = 0.0f;
// }
// if (_steering.linear.sqrMagnitude == 0.0f)
// {
// _velocity = Vector3.zero;
// }
}
}
}
@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: fdcd01ab3c5147e4bfa3619d60fec5fc
timeCreated: 1770394482
@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 4f9bd0b568944e1f9b11f60f0fb79590
timeCreated: 1770394574
@@ -1,53 +0,0 @@
using UnityEngine;
namespace Code.Example.Race.Racer.AI.ID
{
public class Agent : MonoBehaviour
{
public float maxSpeed;
public float maxAccel;
public float orientation;
public float rotation;
public Vector3 velocity;
protected Steering steering;
private void Start()
{
velocity = Vector3.zero;
steering = new Steering();
}
public virtual void Update ()
{
Vector3 displacement = velocity * Time.deltaTime;
orientation += rotation * Time.deltaTime;
// необходимо ограничить значение переменной orientation
// диапазоном (0-360)
if (orientation < 0.0f)
orientation += 360.0f;
else if (orientation > 360.0f)
orientation -= 360.0f;
transform.Translate(displacement, Space.World);
transform.rotation = new Quaternion();
transform.Rotate(Vector3.up, orientation);
}
public virtual void LateUpdate()
{
velocity += steering.linear * Time.deltaTime;
rotation += steering.angular * Time.deltaTime;
if (velocity.magnitude > maxSpeed)
{
velocity = velocity.normalized * maxSpeed; // Исправлено: корректное нормирование вектора
}
if (steering.angular == 0.0f)
{
rotation = 0.0f;
}
if (steering.linear.sqrMagnitude == 0.0f)
{
velocity = Vector3.zero;
}
// Удалена строка: steering = new Steering();
// (создание нового объекта каждый кадр приведет к утечке памяти и сбросу данных)
}
}
}
@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 6d51ddde70f34264954a75923b43dcee
timeCreated: 1770394764
@@ -1,11 +0,0 @@
using UnityEngine;
namespace Code.Example.Race.Racer.AI.ID
{
public abstract class AgentBehaviour : MonoBehaviour
{
[SerializeField] protected AIRacerID agent;
public abstract Steering GetSteering(Transform target);
}
}
@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 5af0fc1b61bd44d9a53fd01f93fe6029
timeCreated: 1770394682
@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 70ca406222fb4e8e848ccf43db320cc9
timeCreated: 1770395746
@@ -1,17 +0,0 @@
using UnityEngine;
namespace Code.Example.Race.Racer.AI.ID.Behaviours
{
public class Flee : AgentBehaviour
{
public override Steering GetSteering(Transform target)
{
Steering steering = new Steering();
steering.linear = transform.position - target.position;
steering.linear.Normalize();
// steering.linear *= agent.Data.maxAcceleration;
return steering;
}
}
}
@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 437d2ae2cd65457a82abc34df278228d
timeCreated: 1770395798
@@ -1,42 +0,0 @@
using UnityEngine;
using System.Collections;
namespace Code.Example.Race.Racer.AI.ID.Behaviours
{
public class Pursue : Seek
{
public float maxPrediction;
private GameObject _targetAux;
private GameObject _target;
public void Awake()
{
_targetAux = _target;
_target = new GameObject();
}
void OnDestroy()
{
Destroy(_targetAux);
}
public override Steering GetSteering(Transform targetTransform)
{
var direction = _targetAux.transform.position - transform.position;
var distance = direction.magnitude;
var speed = agent.CarRigidbody.linearVelocity.magnitude;
float prediction;
if (speed <= distance / maxPrediction)
prediction = maxPrediction;
else
prediction = distance / speed;
_target.transform.position = _targetAux.transform.position;
// _target.transform.position += targetAgent.velocity * prediction;
return base.GetSteering(_target.transform);
}
}
}
@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: c3a071d2cab443528dd16bdc044bab65
timeCreated: 1770998212
@@ -1,18 +0,0 @@
using UnityEngine;
namespace Code.Example.Race.Racer.AI.ID.Behaviours
{
public class Seek : AgentBehaviour
{
public override Steering GetSteering(Transform target)
{
Steering steering = new Steering();
steering.linear = target.position - transform.position;
UnityEngine.Debug.DrawRay(transform.position, steering.linear, Color.yellow, 5f);
// steering.linear *= agent.Data.maxAcceleration;
steering.linear.Normalize();
return steering;
}
}
}
@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: aa69eb79c9ec48b682606dac0c0d4f2d
timeCreated: 1770395751
@@ -1,16 +0,0 @@
using UnityEngine;
namespace Code.Example.Race.Racer.AI.ID
{
public struct Steering
{
public float angular;
public Vector3 linear;
public Steering(float angular, Vector3 linear)
{
this.angular = angular;
this.linear = linear;
}
}
}
@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 0395b595869e49b5b177fe54db531823
timeCreated: 1770394582
-3
View File
@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 2c5dfd92289c4aa38bb9a8bafc07d204
timeCreated: 1769699718
@@ -1,32 +0,0 @@
using UnityEngine;
using UnityEngine.AI;
namespace Code.Example.Race.Racer.Car
{
public class CarWheelRotator : MonoBehaviour
{
[SerializeField] private NavMeshAgent agent;
[SerializeField] private Transform[] wheels;
[SerializeField] private bool rotateDebug;
private void Update()
{
Vector3 wheelRotation;
foreach (var wheel in wheels)
{
if (rotateDebug)
{
UnityEngine.Debug.DrawRay(
wheel.position,
Vector3.Project(agent.velocity, agent.gameObject.transform.right),
Color.yellow, 900f);
UnityEngine.Debug.Log(Vector3.Project(agent.velocity, agent.gameObject.transform.right).magnitude);
}
wheelRotation = wheel.localRotation.eulerAngles;
wheelRotation.y = Vector3.Project(agent.velocity, agent.gameObject.transform.right).magnitude * 10f;
wheel.localRotation = Quaternion.Euler(wheelRotation);
}
}
}
}
@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 3634956b4d55431b8772a8612e2e3a4d
timeCreated: 1769699734
@@ -1,23 +0,0 @@
using PrimeTween;
using UnityEngine;
namespace Code.Example.Race.Racer.Car
{
public class CarWheelRotatorPlayer : MonoBehaviour
{
[SerializeField] private Transform[] wheels;
[SerializeField] private bool rotateDebug;
public void RotateWheels(float amount)
{
// UnityEngine.Debug.Log("Rotating Wheels: " + amount);
foreach (var wheel in wheels)
{
var wheelRotation = wheel.localRotation.eulerAngles;
wheelRotation.y = amount;
Tween.LocalRotation(wheel,wheelRotation, 1f);
// wheel.localRotation = Quaternion.Euler(wheelRotation);
}
}
}
}
@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: c90fde90552d48f592b955cbf1ec5c77
timeCreated: 1769705011
@@ -1,165 +0,0 @@
using System;
using System.Collections.Generic;
using UnityEngine;
namespace Code.Example.Race.Racer
{
public abstract class CarControllerRB : MonoBehaviour
{
public enum ControlMode
{
Keyboard,
Buttons
};
public enum Axel
{
Front,
Rear
}
[Serializable]
public struct Wheel
{
public GameObject wheelModel;
public WheelCollider wheelCollider;
public GameObject wheelEffectObj;
public ParticleSystem smokeParticle;
public Axel axel;
}
public ControlMode control;
public Vector3 _centerOfMass;
public List<Wheel> wheels;
protected Rigidbody CarRb;
protected Vector2 SteeringInput = Vector2.zero;
public abstract void SetSteering(Vector2 steeringLinear);
[SerializeField] protected Racer racer;
// private CarLights carLights;
private void Start()
{
CarRb = GetComponent<Rigidbody>();
CarRb.centerOfMass = _centerOfMass;
// carLights = GetComponent<CarLights>();
}
protected virtual void Update()
{
// GetInputs();
AnimateWheels();
// WheelEffects();
}
private void FixedUpdate()
{
Move();
Steer();
Brake();
}
// public void MoveInput(float input)
// {
// moveInput = input;
// }
//
// public void SteerInput(float input)
// {
// steerInput = input;
// }
void GetInputs()
{
// if (control == ControlMode.Keyboard)
// {
// moveInput = Input.GetAxis("Vertical");
// steerInput = Input.GetAxis("Horizontal");
// }
}
private void Move()
{
foreach (var wheel in wheels)
{
wheel.wheelCollider.motorTorque = SteeringInput.y * 600 * racer.Data.maxAcceleration * Time.fixedDeltaTime;
// wheel.wheelCollider.motorTorque = _playerCarInput.MovementInput.y * 600 * _playerRacer.Data.maxAcceleration * Time.fixedDeltaTime;
}
}
private void Steer()
{
foreach (var wheel in wheels)
{
if (wheel.axel != Axel.Front) continue;
var steerAngle = SteeringInput.x * racer.Data.turnSensitivity * racer.Data.maxSteerAngle;
// var _steerAngle = _playerCarInput.MovementInput.x * _playerRacer.Data.turnSensitivity * _playerRacer.Data.maxSteerAngle;
wheel.wheelCollider.steerAngle = steerAngle;
// wheel.wheelCollider.steerAngle = Mathf.Lerp(wheel.wheelCollider.steerAngle, _steerAngle, 0.6f);
}
}
protected virtual void Brake()
{
//|| _playerCarInput.MovementInput.y == 0
// if (_playerCarInput.Brake )
// {
// foreach (var wheel in wheels)
// {
// wheel.wheelCollider.brakeTorque = 300 * _racer.Data.brakeAcceleration * Time.fixedDeltaTime;
// }
//
// // carLights.isBackLightOn = true;
// // carLights.OperateBackLights();
// }
// else
// {
// foreach (var wheel in wheels)
// {
// wheel.wheelCollider.brakeTorque = 0;
// }
//
// // carLights.isBackLightOn = false;
// // carLights.OperateBackLights();
// }
}
private void AnimateWheels()
{
foreach (var wheel in wheels)
{
Quaternion rot;
Vector3 pos;
wheel.wheelCollider.GetWorldPose(out pos, out rot);
wheel.wheelModel.transform.position = pos;
wheel.wheelModel.transform.rotation = rot;
}
}
private void WheelEffects()
{
foreach (var wheel in wheels)
{
//var dirtParticleMainSettings = wheel.smokeParticle.main;
if (wheel.axel == Axel.Rear && wheel.wheelCollider.isGrounded &&
CarRb.linearVelocity.magnitude >= 10.0f)
{
// wheel.wheelEffectObj.GetComponentInChildren<TrailRenderer>().emitting = true;
// wheel.smokeParticle.Emit(1);
}
else
{
// wheel.wheelEffectObj.GetComponentInChildren<TrailRenderer>().emitting = false;
}
}
}
}
}
@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 5f093c913ff54cb99cd22d7e473931e7
timeCreated: 1770299509
@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 7d9a0a4882314e2f91bb356ea0f82538
timeCreated: 1769705255
@@ -1,55 +0,0 @@
using Code.Example.Race.Racer.AI;
using Code.Example.Race.Racer.Car;
using UnityEngine;
namespace Code.Example.Race.Racer.Player
{
public class PlayerCarController : MonoBehaviour
{
[SerializeField] private Rigidbody _rigidbody;
[SerializeField] private PlayerCarInput _playerCarInput;
[SerializeField] private PlayerRacer _playerRacer;
[SerializeField] private CarWheelRotatorPlayer _wheels;
private void Update()
{
if (_playerCarInput.MovementInput == Vector2.zero) return;
// var movementForward = transform.forward * (_playerCarInput.MovementInput.y * _playerRacer.Data.speed);
//
// _rigidbody.AddForce(movementForward * Time.fixedDeltaTime, ForceMode.Force);
var force = transform.forward * (_playerCarInput.MovementInput.y * _playerRacer.Data.speed);
_rigidbody.AddForce(force, ForceMode.Force);
// if (Mathf.Abs(_playerCarInput.MovementInput.y) < 0.1f && _rigidbody.linearVelocity.magnitude > 0.3f)
// {
// _rigidbody.AddForce(-_rigidbody.linearVelocity * (_playerRacer.Data.brakeForce * Time.fixedDeltaTime),
// ForceMode.Force);
// }
var steerInput = _playerCarInput.MovementInput.x;
if (_playerCarInput.MovementInput.y < 0)
steerInput = -_playerCarInput.MovementInput.x;
// var steer = steerInput * maxSteerAngle;
//
// if (frontLeftWheel) frontLeftWheel.localRotation = Quaternion.Euler(0, steer, 0);
// if (frontRightWheel) frontRightWheel.localRotation = Quaternion.Euler(0, steer, 0);
if (!(_rigidbody.linearVelocity.magnitude > 0.5f)) return;
// var turn = steerInput * _playerRacer.Data.turnSpeed * Time.fixedDeltaTime;
// _rigidbody.MoveRotation(_rigidbody.rotation * Quaternion.Euler(0, turn, 0));
if (!(_rigidbody.linearVelocity.magnitude is > 1f or < -1f)) return;
var rotateAmount = _playerCarInput.MovementInput.x * _playerRacer.Data.angularSpeed;
_wheels.RotateWheels(rotateAmount * 10 * Time.fixedDeltaTime);
var wheelRotation = transform.rotation.eulerAngles;
wheelRotation.y += rotateAmount;
transform.rotation = Quaternion.Euler(wheelRotation);
}
}
}
@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 4b9e2e4a3ddc437ab250f609ea7fc33e
timeCreated: 1769705285
@@ -1,41 +0,0 @@
using Code.Infrastructure.Input;
using Reflex.Attributes;
using UnityEngine;
using UnityEngine.InputSystem;
namespace Code.Example.Race.Racer.Player
{
public class PlayerCarInput : MonoBehaviour
{
private IInputService _inputService;
public Vector2 MovementInput { get; private set; }
public bool Brake { get; private set; }
[Inject]
public void Construct(IInputService inputService)
{
_inputService = inputService;
_inputService.BindActionPerformed((int)ActionMappings.Race, (int)RaceActions.Move, MovementPerformed);
_inputService.BindActionCancelled((int)ActionMappings.Race, (int)RaceActions.Move, MovementEnded);
_inputService.BindActionPerformed((int)ActionMappings.Race, (int)RaceActions.Brake, BrakePerformed);
_inputService.BindActionCancelled((int)ActionMappings.Race, (int)RaceActions.Brake, BrakeEnded);
}
private void MovementPerformed(InputAction.CallbackContext context) => MovementInput = context.ReadValue<Vector2>();
private void MovementEnded(InputAction.CallbackContext context) => MovementInput = Vector2.zero;
private void BrakePerformed(InputAction.CallbackContext context) => Brake = true;
private void BrakeEnded(InputAction.CallbackContext context) => Brake = false;
private void OnDestroy()
{
if (_inputService == null) return;
_inputService.UnbindActionPerformed((int)ActionMappings.Race, (int)RaceActions.Move, MovementPerformed);
_inputService.UnbindActionCancelled((int)ActionMappings.Race, (int)RaceActions.Move, MovementEnded);
_inputService.UnbindActionPerformed((int)ActionMappings.Race, (int)RaceActions.Brake, BrakePerformed);
_inputService.UnbindActionCancelled((int)ActionMappings.Race, (int)RaceActions.Brake, BrakeEnded);
}
}
}
@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: e52315b65c57499981981e2507aaf7bc
timeCreated: 1769705872
@@ -1,44 +0,0 @@
using UnityEngine;
namespace Code.Example.Race.Racer.Player
{
public class PlayerRBCarController : CarControllerRB
{
[SerializeField] private PlayerCarInput playerCarInput;
public override void SetSteering(Vector2 steeringLinear)
{
}
protected override void Update()
{
SteeringInput = playerCarInput.MovementInput;
base.Update();
}
protected override void Brake()
{
if (playerCarInput.Brake )
{
foreach (var wheel in wheels)
{
wheel.wheelCollider.brakeTorque = 300 * racer.Data.brakeAcceleration * Time.fixedDeltaTime;
}
// carLights.isBackLightOn = true;
// carLights.OperateBackLights();
}
else
{
foreach (var wheel in wheels)
{
wheel.wheelCollider.brakeTorque = 0;
}
// carLights.isBackLightOn = false;
// carLights.OperateBackLights();
}
}
}
}
@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: bad2326aa0f24acb9bdfeb5fb7d3d208
timeCreated: 1770640123
@@ -1,43 +0,0 @@
using System.Collections.Generic;
using Code.Example.Race.Track;
using Code.Infrastructure.EventBus;
using Reflex.Attributes;
using UnityEngine;
namespace Code.Example.Race.Racer.Player
{
public class PlayerRacer : Racer
{
[Inject] private EventBus _eventBus;
public Transform CameraPosition;
public override void SetData(RacerData data)
{
Data = data;
}
public override void Initialize(List<Transform> waypoints)
{
Waypoints = waypoints;
}
public override void NextWaypoint()
{
if (++CurrentWaypointIndex < Waypoints.Count) return;
CurrentWaypointIndex = 0;
_eventBus.RaiseEvent<IPlayerPassedCheckpointHandler>(x=> x.OnPlayerLapPassed(this));
_eventBus.RaiseEvent<IRacerPassedCheckpointHandler>(x=> x.LapPassed(this));
}
public bool RaceStarted { get; set; }
public override void StartRacer()
{
RaceStarted = true;
}
public override void StopRacer()
{
RaceStarted = false;
}
}
}
@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 6d3497d41c87415eab67cfc865262b79
timeCreated: 1769619757
-22
View File
@@ -1,22 +0,0 @@
using System.Collections.Generic;
using UnityEngine;
namespace Code.Example.Race.Racer
{
public abstract class Racer : MonoBehaviour
{
protected List<Transform> Waypoints;
public int CurrentWaypointIndex { get; protected set; }
public RacerData Data { get; protected set; }
public int Id { get; set; }
public abstract void SetData(RacerData data);
public abstract void Initialize(List<Transform> waypoints);
public abstract void NextWaypoint();
public abstract void StartRacer();
public abstract void StopRacer();
[SerializeField] protected Rigidbody carRigidbody;
public Rigidbody CarRigidbody => GetComponent<Rigidbody>();
}
}
@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 7f87ed38713d4b779df9e46c83b03fb7
timeCreated: 1769619306
@@ -1,97 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Code.Infrastructure.Configs;
using Code.Infrastructure.EventBus;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;
using EventBus = Code.Infrastructure.EventBus.EventBus;
namespace Code.Example.Race.Racer
{
public interface IRacerFactory
{
RacerSettingsConfig GetConfig(RacerType racerType);
UniTaskVoid LoadRacer(RacerType racerType);
void ReleaseRacer(RacerType racerType);
}
public class RacerFactory : IDisposable, IRacerFactory
{
private Dictionary<RacerType, RacerSettingsConfig> _racerConfigs;
private Dictionary<RacerType, AsyncOperationHandle<GameObject>> _racerPrefabsHandle = new();
private string _racerConfigsLabel;
private AsyncOperationHandle<IList<RacerSettingsConfig>> _racerConfigsHandle;
private EventBus _eventBus;
public RacerFactory(IConfigLocator configLocator, EventBus eventBus)
{
_eventBus = eventBus;
_racerConfigsLabel = configLocator.TryGetManyConfigAssetReferences<RacerSettingsConfig>();
LoadConfigs().Forget();
}
private async UniTaskVoid LoadConfigs()
{
_racerConfigsHandle = Addressables.LoadAssetsAsync<RacerSettingsConfig>(_racerConfigsLabel);
await _racerConfigsHandle.ToUniTask();
_racerConfigs = _racerConfigsHandle.Result.ToDictionary(x => x.racerData.type);
_eventBus.RaiseEvent<IRacerFactoryInitializedHandle>(x => x.RacerFactoryInitialized());
}
public RacerSettingsConfig GetConfig(RacerType racerType) => _racerConfigs[racerType];
public async UniTaskVoid LoadRacer(RacerType racerType)
{
if (_racerPrefabsHandle.ContainsKey(racerType))
{
_eventBus.RaiseEvent<IRacerLoadedHandle>(x => x.RacerLoaded(racerType, null));
return;
}
UnityEngine.Debug.LogWarning($"Racer loaded {racerType}");
_racerPrefabsHandle.Add(racerType,
Addressables.LoadAssetAsync<GameObject>(_racerConfigs[racerType].prefabReference));
await _racerPrefabsHandle[racerType].ToUniTask();
var racer = _racerPrefabsHandle[racerType].Result.GetComponent<Racer>();
racer.SetData(_racerConfigs[racerType].racerData);
_eventBus.RaiseEvent<IRacerLoadedHandle>(x => x.RacerLoaded(racerType, racer));
}
public void ReleaseRacer(RacerType racerType)
{
_racerPrefabsHandle[racerType].Release();
_racerPrefabsHandle.Remove(racerType);
}
public void Dispose()
{
UnityEngine.Debug.LogWarning($"Racers released");
foreach (var prefab in _racerPrefabsHandle)
prefab.Value.Release();
_racerPrefabsHandle.Clear();
_racerConfigsHandle.Release();
}
}
public interface IRacerFactoryInitializedHandle : IGlobalSubscriber
{
public void RacerFactoryInitialized();
}
public interface IRacerLoadedHandle : IGlobalSubscriber
{
public void RacerLoaded(RacerType type, Racer racer);
}
}
@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 5ab404f94a89460eae107b9d453fa64d
timeCreated: 1769620039
@@ -1,27 +0,0 @@
using System;
using Code.Infrastructure.Generators;
using UnityEngine.AddressableAssets;
namespace Code.Example.Race.Racer
{
[Config("Configs/Gameplay/RacerSettings", true)]
public class RacerSettings
{
[ToConfig] public RacerData racerData;
[ToConfig] public AssetReference prefabReference;
}
[Serializable]
public struct RacerData
{
public string name;
public float speed;
public float angularSpeed;
public float maxAcceleration;
public float brakeAcceleration;
public float turnSensitivity;
public float maxSteerAngle;
public RacerType type;
}
}
@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: f25b32b493144bfc9ca0c5016741d012
timeCreated: 1769619229
@@ -1,9 +0,0 @@
namespace Code.Example.Race.Racer
{
public enum RacerType
{
Player,
AIGreen,
AIRed
}
}
@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 488f864fcf6f4632b8d50b39038f5472
timeCreated: 1769619126
@@ -1,7 +0,0 @@
namespace Code.Example.Race.Racer
{
public class RacistSpawnListDebug
{
}
}
@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: a9506da417a249929493862133eef179
timeCreated: 1769685790
-3
View File
@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: dbcf0e0163844255817cec8c81839eb1
timeCreated: 1769522093
@@ -1,44 +0,0 @@
using Code.Example.Race.Racer;
using Code.Infrastructure.EventBus;
using Reflex.Attributes;
using UnityEngine;
namespace Code.Example.Race.Track
{
public class CheckPoint : MonoBehaviour
{
[Inject] private EventBus _eventBus;
[SerializeField] private GameObject _checkPointMesh;
[SerializeField] private int _id; // Костыль инвалид лестница
private void OnTriggerEnter(Collider other)
{
var racer = other.GetComponent<Racer.Racer>();
if (racer.CurrentWaypointIndex != _id) return;
racer.NextWaypoint();
if (racer.Data.type == RacerType.Player)
{
Hide();
_eventBus.RaiseEvent<IPlayerPassedCheckpointHandler>(h => h.OnPlayerPassedCheckpoint(racer));
}
_eventBus.RaiseEvent<IRacerPassedCheckpointHandler>(h => h.OnRacerPassedCheckpoint(racer));
}
public void Hide() => _checkPointMesh.SetActive(false);
public void Show() => _checkPointMesh.SetActive(true);
}
public interface IRacerPassedCheckpointHandler : IGlobalSubscriber
{
void OnRacerPassedCheckpoint(Racer.Racer racer);
void LapPassed(Racer.Racer racer);
}
public interface IPlayerPassedCheckpointHandler : IGlobalSubscriber
{
void OnPlayerPassedCheckpoint(Racer.Racer racer);
void OnPlayerLapPassed(Racer.Racer racer);
}
}
@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: e4e29d6d9b0342db9cd6bce229fa358d
timeCreated: 1769522101
@@ -1,19 +0,0 @@
using System.Collections.Generic;
using UnityEngine;
namespace Code.Example.Race.Track
{
public class RaceTrackData : MonoBehaviour
{
public Transform CameraPosition;
public TrackData trackData;
}
[System.Serializable]
public struct TrackData
{
public List<Transform> RacerPoints;
public List<CheckPoint> Checkpoints;
public int LapCount;
}
}
@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 1847a22e722c47c48ec0ce7d5a929580
timeCreated: 1769686034
@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: af09293375544928a9b19a6b697f214e
timeCreated: 1770036714
@@ -1,39 +0,0 @@
namespace Code.Example.Race.Track.WellEditor
{
using UnityEngine;
using UnityEditor;
public static class CheckPointAsset
{
[MenuItem("GameObject/Track/CheckPoint", false, 1)]
private static void CreateCustomPrefab()
{
// Define the path to your prefab in the Project (must be in an "Assets" relative path)
var prefabPath = "Assets/Resources/Example/Misc/Point.prefab"; // Update with your actual path
// Load the prefab asset
var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(prefabPath);
if (!prefab)
{
Debug.LogError("Prefab not found at path: " + prefabPath);
return;
}
// Instantiate the prefab in the scene
var newInstance = (GameObject)PrefabUtility.InstantiatePrefab(prefab);
// Ensure it is placed correctly in the Hierarchy and is undoable
Undo.RegisterCreatedObjectUndo(newInstance, "Create Custom Prefab");
Selection.activeGameObject = newInstance;
// Set parent if an object is selected
if (!Selection.activeTransform)
{
newInstance.transform.parent = Selection.activeTransform;
newInstance.transform.localPosition = Vector3.zero;
}
}
}
}
@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 7d55e4bcf05848eea361440799c21d7e
timeCreated: 1770036738
-3
View File
@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: b875d3daf0cc42e997366fb0b9f0a722
timeCreated: 1770042347
@@ -1,44 +0,0 @@
using System;
using System.Collections.Generic;
using Code.Infrastructure.EventBus;
using Code.Infrastructure.UI;
using Reflex.Attributes;
using TMPro;
using UnityEngine;
namespace Code.Example.Race.UI
{
public partial class PlayerScoreCounter : UIPanel, IScoreChangedHandle
{
[SerializeField] private TMP_Text playerScore;
private EventBus _eventBus;
[Inject]
private void Construct(EventBus eventBus)
{
_eventBus = eventBus;
_eventBus.Subscribe(this);
}
public override void Open()
{
playerScore.gameObject.SetActive(true);
// callback?.Invoke();
// image.DOColor(shownColor, 1f).onComplete = () => callback?.Invoke();
}
public override void Close()
{
playerScore.gameObject.SetActive(false);
// callback?.Invoke();
// image.DOColor(hiddenColor, 1f).onComplete += () => callback?.Invoke();
}
public void ScoreChanged(Racer.Racer racer, ScoreData additionalScore, List<KeyValuePair<Racer.Racer,ScoreData>> scores)
{
// if (racer.Data.type == RacerType.Player)
string output = "";
foreach (var score in scores) output += $@"{score.Key.Data.name}: {score.Value.lapsPassed} \t {score.Value.checkpointsPassed}\n";
playerScore.text = output;
}
}
}
@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: cf68a9a9d3a946f086dccd6d11741dcf
timeCreated: 1770042362
@@ -1,40 +0,0 @@
using System;
using System.Collections.Generic;
using Code.Infrastructure.UI;
using PrimeTween;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
namespace Code.Example.Race.UI
{
public partial class PlayerScores : UIPanel
{
[SerializeField] private Image image;
[SerializeField] private TMP_Text scoreText;
[SerializeField] private Color shownColor;
[SerializeField] private Color hiddenColor;
public void SetText(List<RaceData> scores)
{
scoreText.text = "";
foreach (var score in scores)
{
var t = TimeSpan.FromSeconds(score.raceTimeSeconds);
scoreText.text += $@"{score.place} место за {t:mm\:ss\:fff}\n";
}
}
public override void Open()
{
Tween.Color(image,shownColor, 1f);
// Tween.Color(scoreText,shownColor, 1f).OnComplete( () => callback?.Invoke());
}
public override void Close()
{
Tween.Color(image,hiddenColor, 1f);
// Tween.Color(scoreText,hiddenColor, 1f).OnComplete( () => callback?.Invoke());
}
}
}
@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 250fd47281f3493e86590f89511bba17
timeCreated: 1770654299
-30
View File
@@ -1,30 +0,0 @@
using System;
using Code.Infrastructure.UI;
using PrimeTween;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
namespace Code.Example.Race.UI
{
public partial class WinScreen : UIPanel
{
[SerializeField] private Image image;
[SerializeField] private TMP_Text winText;
[SerializeField] private Color shownColor;
[SerializeField] private Color hiddenColor;
public void SetText(string text) => winText.text = text;
public override void Open()
{
Tween.Color(image,shownColor, 1f);
// Tween.Color(winText,shownColor, 1f).OnComplete( () => callback?.Invoke());
}
public override void Close()
{
Tween.Color(image,hiddenColor, 1f);
// Tween.Color(winText,hiddenColor, 1f).OnComplete( () => callback?.Invoke());
}
}
}
@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 9093110373134c91b06be09705639ddd
timeCreated: 1770455340