Compare commits
28
Commits
UI2
..
Addressables
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7bc15cc03d | ||
|
|
d861e06caf | ||
|
|
f940cbffe0 | ||
|
|
6b1f24b72e | ||
|
|
1ad87e7432 | ||
|
|
09219d9091 | ||
|
|
37f5d15410 | ||
|
|
019da8cfd3 | ||
|
|
edf3821c0d | ||
|
|
45fe19be24 | ||
|
|
bea109175b | ||
|
|
b214bb0f63 | ||
|
|
0ac5ba1e1c | ||
|
|
ab9d444072 | ||
|
|
2335908a90 | ||
|
|
ae76edb0d0 | ||
|
|
6f2b063700 | ||
|
|
c6d1c3bffd | ||
|
|
07ce27618c | ||
|
|
fb85b22e96 | ||
|
|
665114b7dc | ||
|
|
4549617275 | ||
|
|
db541fed8a | ||
|
|
085429d5ca | ||
|
|
981d081bed | ||
|
|
6148889fc1 | ||
|
|
7538ce81af | ||
|
|
9a3743988d |
No files matched your search
@@ -0,0 +1,16 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!114 &11400000
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 0}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: dea69d41f90c6ea4fa55c27c1d60c145, type: 3}
|
||||||
|
m_Name: AddressableAssetGroupSortSettings
|
||||||
|
m_EditorClassIdentifier: Unity.Addressables.Editor::UnityEditor.AddressableAssets.Settings.GroupSchemas.AddressableAssetGroupSortSettings
|
||||||
|
sortOrder:
|
||||||
|
- d447fc60305c17a17bf20948ab295a45
|
||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: 6938984fc7d25285abb4922dd46d9272
|
guid: 88c15d5f41d582974a9b7218c493e4a7
|
||||||
NativeFormatImporter:
|
NativeFormatImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
mainObjectFileID: 11400000
|
mainObjectFileID: 11400000
|
||||||
@@ -15,7 +15,7 @@ MonoBehaviour:
|
|||||||
m_DefaultGroup: d447fc60305c17a17bf20948ab295a45
|
m_DefaultGroup: d447fc60305c17a17bf20948ab295a45
|
||||||
m_currentHash:
|
m_currentHash:
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
Hash: 00000000000000000000000000000000
|
Hash: 90c715b85c1e0904b3dc61a9ed460206
|
||||||
m_OptimizeCatalogSize: 0
|
m_OptimizeCatalogSize: 0
|
||||||
m_BuildRemoteCatalog: 0
|
m_BuildRemoteCatalog: 0
|
||||||
m_CatalogRequestsTimeout: 0
|
m_CatalogRequestsTimeout: 0
|
||||||
@@ -54,7 +54,7 @@ MonoBehaviour:
|
|||||||
m_Id:
|
m_Id:
|
||||||
m_RemoteCatalogLoadPath:
|
m_RemoteCatalogLoadPath:
|
||||||
m_Id:
|
m_Id:
|
||||||
m_ContentStateBuildPathProfileVariableName:
|
m_ContentStateBuildPathProfileVariableName: <default settings path>
|
||||||
m_CustomContentStateBuildPath:
|
m_CustomContentStateBuildPath:
|
||||||
m_ContentStateBuildPath:
|
m_ContentStateBuildPath:
|
||||||
m_BuildAddressablesWithPlayerBuild: 0
|
m_BuildAddressablesWithPlayerBuild: 0
|
||||||
|
|||||||
@@ -14,7 +14,32 @@ MonoBehaviour:
|
|||||||
m_EditorClassIdentifier: Unity.Addressables.Editor::UnityEditor.AddressableAssets.Settings.AddressableAssetGroup
|
m_EditorClassIdentifier: Unity.Addressables.Editor::UnityEditor.AddressableAssets.Settings.AddressableAssetGroup
|
||||||
m_GroupName: Default Local Group
|
m_GroupName: Default Local Group
|
||||||
m_GUID: d447fc60305c17a17bf20948ab295a45
|
m_GUID: d447fc60305c17a17bf20948ab295a45
|
||||||
m_SerializeEntries: []
|
m_SerializeEntries:
|
||||||
|
- m_GUID: 23e11d2c8a4f12f4ea9a7a43d1118464
|
||||||
|
m_Address: Gameplay
|
||||||
|
m_ReadOnly: 0
|
||||||
|
m_SerializedLabels: []
|
||||||
|
FlaggedDuringContentUpdateRestriction: 0
|
||||||
|
- m_GUID: 48aebfe8826dc0df79d047b5afbf8f5b
|
||||||
|
m_Address: Canvas
|
||||||
|
m_ReadOnly: 0
|
||||||
|
m_SerializedLabels: []
|
||||||
|
FlaggedDuringContentUpdateRestriction: 0
|
||||||
|
- m_GUID: b2e8dc2aeb0311cd8a826b51cf8e94dc
|
||||||
|
m_Address: GameOver
|
||||||
|
m_ReadOnly: 0
|
||||||
|
m_SerializedLabels: []
|
||||||
|
FlaggedDuringContentUpdateRestriction: 0
|
||||||
|
- m_GUID: c566fc932edefbbee9e53271eac3c560
|
||||||
|
m_Address: MainMenu
|
||||||
|
m_ReadOnly: 0
|
||||||
|
m_SerializedLabels: []
|
||||||
|
FlaggedDuringContentUpdateRestriction: 0
|
||||||
|
- m_GUID: f23b9fce9594618e5b75845f1cae50de
|
||||||
|
m_Address: LoadingScreen
|
||||||
|
m_ReadOnly: 0
|
||||||
|
m_SerializedLabels: []
|
||||||
|
FlaggedDuringContentUpdateRestriction: 0
|
||||||
m_ReadOnly: 0
|
m_ReadOnly: 0
|
||||||
m_Settings: {fileID: 11400000, guid: 2588e84eb64800d0781c574a37fa48d8, type: 2}
|
m_Settings: {fileID: 11400000, guid: 2588e84eb64800d0781c574a37fa48d8, type: 2}
|
||||||
m_SchemaSet:
|
m_SchemaSet:
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
using Code.App.StateMachine;
|
||||||
|
using Code.StateMachine;
|
||||||
|
|
||||||
|
namespace Code.App.AppStates
|
||||||
|
{
|
||||||
|
public class BootstrapState : BaseState<AppStateMachineContext>
|
||||||
|
{
|
||||||
|
public BootstrapState(AppStateMachineContext context) : base(context)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 0183e73a08c64332babded3df3d06b95
|
||||||
|
timeCreated: 1762122962
|
||||||
@@ -1,5 +1,8 @@
|
|||||||
using Code.App.StateMachine;
|
using Code.App.StateMachine;
|
||||||
|
using Code.Scenes;
|
||||||
using Code.StateMachine;
|
using Code.StateMachine;
|
||||||
|
using Code.UI;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
namespace Code.App.AppStates
|
namespace Code.App.AppStates
|
||||||
{
|
{
|
||||||
@@ -7,17 +10,32 @@ namespace Code.App.AppStates
|
|||||||
{
|
{
|
||||||
public GameOverState(AppStateMachineContext context) : base(context)
|
public GameOverState(AppStateMachineContext context) : base(context)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
private float damnTimer = 3f; // TODO Удалить при первой возможности
|
||||||
|
|
||||||
public override void EnterState()
|
public override void EnterState()
|
||||||
{
|
{
|
||||||
|
Context.UIService.SwitchPanelTo(UIPanel.GameOver);
|
||||||
|
|
||||||
base.EnterState();
|
base.EnterState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void ToMainMenu()
|
||||||
|
{
|
||||||
|
Context.StateMachine.SwitchState(AppState.MainMenu)
|
||||||
|
.AllowStateTransition(AppState.Gameplay);
|
||||||
|
}
|
||||||
|
|
||||||
public override void Tick()
|
public override void Tick()
|
||||||
{ }
|
{
|
||||||
|
damnTimer -= Time.deltaTime;
|
||||||
|
if (damnTimer <= float.Epsilon) ToMainMenu();
|
||||||
|
}
|
||||||
public override void ExitState()
|
public override void ExitState()
|
||||||
{
|
{
|
||||||
|
damnTimer = 5f;
|
||||||
|
|
||||||
|
Context.UIService.LoadingScreen.Show();
|
||||||
base.ExitState();
|
base.ExitState();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,13 +5,16 @@ using Code.Input;
|
|||||||
using Code.Scenes;
|
using Code.Scenes;
|
||||||
using Code.StateMachine;
|
using Code.StateMachine;
|
||||||
using Code.UI;
|
using Code.UI;
|
||||||
using UnityEngine;
|
using UnityEngine.InputSystem;
|
||||||
|
|
||||||
namespace Code.App.AppStates
|
namespace Code.App.AppStates
|
||||||
{
|
{
|
||||||
public class GameplayState : BaseState<AppStateMachineContext>
|
public class GameplayState : BaseState<AppStateMachineContext>
|
||||||
{
|
{
|
||||||
private PlayerHealth _playerHealthPoints;
|
private PlayerHealth _playerHealth;
|
||||||
|
private PlayerMoney _playerMoney;
|
||||||
|
|
||||||
|
private bool _uiLoaded, _sceneLoaded;
|
||||||
|
|
||||||
public GameplayState(AppStateMachineContext context) : base(context)
|
public GameplayState(AppStateMachineContext context) : base(context)
|
||||||
{
|
{
|
||||||
@@ -19,30 +22,94 @@ namespace Code.App.AppStates
|
|||||||
|
|
||||||
public override void EnterState()
|
public override void EnterState()
|
||||||
{
|
{
|
||||||
Context.SceneLoaderService.LoadScene((int)SceneIds.MovementDev, SceneLoaded);
|
_uiLoaded = _sceneLoaded = false;
|
||||||
Context.InputService.EnableMap(ActionMappings.Gameplay);
|
|
||||||
|
|
||||||
Context.UIService.LoadingScreen.Show();
|
Context.UIService.LoadingScreen.Show();
|
||||||
Context.UIService.SwitchPanelTo(UIPanel.Gameplay);
|
|
||||||
|
|
||||||
Context.CameraStateMachine.SwitchState(CameraMode.FirstPerson);
|
_playerMoney = Context.PlayerFactory.CreatePlayerMoney();
|
||||||
}
|
_playerHealth = Context.PlayerFactory.CreatePlayerHealth();
|
||||||
|
|
||||||
|
_playerHealth.OnDeath += EndGame;
|
||||||
|
|
||||||
|
Context.SceneLoaderService.LoadSceneAsync((int)SceneIds.MovementDev, callBack: OnSceneLoaded); // TODO Фабрика игрока Nada
|
||||||
|
|
||||||
|
Context.UIService.SwitchPanelTo(UIPanel.Gameplay, callback: PostUILoaded);
|
||||||
|
|
||||||
private void SceneLoaded()
|
Context.InputService.DebugBindAction((int)ActionMappings.Debug, (int)DebugActions.GiveHealth, GiveHealth);
|
||||||
{
|
Context.InputService.DebugBindAction((int)ActionMappings.Debug, (int)DebugActions.GiveMoney, GiveMoney);
|
||||||
Context.UIService.LoadingScreen.Hide();
|
Context.InputService.DebugBindAction((int)ActionMappings.Debug, (int)DebugActions.LooseHealth, LooseHealth);
|
||||||
|
Context.InputService.DebugBindAction((int)ActionMappings.Debug, (int)DebugActions.LooseMoney, LooseMoney);
|
||||||
base.EnterState();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnSceneLoaded()
|
||||||
|
{
|
||||||
|
_sceneLoaded = true;
|
||||||
|
CheckIfLoaded();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PostUILoaded()
|
||||||
|
{
|
||||||
|
((GameplayPanel)Context.UIService.CurrentPanel).Initialize(_playerMoney, _playerHealth);
|
||||||
|
_uiLoaded = true;
|
||||||
|
CheckIfLoaded();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CheckIfLoaded()
|
||||||
|
{
|
||||||
|
if(!_uiLoaded || !_sceneLoaded) return;
|
||||||
|
|
||||||
|
Context.UIService.LoadingScreen.Hide();
|
||||||
|
|
||||||
|
Context.CameraStateMachine.SwitchState(CameraMode.FirstPerson);
|
||||||
|
Context.InputService.EnableMap(ActionMappings.Gameplay);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Debug
|
||||||
|
private void GiveHealth(InputAction.CallbackContext context)
|
||||||
|
{
|
||||||
|
_playerHealth.GetDamage(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LooseHealth(InputAction.CallbackContext context)
|
||||||
|
{
|
||||||
|
_playerHealth.GetDamage(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GiveMoney(InputAction.CallbackContext context)
|
||||||
|
{
|
||||||
|
_playerMoney.GiveMoney(100);
|
||||||
|
((GameplayPanel)(Context.UIService.CurrentPanel)).SummonDispatcher();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LooseMoney(InputAction.CallbackContext context)
|
||||||
|
{
|
||||||
|
_playerMoney.LooseMoney(100);
|
||||||
|
((GameplayPanel)(Context.UIService.CurrentPanel)).CloseDispatcher();
|
||||||
|
}
|
||||||
|
|
||||||
public override void Tick()
|
public override void Tick()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void EndGame()
|
||||||
|
{
|
||||||
|
Context.StateMachine.SwitchState(AppState.GameOver)
|
||||||
|
.AllowStateTransition(AppState.MainMenu);
|
||||||
|
}
|
||||||
|
|
||||||
public override void ExitState()
|
public override void ExitState()
|
||||||
{
|
{
|
||||||
|
_playerHealth = null;
|
||||||
|
_playerMoney = null;
|
||||||
|
|
||||||
Context.InputService.DisableMap(ActionMappings.Gameplay);
|
Context.InputService.DisableMap(ActionMappings.Gameplay);
|
||||||
|
|
||||||
|
Context.InputService.DebugUnbindAction((int)ActionMappings.Debug, (int)DebugActions.GiveHealth, GiveHealth);
|
||||||
|
Context.InputService.DebugUnbindAction((int)ActionMappings.Debug, (int)DebugActions.GiveMoney, GiveHealth);
|
||||||
|
Context.InputService.DebugUnbindAction((int)ActionMappings.Debug, (int)DebugActions.LooseHealth, LooseHealth);
|
||||||
|
Context.InputService.DebugUnbindAction((int)ActionMappings.Debug, (int)DebugActions.LooseMoney, LooseMoney);
|
||||||
|
|
||||||
base.ExitState();
|
base.ExitState();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,44 +1,81 @@
|
|||||||
using Code.App.StateMachine;
|
using Code.App.StateMachine;
|
||||||
using Code.Gameplay.Camera;
|
using Code.Gameplay.Camera;
|
||||||
|
using Code.Gameplay.Camera.CameraStates;
|
||||||
using Code.Input;
|
using Code.Input;
|
||||||
using Code.Scenes;
|
using Code.Scenes;
|
||||||
|
using Code.Scenes.SceneEnvironments;
|
||||||
using Code.StateMachine;
|
using Code.StateMachine;
|
||||||
using Code.UI;
|
using Code.UI;
|
||||||
|
using Reflex.Extensions;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
using UnityEngine.SceneManagement;
|
||||||
|
|
||||||
namespace Code.App.AppStates
|
namespace Code.App.AppStates
|
||||||
{
|
{
|
||||||
public class MainMenuState : BaseState<AppStateMachineContext>
|
public class MainMenuState : BaseState<AppStateMachineContext>
|
||||||
{
|
{
|
||||||
|
private bool _uiLoaded, _sceneLoaded;
|
||||||
public MainMenuState(AppStateMachineContext context) : base(context)
|
public MainMenuState(AppStateMachineContext context) : base(context)
|
||||||
{ }
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public override void EnterState()
|
public override void EnterState()
|
||||||
{
|
{
|
||||||
Context.SceneLoaderService.LoadScene((int)SceneIds.MainMenu, SceneLoaded);
|
_uiLoaded = _sceneLoaded = false;
|
||||||
Context.InputService.EnableMap(ActionMappings.MainMenu);
|
|
||||||
|
|
||||||
Context.UIService.LoadingScreen.Show();
|
Context.UIService.LoadingScreen.Show();
|
||||||
Context.UIService.SwitchPanelTo(UIPanel.MainMenu);
|
|
||||||
|
Context.SceneLoaderService.LoadSceneAsync((int)SceneIds.MainMenu, callBack: SceneLoaded);
|
||||||
|
|
||||||
|
Context.UIService.SwitchPanelTo(UIPanel.MainMenu, PostUILoaded);
|
||||||
|
|
||||||
|
Context.CameraStateMachine.SwitchState(CameraMode.Static);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PostUILoaded()
|
||||||
|
{
|
||||||
((MainMenuPanel)Context.UIService.CurrentPanel).startButton.onClick.AddListener(StartGame);
|
((MainMenuPanel)Context.UIService.CurrentPanel).startButton.onClick.AddListener(StartGame);
|
||||||
((MainMenuPanel)Context.UIService.CurrentPanel).exitButton.onClick.AddListener(ExitGame);
|
((MainMenuPanel)Context.UIService.CurrentPanel).exitButton.onClick.AddListener(ExitGame);
|
||||||
|
|
||||||
Context.CameraStateMachine.SwitchState(CameraMode.Static);
|
_uiLoaded = true;
|
||||||
|
|
||||||
|
CheckIfLoaded();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SceneLoaded()
|
private void SceneLoaded()
|
||||||
{
|
{
|
||||||
|
var hui = ((MainMenuEnvironment)SceneManager.GetActiveScene()
|
||||||
|
.GetSceneContainer().Resolve<CurrentSceneEnvironment>());
|
||||||
|
|
||||||
|
((StaticState)Context.CameraStateMachine.CurrentBaseState).LookTarget =
|
||||||
|
hui.cameraTarget;
|
||||||
|
|
||||||
|
((BaseCameraState)Context.CameraStateMachine.CurrentBaseState).SetFollowTransform(hui.cameraPosition);
|
||||||
|
|
||||||
|
|
||||||
|
_sceneLoaded = true;
|
||||||
|
|
||||||
|
CheckIfLoaded();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CheckIfLoaded()
|
||||||
|
{
|
||||||
|
if(!_uiLoaded || !_sceneLoaded) return;
|
||||||
|
|
||||||
Context.UIService.LoadingScreen.Hide();
|
Context.UIService.LoadingScreen.Hide();
|
||||||
|
|
||||||
|
Context.InputService.EnableMap(ActionMappings.MainMenu);
|
||||||
|
|
||||||
base.EnterState();
|
base.EnterState();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Tick()
|
public override void Tick()
|
||||||
{ }
|
{
|
||||||
|
}
|
||||||
|
|
||||||
private void StartGame()
|
private void StartGame()
|
||||||
{
|
{
|
||||||
Context.StateMachine.SwitchState(AppState.Gameplay)
|
Context.StateMachine.SwitchState(AppState.Gameplay)
|
||||||
.AllowStateTransition(AppState.MainMenu)
|
|
||||||
.AllowStateTransition(AppState.GameOver);
|
.AllowStateTransition(AppState.GameOver);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,11 +83,11 @@ namespace Code.App.AppStates
|
|||||||
{
|
{
|
||||||
Application.Quit();
|
Application.Quit();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void ExitState()
|
public override void ExitState()
|
||||||
{
|
{
|
||||||
Context.InputService.DisableMap(ActionMappings.MainMenu);
|
Context.InputService.DisableMap(ActionMappings.MainMenu);
|
||||||
|
|
||||||
base.ExitState();
|
base.ExitState();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Code.App.StateMachine;
|
using Code.App.StateMachine;
|
||||||
|
using Code.Gameplay.Camera;
|
||||||
using Code.Input;
|
using Code.Input;
|
||||||
using Code.Scenes;
|
using Code.Scenes;
|
||||||
using Code.StateMachine;
|
using Code.StateMachine;
|
||||||
@@ -14,8 +15,10 @@ namespace Code.App.AppStates
|
|||||||
|
|
||||||
public override void EnterState()
|
public override void EnterState()
|
||||||
{
|
{
|
||||||
Context.SceneLoaderService.LoadScene((int)SceneIds.MovementDev, SceneLoaded);
|
// Context.SceneLoaderService.LoadScene((int)SceneIds.MovementDev, SceneLoaded);
|
||||||
Context.InputService.EnableMap(ActionMappings.Gameplay);
|
Context.InputService.EnableMap(ActionMappings.Gameplay);
|
||||||
|
|
||||||
|
Context.CameraStateMachine.SwitchState(CameraMode.FirstPerson);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SceneLoaded()
|
private void SceneLoaded()
|
||||||
|
|||||||
@@ -1,21 +1,25 @@
|
|||||||
|
using System.Threading.Tasks;
|
||||||
using Code.App.StateMachine;
|
using Code.App.StateMachine;
|
||||||
using Code.Configs;
|
using Code.Configs;
|
||||||
|
using Code.Constants;
|
||||||
using Code.Gameplay.Camera;
|
using Code.Gameplay.Camera;
|
||||||
using Code.Gameplay.Character.Camera;
|
using Code.Gameplay.Player;
|
||||||
using Code.Input;
|
using Code.Input;
|
||||||
using Code.Scenes;
|
using Code.Scenes;
|
||||||
using Code.StaticData;
|
using Code.StaticData;
|
||||||
using Code.UI;
|
using Code.UI;
|
||||||
|
using Code.UI.Panels;
|
||||||
|
using Cysharp.Threading.Tasks;
|
||||||
using Reflex.Core;
|
using Reflex.Core;
|
||||||
using Reflex.Injectors;
|
using Reflex.Injectors;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
using UnityEngine.AddressableAssets;
|
||||||
using UnityEngine.InputSystem;
|
using UnityEngine.InputSystem;
|
||||||
|
|
||||||
namespace Code.App
|
namespace Code.App
|
||||||
{
|
{
|
||||||
public class BootstrapInstaller : MonoBehaviour, IInstaller
|
public class BootstrapInstaller : MonoBehaviour, IInstaller
|
||||||
{
|
{
|
||||||
|
|
||||||
public void InstallBindings(ContainerBuilder containerBuilder)
|
public void InstallBindings(ContainerBuilder containerBuilder)
|
||||||
{
|
{
|
||||||
InstallStaticData(containerBuilder, out IStaticDataService staticDataService);
|
InstallStaticData(containerBuilder, out IStaticDataService staticDataService);
|
||||||
@@ -23,10 +27,11 @@ namespace Code.App
|
|||||||
InstallInfrastructureUnit(containerBuilder, staticDataService);
|
InstallInfrastructureUnit(containerBuilder, staticDataService);
|
||||||
|
|
||||||
containerBuilder.AddSingleton(typeof(InputService), typeof(IInputService));
|
containerBuilder.AddSingleton(typeof(InputService), typeof(IInputService));
|
||||||
containerBuilder.AddSingleton(typeof(UIService), typeof(IUIService));
|
containerBuilder.AddSingleton(typeof(PlayerFactory), typeof(IPlayerFactory));
|
||||||
|
|
||||||
InitializeCamera(containerBuilder, staticDataService);
|
InitializeCamera(containerBuilder, staticDataService);
|
||||||
|
containerBuilder.AddSingleton(typeof(UIFactory), typeof(IUIFactory));
|
||||||
|
containerBuilder.AddSingleton(typeof(UIService), typeof(IUIService));
|
||||||
containerBuilder.AddSingleton(typeof(SceneLoaderService), typeof(ISceneLoaderService));
|
containerBuilder.AddSingleton(typeof(SceneLoaderService), typeof(ISceneLoaderService));
|
||||||
|
|
||||||
containerBuilder.OnContainerBuilt += Bootstrap;
|
containerBuilder.OnContainerBuilt += Bootstrap;
|
||||||
@@ -34,11 +39,8 @@ namespace Code.App
|
|||||||
|
|
||||||
private void InitializeCamera(ContainerBuilder containerBuilder, IStaticDataService staticDataService)
|
private void InitializeCamera(ContainerBuilder containerBuilder, IStaticDataService staticDataService)
|
||||||
{
|
{
|
||||||
// CameraService cameraService = Instantiate(staticDataService.CameraConfig.cameraPrefab);
|
Camera camera = Instantiate(staticDataService.CameraConfig.cameraPrefab);
|
||||||
// containerBuilder.AddSingleton(cameraService);
|
|
||||||
// DontDestroyOnLoad(cameraService);
|
|
||||||
|
|
||||||
Camera camera = Instantiate(staticDataService.CameraConfig.cameraPrefab2);
|
|
||||||
DontDestroyOnLoad(camera);
|
DontDestroyOnLoad(camera);
|
||||||
containerBuilder.AddSingleton(camera);
|
containerBuilder.AddSingleton(camera);
|
||||||
}
|
}
|
||||||
@@ -50,7 +52,7 @@ namespace Code.App
|
|||||||
|
|
||||||
containerBuilder.AddSingleton(infrastructureUnit);
|
containerBuilder.AddSingleton(infrastructureUnit);
|
||||||
containerBuilder.AddSingleton(infrastructureUnit.AddComponent<CoroutineRunner>(),
|
containerBuilder.AddSingleton(infrastructureUnit.AddComponent<CoroutineRunner>(),
|
||||||
typeof(ICoroutineRunner));
|
typeof(ICoroutineRunner));
|
||||||
containerBuilder.AddSingleton(infrastructureUnit.AddComponent<AppStateMachine>());
|
containerBuilder.AddSingleton(infrastructureUnit.AddComponent<AppStateMachine>());
|
||||||
containerBuilder.AddSingleton(infrastructureUnit.AddComponent<CameraStateMachine>());
|
containerBuilder.AddSingleton(infrastructureUnit.AddComponent<CameraStateMachine>());
|
||||||
}
|
}
|
||||||
@@ -62,25 +64,41 @@ namespace Code.App
|
|||||||
|
|
||||||
containerBuilder.AddSingleton(staticDataService, typeof(IStaticDataService));
|
containerBuilder.AddSingleton(staticDataService, typeof(IStaticDataService));
|
||||||
containerBuilder.AddSingleton(staticDataService.InputConfig.inputActionAsset, typeof(InputActionAsset));
|
containerBuilder.AddSingleton(staticDataService.InputConfig.inputActionAsset, typeof(InputActionAsset));
|
||||||
containerBuilder.AddSingleton(staticDataService.UIConfig.canvasPrefab, typeof(Canvas));
|
containerBuilder.AddSingleton(staticDataService.InputConfig, typeof(InputConfig));
|
||||||
containerBuilder.AddSingleton(staticDataService.CameraConfig, typeof(CameraConfig));
|
containerBuilder.AddSingleton(staticDataService.CameraConfig, typeof(CameraConfig));
|
||||||
containerBuilder.AddSingleton(staticDataService.UIConfig.uiElementsPrefabs, typeof(UIElement[]));
|
containerBuilder.AddSingleton(staticDataService.PlayerConfig, typeof(PlayerConfig));
|
||||||
|
containerBuilder.AddSingleton(staticDataService.CharacterConfig, typeof(CharacterConfig));
|
||||||
|
containerBuilder.AddSingleton(staticDataService.UIConfig, typeof(UIConfig));
|
||||||
|
// containerBuilder.AddSingleton(staticDataService.UIConfig.canvasPrefab, typeof(Canvas));
|
||||||
|
// containerBuilder.AddSingleton(staticDataService.UIConfig.uiElementsPrefabs, typeof(UIElement[]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool _onUiLoaded;
|
||||||
|
private AppStateMachine _appStateMachine;
|
||||||
private void Bootstrap(Container container)
|
private void Bootstrap(Container container)
|
||||||
{
|
{
|
||||||
AppStateMachine appStateMachine = container.Resolve<AppStateMachine>();
|
_appStateMachine = container.Resolve<AppStateMachine>();
|
||||||
appStateMachine.Initialize();
|
_appStateMachine.Initialize();
|
||||||
|
AttributeInjector.Inject(_appStateMachine.StateMachineContext, container);
|
||||||
AttributeInjector.Inject(appStateMachine.StateMachineContext, container);
|
|
||||||
|
|
||||||
CameraStateMachine cameraStateMachine = container.Resolve<CameraStateMachine>();
|
CameraStateMachine cameraStateMachine = container.Resolve<CameraStateMachine>();
|
||||||
AttributeInjector.Inject(cameraStateMachine.StateMachineContext, container);
|
AttributeInjector.Inject(cameraStateMachine.StateMachineContext, container);
|
||||||
|
|
||||||
cameraStateMachine.Initialize();
|
cameraStateMachine.Initialize();
|
||||||
|
|
||||||
|
var loadingScreen = GameObject.FindWithTag(Tags.LoadingScreen);
|
||||||
|
DontDestroyOnLoad(loadingScreen);
|
||||||
|
|
||||||
|
IUIService uiService = container.Resolve<IUIService>();
|
||||||
|
uiService.Initialize(loadingScreen.GetComponent<LoadingScreen>());
|
||||||
|
|
||||||
|
TryStartGame();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void TryStartGame()
|
||||||
|
{
|
||||||
|
|
||||||
// TODO: поменяно для теста
|
// TODO: поменяно для теста
|
||||||
appStateMachine
|
_appStateMachine
|
||||||
.SwitchState(AppState.MainMenu)
|
.SwitchState(AppState.MainMenu)
|
||||||
.AllowStateTransition(AppState.Gameplay);
|
.AllowStateTransition(AppState.Gameplay);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: c7a271c6319540abb78d561f392e1396
|
||||||
|
timeCreated: 1761743570
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
using Code.Scenes;
|
||||||
|
using Code.Scenes.SceneEnvironments;
|
||||||
|
using Reflex.Core;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Code.App.SceneInstallers
|
||||||
|
{
|
||||||
|
public class MainMenuSceneInstaller : MonoBehaviour, IInstaller
|
||||||
|
{
|
||||||
|
[SerializeField] private MainMenuEnvironment _mainMenuEnvironment;
|
||||||
|
|
||||||
|
public void InstallBindings(ContainerBuilder containerBuilder)
|
||||||
|
{
|
||||||
|
containerBuilder.AddScoped(typeof(MainMenuEnvironment), typeof(CurrentSceneEnvironment));
|
||||||
|
|
||||||
|
containerBuilder.OnContainerBuilt += Initialize;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Initialize(Container container)
|
||||||
|
{
|
||||||
|
MainMenuEnvironment env = (MainMenuEnvironment)container.Resolve<CurrentSceneEnvironment>();
|
||||||
|
|
||||||
|
env.TransitVariables(_mainMenuEnvironment);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 04145a046c584b66818ca25745652e66
|
||||||
|
timeCreated: 1761743587
|
||||||
@@ -7,6 +7,7 @@ namespace Code.App.StateMachine
|
|||||||
{
|
{
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
|
States.Add(AppState.Bootstrap, new BootstrapState(StateMachineContext));
|
||||||
States.Add(AppState.MainMenu, new MainMenuState(StateMachineContext));
|
States.Add(AppState.MainMenu, new MainMenuState(StateMachineContext));
|
||||||
States.Add(AppState.Gameplay, new GameplayState(StateMachineContext));
|
States.Add(AppState.Gameplay, new GameplayState(StateMachineContext));
|
||||||
States.Add(AppState.GameOver, new GameOverState(StateMachineContext));
|
States.Add(AppState.GameOver, new GameOverState(StateMachineContext));
|
||||||
@@ -16,6 +17,8 @@ namespace Code.App.StateMachine
|
|||||||
AllowedStates |= AppState.MainMenu;
|
AllowedStates |= AppState.MainMenu;
|
||||||
AllowedStates |= AppState.Gameplay;
|
AllowedStates |= AppState.Gameplay;
|
||||||
AllowedStates |= AppState.MovementDev;
|
AllowedStates |= AppState.MovementDev;
|
||||||
|
|
||||||
|
CurrentBaseState = States[AppState.Bootstrap];
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override bool CheckTransitionAllowed(AppState nextState) => AllowedStates.HasFlag(nextState);
|
protected override bool CheckTransitionAllowed(AppState nextState) => AllowedStates.HasFlag(nextState);
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Code.Gameplay.Camera;
|
using Code.Gameplay.Camera;
|
||||||
|
using Code.Gameplay.Player;
|
||||||
using Code.Input;
|
using Code.Input;
|
||||||
using Code.Scenes;
|
using Code.Scenes;
|
||||||
using Code.UI;
|
using Code.UI;
|
||||||
@@ -8,10 +9,11 @@ namespace Code.App.StateMachine
|
|||||||
{
|
{
|
||||||
public class AppStateMachineContext
|
public class AppStateMachineContext
|
||||||
{
|
{
|
||||||
[Inject] public ISceneLoaderService SceneLoaderService;
|
[Inject] public ISceneLoaderService SceneLoaderService { get; private set; }
|
||||||
[Inject] public IInputService InputService;
|
[Inject] public IInputService InputService { get; private set; }
|
||||||
[Inject] public IUIService UIService;
|
[Inject] public AppStateMachine StateMachine { get; private set; }
|
||||||
[Inject] public AppStateMachine StateMachine;
|
[Inject] public CameraStateMachine CameraStateMachine { get; private set; }
|
||||||
[Inject] public CameraStateMachine CameraStateMachine;
|
[Inject] public IUIService UIService { get; private set; }
|
||||||
|
[Inject] public IPlayerFactory PlayerFactory { get; private set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,11 +1,9 @@
|
|||||||
using Code.Gameplay.Camera;
|
|
||||||
using Code.Gameplay.Character.Camera;
|
|
||||||
using Code.Gameplay.Character.Core;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
using UnityEngine.AddressableAssets;
|
||||||
|
|
||||||
namespace Code.Configs
|
namespace Code.Configs
|
||||||
{
|
{
|
||||||
[CreateAssetMenu(fileName = "CharacterCameraConfig", menuName = "Config/CharacterCameraConfig")]
|
[CreateAssetMenu(fileName = "CameraConfig", menuName = "Config/CameraConfig")]
|
||||||
public class CameraConfig : ScriptableObject
|
public class CameraConfig : ScriptableObject
|
||||||
{
|
{
|
||||||
public float
|
public float
|
||||||
@@ -31,13 +29,10 @@ namespace Code.Configs
|
|||||||
maxVerticalAngle = 70f, // Максимальный угол наклона камеры (вверх)
|
maxVerticalAngle = 70f, // Максимальный угол наклона камеры (вверх)
|
||||||
defaultVerticalAngle = 10f; // Стандартный угол наклона камеры
|
defaultVerticalAngle = 10f; // Стандартный угол наклона камеры
|
||||||
|
|
||||||
// Текущий режим камеры
|
// Позиция следования по умолчанию
|
||||||
public CameraMode defaultCameraMode = CameraMode.Bogdan;
|
|
||||||
|
|
||||||
// Позиция следования по умолчанию (для меню)
|
|
||||||
public Vector3 defaultFollowPosition = Vector3.zero;
|
public Vector3 defaultFollowPosition = Vector3.zero;
|
||||||
|
|
||||||
public CameraService cameraPrefab;
|
// Префаб камеры
|
||||||
public Camera cameraPrefab2;
|
public Camera cameraPrefab;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Code.Configs
|
||||||
|
{
|
||||||
|
[CreateAssetMenu(fileName = "CharacterConfig", menuName = "Config/CharacterConfig")]
|
||||||
|
public class CharacterConfig : ScriptableObject
|
||||||
|
{
|
||||||
|
// Основное движение по земле
|
||||||
|
public float
|
||||||
|
maxStableMoveSpeed = 8f, // Максимальная скорость движения по устойчивой поверхности
|
||||||
|
stableMovementSharpness = 15f, // Резкость изменения скорости движения (чем выше - тем резче)
|
||||||
|
orientationSharpness = 10f, // Резкость изменения вращения персонажа (чем выше - тем резче)
|
||||||
|
jumpSpeed = 10f; // Скорость прыжка
|
||||||
|
|
||||||
|
// Спринт
|
||||||
|
public float
|
||||||
|
sprintMoveSpeed = 12f, // Максимальная скорость спринта
|
||||||
|
sprintAngleThreshold = 90f; // Максимальный угол (в градусах) от направления вперёд, при котором разрешён спринт
|
||||||
|
|
||||||
|
// Слайд
|
||||||
|
public float
|
||||||
|
slideSpeed = 20f, // Скорость слайда
|
||||||
|
slideDuration = 0.8f, // Длительность слайда в секундах
|
||||||
|
slideCooldown = 1.5f; // Время перезарядки слайда в секундах
|
||||||
|
|
||||||
|
// Залазание на стены
|
||||||
|
public float
|
||||||
|
wallClimbSpeedFactor = 0.8f, // Коэффициент преобразования горизонтальной скорости в вертикальную при залазании на стену
|
||||||
|
minWallClimbSpeed = 9f, // Минимальная горизонтальная скорость для начала залазания на стену
|
||||||
|
wallDetectionAngleThreshold = 80f; // Максимальный угол (в градусах) от вертикали, при котором поверхность считается "стеной"
|
||||||
|
|
||||||
|
// Наклон при залазании на стены
|
||||||
|
public float
|
||||||
|
maxWallLeanAngle = 45f, // Максимальный угол наклона от стены (в градусах)
|
||||||
|
wallLeanSharpness = 50f, // Скорость наклона/выпрямления (чем выше — тем резче)
|
||||||
|
wallLeanHeightScale = 0.1f; // Множитель: на сколько метров подъёма = 1 единица "наклона"
|
||||||
|
|
||||||
|
// Гравитация
|
||||||
|
public Vector3 gravity = new(0f, -30f, 0f); // Вектор, отвечающий за применение гравитации
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 10cfaf8e57f64eddb8c2eda147e4739a
|
||||||
|
timeCreated: 1761723608
|
||||||
@@ -1,13 +1,12 @@
|
|||||||
using Code.UI;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.Serialization;
|
using UnityEngine.AddressableAssets;
|
||||||
|
|
||||||
namespace Code.Configs
|
namespace Code.Configs
|
||||||
{
|
{
|
||||||
[CreateAssetMenu(menuName = "Config/UI", fileName = "UIConfig")]
|
[CreateAssetMenu(menuName = "Config/UI", fileName = "UIConfig")]
|
||||||
public class UIConfig : ScriptableObject
|
public class UIConfig : ScriptableObject
|
||||||
{
|
{
|
||||||
[FormerlySerializedAs("uiElements")] public UIElement[] uiElementsPrefabs;
|
public AssetReference[] uiPanelsAssetReferences;
|
||||||
[FormerlySerializedAs("canvas")] public Canvas canvasPrefab;
|
public AssetReference canvasAssetReference;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6,4 +6,8 @@ namespace Code.Constants
|
|||||||
public const string ConfigMultiple = "Configs/{0}";
|
public const string ConfigMultiple = "Configs/{0}";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
public static class Tags
|
||||||
|
{
|
||||||
|
public const string LoadingScreen = "LoadingScreen";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -12,6 +12,8 @@ namespace Code.Gameplay.Camera
|
|||||||
States.Add(CameraMode.Static, new StaticState(StateMachineContext));
|
States.Add(CameraMode.Static, new StaticState(StateMachineContext));
|
||||||
States.Add(CameraMode.FirstPerson, new FirstPersonState(StateMachineContext));
|
States.Add(CameraMode.FirstPerson, new FirstPersonState(StateMachineContext));
|
||||||
States.Add(CameraMode.ThirdPerson, new ThirdPersonState(StateMachineContext));
|
States.Add(CameraMode.ThirdPerson, new ThirdPersonState(StateMachineContext));
|
||||||
|
|
||||||
|
CurrentBaseState = States[CameraMode.Static];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,152 @@
|
|||||||
|
using Code.Configs;
|
||||||
|
using Code.Input;
|
||||||
|
using Code.StateMachine;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Code.Gameplay.Camera.CameraStates
|
||||||
|
{
|
||||||
|
public abstract class BaseCameraState : BaseState<CameraStateMachineContext>
|
||||||
|
{
|
||||||
|
// DI сервиса ввода
|
||||||
|
private readonly IInputService _inputService;
|
||||||
|
|
||||||
|
// Конфиг камеры
|
||||||
|
private readonly CameraConfig _config;
|
||||||
|
|
||||||
|
// Используемая камера
|
||||||
|
protected UnityEngine.Camera Camera { get; private set; }
|
||||||
|
|
||||||
|
// Трансформ объекта, за которым следует камера
|
||||||
|
protected Transform FollowTransform;
|
||||||
|
|
||||||
|
// Позиция следования: текущая сглаженная позиция и горизонтальное направление камеры
|
||||||
|
protected Vector3 CurrentFollowPosition;
|
||||||
|
|
||||||
|
// Fallback-позиция для режимов без цели
|
||||||
|
private Vector3 _defaultFollowPosition;
|
||||||
|
|
||||||
|
// Целевой вертикальный угол камеры (наклон вверх/вниз)
|
||||||
|
private float _targetVerticalAngle;
|
||||||
|
|
||||||
|
// Текущая и целевая дистанция камеры от цели
|
||||||
|
protected float CurrentDistance, TargetDistance;
|
||||||
|
|
||||||
|
// Исходные значения дистанции для восстановления
|
||||||
|
protected float OriginalDefaultDistance, OriginalMinDistance, OriginalMaxDistance;
|
||||||
|
|
||||||
|
// Горизонтальное направление камеры (проекция forward на плоскость)
|
||||||
|
private Vector3 PlanarDirection { get; set; }
|
||||||
|
|
||||||
|
// Параметры загружаются из CameraConfig
|
||||||
|
protected float
|
||||||
|
DefaultDistance,
|
||||||
|
MinDistance,
|
||||||
|
MaxDistance,
|
||||||
|
DistanceMovementSpeed,
|
||||||
|
RotationSpeed,
|
||||||
|
RotationSharpness,
|
||||||
|
FollowSharpness,
|
||||||
|
MinVerticalAngle,
|
||||||
|
MaxVerticalAngle,
|
||||||
|
DefaultVerticalAngle;
|
||||||
|
|
||||||
|
// Свойства для доступа к важным данным камеры извне
|
||||||
|
public Vector3 GetPlanarDirection() => PlanarDirection; // Горизонтальное направление камеры
|
||||||
|
public Quaternion GetCameraRotation() => Camera.transform.rotation; // Текущее вращение камеры
|
||||||
|
|
||||||
|
// Конструктор базового состояния
|
||||||
|
protected BaseCameraState(CameraStateMachineContext context) : base(context)
|
||||||
|
{
|
||||||
|
_inputService = context.InputService;
|
||||||
|
_config = context.Config;
|
||||||
|
LoadConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Загрузка конфига для камеры
|
||||||
|
private void LoadConfig()
|
||||||
|
{
|
||||||
|
// Загрузка значений из конфигов
|
||||||
|
DefaultDistance = _config.defaultDistance;
|
||||||
|
MinDistance = _config.minDistance;
|
||||||
|
MaxDistance = _config.maxDistance;
|
||||||
|
DistanceMovementSpeed = _config.distanceMovementSpeed;
|
||||||
|
RotationSpeed = _config.rotationSpeed;
|
||||||
|
RotationSharpness = _config.rotationSharpness;
|
||||||
|
FollowSharpness = _config.followSharpness;
|
||||||
|
MinVerticalAngle = _config.minVerticalAngle;
|
||||||
|
MaxVerticalAngle = _config.maxVerticalAngle;
|
||||||
|
DefaultVerticalAngle = _config.defaultVerticalAngle;
|
||||||
|
_defaultFollowPosition = _config.defaultFollowPosition;
|
||||||
|
|
||||||
|
// Обеспечиваем корректные значения дистанции и угла
|
||||||
|
DefaultDistance = Mathf.Clamp(DefaultDistance, MinDistance, MaxDistance);
|
||||||
|
DefaultVerticalAngle = Mathf.Clamp(DefaultVerticalAngle, MinVerticalAngle, MaxVerticalAngle);
|
||||||
|
|
||||||
|
// Сохраняем оригинальные значения для восстановления
|
||||||
|
OriginalDefaultDistance = DefaultDistance;
|
||||||
|
OriginalMinDistance = MinDistance;
|
||||||
|
OriginalMaxDistance = MaxDistance;
|
||||||
|
|
||||||
|
CurrentDistance = DefaultDistance;
|
||||||
|
TargetDistance = CurrentDistance;
|
||||||
|
_targetVerticalAngle = DefaultVerticalAngle;
|
||||||
|
PlanarDirection = Vector3.forward; // Начальное направление - вперед по оси Z
|
||||||
|
CurrentFollowPosition = _defaultFollowPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Переход в состояние
|
||||||
|
public override void EnterState()
|
||||||
|
{
|
||||||
|
Camera = Context.Camera;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void LateTick()
|
||||||
|
{
|
||||||
|
// Обновляем камеру только если есть цель для следования
|
||||||
|
if (FollowTransform)
|
||||||
|
{
|
||||||
|
UpdateWithInput(Time.deltaTime, _inputService.ZoomInput, _inputService.LookInput);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Абстрактные методы для специфики режима
|
||||||
|
protected abstract void HandlePosition(float deltaTime, float zoomInput, Quaternion targetRotation);
|
||||||
|
|
||||||
|
// Обработка вращения камеры на основе пользовательского ввода
|
||||||
|
// Теперь виртуальный, чтобы статический режим мог работать как хочет
|
||||||
|
protected virtual void HandleRotationInput(float deltaTime, Vector3 rotationInput, out Quaternion targetRotation)
|
||||||
|
{
|
||||||
|
// Вращение вокруг вертикальной оси (горизонтальный поворот)
|
||||||
|
var rotationFromInput = Quaternion.Euler(FollowTransform.up * (rotationInput.x * RotationSpeed));
|
||||||
|
PlanarDirection = rotationFromInput * PlanarDirection;
|
||||||
|
var planarRotation = Quaternion.LookRotation(PlanarDirection, FollowTransform.up);
|
||||||
|
|
||||||
|
// Вращение вокруг горизонтальной оси (вертикальный наклон)
|
||||||
|
_targetVerticalAngle -= rotationInput.y * RotationSpeed;
|
||||||
|
_targetVerticalAngle = Mathf.Clamp(_targetVerticalAngle, MinVerticalAngle, MaxVerticalAngle);
|
||||||
|
var verticalRotation = Quaternion.Euler(_targetVerticalAngle, 0, 0);
|
||||||
|
|
||||||
|
// Интерполяция к целевому вращению для плавности
|
||||||
|
targetRotation = Quaternion.Slerp(Camera.transform.rotation, planarRotation * verticalRotation, deltaTime * RotationSharpness);
|
||||||
|
|
||||||
|
// Применение финального вращения
|
||||||
|
Camera.transform.rotation = targetRotation;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Основной метод обновления камеры, вызываемый извне каждый кадр
|
||||||
|
private void UpdateWithInput(float deltaTime, float zoomInput, Vector3 rotationInput)
|
||||||
|
{
|
||||||
|
// Обработка ввода и позиционирования
|
||||||
|
HandleRotationInput(deltaTime, rotationInput, out var targetRotation);
|
||||||
|
HandlePosition(deltaTime, zoomInput, targetRotation);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Установка цели для следования камеры
|
||||||
|
public void SetFollowTransform(Transform t)
|
||||||
|
{
|
||||||
|
FollowTransform = t;
|
||||||
|
CurrentFollowPosition = t ? t.position : _defaultFollowPosition;
|
||||||
|
if (t) PlanarDirection = t.forward; // Начальное направление совпадает с направлением цели
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 92ff312b40a647b392af24877e699bd5
|
||||||
|
timeCreated: 1761685916
|
||||||
@@ -1,153 +1,43 @@
|
|||||||
using System;
|
|
||||||
using Code.Input;
|
|
||||||
using Code.StateMachine;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace Code.Gameplay.Camera.CameraStates
|
namespace Code.Gameplay.Camera.CameraStates
|
||||||
{
|
{
|
||||||
public class FirstPersonState : BaseState<CameraStateMachineContext>
|
/*
|
||||||
|
* Состояние камеры от первого лица
|
||||||
|
* Камера размещается непосредственно на позиции цели (например, на уровне глаз персонажа)
|
||||||
|
* Дистанция до цели принудительно устанавливается в 0
|
||||||
|
* Вращение управляется мышью, позиция следует за целью без отступа
|
||||||
|
*/
|
||||||
|
public class FirstPersonState : BaseCameraState, ICameraState
|
||||||
{
|
{
|
||||||
// Параметры загружаются из CameraConfig
|
public FirstPersonState(CameraStateMachineContext context) : base(context) { }
|
||||||
private float
|
|
||||||
_defaultDistance,
|
|
||||||
_minDistance,
|
|
||||||
_maxDistance,
|
|
||||||
_distanceMovementSpeed,
|
|
||||||
_rotationSpeed,
|
|
||||||
_rotationSharpness,
|
|
||||||
_followSharpness,
|
|
||||||
_minVerticalAngle,
|
|
||||||
_maxVerticalAngle,
|
|
||||||
_defaultVerticalAngle;
|
|
||||||
|
|
||||||
// Трансформ объекта, за которым следует камера (для 1st-person: уровень глаз)
|
|
||||||
private Transform _followTransform;
|
|
||||||
|
|
||||||
// Позиция следования: текущая сглаженная позиция и горизонтальное направление камеры
|
|
||||||
private Vector3 _currentFollowPosition;
|
|
||||||
|
|
||||||
// Fallback-позиция для режимов без цели (например, MainMenu)
|
|
||||||
private Vector3 _defaultFollowPosition;
|
|
||||||
|
|
||||||
// Целевой вертикальный угол камеры (наклон вверх/вниз)
|
|
||||||
private float _targetVerticalAngle;
|
|
||||||
|
|
||||||
// Текущая и целевая дистанция камеры от цели
|
|
||||||
private float _currentDistance, _targetDistance;
|
|
||||||
|
|
||||||
// Исходные значения дистанции для восстановления после FirstPerson режима
|
|
||||||
private float _originalDefaultDistance, _originalMinDistance, _originalMaxDistance;
|
|
||||||
|
|
||||||
// Горизонтальное направление камеры (проекция forward на плоскость)
|
|
||||||
public Vector3 PlanarDirection { get; private set; }
|
|
||||||
|
|
||||||
private IInputService _inputService;
|
|
||||||
private UnityEngine.Camera _camera;
|
|
||||||
public FirstPersonState(CameraStateMachineContext context) : base(context)
|
|
||||||
{
|
|
||||||
_inputService = context.InputService;
|
|
||||||
// Загрузка значений из конфига
|
|
||||||
|
|
||||||
_defaultDistance = context.Config.defaultDistance;
|
|
||||||
_minDistance = context.Config.minDistance;
|
|
||||||
_maxDistance = context.Config.maxDistance;
|
|
||||||
_distanceMovementSpeed = context.Config.distanceMovementSpeed;
|
|
||||||
_rotationSpeed = context.Config.rotationSpeed;
|
|
||||||
_rotationSharpness = context.Config.rotationSharpness;
|
|
||||||
_followSharpness = context.Config.followSharpness;
|
|
||||||
_minVerticalAngle = context.Config.minVerticalAngle;
|
|
||||||
_maxVerticalAngle = context.Config.maxVerticalAngle;
|
|
||||||
_defaultVerticalAngle = context.Config.defaultVerticalAngle;
|
|
||||||
_defaultFollowPosition = context.Config.defaultFollowPosition;
|
|
||||||
|
|
||||||
// Валидация значений (на случай ручного редактирования конфига)
|
|
||||||
_defaultDistance = Mathf.Clamp(_defaultDistance, _minDistance, _maxDistance);
|
|
||||||
_defaultVerticalAngle = Mathf.Clamp(_defaultVerticalAngle, _minVerticalAngle, _maxVerticalAngle);
|
|
||||||
|
|
||||||
// Сохраняем оригинальные значения для восстановления
|
|
||||||
_originalDefaultDistance = _defaultDistance;
|
|
||||||
_originalMinDistance = _minDistance;
|
|
||||||
_originalMaxDistance = _maxDistance;
|
|
||||||
|
|
||||||
// Инициализация состояния камеры
|
|
||||||
_currentDistance = _defaultDistance;
|
|
||||||
_targetDistance = _currentDistance;
|
|
||||||
_targetVerticalAngle = _defaultVerticalAngle;
|
|
||||||
PlanarDirection = Vector3.forward; // Начальное направление - вперед по оси Z
|
|
||||||
_currentFollowPosition = _defaultFollowPosition;
|
|
||||||
}
|
|
||||||
public override void EnterState()
|
public override void EnterState()
|
||||||
{
|
{
|
||||||
// В FirstPerson режиме дистанция всегда равна 0
|
// В FirstPerson режиме дистанция всегда равна 0
|
||||||
_minDistance = 0f;
|
MinDistance = 0f;
|
||||||
_maxDistance = 0f;
|
MaxDistance = 0f;
|
||||||
_defaultDistance = 0f;
|
DefaultDistance = 0f;
|
||||||
_targetDistance = 0f;
|
TargetDistance = 0f;
|
||||||
_currentDistance = 0f;
|
CurrentDistance = 0f;
|
||||||
|
|
||||||
_camera = Context.Camera;
|
base.EnterState();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void LateTick()
|
protected override void HandlePosition(float deltaTime, float zoomInput, Quaternion targetRotation)
|
||||||
{
|
|
||||||
|
|
||||||
UpdateWithInput(Time.deltaTime,_inputService.ZoomInput, _inputService.LookInput);
|
|
||||||
}
|
|
||||||
// Обработка вращения камеры на основе пользовательского ввода
|
|
||||||
private void HandleRotationInput(float deltaTime, Vector3 rotationInput, out Quaternion targetRotation)
|
|
||||||
{
|
|
||||||
// Вращение вокруг вертикальной оси (горизонтальный поворот)
|
|
||||||
var rotationFromInput = Quaternion.Euler(_followTransform.up * (rotationInput.x * _rotationSpeed));
|
|
||||||
PlanarDirection = rotationFromInput * PlanarDirection;
|
|
||||||
var planarRotation = Quaternion.LookRotation(PlanarDirection, _followTransform.up);
|
|
||||||
|
|
||||||
// Вращение вокруг горизонтальной оси (вертикальный наклон)
|
|
||||||
_targetVerticalAngle -= rotationInput.y * _rotationSpeed;
|
|
||||||
_targetVerticalAngle = Math.Clamp(_targetVerticalAngle, _minVerticalAngle, _maxVerticalAngle);
|
|
||||||
var verticalRotation = Quaternion.Euler(_targetVerticalAngle, 0, 0);
|
|
||||||
|
|
||||||
// Интерполяция к целевому вращению для плавности
|
|
||||||
targetRotation = Quaternion.Slerp(_camera.transform.rotation, planarRotation * verticalRotation, deltaTime * _rotationSharpness);
|
|
||||||
|
|
||||||
|
|
||||||
Debug.Log(_camera.transform.rotation.eulerAngles);
|
|
||||||
// Применение финального вращения
|
|
||||||
_camera.transform.rotation = targetRotation;
|
|
||||||
Debug.Log(_camera.transform.rotation.eulerAngles);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Обработка позиционирования камеры и зума с учетом текущего режима
|
|
||||||
private void HandlePosition(float deltaTime, float zoomInput, Quaternion targetRotation)
|
|
||||||
{
|
{
|
||||||
// Плавное следование за целью с использованием экспоненциального сглаживания
|
// Плавное следование за целью с использованием экспоненциального сглаживания
|
||||||
_currentFollowPosition = Vector3.Lerp(_currentFollowPosition, _followTransform.position, 1f - Mathf.Exp(-_followSharpness * deltaTime));
|
CurrentFollowPosition = Vector3.Lerp(CurrentFollowPosition, FollowTransform.position, 1f - Mathf.Exp(-FollowSharpness * deltaTime));
|
||||||
|
|
||||||
// Вычисление целевой позиции камеры с учетом текущего режима
|
// В FirstPerson режиме камера находится прямо на позиции цели
|
||||||
Vector3 targetPosition;
|
var targetPosition = CurrentFollowPosition;
|
||||||
// В FirstPerson режиме камера находится прямо на позиции цели
|
|
||||||
targetPosition = _currentFollowPosition;
|
|
||||||
|
|
||||||
// Установка финальной позиции камеры
|
// Установка финальной позиции камеры
|
||||||
_camera.transform.position = targetPosition;
|
Camera.transform.position = targetPosition;
|
||||||
}
|
}
|
||||||
|
public CameraMode GetCameraMode()
|
||||||
// Основной метод обновления камеры, вызываемый извне каждый кадр
|
|
||||||
public void UpdateWithInput(float deltaTime, float zoomInput, Vector3 rotationInput)
|
|
||||||
{
|
{
|
||||||
// Проверка наличия цели для следования и проверка на режим главного меню
|
return CameraMode.FirstPerson;
|
||||||
if (!_followTransform) return;
|
|
||||||
|
|
||||||
// Обработка ввода и позиционирования
|
|
||||||
HandleRotationInput(deltaTime, rotationInput, out var targetRotation);
|
|
||||||
HandlePosition(deltaTime, zoomInput, targetRotation);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Установка цели для следования камеры
|
|
||||||
public void SetFollowTransform(Transform t)
|
|
||||||
{
|
|
||||||
_followTransform = t;
|
|
||||||
_currentFollowPosition = t.position;
|
|
||||||
PlanarDirection = t.forward; // Начальное направление совпадает с направлением цели
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
namespace Code.Gameplay.Camera.CameraStates
|
||||||
|
{
|
||||||
|
public interface ICameraState
|
||||||
|
{
|
||||||
|
CameraMode GetCameraMode();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 4f25670e547242e8a91e19894cf6889c
|
||||||
|
timeCreated: 1761687204
|
||||||
@@ -1,23 +1,30 @@
|
|||||||
using Code.StateMachine;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace Code.Gameplay.Camera.CameraStates
|
namespace Code.Gameplay.Camera.CameraStates
|
||||||
{
|
{
|
||||||
public class StaticState : BaseState<CameraStateMachineContext>
|
public class StaticState : BaseCameraState, ICameraState
|
||||||
{
|
{
|
||||||
private Transform _target;
|
public Transform LookTarget;
|
||||||
private Transform _position;
|
public StaticState(CameraStateMachineContext context) : base(context) { }
|
||||||
private UnityEngine.Camera _camera;
|
|
||||||
public StaticState(CameraStateMachineContext context) : base(context)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void EnterState()
|
public override void EnterState()
|
||||||
{
|
{
|
||||||
_camera = Context.Camera;
|
Debug.Log("Static State Enter");
|
||||||
|
|
||||||
base.EnterState();
|
base.EnterState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void HandlePosition(float deltaTime, float zoomInput, Quaternion targetRotation)
|
||||||
|
{
|
||||||
|
Camera.transform.position = FollowTransform.position;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CameraMode GetCameraMode() => CameraMode.Static;
|
||||||
|
|
||||||
|
protected override void HandleRotationInput(float deltaTime, Vector3 rotationInput,
|
||||||
|
out Quaternion targetRotation)
|
||||||
|
{
|
||||||
|
if(LookTarget) Camera.transform.LookAt(LookTarget);
|
||||||
|
targetRotation = Camera.transform.rotation;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,164 +1,58 @@
|
|||||||
using System;
|
|
||||||
using Code.Input;
|
|
||||||
using Code.StateMachine;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace Code.Gameplay.Camera.CameraStates
|
namespace Code.Gameplay.Camera.CameraStates
|
||||||
{
|
{
|
||||||
public class ThirdPersonState : BaseState<CameraStateMachineContext>
|
/*
|
||||||
|
* Состояние камеры от третьего лица
|
||||||
|
* Камера следует за персонажем на заданном расстоянии
|
||||||
|
* Поддерживает зум, плавное следование и вращение с учётом угла наклона
|
||||||
|
* Дистанция и углы настраиваются через конфигурацию
|
||||||
|
*/
|
||||||
|
public class ThirdPersonState : BaseCameraState, ICameraState
|
||||||
{
|
{
|
||||||
// Параметры загружаются из CameraConfig
|
public ThirdPersonState(CameraStateMachineContext context) : base(context) { }
|
||||||
private float
|
|
||||||
_defaultDistance,
|
|
||||||
_minDistance,
|
|
||||||
_maxDistance,
|
|
||||||
_distanceMovementSpeed,
|
|
||||||
_rotationSpeed,
|
|
||||||
_rotationSharpness,
|
|
||||||
_followSharpness,
|
|
||||||
_minVerticalAngle,
|
|
||||||
_maxVerticalAngle,
|
|
||||||
_defaultVerticalAngle;
|
|
||||||
|
|
||||||
// Трансформ объекта, за которым следует камера (для 1st-person: уровень глаз)
|
|
||||||
private Transform _followTransform;
|
|
||||||
|
|
||||||
// Позиция следования: текущая сглаженная позиция и горизонтальное направление камеры
|
|
||||||
private Vector3 _currentFollowPosition;
|
|
||||||
|
|
||||||
// Fallback-позиция для режимов без цели (например, MainMenu)
|
|
||||||
private Vector3 _defaultFollowPosition;
|
|
||||||
|
|
||||||
// Целевой вертикальный угол камеры (наклон вверх/вниз)
|
|
||||||
private float _targetVerticalAngle;
|
|
||||||
|
|
||||||
// Текущая и целевая дистанция камеры от цели
|
|
||||||
private float _currentDistance, _targetDistance;
|
|
||||||
|
|
||||||
// Исходные значения дистанции для восстановления после FirstPerson режима
|
|
||||||
private float _originalDefaultDistance, _originalMinDistance, _originalMaxDistance;
|
|
||||||
|
|
||||||
// Горизонтальное направление камеры (проекция forward на плоскость)
|
|
||||||
public Vector3 PlanarDirection { get; private set; }
|
|
||||||
|
|
||||||
private IInputService _inputService;
|
|
||||||
private UnityEngine.Camera _camera;
|
|
||||||
|
|
||||||
public ThirdPersonState(CameraStateMachineContext context) : base(context)
|
|
||||||
{
|
|
||||||
_inputService = context.InputService;
|
|
||||||
// Загрузка значений из конфига
|
|
||||||
|
|
||||||
_defaultDistance = context.Config.defaultDistance;
|
|
||||||
_minDistance = context.Config.minDistance;
|
|
||||||
_maxDistance = context.Config.maxDistance;
|
|
||||||
_distanceMovementSpeed = context.Config.distanceMovementSpeed;
|
|
||||||
_rotationSpeed = context.Config.rotationSpeed;
|
|
||||||
_rotationSharpness = context.Config.rotationSharpness;
|
|
||||||
_followSharpness = context.Config.followSharpness;
|
|
||||||
_minVerticalAngle = context.Config.minVerticalAngle;
|
|
||||||
_maxVerticalAngle = context.Config.maxVerticalAngle;
|
|
||||||
_defaultVerticalAngle = context.Config.defaultVerticalAngle;
|
|
||||||
_defaultFollowPosition = context.Config.defaultFollowPosition;
|
|
||||||
|
|
||||||
// Валидация значений (на случай ручного редактирования конфига)
|
|
||||||
_defaultDistance = Mathf.Clamp(_defaultDistance, _minDistance, _maxDistance);
|
|
||||||
_defaultVerticalAngle = Mathf.Clamp(_defaultVerticalAngle, _minVerticalAngle, _maxVerticalAngle);
|
|
||||||
|
|
||||||
// Сохраняем оригинальные значения для восстановления
|
|
||||||
_originalDefaultDistance = _defaultDistance;
|
|
||||||
_originalMinDistance = _minDistance;
|
|
||||||
_originalMaxDistance = _maxDistance;
|
|
||||||
|
|
||||||
// Инициализация состояния камеры
|
|
||||||
_currentDistance = _defaultDistance;
|
|
||||||
_targetDistance = _currentDistance;
|
|
||||||
_targetVerticalAngle = _defaultVerticalAngle;
|
|
||||||
PlanarDirection = Vector3.forward; // Начальное направление - вперед по оси Z
|
|
||||||
_currentFollowPosition = _defaultFollowPosition;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void EnterState()
|
public override void EnterState()
|
||||||
{
|
{
|
||||||
// Восстанавливаем исходные значения дистанции
|
// Восстанавливаем исходные значения дистанции
|
||||||
_minDistance = _originalMinDistance;
|
MinDistance = OriginalMinDistance;
|
||||||
_maxDistance = _originalMaxDistance;
|
MaxDistance = OriginalMaxDistance;
|
||||||
_defaultDistance = _originalDefaultDistance;
|
DefaultDistance = OriginalDefaultDistance;
|
||||||
_targetDistance = _defaultDistance;
|
TargetDistance = DefaultDistance;
|
||||||
|
|
||||||
_camera = Context.Camera;
|
base.EnterState();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void LateTick()
|
protected override void HandlePosition(float deltaTime, float zoomInput, Quaternion targetRotation)
|
||||||
{
|
|
||||||
UpdateWithInput(Time.deltaTime, _inputService.ZoomInput, _inputService.LookInput);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Основной метод обновления камеры, вызываемый извне каждый кадр
|
|
||||||
public void UpdateWithInput(float deltaTime, float zoomInput, Vector3 rotationInput)
|
|
||||||
{
|
|
||||||
// Проверка наличия цели для следования и проверка на режим главного меню
|
|
||||||
if (!_followTransform) return;
|
|
||||||
|
|
||||||
// Обработка ввода и позиционирования
|
|
||||||
HandleRotationInput(deltaTime, rotationInput, out var targetRotation);
|
|
||||||
HandlePosition(deltaTime, zoomInput, targetRotation);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Обработка вращения камеры на основе пользовательского ввода
|
|
||||||
private void HandleRotationInput(float deltaTime, Vector3 rotationInput, out Quaternion targetRotation)
|
|
||||||
{
|
|
||||||
// Вращение вокруг вертикальной оси (горизонтальный поворот)
|
|
||||||
var rotationFromInput = Quaternion.Euler(_followTransform.up * (rotationInput.x * _rotationSpeed));
|
|
||||||
PlanarDirection = rotationFromInput * PlanarDirection;
|
|
||||||
var planarRotation = Quaternion.LookRotation(PlanarDirection, _followTransform.up);
|
|
||||||
|
|
||||||
// Вращение вокруг горизонтальной оси (вертикальный наклон)
|
|
||||||
_targetVerticalAngle -= rotationInput.y * _rotationSpeed;
|
|
||||||
_targetVerticalAngle = Math.Clamp(_targetVerticalAngle, _minVerticalAngle, _maxVerticalAngle);
|
|
||||||
var verticalRotation = Quaternion.Euler(_targetVerticalAngle, 0, 0);
|
|
||||||
|
|
||||||
// Интерполяция к целевому вращению для плавности
|
|
||||||
targetRotation = Quaternion.Slerp(_camera.transform.rotation, planarRotation * verticalRotation,
|
|
||||||
deltaTime * _rotationSharpness);
|
|
||||||
|
|
||||||
// Применение финального вращения
|
|
||||||
_camera.transform.rotation = targetRotation;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Обработка позиционирования камеры и зума с учетом текущего режима
|
|
||||||
private void HandlePosition(float deltaTime, float zoomInput, Quaternion targetRotation)
|
|
||||||
{
|
{
|
||||||
// Обновление целевой дистанции на основе ввода зума
|
// Обновление целевой дистанции на основе ввода зума
|
||||||
_targetDistance += zoomInput * _distanceMovementSpeed;
|
TargetDistance += zoomInput * DistanceMovementSpeed;
|
||||||
_targetDistance = Mathf.Clamp(_targetDistance, _minDistance, _maxDistance);
|
TargetDistance = Mathf.Clamp(TargetDistance, MinDistance, MaxDistance);
|
||||||
|
|
||||||
// Плавное следование за целью с использованием экспоненциального сглаживания
|
// Плавное следование за целью с использованием экспоненциального сглаживания
|
||||||
_currentFollowPosition = Vector3.Lerp(_currentFollowPosition, _followTransform.position,
|
CurrentFollowPosition = Vector3.Lerp(
|
||||||
1f - Mathf.Exp(-_followSharpness * deltaTime));
|
CurrentFollowPosition,
|
||||||
|
FollowTransform.position,
|
||||||
// Вычисление целевой позиции камеры с учетом текущего режима
|
1f - Mathf.Exp(-FollowSharpness * deltaTime)
|
||||||
Vector3 targetPosition;
|
);
|
||||||
|
|
||||||
// В ThirdPerson режиме камера отодвинута на расстояние от цели
|
// В ThirdPerson режиме камера отодвинута на расстояние от цели
|
||||||
targetPosition = _currentFollowPosition - targetRotation * Vector3.forward * _currentDistance;
|
var targetPosition = CurrentFollowPosition - targetRotation * Vector3.forward * CurrentDistance;
|
||||||
|
|
||||||
// Плавное изменение текущей дистанции к целевой (только для ThirdPerson)
|
|
||||||
|
|
||||||
_currentDistance = Mathf.Lerp(_currentDistance, _targetDistance,
|
|
||||||
1f - Mathf.Exp(-_distanceMovementSpeed * deltaTime));
|
|
||||||
|
|
||||||
|
// Плавное изменение текущей дистанции к целевой
|
||||||
|
CurrentDistance = Mathf.Lerp(
|
||||||
|
CurrentDistance,
|
||||||
|
TargetDistance,
|
||||||
|
1f - Mathf.Exp(-DistanceMovementSpeed * deltaTime)
|
||||||
|
);
|
||||||
|
|
||||||
// Установка финальной позиции камеры
|
// Установка финальной позиции камеры
|
||||||
_camera.transform.position = targetPosition;
|
Camera.transform.position = targetPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Установка цели для следования камеры
|
public CameraMode GetCameraMode()
|
||||||
public void SetFollowTransform(Transform t)
|
|
||||||
{
|
{
|
||||||
_followTransform = t;
|
return CameraMode.ThirdPerson;
|
||||||
_currentFollowPosition = t.position;
|
|
||||||
PlanarDirection = t.forward; // Начальное направление совпадает с направлением цели
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: b36ec6a31fb74d608232394fd5df657c
|
|
||||||
timeCreated: 1761570832
|
|
||||||
@@ -1,215 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Code.Configs;
|
|
||||||
using Code.Gameplay.Camera;
|
|
||||||
using Code.Gameplay.Character.Core;
|
|
||||||
using Code.StaticData;
|
|
||||||
using Reflex.Attributes;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace Code.Gameplay.Character.Camera
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Скрипт, отвечающий за поведение камеры при передвижении
|
|
||||||
* Поддерживает как 3rd-person, так и 1st-person режимы камеры
|
|
||||||
* Реализует плавное следование за персонажем, вращение и зум камеры
|
|
||||||
*
|
|
||||||
* Источник: Tvtig, https://www.youtube.com/watch?v=9ibpY64wBYM
|
|
||||||
*/
|
|
||||||
public class CameraService : MonoBehaviour
|
|
||||||
{
|
|
||||||
// Параметры загружаются из CameraConfig
|
|
||||||
private float
|
|
||||||
_defaultDistance,
|
|
||||||
_minDistance,
|
|
||||||
_maxDistance,
|
|
||||||
_distanceMovementSpeed,
|
|
||||||
_rotationSpeed,
|
|
||||||
_rotationSharpness,
|
|
||||||
_followSharpness,
|
|
||||||
_minVerticalAngle,
|
|
||||||
_maxVerticalAngle,
|
|
||||||
_defaultVerticalAngle;
|
|
||||||
|
|
||||||
// Трансформ объекта, за которым следует камера (для 1st-person: уровень глаз)
|
|
||||||
private Transform _followTransform;
|
|
||||||
|
|
||||||
// Позиция следования: текущая сглаженная позиция и горизонтальное направление камеры
|
|
||||||
private Vector3 _currentFollowPosition;
|
|
||||||
|
|
||||||
// Fallback-позиция для режимов без цели (например, MainMenu)
|
|
||||||
private Vector3 _defaultFollowPosition;
|
|
||||||
|
|
||||||
// Целевой вертикальный угол камеры (наклон вверх/вниз)
|
|
||||||
private float _targetVerticalAngle;
|
|
||||||
|
|
||||||
// Текущая и целевая дистанция камеры от цели
|
|
||||||
private float _currentDistance, _targetDistance;
|
|
||||||
|
|
||||||
// Исходные значения дистанции для восстановления после FirstPerson режима
|
|
||||||
private float _originalDefaultDistance, _originalMinDistance, _originalMaxDistance;
|
|
||||||
|
|
||||||
// Горизонтальное направление камеры (проекция forward на плоскость)
|
|
||||||
public Vector3 PlanarDirection { get; private set; }
|
|
||||||
|
|
||||||
// Текущий режим работы камеры
|
|
||||||
public CameraMode CurrentMode { get; private set; }
|
|
||||||
|
|
||||||
// Загрузка конфига для камеры
|
|
||||||
[Inject]
|
|
||||||
private void LoadConfig(CameraConfig config)
|
|
||||||
{
|
|
||||||
// Загрузка значений из конфига
|
|
||||||
|
|
||||||
_defaultDistance = config.defaultDistance;
|
|
||||||
_minDistance = config.minDistance;
|
|
||||||
_maxDistance = config.maxDistance;
|
|
||||||
_distanceMovementSpeed = config.distanceMovementSpeed;
|
|
||||||
_rotationSpeed = config.rotationSpeed;
|
|
||||||
_rotationSharpness = config.rotationSharpness;
|
|
||||||
_followSharpness = config.followSharpness;
|
|
||||||
_minVerticalAngle = config.minVerticalAngle;
|
|
||||||
_maxVerticalAngle = config.maxVerticalAngle;
|
|
||||||
_defaultVerticalAngle = config.defaultVerticalAngle;
|
|
||||||
CurrentMode = config.defaultCameraMode;
|
|
||||||
_defaultFollowPosition = config.defaultFollowPosition;
|
|
||||||
|
|
||||||
// Валидация значений (на случай ручного редактирования конфига)
|
|
||||||
_defaultDistance = Mathf.Clamp(_defaultDistance, _minDistance, _maxDistance);
|
|
||||||
_defaultVerticalAngle = Mathf.Clamp(_defaultVerticalAngle, _minVerticalAngle, _maxVerticalAngle);
|
|
||||||
|
|
||||||
// Сохраняем оригинальные значения для восстановления
|
|
||||||
_originalDefaultDistance = _defaultDistance;
|
|
||||||
_originalMinDistance = _minDistance;
|
|
||||||
_originalMaxDistance = _maxDistance;
|
|
||||||
|
|
||||||
// Инициализация состояния камеры
|
|
||||||
_currentDistance = _defaultDistance;
|
|
||||||
_targetDistance = _currentDistance;
|
|
||||||
_targetVerticalAngle = _defaultVerticalAngle;
|
|
||||||
PlanarDirection = Vector3.forward; // Начальное направление - вперед по оси Z
|
|
||||||
_currentFollowPosition = _defaultFollowPosition;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Установка цели для следования камеры
|
|
||||||
public void SetFollowTransform(Transform t)
|
|
||||||
{
|
|
||||||
_followTransform = t;
|
|
||||||
_currentFollowPosition = t.position;
|
|
||||||
PlanarDirection = t.forward; // Начальное направление совпадает с направлением цели
|
|
||||||
}
|
|
||||||
|
|
||||||
// Обработка вращения камеры на основе пользовательского ввода
|
|
||||||
private void HandleRotationInput(float deltaTime, Vector3 rotationInput, out Quaternion targetRotation)
|
|
||||||
{
|
|
||||||
// Вращение вокруг вертикальной оси (горизонтальный поворот)
|
|
||||||
var rotationFromInput = Quaternion.Euler(_followTransform.up * (rotationInput.x * _rotationSpeed));
|
|
||||||
PlanarDirection = rotationFromInput * PlanarDirection;
|
|
||||||
var planarRotation = Quaternion.LookRotation(PlanarDirection, _followTransform.up);
|
|
||||||
|
|
||||||
// Вращение вокруг горизонтальной оси (вертикальный наклон)
|
|
||||||
_targetVerticalAngle -= rotationInput.y * _rotationSpeed;
|
|
||||||
_targetVerticalAngle = Math.Clamp(_targetVerticalAngle, _minVerticalAngle, _maxVerticalAngle);
|
|
||||||
var verticalRotation = Quaternion.Euler(_targetVerticalAngle, 0, 0);
|
|
||||||
|
|
||||||
// Интерполяция к целевому вращению для плавности
|
|
||||||
targetRotation = Quaternion.Slerp(transform.rotation, planarRotation * verticalRotation, deltaTime * _rotationSharpness);
|
|
||||||
|
|
||||||
// Применение финального вращения
|
|
||||||
transform.rotation = targetRotation;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Обработка позиционирования камеры и зума с учетом текущего режима
|
|
||||||
private void HandlePosition(float deltaTime, float zoomInput, Quaternion targetRotation)
|
|
||||||
{
|
|
||||||
// В FirstPerson режиме зум отключается
|
|
||||||
if (CurrentMode != CameraMode.FirstPerson)
|
|
||||||
{
|
|
||||||
// Обновление целевой дистанции на основе ввода зума
|
|
||||||
_targetDistance += zoomInput * _distanceMovementSpeed;
|
|
||||||
_targetDistance = Mathf.Clamp(_targetDistance, _minDistance, _maxDistance);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Плавное следование за целью с использованием экспоненциального сглаживания
|
|
||||||
_currentFollowPosition = Vector3.Lerp(_currentFollowPosition, _followTransform.position, 1f - Mathf.Exp(-_followSharpness * deltaTime));
|
|
||||||
|
|
||||||
// Вычисление целевой позиции камеры с учетом текущего режима
|
|
||||||
Vector3 targetPosition;
|
|
||||||
if (CurrentMode == CameraMode.FirstPerson)
|
|
||||||
{
|
|
||||||
// В FirstPerson режиме камера находится прямо на позиции цели
|
|
||||||
targetPosition = _currentFollowPosition;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// В ThirdPerson режиме камера отодвинута на расстояние от цели
|
|
||||||
targetPosition = _currentFollowPosition - targetRotation * Vector3.forward * _currentDistance;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Плавное изменение текущей дистанции к целевой (только для ThirdPerson)
|
|
||||||
if (CurrentMode != CameraMode.FirstPerson)
|
|
||||||
{
|
|
||||||
_currentDistance = Mathf.Lerp(_currentDistance, _targetDistance, 1f - Mathf.Exp(-_distanceMovementSpeed * deltaTime));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Установка финальной позиции камеры
|
|
||||||
transform.position = targetPosition;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Основной метод обновления камеры, вызываемый извне каждый кадр
|
|
||||||
public void UpdateWithInput(float deltaTime, float zoomInput, Vector3 rotationInput)
|
|
||||||
{
|
|
||||||
// Проверка наличия цели для следования и проверка на режим главного меню
|
|
||||||
if (!_followTransform || CurrentMode == CameraMode.Bogdan) return;
|
|
||||||
|
|
||||||
// Обработка ввода и позиционирования
|
|
||||||
HandleRotationInput(deltaTime, rotationInput, out var targetRotation);
|
|
||||||
HandlePosition(deltaTime, zoomInput, targetRotation);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Смена режима камеры
|
|
||||||
public void SetCameraMode(CameraMode newMode)
|
|
||||||
{
|
|
||||||
if (CurrentMode == newMode) return;
|
|
||||||
CurrentMode = newMode;
|
|
||||||
|
|
||||||
// Применяем настройки специфичные для режима
|
|
||||||
ApplyModeSpecificSettings();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Применение настроек специфичных для текущего режима
|
|
||||||
private void ApplyModeSpecificSettings()
|
|
||||||
{
|
|
||||||
switch (CurrentMode)
|
|
||||||
{
|
|
||||||
case CameraMode.FirstPerson:
|
|
||||||
// В FirstPerson режиме дистанция всегда равна 0
|
|
||||||
_minDistance = 0f;
|
|
||||||
_maxDistance = 0f;
|
|
||||||
_defaultDistance = 0f;
|
|
||||||
_targetDistance = 0f;
|
|
||||||
_currentDistance = 0f;
|
|
||||||
break;
|
|
||||||
case CameraMode.ThirdPerson:
|
|
||||||
// Восстанавливаем исходные значения дистанции
|
|
||||||
_minDistance = _originalMinDistance;
|
|
||||||
_maxDistance = _originalMaxDistance;
|
|
||||||
_defaultDistance = _originalDefaultDistance;
|
|
||||||
_targetDistance = _defaultDistance;
|
|
||||||
break;
|
|
||||||
// Заготовка на будущее (если понадобится)
|
|
||||||
case CameraMode.Bogdan:
|
|
||||||
_minDistance = 0f;
|
|
||||||
_maxDistance = 0f;
|
|
||||||
_defaultDistance = 0f;
|
|
||||||
_targetDistance = 0f;
|
|
||||||
_currentDistance = 0f;
|
|
||||||
break;
|
|
||||||
case CameraMode.Static:
|
|
||||||
case CameraMode.Cinematic:
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: f1d98e6c5419411098391c07861e627e
|
|
||||||
timeCreated: 1760627986
|
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
using Code.Gameplay.Camera;
|
using Code.Gameplay.Camera;
|
||||||
using KinematicCharacterController;
|
using KinematicCharacterController;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using Code.Gameplay.Character.Core;
|
|
||||||
|
|
||||||
namespace Code.Gameplay.Character.Controller.Abilities
|
namespace Code.Gameplay.Character.Controller.Abilities
|
||||||
{
|
{
|
||||||
|
|||||||
+7
-3
@@ -13,12 +13,16 @@ namespace Code.Gameplay.Character.Controller.Abilities
|
|||||||
private readonly float _wallClimbSpeedFactor;
|
private readonly float _wallClimbSpeedFactor;
|
||||||
// Минимальная горизонтальная скорость для начала залазания на стену
|
// Минимальная горизонтальная скорость для начала залазания на стену
|
||||||
private readonly float _minWallClimbSpeed;
|
private readonly float _minWallClimbSpeed;
|
||||||
|
// Пороговый косинус стены
|
||||||
|
public float WallNormalThreshold { get; }
|
||||||
|
|
||||||
// Конструктор механики залазания на стену
|
// Конструктор механики залазания на стену
|
||||||
public WallClimbMechanic(float wallClimbSpeedFactor, float minWallClimbSpeed)
|
public WallClimbMechanic(float wallClimbSpeedFactor, float minWallClimbSpeed, float wallDetectionAngleThreshold)
|
||||||
{
|
{
|
||||||
_wallClimbSpeedFactor = wallClimbSpeedFactor;
|
_wallClimbSpeedFactor = wallClimbSpeedFactor;
|
||||||
_minWallClimbSpeed = minWallClimbSpeed;
|
_minWallClimbSpeed = minWallClimbSpeed;
|
||||||
|
// Преобразуем угол в косинус порога: если |dot| > cos(threshold), то это НЕ стена
|
||||||
|
WallNormalThreshold = Mathf.Cos(Mathf.Deg2Rad * wallDetectionAngleThreshold);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Обработка столкновения при движении (вызывается при ударе о препятствие)
|
// Обработка столкновения при движении (вызывается при ударе о препятствие)
|
||||||
@@ -26,7 +30,7 @@ namespace Code.Gameplay.Character.Controller.Abilities
|
|||||||
{
|
{
|
||||||
// Проверяем, что это вертикальная или почти вертикальная поверхность (стена)
|
// Проверяем, что это вертикальная или почти вертикальная поверхность (стена)
|
||||||
var dotWithUp = Vector3.Dot(hitNormal, motor.CharacterUp);
|
var dotWithUp = Vector3.Dot(hitNormal, motor.CharacterUp);
|
||||||
if (Mathf.Abs(dotWithUp) > 0.1f) return; // Не стена — это пол или потолок
|
if (Mathf.Abs(dotWithUp) > WallNormalThreshold) return; // Не стена — это пол или потолок
|
||||||
|
|
||||||
// Получаем текущую скорость персонажа
|
// Получаем текущую скорость персонажа
|
||||||
var currentVelocity = motor.Velocity;
|
var currentVelocity = motor.Velocity;
|
||||||
|
|||||||
+79
@@ -0,0 +1,79 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
using KinematicCharacterController;
|
||||||
|
|
||||||
|
namespace Code.Gameplay.Character.Controller.Abilities
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Механика наклона персонажа при контакте со стеной
|
||||||
|
* Управляет визуальным наклоном модели в зависимости от высоты подъёма по стене
|
||||||
|
*/
|
||||||
|
public class WallLeanMechanic
|
||||||
|
{
|
||||||
|
private readonly float _maxLeanAngle;
|
||||||
|
private readonly float _leanSharpness;
|
||||||
|
private readonly float _heightScale;
|
||||||
|
|
||||||
|
private Transform _characterTransform;
|
||||||
|
private Vector3 _lastWallNormal;
|
||||||
|
private float _lastWallContactHeight;
|
||||||
|
private float _leanFactor;
|
||||||
|
|
||||||
|
public WallLeanMechanic(float maxLeanAngle, float leanSharpness, float heightScale)
|
||||||
|
{
|
||||||
|
_maxLeanAngle = maxLeanAngle;
|
||||||
|
_leanSharpness = leanSharpness;
|
||||||
|
_heightScale = heightScale;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Назначаем трансформ визуальной модели один раз
|
||||||
|
public void SetCharacterTransform(Transform transform)
|
||||||
|
{
|
||||||
|
_characterTransform = transform;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Вызывается из OnMovementHit
|
||||||
|
public void OnWallContact(Vector3 wallNormal, float contactHeight)
|
||||||
|
{
|
||||||
|
_lastWallNormal = wallNormal;
|
||||||
|
_lastWallContactHeight = contactHeight; }
|
||||||
|
|
||||||
|
// Обновление каждый кадр
|
||||||
|
public void UpdateLean(KinematicCharacterMotor motor, float deltaTime)
|
||||||
|
{
|
||||||
|
if (!_characterTransform) return;
|
||||||
|
|
||||||
|
var isGrounded = motor.GroundingStatus.IsStableOnGround;
|
||||||
|
|
||||||
|
if (!isGrounded)
|
||||||
|
{
|
||||||
|
var heightDelta = motor.TransientPosition.y - _lastWallContactHeight;
|
||||||
|
var targetLeanFactor = Mathf.Clamp01(heightDelta * _heightScale);
|
||||||
|
_leanFactor = Mathf.Lerp(_leanFactor, targetLeanFactor, 1f - Mathf.Exp(-_leanSharpness * deltaTime));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_leanFactor = Mathf.Lerp(_leanFactor, 0f, 1f - Mathf.Exp(-_leanSharpness * deltaTime));
|
||||||
|
}
|
||||||
|
|
||||||
|
ApplyLeanRotation(motor);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ApplyLeanRotation(KinematicCharacterMotor motor)
|
||||||
|
{
|
||||||
|
if (_leanFactor <= 0.01f)
|
||||||
|
{
|
||||||
|
_characterTransform.localRotation = Quaternion.identity;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var leanDirection = -_lastWallNormal;
|
||||||
|
leanDirection = Vector3.ProjectOnPlane(leanDirection, motor.CharacterUp).normalized;
|
||||||
|
|
||||||
|
if (leanDirection.sqrMagnitude < 0.01f) return;
|
||||||
|
|
||||||
|
var leanAngle = _leanFactor * _maxLeanAngle;
|
||||||
|
var leanRotation = Quaternion.AngleAxis(leanAngle, Vector3.Cross(motor.CharacterUp, leanDirection));
|
||||||
|
_characterTransform.localRotation = leanRotation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: dfaefcb035124edb84b7874c5938defc
|
||||||
|
timeCreated: 1761738483
|
||||||
+69
-46
@@ -1,9 +1,11 @@
|
|||||||
|
using Code.Configs;
|
||||||
using Code.Gameplay.Camera;
|
using Code.Gameplay.Camera;
|
||||||
using Code.Gameplay.Character.Controller.Abilities;
|
using Code.Gameplay.Character.Controller.Abilities;
|
||||||
using Code.Gameplay.Character.Controller.Input;
|
using Code.Gameplay.Character.Controller.Input;
|
||||||
using Code.Gameplay.Character.Controller.Movement;
|
using Code.Gameplay.Character.Controller.Movement;
|
||||||
using Code.Gameplay.Character.Core;
|
using Code.Gameplay.Character.Core;
|
||||||
using KinematicCharacterController;
|
using KinematicCharacterController;
|
||||||
|
using Reflex.Attributes;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace Code.Gameplay.Character.Controller
|
namespace Code.Gameplay.Character.Controller
|
||||||
@@ -17,50 +19,61 @@ namespace Code.Gameplay.Character.Controller
|
|||||||
*/
|
*/
|
||||||
public class CustomCharacterController : MonoBehaviour, ICharacterController
|
public class CustomCharacterController : MonoBehaviour, ICharacterController
|
||||||
{
|
{
|
||||||
[SerializeField]
|
[Inject] private CharacterConfig _characterConfig; // Конфиг персонажа через DI
|
||||||
private KinematicCharacterMotor motor; // Движок физического перемещения персонажа
|
|
||||||
|
|
||||||
[SerializeField]
|
[SerializeField] private KinematicCharacterMotor motor; // Движок физического перемещения персонажа
|
||||||
private float
|
|
||||||
maxStableMoveSpeed = 8f, // Максимальная скорость движения по устойчивой поверхности
|
[SerializeField] private Transform characterTransform; // Трансформ персонажа (с точкой отслеживания камеры)
|
||||||
sprintMoveSpeed = 12f, // Максимальная скорость спринта
|
|
||||||
slideSpeed = 20f, // Скорость слайда
|
|
||||||
slideDuration = 0.8f, // Длительность слайда в секундах
|
|
||||||
slideCooldown = 1.5f, // Время перезарядки слайда
|
|
||||||
stableMovementSharpness = 15f, // Резкость изменения скорости движения (чем выше - тем резче)
|
|
||||||
orientationSharpness = 10f, // Резкость изменения вращения персонажа (чем выше - тем резче)
|
|
||||||
jumpSpeed = 10f, // Скорость прыжка
|
|
||||||
wallClimbSpeedFactor = 0.8f, // Коэффициент преобразования горизонтальной скорости в вертикальную при залазании на стену
|
|
||||||
minWallClimbSpeed = 9f; // Минимальная горизонтальная скорость для начала залазания на стену
|
|
||||||
|
|
||||||
[SerializeField]
|
|
||||||
private Vector3 gravity = new(0, -30f, 0); // Вектор, отвечающий за применение гравитации
|
|
||||||
|
|
||||||
// Подсистемы
|
// Подсистемы
|
||||||
private readonly CharacterInputHandler _inputHandler;
|
private CharacterInputHandler _inputHandler;
|
||||||
private readonly SlideMechanic _slideMechanic;
|
private SlideMechanic _slideMechanic;
|
||||||
private readonly WallClimbMechanic _wallClimbMechanic;
|
private WallClimbMechanic _wallClimbMechanic;
|
||||||
private readonly GroundMovementSystem _groundMovement;
|
private WallLeanMechanic _wallLeanMechanic;
|
||||||
private readonly AirMovementSystem _airMovement;
|
private GroundMovementSystem _groundMovement;
|
||||||
|
private AirMovementSystem _airMovement;
|
||||||
|
|
||||||
// Конструктор без параметров, инициализирующий контроллер
|
// Инициализация контроллера
|
||||||
public CustomCharacterController()
|
private void Awake()
|
||||||
{
|
{
|
||||||
_inputHandler = new CharacterInputHandler();
|
// Инициализация подсистем с параметрами из конфига
|
||||||
_slideMechanic = new SlideMechanic(slideSpeed, slideDuration, slideCooldown);
|
_inputHandler = new CharacterInputHandler(
|
||||||
_wallClimbMechanic = new WallClimbMechanic(wallClimbSpeedFactor, minWallClimbSpeed);
|
_characterConfig.sprintAngleThreshold
|
||||||
_groundMovement = new GroundMovementSystem(maxStableMoveSpeed, sprintMoveSpeed, stableMovementSharpness, jumpSpeed);
|
);
|
||||||
_airMovement = new AirMovementSystem(gravity);
|
_slideMechanic = new SlideMechanic(
|
||||||
|
_characterConfig.slideSpeed,
|
||||||
|
_characterConfig.slideDuration,
|
||||||
|
_characterConfig.slideCooldown
|
||||||
|
);
|
||||||
|
_wallClimbMechanic = new WallClimbMechanic(
|
||||||
|
_characterConfig.wallClimbSpeedFactor,
|
||||||
|
_characterConfig.minWallClimbSpeed,
|
||||||
|
_characterConfig.wallDetectionAngleThreshold
|
||||||
|
);
|
||||||
|
_wallLeanMechanic = new WallLeanMechanic(
|
||||||
|
_characterConfig.maxWallLeanAngle,
|
||||||
|
_characterConfig.wallLeanSharpness,
|
||||||
|
_characterConfig.wallLeanHeightScale
|
||||||
|
);
|
||||||
|
_groundMovement = new GroundMovementSystem(
|
||||||
|
_characterConfig.maxStableMoveSpeed,
|
||||||
|
_characterConfig.sprintMoveSpeed,
|
||||||
|
_characterConfig.stableMovementSharpness,
|
||||||
|
_characterConfig.jumpSpeed
|
||||||
|
);
|
||||||
|
_airMovement = new AirMovementSystem(_characterConfig.gravity);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Текущий режим камеры для адаптации поведения
|
// Текущий режим камеры для адаптации поведения
|
||||||
private CameraMode _currentCameraMode = CameraMode.ThirdPerson;
|
private CameraMode _currentCameraMode = CameraMode.FirstPerson;
|
||||||
|
|
||||||
// Инициализация контроллера
|
// Инициализация контроллера
|
||||||
private void Start()
|
private void Start()
|
||||||
{
|
{
|
||||||
motor.CharacterController = this; // Регистрация этого контроллера в движке
|
motor.CharacterController = this; // Регистрация этого контроллера в движке
|
||||||
_inputHandler.FirstPersonCameraRotation = motor.Transform.rotation; // Начальное вращение совпадает с персонажем
|
_inputHandler.FirstPersonCameraRotation =
|
||||||
|
motor.Transform.rotation; // Начальное вращение совпадает с персонажемс
|
||||||
|
_wallLeanMechanic.SetCharacterTransform(characterTransform);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Обработка и преобразование входных данных от персонажа
|
// Обработка и преобразование входных данных от персонажа
|
||||||
@@ -68,7 +81,7 @@ namespace Code.Gameplay.Character.Controller
|
|||||||
{
|
{
|
||||||
// Обновляем таймер перезарядки слайда
|
// Обновляем таймер перезарядки слайда
|
||||||
_slideMechanic.TickCooldown(Time.deltaTime);
|
_slideMechanic.TickCooldown(Time.deltaTime);
|
||||||
|
|
||||||
// Если активен слайд - игнорируем весь остальной ввод
|
// Если активен слайд - игнорируем весь остальной ввод
|
||||||
if (_slideMechanic.IsSliding)
|
if (_slideMechanic.IsSliding)
|
||||||
{
|
{
|
||||||
@@ -79,16 +92,16 @@ namespace Code.Gameplay.Character.Controller
|
|||||||
_groundMovement.RequestJump(inputs.JumpPressed);
|
_groundMovement.RequestJump(inputs.JumpPressed);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Сохраняем текущий режим камеры
|
// Сохраняем текущий режим камеры
|
||||||
_currentCameraMode = inputs.CameraMode;
|
_currentCameraMode = inputs.CameraMode;
|
||||||
|
|
||||||
// Обработка слайда
|
// Обработка слайда
|
||||||
_slideMechanic.RequestSlide(inputs.SlidePressed);
|
_slideMechanic.RequestSlide(inputs.SlidePressed);
|
||||||
|
|
||||||
// Обработка остального ввода
|
// Обработка остального ввода
|
||||||
_inputHandler.ProcessInputs(ref inputs, motor);
|
_inputHandler.ProcessInputs(ref inputs, motor);
|
||||||
|
|
||||||
// Передаём запрос прыжка напрямую в систему движения по земле
|
// Передаём запрос прыжка напрямую в систему движения по земле
|
||||||
_groundMovement.RequestJump(inputs.JumpPressed);
|
_groundMovement.RequestJump(inputs.JumpPressed);
|
||||||
}
|
}
|
||||||
@@ -110,13 +123,13 @@ namespace Code.Gameplay.Character.Controller
|
|||||||
case CameraMode.ThirdPerson:
|
case CameraMode.ThirdPerson:
|
||||||
{
|
{
|
||||||
// Вращение применяется только если есть направление движения и разрешена резкость вращения
|
// Вращение применяется только если есть направление движения и разрешена резкость вращения
|
||||||
if (_inputHandler.LookInputVector.sqrMagnitude > 0 && orientationSharpness > 0)
|
if (_inputHandler.LookInputVector.sqrMagnitude > 0 && _characterConfig.orientationSharpness > 0)
|
||||||
{
|
{
|
||||||
// Плавная интерполяция текущего направления к целевому с экспоненциальным сглаживанием
|
// Плавная интерполяция текущего направления к целевому с экспоненциальным сглаживанием
|
||||||
var smoothedLookInputDirection = Vector3.Slerp(
|
var smoothedLookInputDirection = Vector3.Slerp(
|
||||||
motor.CharacterForward,
|
motor.CharacterForward,
|
||||||
_inputHandler.LookInputVector,
|
_inputHandler.LookInputVector,
|
||||||
1f - Mathf.Exp(-orientationSharpness * deltaTime)
|
1f - Mathf.Exp(-_characterConfig.orientationSharpness * deltaTime)
|
||||||
).normalized;
|
).normalized;
|
||||||
|
|
||||||
// Установка нового вращения смотря в сглаженном направлении
|
// Установка нового вращения смотря в сглаженном направлении
|
||||||
@@ -142,11 +155,12 @@ namespace Code.Gameplay.Character.Controller
|
|||||||
{
|
{
|
||||||
_slideMechanic.EndSlide();
|
_slideMechanic.EndSlide();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Проверяем запрос слайда и запускаем его если можно
|
// Проверяем запрос слайда и запускаем его если можно
|
||||||
if (!_slideMechanic.IsSliding)
|
if (!_slideMechanic.IsSliding)
|
||||||
{
|
{
|
||||||
_slideMechanic.TryStartSlide(motor, _currentCameraMode, _inputHandler.FirstPersonCameraRotation, _inputHandler.LookInputVector);
|
_slideMechanic.TryStartSlide(motor, _currentCameraMode, _inputHandler.FirstPersonCameraRotation,
|
||||||
|
_inputHandler.LookInputVector);
|
||||||
}
|
}
|
||||||
// Если активен слайд - обрабатываем отдельно
|
// Если активен слайд - обрабатываем отдельно
|
||||||
else
|
else
|
||||||
@@ -154,7 +168,7 @@ namespace Code.Gameplay.Character.Controller
|
|||||||
_slideMechanic.HandleSlide(ref currentVelocity, deltaTime, motor);
|
_slideMechanic.HandleSlide(ref currentVelocity, deltaTime, motor);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Если персонаж находится на земле
|
// Если персонаж находится на земле
|
||||||
if (motor.GroundingStatus.IsStableOnGround)
|
if (motor.GroundingStatus.IsStableOnGround)
|
||||||
{
|
{
|
||||||
@@ -184,9 +198,10 @@ namespace Code.Gameplay.Character.Controller
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Метод вызывается после обновления персонажа (можно использовать для пост-обработки)
|
// Метод вызывается после обновления персонажа
|
||||||
public void AfterCharacterUpdate(float deltaTime)
|
public void AfterCharacterUpdate(float deltaTime)
|
||||||
{
|
{
|
||||||
|
_wallLeanMechanic.UpdateLean(motor, deltaTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Проверка валидности коллайдера для обработки столкновений
|
// Проверка валидности коллайдера для обработки столкновений
|
||||||
@@ -196,7 +211,8 @@ namespace Code.Gameplay.Character.Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Обработка столкновения с землей (вызывается при приземлении)
|
// Обработка столкновения с землей (вызывается при приземлении)
|
||||||
public void OnGroundHit(Collider hitCollider, Vector3 hitNormal, Vector3 hitPoint, ref HitStabilityReport hitStabilityReport)
|
public void OnGroundHit(Collider hitCollider, Vector3 hitNormal, Vector3 hitPoint,
|
||||||
|
ref HitStabilityReport hitStabilityReport)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,10 +221,17 @@ namespace Code.Gameplay.Character.Controller
|
|||||||
ref HitStabilityReport hitStabilityReport)
|
ref HitStabilityReport hitStabilityReport)
|
||||||
{
|
{
|
||||||
_wallClimbMechanic.OnMovementHit(motor, hitNormal);
|
_wallClimbMechanic.OnMovementHit(motor, hitNormal);
|
||||||
|
|
||||||
|
var dotWithUp = Vector3.Dot(hitNormal, motor.CharacterUp);
|
||||||
|
if (Mathf.Abs(dotWithUp) <= _wallClimbMechanic.WallNormalThreshold)
|
||||||
|
{
|
||||||
|
_wallLeanMechanic.OnWallContact(hitNormal, motor.TransientPosition.y);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Обработка отчета о стабильности столкновения
|
// Обработка отчета о стабильности столкновения
|
||||||
public void ProcessHitStabilityReport(Collider hitCollider, Vector3 hitNormal, Vector3 hitPoint, Vector3 atCharacterPosition,
|
public void ProcessHitStabilityReport(Collider hitCollider, Vector3 hitNormal, Vector3 hitPoint,
|
||||||
|
Vector3 atCharacterPosition,
|
||||||
Quaternion atCharacterRotation, ref HitStabilityReport hitStabilityReport)
|
Quaternion atCharacterRotation, ref HitStabilityReport hitStabilityReport)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
+14
-2
@@ -11,6 +11,9 @@ namespace Code.Gameplay.Character.Controller.Input
|
|||||||
*/
|
*/
|
||||||
public class CharacterInputHandler
|
public class CharacterInputHandler
|
||||||
{
|
{
|
||||||
|
// Косинус порогового угла для спринта (предвычислен)
|
||||||
|
private readonly float _sprintAngleThresholdCos;
|
||||||
|
|
||||||
// Векторы движения и направления взгляда
|
// Векторы движения и направления взгляда
|
||||||
public Vector3 MoveInputVector { get; set; }
|
public Vector3 MoveInputVector { get; set; }
|
||||||
public Vector3 LookInputVector { get; set; }
|
public Vector3 LookInputVector { get; set; }
|
||||||
@@ -23,7 +26,16 @@ namespace Code.Gameplay.Character.Controller.Input
|
|||||||
|
|
||||||
// Флаг-свойство указывающий, что нужно применить вращение камеры к персонажу
|
// Флаг-свойство указывающий, что нужно применить вращение камеры к персонажу
|
||||||
public bool ShouldApplyCameraRotation { get; private set; }
|
public bool ShouldApplyCameraRotation { get; private set; }
|
||||||
|
|
||||||
|
// Конструктор с пороговым углом
|
||||||
|
public CharacterInputHandler(float sprintAngleThreshold)
|
||||||
|
{
|
||||||
|
// Предвычисляем косинус порогового угла для эффективности
|
||||||
|
// Угол в градусах → радианы → косинус
|
||||||
|
// Чем меньше угол — тем строже условие
|
||||||
|
_sprintAngleThresholdCos = Mathf.Cos(Mathf.Deg2Rad * sprintAngleThreshold);
|
||||||
|
}
|
||||||
|
|
||||||
// Обработка и преобразование входных данных от персонажа
|
// Обработка и преобразование входных данных от персонажа
|
||||||
public void ProcessInputs(ref CharacterInputs inputs, KinematicCharacterMotor motor)
|
public void ProcessInputs(ref CharacterInputs inputs, KinematicCharacterMotor motor)
|
||||||
{
|
{
|
||||||
@@ -31,7 +43,7 @@ namespace Code.Gameplay.Character.Controller.Input
|
|||||||
var currentCameraMode = inputs.CameraMode;
|
var currentCameraMode = inputs.CameraMode;
|
||||||
|
|
||||||
// Обработка спринта
|
// Обработка спринта
|
||||||
IsSprinting = inputs is { SprintPressed: true, MoveAxisForward: > 0.1f }; // Спринт только при движении вперёд
|
IsSprinting = inputs.SprintPressed && inputs.MoveAxisForward > _sprintAngleThresholdCos; // Спринт только при движении на заданный в конфиге угол
|
||||||
|
|
||||||
// Нормализация вектора движения и ограничение его величины до 1
|
// Нормализация вектора движения и ограничение его величины до 1
|
||||||
var moveInputVector =
|
var moveInputVector =
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
using Code.Gameplay.Camera;
|
using Code.Gameplay.Camera;
|
||||||
using Code.Gameplay.Camera.CameraStates;
|
using Code.Gameplay.Camera.CameraStates;
|
||||||
using Code.Gameplay.Character.Camera;
|
|
||||||
using Code.Gameplay.Character.Controller;
|
using Code.Gameplay.Character.Controller;
|
||||||
using Code.Input;
|
using Code.Input;
|
||||||
using Reflex.Attributes;
|
using Reflex.Attributes;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.Serialization;
|
|
||||||
|
|
||||||
namespace Code.Gameplay.Character.Core
|
namespace Code.Gameplay.Character.Core
|
||||||
{
|
{
|
||||||
@@ -17,7 +15,7 @@ namespace Code.Gameplay.Character.Core
|
|||||||
*/
|
*/
|
||||||
public class Character : MonoBehaviour
|
public class Character : MonoBehaviour
|
||||||
{
|
{
|
||||||
[Inject] private CameraStateMachine _cameraService; // Компонент камеры персонажа
|
[Inject] private CameraStateMachine _cameraStateMachine; // Стейт-машина камеры (нужна для транзакций и т.п.)
|
||||||
[SerializeField] private CustomCharacterController customCharacterController; // Компонент управления персонажем
|
[SerializeField] private CustomCharacterController customCharacterController; // Компонент управления персонажем
|
||||||
[SerializeField] private Transform cameraFollowPoint; // Точка следования камеры (уровень глаз для FirstPerson)
|
[SerializeField] private Transform cameraFollowPoint; // Точка следования камеры (уровень глаз для FirstPerson)
|
||||||
|
|
||||||
@@ -30,7 +28,7 @@ namespace Code.Gameplay.Character.Core
|
|||||||
private void Start()
|
private void Start()
|
||||||
{
|
{
|
||||||
// Настройка камеры для следования за точкой камеры
|
// Настройка камеры для следования за точкой камеры
|
||||||
((FirstPersonState)_cameraService.CurrentBaseState).SetFollowTransform(cameraFollowPoint);
|
((BaseCameraState)_cameraStateMachine.CurrentBaseState).SetFollowTransform(cameraFollowPoint);
|
||||||
|
|
||||||
// Включение Gameplay мапа ввода
|
// Включение Gameplay мапа ввода
|
||||||
_inputService.EnableMap(ActionMappings.Gameplay);
|
_inputService.EnableMap(ActionMappings.Gameplay);
|
||||||
@@ -49,9 +47,11 @@ namespace Code.Gameplay.Character.Core
|
|||||||
inputs.JumpPressed = _inputService.JumpPressed; // Прыжки (Space)
|
inputs.JumpPressed = _inputService.JumpPressed; // Прыжки (Space)
|
||||||
inputs.SprintPressed = _inputService.SprintPressed; // Спринт (Shift)
|
inputs.SprintPressed = _inputService.SprintPressed; // Спринт (Shift)
|
||||||
inputs.SlidePressed = _inputService.SlidePressed; // Слайд (Ctrl)
|
inputs.SlidePressed = _inputService.SlidePressed; // Слайд (Ctrl)
|
||||||
|
inputs.CameraMode = ((ICameraState)_cameraStateMachine.CurrentBaseState).GetCameraMode();
|
||||||
|
|
||||||
// Передаем информацию о камере для адаптивного поведения
|
// Передаем информацию о камере для адаптивного поведения
|
||||||
inputs.CameraRotation = _cameraService.transform.rotation;
|
inputs.CameraRotation = ((BaseCameraState)_cameraStateMachine.CurrentBaseState).GetCameraRotation();
|
||||||
|
inputs.CameraPlanarDirection = ((BaseCameraState)_cameraStateMachine.CurrentBaseState).GetPlanarDirection();
|
||||||
|
|
||||||
// Передаем ввод в контроллер персонажа
|
// Передаем ввод в контроллер персонажа
|
||||||
customCharacterController.SetInputs(ref inputs);
|
customCharacterController.SetInputs(ref inputs);
|
||||||
@@ -67,7 +67,7 @@ namespace Code.Gameplay.Character.Core
|
|||||||
{
|
{
|
||||||
// Обрабатываем нажатие только один раз при первом обнаружении
|
// Обрабатываем нажатие только один раз при первом обнаружении
|
||||||
case true when !_cameraModeToggleHandled:
|
case true when !_cameraModeToggleHandled:
|
||||||
// ToggleCameraMode();
|
ToggleCameraMode();
|
||||||
_cameraModeToggleHandled = true;
|
_cameraModeToggleHandled = true;
|
||||||
break;
|
break;
|
||||||
// Сбрасываем флаг когда кнопка отпущена
|
// Сбрасываем флаг когда кнопка отпущена
|
||||||
@@ -76,6 +76,17 @@ namespace Code.Gameplay.Character.Core
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Метод для переключения режимов камеры
|
||||||
|
private void ToggleCameraMode()
|
||||||
|
{
|
||||||
|
var currentMode = ((ICameraState)_cameraStateMachine.CurrentBaseState).GetCameraMode();
|
||||||
|
var newMode = currentMode == CameraMode.FirstPerson ? CameraMode.ThirdPerson : CameraMode.FirstPerson;
|
||||||
|
|
||||||
|
_cameraStateMachine.SwitchState(newMode);
|
||||||
|
((BaseCameraState)_cameraStateMachine.CurrentBaseState).SetFollowTransform(cameraFollowPoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Обновление логики каждый кадр
|
// Обновление логики каждый кадр
|
||||||
private void Update()
|
private void Update()
|
||||||
@@ -86,10 +97,5 @@ namespace Code.Gameplay.Character.Core
|
|||||||
// Обработка переключения режима камеры
|
// Обработка переключения режима камеры
|
||||||
HandleCameraModeInput();
|
HandleCameraModeInput();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Обновление после всех вычислений (идеально для камеры)
|
|
||||||
private void LateUpdate()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
namespace Code.Gameplay.Player
|
||||||
|
{
|
||||||
|
public interface IPlayerFactory
|
||||||
|
{
|
||||||
|
PlayerHealth CreatePlayerHealth(int count = -1);
|
||||||
|
PlayerMoney CreatePlayerMoney(int count = 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 6d2689e8fb7e48a4a8a62a97d292e1e3
|
||||||
|
timeCreated: 1761761977
|
||||||
@@ -4,15 +4,16 @@ using Reflex.Attributes;
|
|||||||
|
|
||||||
namespace Code.Gameplay.Player
|
namespace Code.Gameplay.Player
|
||||||
{
|
{
|
||||||
public class PlayerFactory
|
public class PlayerFactory : IPlayerFactory
|
||||||
{
|
{
|
||||||
[Inject] PlayerConfig _playerConfig;
|
[Inject] PlayerConfig _playerConfig;
|
||||||
|
|
||||||
public PlayerHealth CreatePlayerHP(int count = -1)
|
public PlayerHealth CreatePlayerHealth(int count = -1)
|
||||||
{
|
{
|
||||||
if (count < 0) count = _playerConfig.maxHealth;
|
if (count < 0) count = _playerConfig.maxHealth;
|
||||||
|
|
||||||
return new PlayerHealth(count);
|
return new(count);
|
||||||
}
|
}
|
||||||
|
public PlayerMoney CreatePlayerMoney(int count = 0) => new(count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6,22 +6,27 @@ namespace Code.Gameplay.Player
|
|||||||
|
|
||||||
public event OnDeathDelegate OnDeath;
|
public event OnDeathDelegate OnDeath;
|
||||||
|
|
||||||
public delegate void OnDamageDelegate(int damage);
|
public delegate void OnDamageDelegate(int damage, PlayerHealth health);
|
||||||
|
|
||||||
public event OnDamageDelegate OnDamage;
|
public event OnDamageDelegate OnDamage;
|
||||||
|
|
||||||
private int _healthPoints;
|
private int _healthPoints;
|
||||||
|
|
||||||
public int HealthPoints => _healthPoints;
|
public int HealthPoints => _healthPoints;
|
||||||
|
|
||||||
|
public int MaxHealthPoints { get; private set; }
|
||||||
|
|
||||||
public void GetDamage(int count)
|
public void GetDamage(int count)
|
||||||
{
|
{
|
||||||
_healthPoints -= count;
|
_healthPoints -= count;
|
||||||
OnDamage?.Invoke(count);
|
OnDamage?.Invoke(count, this);
|
||||||
|
|
||||||
if (_healthPoints <= 0) OnDeath?.Invoke();
|
if (_healthPoints <= 0) OnDeath?.Invoke();
|
||||||
}
|
}
|
||||||
|
|
||||||
public PlayerHealth(int healthPoints = 1) => _healthPoints = healthPoints;
|
public PlayerHealth(int maxHealthPoints = 1)
|
||||||
|
{
|
||||||
|
_healthPoints = maxHealthPoints;
|
||||||
|
MaxHealthPoints = maxHealthPoints;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
namespace Code.Gameplay.Player
|
||||||
|
{
|
||||||
|
public class PlayerMoney
|
||||||
|
{
|
||||||
|
public delegate void OnMoneyGetDelegate(int count, int money);
|
||||||
|
public event OnMoneyGetDelegate OnMoneyGet;
|
||||||
|
public delegate void OnMoneyLooseDelegate(int count, int money);
|
||||||
|
public event OnMoneyLooseDelegate OnMoneyLoose;
|
||||||
|
|
||||||
|
private int _money;
|
||||||
|
public int Money => _money;
|
||||||
|
|
||||||
|
public void GiveMoney(int amount)
|
||||||
|
{
|
||||||
|
_money += amount;
|
||||||
|
OnMoneyGet?.Invoke(amount, _money);
|
||||||
|
}
|
||||||
|
public void LooseMoney(int amount)
|
||||||
|
{
|
||||||
|
_money -= amount;
|
||||||
|
OnMoneyLoose?.Invoke(amount, _money);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PlayerMoney(int money) => _money = money;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 455b08dd38eb4f4f8ab62b9493cd5e12
|
||||||
|
timeCreated: 1761760097
|
||||||
@@ -4,6 +4,7 @@ namespace Code.Input
|
|||||||
{
|
{
|
||||||
MainMenu,
|
MainMenu,
|
||||||
UI,
|
UI,
|
||||||
Gameplay
|
Gameplay,
|
||||||
|
Debug
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6,4 +6,11 @@ namespace Code.Input
|
|||||||
Look,
|
Look,
|
||||||
Zoom
|
Zoom
|
||||||
}
|
}
|
||||||
|
public enum DebugActions
|
||||||
|
{
|
||||||
|
GiveHealth,
|
||||||
|
LooseHealth,
|
||||||
|
GiveMoney,
|
||||||
|
LooseMoney
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
|
using System;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
using UnityEngine.InputSystem;
|
||||||
|
|
||||||
namespace Code.Input
|
namespace Code.Input
|
||||||
{
|
{
|
||||||
@@ -19,5 +21,7 @@ namespace Code.Input
|
|||||||
|
|
||||||
// Для переключения режима камеры
|
// Для переключения режима камеры
|
||||||
bool ToggleCameraModePressed { get; }
|
bool ToggleCameraModePressed { get; }
|
||||||
|
void DebugBindAction(int mapId, int actionId, Action<InputAction.CallbackContext> action);
|
||||||
|
void DebugUnbindAction(int mapId, int actionId, Action<InputAction.CallbackContext> action);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -21,6 +21,8 @@ namespace Code.Input
|
|||||||
{
|
{
|
||||||
_inputActionAsset = inputActionAsset;
|
_inputActionAsset = inputActionAsset;
|
||||||
SetupInputCallbacks();
|
SetupInputCallbacks();
|
||||||
|
|
||||||
|
inputActionAsset.actionMaps[(int)ActionMappings.Debug].Enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Обработка всех карт ввода
|
// Обработка всех карт ввода
|
||||||
@@ -165,10 +167,10 @@ namespace Code.Input
|
|||||||
public void EnableMap(ActionMappings actionMap) => _inputActionAsset.actionMaps[(int)actionMap].Enable();
|
public void EnableMap(ActionMappings actionMap) => _inputActionAsset.actionMaps[(int)actionMap].Enable();
|
||||||
public void DisableMap(ActionMappings actionMap) => _inputActionAsset.actionMaps[(int)actionMap].Disable();
|
public void DisableMap(ActionMappings actionMap) => _inputActionAsset.actionMaps[(int)actionMap].Disable();
|
||||||
|
|
||||||
public void BindAction(int mapId, int actionId, Action<InputAction.CallbackContext> action) => _inputActionAsset
|
public void DebugBindAction(int mapId, int actionId, Action<InputAction.CallbackContext> action) => _inputActionAsset
|
||||||
.actionMaps[mapId].actions[actionId].performed += action;
|
.actionMaps[mapId].actions[actionId].performed += action;
|
||||||
|
|
||||||
public void UnbindAction(int mapId, int actionId, Action<InputAction.CallbackContext> action) =>
|
public void DebugUnbindAction(int mapId, int actionId, Action<InputAction.CallbackContext> action) =>
|
||||||
_inputActionAsset
|
_inputActionAsset
|
||||||
.actionMaps[mapId].actions[actionId].performed -= action;
|
.actionMaps[mapId].actions[actionId].performed -= action;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Code.Scenes
|
||||||
|
{
|
||||||
|
public abstract class CurrentSceneEnvironment
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: e67772183eee40b0bd3ca806dae98f20
|
||||||
|
timeCreated: 1761736090
|
||||||
@@ -1,10 +1,11 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using Cysharp.Threading.Tasks;
|
||||||
|
|
||||||
namespace Code.Scenes
|
namespace Code.Scenes
|
||||||
{
|
{
|
||||||
public interface ISceneLoaderService
|
public interface ISceneLoaderService
|
||||||
{
|
{
|
||||||
void LoadScene(string sceneName, Action callback = null, float waitFor = 0f);
|
UniTaskVoid LoadSceneAsync(string sceneName, float waitFor = 0f, Action callBack = null);
|
||||||
void LoadScene(int sceneId, Action callback = null, float waitFor = 0f);
|
UniTaskVoid LoadSceneAsync(int sceneId, float waitFor = 0f, Action callBack = null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: a1364bdc4fb54b40843a614990de89ad
|
||||||
|
timeCreated: 1761736163
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.Serialization;
|
||||||
|
|
||||||
|
namespace Code.Scenes.SceneEnvironments
|
||||||
|
{
|
||||||
|
[System.Serializable]
|
||||||
|
public class MainMenuEnvironment : CurrentSceneEnvironment
|
||||||
|
{
|
||||||
|
public Transform cameraTarget;
|
||||||
|
public Transform cameraPosition;
|
||||||
|
|
||||||
|
public void TransitVariables(MainMenuEnvironment env)
|
||||||
|
{
|
||||||
|
cameraTarget = env.cameraTarget;
|
||||||
|
cameraPosition = env.cameraPosition;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 2e7be1a504f64b20ac431e6e231c1f70
|
||||||
|
timeCreated: 1761736177
|
||||||
@@ -6,6 +6,7 @@ namespace Code.Scenes
|
|||||||
MainMenu,
|
MainMenu,
|
||||||
Gameplay,
|
Gameplay,
|
||||||
// TODO: поменяно для теста
|
// TODO: поменяно для теста
|
||||||
MovementDev
|
MovementDev,
|
||||||
|
DevGen
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,46 +1,33 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using Cysharp.Threading.Tasks;
|
||||||
using Code.App;
|
|
||||||
using Reflex.Attributes;
|
|
||||||
using UnityEngine;
|
|
||||||
using UnityEngine.SceneManagement;
|
using UnityEngine.SceneManagement;
|
||||||
|
|
||||||
namespace Code.Scenes
|
namespace Code.Scenes
|
||||||
{
|
{
|
||||||
public class SceneLoaderService : ISceneLoaderService
|
public class SceneLoaderService : ISceneLoaderService
|
||||||
{
|
{
|
||||||
[Inject] private ICoroutineRunner _coroutineRunner;
|
public async UniTaskVoid LoadSceneAsync(string sceneName, float waitFor = 0f, Action callBack = null)
|
||||||
|
|
||||||
public void LoadScene(string sceneName, Action callback = null, float waitFor = 0f) =>
|
|
||||||
_coroutineRunner.StartCoroutine(LoadSceneAsync(sceneName, callback, waitFor));
|
|
||||||
|
|
||||||
public void LoadScene(int sceneId, Action callback = null, float waitFor = 0f) =>
|
|
||||||
_coroutineRunner.StartCoroutine(LoadSceneAsync(sceneId, callback, waitFor));
|
|
||||||
|
|
||||||
private IEnumerator LoadSceneAsync(string sceneName, Action callback = null, float waitFor = 0f)
|
|
||||||
{
|
{
|
||||||
if (waitFor > 0f)
|
// if (waitFor > 0f)
|
||||||
yield return new WaitForSeconds(waitFor);
|
// yield return new WaitForSeconds(waitFor);
|
||||||
|
|
||||||
AsyncOperation waitNextScene = SceneManager.LoadSceneAsync(sceneName, LoadSceneMode.Single);
|
// AsyncOperation waitNextScene = SceneManager.LoadSceneAsync(sceneName, LoadSceneMode.Single);
|
||||||
|
|
||||||
while (!waitNextScene.isDone)
|
// while (!waitNextScene.isDone)
|
||||||
yield return null;
|
// yield return null;
|
||||||
|
|
||||||
callback?.Invoke();
|
// callback?.Invoke();
|
||||||
|
await UniTask.Delay(TimeSpan.FromSeconds(waitFor));
|
||||||
|
await SceneManager.LoadSceneAsync(sceneName, LoadSceneMode.Single).ToUniTask();
|
||||||
|
callBack?.Invoke();
|
||||||
}
|
}
|
||||||
|
|
||||||
private IEnumerator LoadSceneAsync(int sceneId, Action callback = null, float waitFor = 0f)
|
public async UniTaskVoid LoadSceneAsync(int sceneId, float waitFor = 0f, Action callBack = null)
|
||||||
{
|
{
|
||||||
if (waitFor > 0f)
|
await UniTask.WhenAll(
|
||||||
yield return new WaitForSeconds(waitFor);
|
UniTask.Delay(TimeSpan.FromSeconds(waitFor)),
|
||||||
|
SceneManager.LoadSceneAsync(sceneId, LoadSceneMode.Single).ToUniTask());
|
||||||
AsyncOperation waitNextScene = SceneManager.LoadSceneAsync(sceneId, LoadSceneMode.Single);
|
callBack?.Invoke();
|
||||||
|
|
||||||
while (!waitNextScene.isDone)
|
|
||||||
yield return null;
|
|
||||||
|
|
||||||
callback?.Invoke();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -8,8 +8,8 @@ namespace Code.StateMachine
|
|||||||
: MonoBehaviour
|
: MonoBehaviour
|
||||||
where TStateMachineContext : new()
|
where TStateMachineContext : new()
|
||||||
{
|
{
|
||||||
public TStateEnum CurrentState { get; private set; }
|
public TStateEnum CurrentState { get; protected set; }
|
||||||
public BaseState<TStateMachineContext> CurrentBaseState { get; private set; }
|
public BaseState<TStateMachineContext> CurrentBaseState { get; protected set; }
|
||||||
private BaseState<TStateMachineContext> _previousBaseState;
|
private BaseState<TStateMachineContext> _previousBaseState;
|
||||||
|
|
||||||
protected Dictionary<TStateEnum, BaseState<TStateMachineContext>> States = new();
|
protected Dictionary<TStateEnum, BaseState<TStateMachineContext>> States = new();
|
||||||
@@ -37,11 +37,9 @@ namespace Code.StateMachine
|
|||||||
{
|
{
|
||||||
if (!CheckTransitionAllowed(nextState))
|
if (!CheckTransitionAllowed(nextState))
|
||||||
{
|
{
|
||||||
Debug.LogError("TransitionNotAllowed");
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Debug.Log("Entered " + nextState);
|
|
||||||
ResetAllowedTransitions();
|
ResetAllowedTransitions();
|
||||||
|
|
||||||
_previousBaseState = CurrentBaseState;
|
_previousBaseState = CurrentBaseState;
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using Code.Configs;
|
using Code.Configs;
|
||||||
|
using Cysharp.Threading.Tasks;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.AddressableAssets;
|
||||||
|
|
||||||
namespace Code.StaticData
|
namespace Code.StaticData
|
||||||
{
|
{
|
||||||
@@ -8,7 +13,10 @@ namespace Code.StaticData
|
|||||||
void Load();
|
void Load();
|
||||||
InputConfig InputConfig { get; }
|
InputConfig InputConfig { get; }
|
||||||
AppConfig AppConfig { get; }
|
AppConfig AppConfig { get; }
|
||||||
UIConfig UIConfig { get; }
|
|
||||||
CameraConfig CameraConfig { get; }
|
CameraConfig CameraConfig { get; }
|
||||||
|
CharacterConfig CharacterConfig { get; }
|
||||||
|
UIConfig UIConfig { get; }
|
||||||
|
PlayerConfig PlayerConfig { get; }
|
||||||
|
Task<T> InstantiateAsset<T>(AssetReference assetReference) where T : Behaviour;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,9 @@
|
|||||||
|
using System.Threading.Tasks;
|
||||||
using Code.Configs;
|
using Code.Configs;
|
||||||
using Code.Constants;
|
using Code.Constants;
|
||||||
|
using Cysharp.Threading.Tasks;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
using UnityEngine.AddressableAssets;
|
||||||
|
|
||||||
namespace Code.StaticData
|
namespace Code.StaticData
|
||||||
{
|
{
|
||||||
@@ -8,15 +11,24 @@ namespace Code.StaticData
|
|||||||
{
|
{
|
||||||
public AppConfig AppConfig { get; private set; }
|
public AppConfig AppConfig { get; private set; }
|
||||||
public InputConfig InputConfig { get; private set; }
|
public InputConfig InputConfig { get; private set; }
|
||||||
public UIConfig UIConfig { get; private set; }
|
|
||||||
public CameraConfig CameraConfig { get; private set; }
|
public CameraConfig CameraConfig { get; private set; }
|
||||||
|
public CharacterConfig CharacterConfig { get; private set; }
|
||||||
|
public UIConfig UIConfig { get; private set; }
|
||||||
|
public PlayerConfig PlayerConfig { get; private set; }
|
||||||
|
|
||||||
public void Load()
|
public void Load()
|
||||||
{
|
{
|
||||||
InputConfig = Resources.Load<InputConfig>(string.Format(StringPaths.ConfigSingle, "App", "InputConfig"));
|
InputConfig = Resources.Load<InputConfig>(string.Format(StringPaths.ConfigSingle, "App", "InputConfig"));
|
||||||
AppConfig = Resources.Load<AppConfig>(string.Format(StringPaths.ConfigSingle, "App", "AppConfig"));
|
AppConfig = Resources.Load<AppConfig>(string.Format(StringPaths.ConfigSingle, "App", "AppConfig"));
|
||||||
CameraConfig = Resources.Load<CameraConfig>(string.Format(StringPaths.ConfigSingle, "App", "CharacterCameraConfig"));
|
CameraConfig = Resources.Load<CameraConfig>(string.Format(StringPaths.ConfigSingle, "App", "CameraConfig"));
|
||||||
|
CharacterConfig = Resources.Load<CharacterConfig>(string.Format(StringPaths.ConfigSingle, "App", "CharacterConfig"));
|
||||||
UIConfig = Resources.Load<UIConfig>(string.Format(StringPaths.ConfigSingle, "App", "UIConfig"));
|
UIConfig = Resources.Load<UIConfig>(string.Format(StringPaths.ConfigSingle, "App", "UIConfig"));
|
||||||
|
PlayerConfig = Resources.Load<PlayerConfig>(string.Format(StringPaths.ConfigSingle, "App", "PlayerConfig"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<T> InstantiateAsset<T>(AssetReference assetReference) where T : Behaviour
|
||||||
|
{
|
||||||
|
return (await Addressables.InstantiateAsync(assetReference).ToUniTask()).GetComponent<T>();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
using Cysharp.Threading.Tasks;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Code.UI
|
||||||
|
{
|
||||||
|
public interface IUIFactory
|
||||||
|
{
|
||||||
|
UniTask<Canvas> CreateCanvas();
|
||||||
|
UniTask<UIElement> CreatePanel(Canvas canvas, UIPanel uiPanel);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 61892c4ae3ab4b1498c3df219c5c75d6
|
||||||
|
timeCreated: 1761922548
|
||||||
@@ -1,11 +1,13 @@
|
|||||||
|
using System;
|
||||||
|
using Code.UI.Panels;
|
||||||
|
|
||||||
namespace Code.UI
|
namespace Code.UI
|
||||||
{
|
{
|
||||||
public interface IUIService
|
public interface IUIService
|
||||||
{
|
{
|
||||||
void EnablePanel();
|
void SwitchPanelTo(UIPanel uiPanel, Action callback = null);
|
||||||
void DisablePanel();
|
|
||||||
void SwitchPanelTo(UIPanel uiPanel);
|
|
||||||
UIElement CurrentPanel { get; }
|
UIElement CurrentPanel { get; }
|
||||||
LoadingPanel LoadingScreen { get; }
|
LoadingScreen LoadingScreen { get; }
|
||||||
|
void Initialize(LoadingScreen loadingScreen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace Code.UI
|
|
||||||
{
|
|
||||||
public class LoadingPanel : UIElement
|
|
||||||
{
|
|
||||||
public void Hide()
|
|
||||||
{
|
|
||||||
gameObject.SetActive(false);
|
|
||||||
}
|
|
||||||
public void Show()
|
|
||||||
{
|
|
||||||
gameObject.SetActive(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: e8f289dfee4b4bd4988d217b988ae82d
|
||||||
|
timeCreated: 1761951389
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
|
||||||
|
namespace Code.UI
|
||||||
|
{
|
||||||
|
public class GameOverPanel : UIElement
|
||||||
|
{
|
||||||
|
[SerializeField] private Image _background;
|
||||||
|
|
||||||
|
public override void Hide()
|
||||||
|
{
|
||||||
|
_background.enabled = false;
|
||||||
|
}
|
||||||
|
public override void Show()
|
||||||
|
{
|
||||||
|
_background.enabled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: ecbe291069244405ac22e5470f3ba62b
|
||||||
|
timeCreated: 1761948692
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
using Code.Gameplay.Player;
|
||||||
|
using DG.Tweening;
|
||||||
|
using TMPro;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.Serialization;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
|
||||||
|
namespace Code.UI
|
||||||
|
{
|
||||||
|
public class GameplayPanel : UIElement
|
||||||
|
{
|
||||||
|
[Header("Dispatcher")]
|
||||||
|
[SerializeField] private Image dispatcher;
|
||||||
|
[SerializeField] private RectTransform dispatcherHiddenPosition;
|
||||||
|
[SerializeField] private RectTransform dispatcherShownPosition;
|
||||||
|
[SerializeField] private float dispatcherTransitionTime = 0.5f;
|
||||||
|
[Header("Timer")]
|
||||||
|
[SerializeField] private TMP_Text timer;
|
||||||
|
[Header("HealthBar")]
|
||||||
|
[SerializeField] private Image healthBar;
|
||||||
|
[Header("MoneyBar")]
|
||||||
|
[SerializeField] private TMP_Text moneyText;
|
||||||
|
|
||||||
|
private void MoneyUpdate(int count, int money)
|
||||||
|
{
|
||||||
|
// TODO Анимация получения\потери
|
||||||
|
moneyText.text = money.ToString();
|
||||||
|
}
|
||||||
|
private void HealthUpdate(int count, PlayerHealth health)
|
||||||
|
{
|
||||||
|
// TODO Анимация потери
|
||||||
|
float fillAmount = (float)health.HealthPoints / health.MaxHealthPoints;
|
||||||
|
healthBar.fillAmount = fillAmount;
|
||||||
|
}
|
||||||
|
public void Initialize(PlayerMoney money, PlayerHealth health)
|
||||||
|
{
|
||||||
|
money.OnMoneyGet += MoneyUpdate;
|
||||||
|
money.OnMoneyLoose += MoneyUpdate;
|
||||||
|
MoneyUpdate(0,money.Money);
|
||||||
|
|
||||||
|
health.OnDamage += HealthUpdate;
|
||||||
|
HealthUpdate(0,health);
|
||||||
|
}
|
||||||
|
private void Update()
|
||||||
|
{
|
||||||
|
timer.text = Time.deltaTime.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SummonDispatcher()
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
dispatcher.transform.DOMoveX(dispatcherShownPosition.position.x, dispatcherTransitionTime);
|
||||||
|
}
|
||||||
|
public void CloseDispatcher()
|
||||||
|
{
|
||||||
|
dispatcher.transform.DOMoveX(dispatcherHiddenPosition.position.x, dispatcherTransitionTime);
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
public override void Hide()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
public override void Show()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: d79893d2e9024719924dc5c15d582e33
|
||||||
|
timeCreated: 1761760839
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
using TMPro;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
|
||||||
|
namespace Code.UI.Panels
|
||||||
|
{
|
||||||
|
public class LoadingScreen : UIElement
|
||||||
|
{
|
||||||
|
[SerializeField] private Image background;
|
||||||
|
[SerializeField] private TMP_Text loadingTitle;
|
||||||
|
public override void Hide()
|
||||||
|
{
|
||||||
|
background.enabled = false;
|
||||||
|
loadingTitle.enabled = false;
|
||||||
|
}
|
||||||
|
public override void Show()
|
||||||
|
{
|
||||||
|
background.enabled = true;
|
||||||
|
loadingTitle.enabled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
File renamed without changes.
+7
@@ -7,5 +7,12 @@ namespace Code.UI
|
|||||||
{
|
{
|
||||||
public Button startButton;
|
public Button startButton;
|
||||||
public Button exitButton;
|
public Button exitButton;
|
||||||
|
public override void Show()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Hide()
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
File renamed without changes.
@@ -2,7 +2,9 @@ using UnityEngine;
|
|||||||
|
|
||||||
namespace Code.UI
|
namespace Code.UI
|
||||||
{
|
{
|
||||||
public class UIElement : MonoBehaviour
|
public abstract class UIElement : MonoBehaviour
|
||||||
{
|
{
|
||||||
|
public abstract void Show();
|
||||||
|
public abstract void Hide();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
using Code.Configs;
|
||||||
|
using Cysharp.Threading.Tasks;
|
||||||
|
using Reflex.Attributes;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.AddressableAssets;
|
||||||
|
using UnityEngine.ResourceManagement.AsyncOperations;
|
||||||
|
using Object = UnityEngine.Object;
|
||||||
|
|
||||||
|
namespace Code.UI
|
||||||
|
{
|
||||||
|
public class UIFactory : IUIFactory
|
||||||
|
{
|
||||||
|
private AssetReference _canvasAssetReference;
|
||||||
|
private AssetReference[] _uiPanelsAssetReferences;
|
||||||
|
|
||||||
|
public UIFactory(UIConfig uiConfig)
|
||||||
|
{
|
||||||
|
_canvasAssetReference = uiConfig.canvasAssetReference;
|
||||||
|
_uiPanelsAssetReferences = uiConfig.uiPanelsAssetReferences;
|
||||||
|
}
|
||||||
|
public async UniTask<Canvas> CreateCanvas()
|
||||||
|
{
|
||||||
|
// Canvas canvasPrefab = await Addressables.LoadAssetAsync<Canvas>(_canvasAssetReference);
|
||||||
|
Canvas canvas = (await Addressables.InstantiateAsync(_canvasAssetReference).ToUniTask()).GetComponent<Canvas>();
|
||||||
|
|
||||||
|
Object.DontDestroyOnLoad(canvas);
|
||||||
|
|
||||||
|
return canvas;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async UniTask<UIElement> CreatePanel(Canvas canvas, UIPanel uiPanel)
|
||||||
|
{
|
||||||
|
return (await Addressables.InstantiateAsync(_uiPanelsAssetReferences[(int)uiPanel], canvas.transform).ToUniTask()).GetComponent<UIElement>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 2250767e26ad4e0aa313b80087696ea9
|
||||||
|
timeCreated: 1761922359
|
||||||
@@ -4,6 +4,7 @@ namespace Code.UI
|
|||||||
{
|
{
|
||||||
Loading,
|
Loading,
|
||||||
MainMenu,
|
MainMenu,
|
||||||
Gameplay
|
Gameplay,
|
||||||
|
GameOver
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,33 +1,44 @@
|
|||||||
|
using System;
|
||||||
|
using System.Threading;
|
||||||
|
using Code.UI.Panels;
|
||||||
|
using Cysharp.Threading.Tasks;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
using UnityEngine.AddressableAssets;
|
||||||
|
using Object = UnityEngine.Object;
|
||||||
|
|
||||||
namespace Code.UI
|
namespace Code.UI
|
||||||
{
|
{
|
||||||
public class UIService : IUIService
|
public class UIService : IUIService
|
||||||
{
|
{
|
||||||
private UIElement[] _uiPanelsPrefabs;
|
|
||||||
private Canvas _canvas;
|
private Canvas _canvas;
|
||||||
|
private IUIFactory _factory;
|
||||||
|
|
||||||
public UIElement CurrentPanel { get; private set; }
|
public UIElement CurrentPanel { get; private set; }
|
||||||
public LoadingPanel LoadingScreen { get; private set; }
|
|
||||||
|
public LoadingScreen LoadingScreen { get; private set; }
|
||||||
public UIService(UIElement[] uiPanelsPrefabs, Canvas canvas)
|
|
||||||
|
public UIService(IUIFactory factory)
|
||||||
{
|
{
|
||||||
_canvas = Object.Instantiate(canvas);
|
_factory = factory;
|
||||||
Object.DontDestroyOnLoad(_canvas);
|
|
||||||
|
|
||||||
_uiPanelsPrefabs = uiPanelsPrefabs;
|
|
||||||
|
|
||||||
LoadingScreen = (LoadingPanel)Object.Instantiate(_uiPanelsPrefabs[(int)UIPanel.Loading], _canvas.transform);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void EnablePanel() => CurrentPanel.gameObject.SetActive(true);
|
public async void Initialize(LoadingScreen loadingScreen)
|
||||||
public void DisablePanel() => CurrentPanel.gameObject.SetActive(false);
|
|
||||||
|
|
||||||
public void SwitchPanelTo(UIPanel uiPanel)
|
|
||||||
{
|
{
|
||||||
if (CurrentPanel != null)
|
LoadingScreen = loadingScreen;
|
||||||
Object.Destroy(CurrentPanel.gameObject);
|
LoadingScreen.Show();
|
||||||
|
|
||||||
CurrentPanel = Object.Instantiate(_uiPanelsPrefabs[(int)uiPanel], _canvas.transform);
|
_canvas = await _factory.CreateCanvas();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async void SwitchPanelTo(UIPanel uiPanel, Action callback = null)
|
||||||
|
{
|
||||||
|
if (!_canvas) await UniTask.WaitUntil(() => _canvas );
|
||||||
|
|
||||||
|
if(CurrentPanel) Addressables.ReleaseInstance(CurrentPanel.gameObject);//Object.Destroy(CurrentPanel.gameObject);
|
||||||
|
|
||||||
|
CurrentPanel = await _factory.CreatePanel(_canvas, uiPanel);
|
||||||
|
|
||||||
|
callback?.Invoke();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 818f68f6dbb84d44d80bc53754eb6352
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: e07037ec18739b44fb4040e9a19a8b2a
|
||||||
|
TextScriptImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
Binary file not shown.
@@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 26b8dbfe064a19e4eb85bf9f0f2cd2a1
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: e67b7301aadd4a946a3c815ca954708a
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,144 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<doc>
|
||||||
|
<assembly>
|
||||||
|
<name>DOTweenEditor</name>
|
||||||
|
</assembly>
|
||||||
|
<members>
|
||||||
|
<member name="T:DG.DOTweenEditor.EditorCompatibilityUtils">
|
||||||
|
<summary>
|
||||||
|
Contains compatibility methods taken from DemiEditor (for when DOTween is without it)
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:DG.DOTweenEditor.EditorCompatibilityUtils.FindObjectOfType``1(System.Boolean)">
|
||||||
|
<summary>
|
||||||
|
Warning: some versions of this method don't have the includeInactive parameter so it won't be taken into account
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:DG.DOTweenEditor.EditorCompatibilityUtils.FindObjectOfType(System.Type,System.Boolean)">
|
||||||
|
<summary>
|
||||||
|
Warning: some versions of this method don't have the includeInactive parameter so it won't be taken into account
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:DG.DOTweenEditor.EditorCompatibilityUtils.FindObjectsOfType``1(System.Boolean)">
|
||||||
|
<summary>
|
||||||
|
Warning: some versions of this method don't have the includeInactive parameter so it won't be taken into account
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:DG.DOTweenEditor.EditorCompatibilityUtils.FindObjectsOfType(System.Type,System.Boolean)">
|
||||||
|
<summary>
|
||||||
|
Warning: some versions of this method don't have the includeInactive parameter so it won't be taken into account
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:DG.DOTweenEditor.DOTweenEditorPreview.Start(System.Action)">
|
||||||
|
<summary>
|
||||||
|
Starts the update loop of tween in the editor. Has no effect during playMode.
|
||||||
|
</summary>
|
||||||
|
<param name="onPreviewUpdated">Eventual callback to call after every update</param>
|
||||||
|
</member>
|
||||||
|
<member name="M:DG.DOTweenEditor.DOTweenEditorPreview.Stop(System.Boolean,System.Boolean)">
|
||||||
|
<summary>
|
||||||
|
Stops the update loop and clears the onPreviewUpdated callback.
|
||||||
|
</summary>
|
||||||
|
<param name="resetTweenTargets">If TRUE also resets the tweened objects to their original state.
|
||||||
|
Note that this works by calling Rewind on all tweens, so it will work correctly
|
||||||
|
only if you have a single tween type per object and it wasn't killed</param>
|
||||||
|
<param name="clearTweens">If TRUE also kills any cached tween</param>
|
||||||
|
</member>
|
||||||
|
<member name="M:DG.DOTweenEditor.DOTweenEditorPreview.PrepareTweenForPreview(DG.Tweening.Tween,System.Boolean,System.Boolean,System.Boolean)">
|
||||||
|
<summary>
|
||||||
|
Readies the tween for editor preview by setting its UpdateType to Manual plus eventual extra settings.
|
||||||
|
</summary>
|
||||||
|
<param name="t">The tween to ready</param>
|
||||||
|
<param name="clearCallbacks">If TRUE (recommended) removes all callbacks (OnComplete/Rewind/etc)</param>
|
||||||
|
<param name="preventAutoKill">If TRUE prevents the tween from being auto-killed at completion</param>
|
||||||
|
<param name="andPlay">If TRUE starts playing the tween immediately</param>
|
||||||
|
</member>
|
||||||
|
<member name="F:DG.DOTweenEditor.EditorVersion.Version">
|
||||||
|
<summary>Full major version + first minor version (ex: 2018.1f)</summary>
|
||||||
|
</member>
|
||||||
|
<member name="F:DG.DOTweenEditor.EditorVersion.MajorVersion">
|
||||||
|
<summary>Major version</summary>
|
||||||
|
</member>
|
||||||
|
<member name="F:DG.DOTweenEditor.EditorVersion.MinorVersion">
|
||||||
|
<summary>First minor version (ex: in 2018.1 it would be 1)</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:DG.DOTweenEditor.EditorUtils.SetEditorTexture(UnityEngine.Texture2D,UnityEngine.FilterMode,System.Int32)">
|
||||||
|
<summary>
|
||||||
|
Checks that the given editor texture use the correct import settings,
|
||||||
|
and applies them if they're incorrect.
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:DG.DOTweenEditor.EditorUtils.DOTweenSetupRequired">
|
||||||
|
<summary>
|
||||||
|
Returns TRUE if setup is required
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:DG.DOTweenEditor.EditorUtils.AssetExists(System.String)">
|
||||||
|
<summary>
|
||||||
|
Returns TRUE if the file/directory at the given path exists.
|
||||||
|
</summary>
|
||||||
|
<param name="adbPath">Path, relative to Unity's project folder</param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:DG.DOTweenEditor.EditorUtils.ADBPathToFullPath(System.String)">
|
||||||
|
<summary>
|
||||||
|
Converts the given project-relative path to a full path,
|
||||||
|
with backward (\) slashes).
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:DG.DOTweenEditor.EditorUtils.FullPathToADBPath(System.String)">
|
||||||
|
<summary>
|
||||||
|
Converts the given full path to a path usable with AssetDatabase methods
|
||||||
|
(relative to Unity's project folder, and with the correct Unity forward (/) slashes).
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:DG.DOTweenEditor.EditorUtils.ConnectToSourceAsset``1(System.String,System.Boolean)">
|
||||||
|
<summary>
|
||||||
|
Connects to a <see cref="T:UnityEngine.ScriptableObject"/> asset.
|
||||||
|
If the asset already exists at the given path, loads it and returns it.
|
||||||
|
Otherwise, either returns NULL or automatically creates it before loading and returning it
|
||||||
|
(depending on the given parameters).
|
||||||
|
</summary>
|
||||||
|
<typeparam name="T">Asset type</typeparam>
|
||||||
|
<param name="adbFilePath">File path (relative to Unity's project folder)</param>
|
||||||
|
<param name="createIfMissing">If TRUE and the requested asset doesn't exist, forces its creation</param>
|
||||||
|
</member>
|
||||||
|
<member name="M:DG.DOTweenEditor.EditorUtils.GetAssemblyFilePath(System.Reflection.Assembly)">
|
||||||
|
<summary>
|
||||||
|
Full path for the given loaded assembly, assembly file included
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:DG.DOTweenEditor.EditorUtils.AddGlobalDefine(System.String)">
|
||||||
|
<summary>
|
||||||
|
Adds the given global define if it's not already present
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:DG.DOTweenEditor.EditorUtils.RemoveGlobalDefine(System.String)">
|
||||||
|
<summary>
|
||||||
|
Removes the given global define if it's present
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:DG.DOTweenEditor.EditorUtils.HasGlobalDefine(System.String,System.Nullable{UnityEditor.BuildTargetGroup})">
|
||||||
|
<summary>
|
||||||
|
Returns TRUE if the given global define is present in all the <see cref="T:UnityEditor.BuildTargetGroup"/>
|
||||||
|
or only in the given <see cref="T:UnityEditor.BuildTargetGroup"/>, depending on passed parameters.<para/>
|
||||||
|
</summary>
|
||||||
|
<param name="id"></param>
|
||||||
|
<param name="buildTargetGroup"><see cref="T:UnityEditor.BuildTargetGroup"/>to use. Leave NULL to check in all of them.</param>
|
||||||
|
</member>
|
||||||
|
<member name="T:DG.DOTweenEditor.DOTweenDefines">
|
||||||
|
<summary>
|
||||||
|
Not used as menu item anymore, but as a utility function
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="F:DG.DOTweenEditor.UnityEditorVersion.Version">
|
||||||
|
<summary>Full major version + first minor version (ex: 2018.1f)</summary>
|
||||||
|
</member>
|
||||||
|
<member name="F:DG.DOTweenEditor.UnityEditorVersion.MajorVersion">
|
||||||
|
<summary>Major version</summary>
|
||||||
|
</member>
|
||||||
|
<member name="F:DG.DOTweenEditor.UnityEditorVersion.MinorVersion">
|
||||||
|
<summary>First minor version (ex: in 2018.1 it would be 1)</summary>
|
||||||
|
</member>
|
||||||
|
</members>
|
||||||
|
</doc>
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: c3a0d4ea64302bb4991712323bb30d9e
|
||||||
|
TextScriptImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
Binary file not shown.
@@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 94b982fba6cf0aa45bcdf01c3482d100
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 95b29595c168b71499bad9d6478e8197
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
Binary file not shown.
@@ -0,0 +1,117 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b902d1eb53417de449e5bca5240aa270
|
||||||
|
TextureImporter:
|
||||||
|
internalIDToNameTable: []
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 13
|
||||||
|
mipmaps:
|
||||||
|
mipMapMode: 0
|
||||||
|
enableMipMap: 1
|
||||||
|
sRGBTexture: 1
|
||||||
|
linearTexture: 0
|
||||||
|
fadeOut: 0
|
||||||
|
borderMipMap: 0
|
||||||
|
mipMapsPreserveCoverage: 0
|
||||||
|
alphaTestReferenceValue: 0.5
|
||||||
|
mipMapFadeDistanceStart: 1
|
||||||
|
mipMapFadeDistanceEnd: 3
|
||||||
|
bumpmap:
|
||||||
|
convertToNormalMap: 0
|
||||||
|
externalNormalMap: 0
|
||||||
|
heightScale: 0.25
|
||||||
|
normalMapFilter: 0
|
||||||
|
flipGreenChannel: 0
|
||||||
|
isReadable: 0
|
||||||
|
streamingMipmaps: 0
|
||||||
|
streamingMipmapsPriority: 0
|
||||||
|
vTOnly: 0
|
||||||
|
ignoreMipmapLimit: 0
|
||||||
|
grayScaleToAlpha: 0
|
||||||
|
generateCubemap: 6
|
||||||
|
cubemapConvolution: 0
|
||||||
|
seamlessCubemap: 0
|
||||||
|
textureFormat: 1
|
||||||
|
maxTextureSize: 2048
|
||||||
|
textureSettings:
|
||||||
|
serializedVersion: 2
|
||||||
|
filterMode: 1
|
||||||
|
aniso: 1
|
||||||
|
mipBias: 0
|
||||||
|
wrapU: 0
|
||||||
|
wrapV: 0
|
||||||
|
wrapW: 0
|
||||||
|
nPOTScale: 1
|
||||||
|
lightmap: 0
|
||||||
|
compressionQuality: 50
|
||||||
|
spriteMode: 0
|
||||||
|
spriteExtrude: 1
|
||||||
|
spriteMeshType: 1
|
||||||
|
alignment: 0
|
||||||
|
spritePivot: {x: 0.5, y: 0.5}
|
||||||
|
spritePixelsToUnits: 100
|
||||||
|
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
spriteGenerateFallbackPhysicsShape: 1
|
||||||
|
alphaUsage: 1
|
||||||
|
alphaIsTransparency: 0
|
||||||
|
spriteTessellationDetail: -1
|
||||||
|
textureType: 0
|
||||||
|
textureShape: 1
|
||||||
|
singleChannelComponent: 0
|
||||||
|
flipbookRows: 1
|
||||||
|
flipbookColumns: 1
|
||||||
|
maxTextureSizeSet: 0
|
||||||
|
compressionQualitySet: 0
|
||||||
|
textureFormatSet: 0
|
||||||
|
ignorePngGamma: 0
|
||||||
|
applyGammaDecoding: 0
|
||||||
|
swizzle: 50462976
|
||||||
|
cookieLightType: 0
|
||||||
|
platformSettings:
|
||||||
|
- serializedVersion: 4
|
||||||
|
buildTarget: DefaultTexturePlatform
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
ignorePlatformSupport: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
- serializedVersion: 4
|
||||||
|
buildTarget: Standalone
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
ignorePlatformSupport: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
spriteSheet:
|
||||||
|
serializedVersion: 2
|
||||||
|
sprites: []
|
||||||
|
outline: []
|
||||||
|
customData:
|
||||||
|
physicsShape: []
|
||||||
|
bones: []
|
||||||
|
spriteID:
|
||||||
|
internalID: 0
|
||||||
|
vertices: []
|
||||||
|
indices:
|
||||||
|
edges: []
|
||||||
|
weights: []
|
||||||
|
secondaryTextures: []
|
||||||
|
spriteCustomMetadata:
|
||||||
|
entries: []
|
||||||
|
nameFileIdTable: {}
|
||||||
|
mipmapLimitGroupName:
|
||||||
|
pSDRemoveMatte: 0
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
Binary file not shown.
@@ -0,0 +1,117 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 1db1e959b7dc07649ac59e1c7893d491
|
||||||
|
TextureImporter:
|
||||||
|
internalIDToNameTable: []
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 13
|
||||||
|
mipmaps:
|
||||||
|
mipMapMode: 0
|
||||||
|
enableMipMap: 1
|
||||||
|
sRGBTexture: 1
|
||||||
|
linearTexture: 0
|
||||||
|
fadeOut: 0
|
||||||
|
borderMipMap: 0
|
||||||
|
mipMapsPreserveCoverage: 0
|
||||||
|
alphaTestReferenceValue: 0.5
|
||||||
|
mipMapFadeDistanceStart: 1
|
||||||
|
mipMapFadeDistanceEnd: 3
|
||||||
|
bumpmap:
|
||||||
|
convertToNormalMap: 0
|
||||||
|
externalNormalMap: 0
|
||||||
|
heightScale: 0.25
|
||||||
|
normalMapFilter: 0
|
||||||
|
flipGreenChannel: 0
|
||||||
|
isReadable: 0
|
||||||
|
streamingMipmaps: 0
|
||||||
|
streamingMipmapsPriority: 0
|
||||||
|
vTOnly: 0
|
||||||
|
ignoreMipmapLimit: 0
|
||||||
|
grayScaleToAlpha: 0
|
||||||
|
generateCubemap: 6
|
||||||
|
cubemapConvolution: 0
|
||||||
|
seamlessCubemap: 0
|
||||||
|
textureFormat: 1
|
||||||
|
maxTextureSize: 2048
|
||||||
|
textureSettings:
|
||||||
|
serializedVersion: 2
|
||||||
|
filterMode: 1
|
||||||
|
aniso: 1
|
||||||
|
mipBias: 0
|
||||||
|
wrapU: 0
|
||||||
|
wrapV: 0
|
||||||
|
wrapW: 0
|
||||||
|
nPOTScale: 1
|
||||||
|
lightmap: 0
|
||||||
|
compressionQuality: 50
|
||||||
|
spriteMode: 0
|
||||||
|
spriteExtrude: 1
|
||||||
|
spriteMeshType: 1
|
||||||
|
alignment: 0
|
||||||
|
spritePivot: {x: 0.5, y: 0.5}
|
||||||
|
spritePixelsToUnits: 100
|
||||||
|
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
spriteGenerateFallbackPhysicsShape: 1
|
||||||
|
alphaUsage: 1
|
||||||
|
alphaIsTransparency: 0
|
||||||
|
spriteTessellationDetail: -1
|
||||||
|
textureType: 0
|
||||||
|
textureShape: 1
|
||||||
|
singleChannelComponent: 0
|
||||||
|
flipbookRows: 1
|
||||||
|
flipbookColumns: 1
|
||||||
|
maxTextureSizeSet: 0
|
||||||
|
compressionQualitySet: 0
|
||||||
|
textureFormatSet: 0
|
||||||
|
ignorePngGamma: 0
|
||||||
|
applyGammaDecoding: 0
|
||||||
|
swizzle: 50462976
|
||||||
|
cookieLightType: 0
|
||||||
|
platformSettings:
|
||||||
|
- serializedVersion: 4
|
||||||
|
buildTarget: DefaultTexturePlatform
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
ignorePlatformSupport: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
- serializedVersion: 4
|
||||||
|
buildTarget: Standalone
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
ignorePlatformSupport: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
spriteSheet:
|
||||||
|
serializedVersion: 2
|
||||||
|
sprites: []
|
||||||
|
outline: []
|
||||||
|
customData:
|
||||||
|
physicsShape: []
|
||||||
|
bones: []
|
||||||
|
spriteID:
|
||||||
|
internalID: 0
|
||||||
|
vertices: []
|
||||||
|
indices:
|
||||||
|
edges: []
|
||||||
|
weights: []
|
||||||
|
secondaryTextures: []
|
||||||
|
spriteCustomMetadata:
|
||||||
|
entries: []
|
||||||
|
nameFileIdTable: {}
|
||||||
|
mipmapLimitGroupName:
|
||||||
|
pSDRemoveMatte: 0
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
Binary file not shown.
@@ -0,0 +1,117 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: d248ad19bd4cd6441903457017e9a89e
|
||||||
|
TextureImporter:
|
||||||
|
internalIDToNameTable: []
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 13
|
||||||
|
mipmaps:
|
||||||
|
mipMapMode: 0
|
||||||
|
enableMipMap: 0
|
||||||
|
sRGBTexture: 1
|
||||||
|
linearTexture: 0
|
||||||
|
fadeOut: 0
|
||||||
|
borderMipMap: 0
|
||||||
|
mipMapsPreserveCoverage: 0
|
||||||
|
alphaTestReferenceValue: 0.5
|
||||||
|
mipMapFadeDistanceStart: 1
|
||||||
|
mipMapFadeDistanceEnd: 3
|
||||||
|
bumpmap:
|
||||||
|
convertToNormalMap: 0
|
||||||
|
externalNormalMap: 0
|
||||||
|
heightScale: 0.25
|
||||||
|
normalMapFilter: 0
|
||||||
|
flipGreenChannel: 0
|
||||||
|
isReadable: 0
|
||||||
|
streamingMipmaps: 0
|
||||||
|
streamingMipmapsPriority: 0
|
||||||
|
vTOnly: 0
|
||||||
|
ignoreMipmapLimit: 0
|
||||||
|
grayScaleToAlpha: 0
|
||||||
|
generateCubemap: 6
|
||||||
|
cubemapConvolution: 0
|
||||||
|
seamlessCubemap: 0
|
||||||
|
textureFormat: 1
|
||||||
|
maxTextureSize: 2048
|
||||||
|
textureSettings:
|
||||||
|
serializedVersion: 2
|
||||||
|
filterMode: 1
|
||||||
|
aniso: 1
|
||||||
|
mipBias: 0
|
||||||
|
wrapU: 1
|
||||||
|
wrapV: 1
|
||||||
|
wrapW: 1
|
||||||
|
nPOTScale: 0
|
||||||
|
lightmap: 0
|
||||||
|
compressionQuality: 50
|
||||||
|
spriteMode: 0
|
||||||
|
spriteExtrude: 1
|
||||||
|
spriteMeshType: 1
|
||||||
|
alignment: 0
|
||||||
|
spritePivot: {x: 0.5, y: 0.5}
|
||||||
|
spritePixelsToUnits: 100
|
||||||
|
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
spriteGenerateFallbackPhysicsShape: 1
|
||||||
|
alphaUsage: 1
|
||||||
|
alphaIsTransparency: 1
|
||||||
|
spriteTessellationDetail: -1
|
||||||
|
textureType: 2
|
||||||
|
textureShape: 1
|
||||||
|
singleChannelComponent: 0
|
||||||
|
flipbookRows: 1
|
||||||
|
flipbookColumns: 1
|
||||||
|
maxTextureSizeSet: 0
|
||||||
|
compressionQualitySet: 0
|
||||||
|
textureFormatSet: 0
|
||||||
|
ignorePngGamma: 0
|
||||||
|
applyGammaDecoding: 0
|
||||||
|
swizzle: 50462976
|
||||||
|
cookieLightType: 0
|
||||||
|
platformSettings:
|
||||||
|
- serializedVersion: 4
|
||||||
|
buildTarget: DefaultTexturePlatform
|
||||||
|
maxTextureSize: 256
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 0
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
ignorePlatformSupport: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
- serializedVersion: 4
|
||||||
|
buildTarget: Standalone
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
ignorePlatformSupport: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
spriteSheet:
|
||||||
|
serializedVersion: 2
|
||||||
|
sprites: []
|
||||||
|
outline: []
|
||||||
|
customData:
|
||||||
|
physicsShape: []
|
||||||
|
bones: []
|
||||||
|
spriteID:
|
||||||
|
internalID: 0
|
||||||
|
vertices: []
|
||||||
|
indices:
|
||||||
|
edges: []
|
||||||
|
weights: []
|
||||||
|
secondaryTextures: []
|
||||||
|
spriteCustomMetadata:
|
||||||
|
entries: []
|
||||||
|
nameFileIdTable: {}
|
||||||
|
mipmapLimitGroupName:
|
||||||
|
pSDRemoveMatte: 0
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
Binary file not shown.
@@ -0,0 +1,117 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 303132c0f3de1ad41a12da103de7e06d
|
||||||
|
TextureImporter:
|
||||||
|
internalIDToNameTable: []
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 13
|
||||||
|
mipmaps:
|
||||||
|
mipMapMode: 0
|
||||||
|
enableMipMap: 1
|
||||||
|
sRGBTexture: 1
|
||||||
|
linearTexture: 0
|
||||||
|
fadeOut: 0
|
||||||
|
borderMipMap: 0
|
||||||
|
mipMapsPreserveCoverage: 0
|
||||||
|
alphaTestReferenceValue: 0.5
|
||||||
|
mipMapFadeDistanceStart: 1
|
||||||
|
mipMapFadeDistanceEnd: 3
|
||||||
|
bumpmap:
|
||||||
|
convertToNormalMap: 0
|
||||||
|
externalNormalMap: 0
|
||||||
|
heightScale: 0.25
|
||||||
|
normalMapFilter: 0
|
||||||
|
flipGreenChannel: 0
|
||||||
|
isReadable: 0
|
||||||
|
streamingMipmaps: 0
|
||||||
|
streamingMipmapsPriority: 0
|
||||||
|
vTOnly: 0
|
||||||
|
ignoreMipmapLimit: 0
|
||||||
|
grayScaleToAlpha: 0
|
||||||
|
generateCubemap: 6
|
||||||
|
cubemapConvolution: 0
|
||||||
|
seamlessCubemap: 0
|
||||||
|
textureFormat: 1
|
||||||
|
maxTextureSize: 2048
|
||||||
|
textureSettings:
|
||||||
|
serializedVersion: 2
|
||||||
|
filterMode: 1
|
||||||
|
aniso: 1
|
||||||
|
mipBias: 0
|
||||||
|
wrapU: 0
|
||||||
|
wrapV: 0
|
||||||
|
wrapW: 0
|
||||||
|
nPOTScale: 1
|
||||||
|
lightmap: 0
|
||||||
|
compressionQuality: 50
|
||||||
|
spriteMode: 0
|
||||||
|
spriteExtrude: 1
|
||||||
|
spriteMeshType: 1
|
||||||
|
alignment: 0
|
||||||
|
spritePivot: {x: 0.5, y: 0.5}
|
||||||
|
spritePixelsToUnits: 100
|
||||||
|
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
spriteGenerateFallbackPhysicsShape: 1
|
||||||
|
alphaUsage: 1
|
||||||
|
alphaIsTransparency: 0
|
||||||
|
spriteTessellationDetail: -1
|
||||||
|
textureType: 0
|
||||||
|
textureShape: 1
|
||||||
|
singleChannelComponent: 0
|
||||||
|
flipbookRows: 1
|
||||||
|
flipbookColumns: 1
|
||||||
|
maxTextureSizeSet: 0
|
||||||
|
compressionQualitySet: 0
|
||||||
|
textureFormatSet: 0
|
||||||
|
ignorePngGamma: 0
|
||||||
|
applyGammaDecoding: 0
|
||||||
|
swizzle: 50462976
|
||||||
|
cookieLightType: 0
|
||||||
|
platformSettings:
|
||||||
|
- serializedVersion: 4
|
||||||
|
buildTarget: DefaultTexturePlatform
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
ignorePlatformSupport: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
- serializedVersion: 4
|
||||||
|
buildTarget: Standalone
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
ignorePlatformSupport: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
spriteSheet:
|
||||||
|
serializedVersion: 2
|
||||||
|
sprites: []
|
||||||
|
outline: []
|
||||||
|
customData:
|
||||||
|
physicsShape: []
|
||||||
|
bones: []
|
||||||
|
spriteID:
|
||||||
|
internalID: 0
|
||||||
|
vertices: []
|
||||||
|
indices:
|
||||||
|
edges: []
|
||||||
|
weights: []
|
||||||
|
secondaryTextures: []
|
||||||
|
spriteCustomMetadata:
|
||||||
|
entries: []
|
||||||
|
nameFileIdTable: {}
|
||||||
|
mipmapLimitGroupName:
|
||||||
|
pSDRemoveMatte: 0
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
Binary file not shown.
@@ -0,0 +1,117 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 2b04f9c855a815247965dd166a078a2e
|
||||||
|
TextureImporter:
|
||||||
|
internalIDToNameTable: []
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 13
|
||||||
|
mipmaps:
|
||||||
|
mipMapMode: 0
|
||||||
|
enableMipMap: 0
|
||||||
|
sRGBTexture: 1
|
||||||
|
linearTexture: 0
|
||||||
|
fadeOut: 0
|
||||||
|
borderMipMap: 0
|
||||||
|
mipMapsPreserveCoverage: 0
|
||||||
|
alphaTestReferenceValue: 0.5
|
||||||
|
mipMapFadeDistanceStart: 1
|
||||||
|
mipMapFadeDistanceEnd: 3
|
||||||
|
bumpmap:
|
||||||
|
convertToNormalMap: 0
|
||||||
|
externalNormalMap: 0
|
||||||
|
heightScale: 0.25
|
||||||
|
normalMapFilter: 0
|
||||||
|
flipGreenChannel: 0
|
||||||
|
isReadable: 0
|
||||||
|
streamingMipmaps: 0
|
||||||
|
streamingMipmapsPriority: 0
|
||||||
|
vTOnly: 0
|
||||||
|
ignoreMipmapLimit: 0
|
||||||
|
grayScaleToAlpha: 0
|
||||||
|
generateCubemap: 6
|
||||||
|
cubemapConvolution: 0
|
||||||
|
seamlessCubemap: 0
|
||||||
|
textureFormat: 1
|
||||||
|
maxTextureSize: 2048
|
||||||
|
textureSettings:
|
||||||
|
serializedVersion: 2
|
||||||
|
filterMode: 1
|
||||||
|
aniso: 1
|
||||||
|
mipBias: 0
|
||||||
|
wrapU: 1
|
||||||
|
wrapV: 1
|
||||||
|
wrapW: 1
|
||||||
|
nPOTScale: 0
|
||||||
|
lightmap: 0
|
||||||
|
compressionQuality: 50
|
||||||
|
spriteMode: 0
|
||||||
|
spriteExtrude: 1
|
||||||
|
spriteMeshType: 1
|
||||||
|
alignment: 0
|
||||||
|
spritePivot: {x: 0.5, y: 0.5}
|
||||||
|
spritePixelsToUnits: 100
|
||||||
|
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
spriteGenerateFallbackPhysicsShape: 1
|
||||||
|
alphaUsage: 1
|
||||||
|
alphaIsTransparency: 1
|
||||||
|
spriteTessellationDetail: -1
|
||||||
|
textureType: 2
|
||||||
|
textureShape: 1
|
||||||
|
singleChannelComponent: 0
|
||||||
|
flipbookRows: 1
|
||||||
|
flipbookColumns: 1
|
||||||
|
maxTextureSizeSet: 0
|
||||||
|
compressionQualitySet: 0
|
||||||
|
textureFormatSet: 0
|
||||||
|
ignorePngGamma: 0
|
||||||
|
applyGammaDecoding: 0
|
||||||
|
swizzle: 50462976
|
||||||
|
cookieLightType: 0
|
||||||
|
platformSettings:
|
||||||
|
- serializedVersion: 4
|
||||||
|
buildTarget: DefaultTexturePlatform
|
||||||
|
maxTextureSize: 512
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 0
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
ignorePlatformSupport: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
- serializedVersion: 4
|
||||||
|
buildTarget: Standalone
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
ignorePlatformSupport: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
spriteSheet:
|
||||||
|
serializedVersion: 2
|
||||||
|
sprites: []
|
||||||
|
outline: []
|
||||||
|
customData:
|
||||||
|
physicsShape: []
|
||||||
|
bones: []
|
||||||
|
spriteID:
|
||||||
|
internalID: 0
|
||||||
|
vertices: []
|
||||||
|
indices:
|
||||||
|
edges: []
|
||||||
|
weights: []
|
||||||
|
secondaryTextures: []
|
||||||
|
spriteCustomMetadata:
|
||||||
|
entries: []
|
||||||
|
nameFileIdTable: {}
|
||||||
|
mipmapLimitGroupName:
|
||||||
|
pSDRemoveMatte: 0
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 687808f6960389c42be607a9d0c85db8
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
Loaded 100 of 199 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user