camera_system #5

Merged
Jeonghyeon merged 18 commits from camera_system into develop 2025-07-14 07:10:06 +00:00
48 changed files with 1303 additions and 1638 deletions
Showing only changes of commit f76256d49d - Show all commits

View File

@ -15,29 +15,48 @@ MonoBehaviour:
m_GroupName: Group m_GroupName: Group
m_GUID: 30e7f67fe9aaa7849a34c9b6e2bc53ae m_GUID: 30e7f67fe9aaa7849a34c9b6e2bc53ae
m_SerializeEntries: m_SerializeEntries:
- m_GUID: 1aad5f6adfc7c7d44b36ce007d3c0f1e
m_Address: Items
m_ReadOnly: 0
m_SerializedLabels:
- Atlas
FlaggedDuringContentUpdateRestriction: 0
- m_GUID: 29dcda970aef9584d9b157e766b8a278
m_Address: RestaurantPlayer
m_ReadOnly: 0
m_SerializedLabels:
- Prefab
FlaggedDuringContentUpdateRestriction: 0
- m_GUID: 2eb88deceda8c443db7ec557aaef30af - m_GUID: 2eb88deceda8c443db7ec557aaef30af
m_Address: Entry m_Address: Entry
m_ReadOnly: 0 m_ReadOnly: 0
m_SerializedLabels: m_SerializedLabels:
- Scene - Scene
FlaggedDuringContentUpdateRestriction: 0 FlaggedDuringContentUpdateRestriction: 0
- m_GUID: 4c9d045012b65fc4b974bb4e132e6e6a
m_Address: CreateRestaurantPlayer
m_ReadOnly: 0
m_SerializedLabels:
- Prefab
FlaggedDuringContentUpdateRestriction: 0
- m_GUID: a60e7a432b7eb65419f3942f4f422fb4 - m_GUID: a60e7a432b7eb65419f3942f4f422fb4
m_Address: Voyage m_Address: Voyage
m_ReadOnly: 0 m_ReadOnly: 0
m_SerializedLabels: m_SerializedLabels:
- Scene - Scene
FlaggedDuringContentUpdateRestriction: 0 FlaggedDuringContentUpdateRestriction: 0
- m_GUID: ddb0db863be8f254bb8a8f07d39a960e
m_Address: RestaurantPlayerDataSo
m_ReadOnly: 0
m_SerializedLabels:
- So
FlaggedDuringContentUpdateRestriction: 0
- m_GUID: de073d0136201ac4cbb36dbeb4b76fb2 - m_GUID: de073d0136201ac4cbb36dbeb4b76fb2
m_Address: Restaurant m_Address: Restaurant
m_ReadOnly: 0 m_ReadOnly: 0
m_SerializedLabels: m_SerializedLabels:
- Scene - Scene
FlaggedDuringContentUpdateRestriction: 0 FlaggedDuringContentUpdateRestriction: 0
- m_GUID: e15933f76da90e742866563b5cd9e45f
m_Address: Gold
m_ReadOnly: 0
m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0
m_ReadOnly: 0 m_ReadOnly: 0
m_Settings: {fileID: 11400000, guid: d12ffbb6f886d48418efb0b6d15ccb88, type: 2} m_Settings: {fileID: 11400000, guid: d12ffbb6f886d48418efb0b6d15ccb88, type: 2}
m_SchemaSet: m_SchemaSet:

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: ef03a607bdc3e914aad8e99ab5c6f91b guid: 190b0dbdbdc29b2459a7d0eae707f531
folderAsset: yes folderAsset: yes
DefaultImporter: DefaultImporter:
externalObjects: {} externalObjects: {}

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: ba3a9fb25b878f647b1df9cfebb30f5b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,18 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!612988286 &1
SpriteAtlasAsset:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name:
serializedVersion: 2
m_MasterAtlas: {fileID: 0}
m_ImporterData:
packables:
- {fileID: 21300000, guid: 189d780f1507008429f2cdd1a2b4c9e8, type: 3}
- {fileID: 21300000, guid: e15933f76da90e742866563b5cd9e45f, type: 3}
- {fileID: 21300000, guid: 0db84c35b16f34681b0309b33d8760fe, type: 3}
m_IsVariant: 0
m_ScriptablePacker: {fileID: 0}

View File

@ -0,0 +1,30 @@
fileFormatVersion: 2
guid: b16c797aa0ede8947b35fd354145121e
SpriteAtlasImporter:
externalObjects: {}
textureSettings:
serializedVersion: 2
anisoLevel: 0
compressionQuality: 0
maxTextureSize: 0
textureCompression: 0
filterMode: 1
generateMipMaps: 0
readable: 0
crunchedCompression: 0
sRGB: 1
platformSettings: []
packingSettings:
serializedVersion: 2
padding: 4
blockOffset: 0
allowAlphaSplitting: 0
enableRotation: 0
enableTightPacking: 0
enableAlphaDilation: 0
secondaryTextureSettings: {}
variantMultiplier: 1
bindAsDefault: 1
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 31fdb3fac3e3a964f9e5bf1aa25158af
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,47 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &5717669528680924896
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 5172050782918397531}
- component: {fileID: 5336591719806944066}
m_Layer: 0
m_Name: CreateRestaurantPlayer
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &5172050782918397531
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5717669528680924896}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 1
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &5336591719806944066
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5717669528680924896}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 246a7785bd15ac84b9f240005b987f1f, type: 3}
m_Name:
m_EditorClassIdentifier:
_spawnPosition: {x: 0, y: 0, z: 15}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 4c9d045012b65fc4b974bb4e132e6e6a
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -52,6 +52,10 @@ PrefabInstance:
propertyPath: m_LocalEulerAnglesHint.z propertyPath: m_LocalEulerAnglesHint.z
value: 0 value: 0
objectReference: {fileID: 0} objectReference: {fileID: 0}
- target: {fileID: 3095965496140440094, guid: 3db3fc62639929c4ba6031ca4ae6600c, type: 3}
propertyPath: _initialSkinName
value: Basic
objectReference: {fileID: 0}
- target: {fileID: 5259510642736920361, guid: 3db3fc62639929c4ba6031ca4ae6600c, type: 3} - target: {fileID: 5259510642736920361, guid: 3db3fc62639929c4ba6031ca4ae6600c, type: 3}
propertyPath: m_Name propertyPath: m_Name
value: RestaurantPlayer value: RestaurantPlayer
@ -63,10 +67,10 @@ PrefabInstance:
m_AddedGameObjects: [] m_AddedGameObjects: []
m_AddedComponents: m_AddedComponents:
- targetCorrespondingSourceObject: {fileID: 5259510642736920361, guid: 3db3fc62639929c4ba6031ca4ae6600c, type: 3} - targetCorrespondingSourceObject: {fileID: 5259510642736920361, guid: 3db3fc62639929c4ba6031ca4ae6600c, type: 3}
insertIndex: 3 insertIndex: 4
addedObject: {fileID: 4699468658517678862} addedObject: {fileID: 4699468658517678862}
- targetCorrespondingSourceObject: {fileID: 5259510642736920361, guid: 3db3fc62639929c4ba6031ca4ae6600c, type: 3} - targetCorrespondingSourceObject: {fileID: 5259510642736920361, guid: 3db3fc62639929c4ba6031ca4ae6600c, type: 3}
insertIndex: 4 insertIndex: 5
addedObject: {fileID: 4956037093100801085} addedObject: {fileID: 4956037093100801085}
m_SourcePrefab: {fileID: 100100000, guid: 3db3fc62639929c4ba6031ca4ae6600c, type: 3} m_SourcePrefab: {fileID: 100100000, guid: 3db3fc62639929c4ba6031ca4ae6600c, type: 3}
--- !u!1 &7316134055819320434 stripped --- !u!1 &7316134055819320434 stripped

File diff suppressed because it is too large Load Diff

View File

@ -240,146 +240,8 @@ Transform:
m_Children: [] m_Children: []
m_Father: {fileID: 0} m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0} m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0}
--- !u!1 &961739749
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 961739753}
- component: {fileID: 961739752}
- component: {fileID: 961739751}
- component: {fileID: 961739750}
m_Layer: 0
m_Name: Main Camera
m_TagString: MainCamera
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &961739750
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 961739749}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: a79441f348de89743a2939f4d699eac1, type: 3}
m_Name:
m_EditorClassIdentifier:
m_RenderShadows: 1
m_RequiresDepthTextureOption: 2
m_RequiresOpaqueTextureOption: 2
m_CameraType: 0
m_Cameras: []
m_RendererIndex: -1
m_VolumeLayerMask:
serializedVersion: 2
m_Bits: 1
m_VolumeTrigger: {fileID: 0}
m_VolumeFrameworkUpdateModeOption: 2
m_RenderPostProcessing: 0
m_Antialiasing: 0
m_AntialiasingQuality: 2
m_StopNaN: 0
m_Dithering: 0
m_ClearDepth: 1
m_AllowXRRendering: 1
m_AllowHDROutput: 1
m_UseScreenCoordOverride: 0
m_ScreenSizeOverride: {x: 0, y: 0, z: 0, w: 0}
m_ScreenCoordScaleBias: {x: 0, y: 0, z: 0, w: 0}
m_RequiresDepthTexture: 0
m_RequiresColorTexture: 0
m_Version: 2
m_TaaSettings:
m_Quality: 3
m_FrameInfluence: 0.1
m_JitterScale: 1
m_MipBias: 0
m_VarianceClampScale: 0.9
m_ContrastAdaptiveSharpening: 0
--- !u!81 &961739751
AudioListener:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 961739749}
m_Enabled: 1
--- !u!20 &961739752
Camera:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 961739749}
m_Enabled: 1
serializedVersion: 2
m_ClearFlags: 1
m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0}
m_projectionMatrixMode: 1
m_GateFitMode: 2
m_FOVAxisMode: 0
m_Iso: 200
m_ShutterSpeed: 0.005
m_Aperture: 16
m_FocusDistance: 10
m_FocalLength: 50
m_BladeCount: 5
m_Curvature: {x: 2, y: 11}
m_BarrelClipping: 0.25
m_Anamorphism: 0
m_SensorSize: {x: 36, y: 24}
m_LensShift: {x: 0, y: 0}
m_NormalizedViewPortRect:
serializedVersion: 2
x: 0
y: 0
width: 1
height: 1
near clip plane: 0.3
far clip plane: 1000
field of view: 60
orthographic: 0
orthographic size: 5
m_Depth: -1
m_CullingMask:
serializedVersion: 2
m_Bits: 4294967295
m_RenderingPath: -1
m_TargetTexture: {fileID: 0}
m_TargetDisplay: 0
m_TargetEye: 3
m_HDR: 1
m_AllowMSAA: 1
m_AllowDynamicResolution: 0
m_ForceIntoRT: 0
m_OcclusionCulling: 1
m_StereoConvergence: 10
m_StereoSeparation: 0.022
--- !u!4 &961739753
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 961739749}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 1, z: -10}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1660057539 &9223372036854775807 --- !u!1660057539 &9223372036854775807
SceneRoots: SceneRoots:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
m_Roots: m_Roots:
- {fileID: 961739753}
- {fileID: 203844589} - {fileID: 203844589}

View File

@ -18,3 +18,7 @@ MonoBehaviour:
DashSpeed: 20 DashSpeed: 20
DashTime: 0.2 DashTime: 0.2
DashCooldown: 0.5 DashCooldown: 0.5
WalkingSfxName:
DashSfxName:
MoveActionReference: {fileID: -1680190386980627800, guid: 052faaac586de48259a63d0c4782560b, type: 3}
DashActionReference: {fileID: -8150158440837788775, guid: 052faaac586de48259a63d0c4782560b, type: 3}

View File

@ -25,7 +25,7 @@ public async void PostInit()
} }
catch (Exception e) catch (Exception e)
{ {
Debug.Assert(false, "Addressables initialization failed"); Debug.Assert(false, $"Addressables initialization failed\n{e}");
} }
} }

View File

@ -21,11 +21,21 @@ private void Start()
} }
private void OnDestroy() private void OnDestroy()
{
if (CameraManager.Instance)
{ {
CameraManager.Instance.UnRegisterCamera(this); CameraManager.Instance.UnRegisterCamera(this);
} }
}
public int GetPriority() => _cinemachineCamera.Priority; public int GetPriority() => _cinemachineCamera.Priority;
public void SetPriority(int newPriority) => _cinemachineCamera.Priority = newPriority; public void SetPriority(int newPriority) => _cinemachineCamera.Priority = newPriority;
public void SetFollowTarget(Transform target) => _cinemachineCamera.Follow = target;
public void SetLookAtTarget(Transform target) => _cinemachineCamera.LookAt = target;
public void SetFollowAndLookAtTarget(Transform target)
{
SetFollowTarget(target);
SetLookAtTarget(target);
}
} }
} }

View File

@ -7,13 +7,12 @@ namespace DDD
public class CameraManager : Singleton<CameraManager>, IManager public class CameraManager : Singleton<CameraManager>, IManager
{ {
[ShowInInspector, ReadOnly] [ShowInInspector, ReadOnly]
private Dictionary<string, CameraGameObject> _cameraGameObjects; private Dictionary<string, CameraGameObject> _cameraGameObjects = new();
private CinemachineBrain _cinemachineBrain; private CinemachineBrain _cinemachineBrain;
public void Init() public void Init()
{ {
_cameraGameObjects = new Dictionary<string, CameraGameObject>();
_cinemachineBrain = GetComponent<CinemachineBrain>(); _cinemachineBrain = GetComponent<CinemachineBrain>();
} }
@ -41,5 +40,7 @@ public void SwitchCamera(CameraGameObject cameraGameObject, CinemachineBlendDefi
item.Value.SetPriority(newPriority); item.Value.SetPriority(newPriority);
} }
} }
public CameraGameObject GetCameraGameObject(string id) => _cameraGameObjects[id];
} }
} }

View File

@ -45,7 +45,7 @@ Camera:
m_GameObject: {fileID: 7292682221138498026} m_GameObject: {fileID: 7292682221138498026}
m_Enabled: 1 m_Enabled: 1
serializedVersion: 2 serializedVersion: 2
m_ClearFlags: 2 m_ClearFlags: 1
m_BackGroundColor: {r: 0, g: 0, b: 0, a: 0} m_BackGroundColor: {r: 0, g: 0, b: 0, a: 0}
m_projectionMatrixMode: 1 m_projectionMatrixMode: 1
m_GateFitMode: 2 m_GateFitMode: 2

View File

@ -56,7 +56,50 @@ MonoBehaviour:
Data: 1 Data: 1
- Name: - Name:
Entry: 12 Entry: 12
Data: 0 Data: 1
- Name:
Entry: 7
Data:
- Name: $k
Entry: 3
Data: 1
- Name: $v
Entry: 7
Data: 3|System.Collections.Generic.List`1[[UnityEngine.AddressableAssets.AssetReference,
Unity.Addressables]], mscorlib
- Name:
Entry: 12
Data: 1
- Name:
Entry: 7
Data: 4|UnityEngine.AddressableAssets.AssetReference, Unity.Addressables
- Name: m_AssetGUID
Entry: 1
Data: 4c9d045012b65fc4b974bb4e132e6e6a
- Name: m_SubObjectName
Entry: 6
Data:
- Name: m_SubObjectType
Entry: 6
Data:
- Name: m_SubObjectGUID
Entry: 1
Data:
- Name: m_EditorAssetChanged
Entry: 5
Data: true
- Name:
Entry: 8
Data:
- Name:
Entry: 13
Data:
- Name:
Entry: 8
Data:
- Name:
Entry: 8
Data:
- Name: - Name:
Entry: 13 Entry: 13
Data: Data:

View File

@ -2,8 +2,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using UnityEngine; using UnityEngine;
using UnityEngine.ResourceManagement.ResourceProviders; using UnityEngine.AddressableAssets;
using UnityEngine.SceneManagement;
namespace DDD namespace DDD
{ {
@ -23,7 +22,7 @@ public class GameFlowManager : Singleton<GameFlowManager>, IManager
public void Init() public void Init()
{ {
GameFlowDataSo.CurrentGameState = GameFlowState.None;
} }
public async void PostInit() public async void PostInit()
@ -42,7 +41,7 @@ public async void PostInit()
} }
} }
public bool IsGameStarted() => GameFlowDataSo.CurrentGameState != GameFlowState.None; private bool IsGameStarted() => GameFlowDataSo.CurrentGameState != GameFlowState.None;
public async Task ChangeFlow(GameFlowState newFlowState) public async Task ChangeFlow(GameFlowState newFlowState)
{ {
@ -62,33 +61,38 @@ private bool CanChangeFlow(GameFlowState newFlowState)
return true; return true;
} }
public void EndCurrentFlow() private void EndCurrentFlow()
{ {
} }
public async Task ReadyNewFlow(GameFlowState newFlowState) private async Task ReadyNewFlow(GameFlowState newFlowState)
{ {
GameFlowDataSo.CurrentGameState = newFlowState;
if (GameFlowAssetsSo.FlowItems.TryGetValue(newFlowState, out var stringKeys)) if (GameFlowAssetsSo.FlowItems.TryGetValue(newFlowState, out var stringKeys))
{ {
List<Task<UnityEngine.Object>> loadTasks = new(stringKeys.Count);
foreach (var key in stringKeys) foreach (var key in stringKeys)
{ {
loadTasks.Add(AssetManager.LoadAsset<UnityEngine.Object>(key)); await AssetManager.LoadAsset<UnityEngine.Object>(key);
} }
await Task.WhenAll(loadTasks);
} }
if (GameFlowAssetsSo.FlowAssets.TryGetValue(newFlowState, out var assetRefs)) if (GameFlowAssetsSo.FlowAssets.TryGetValue(newFlowState, out var assetRefs))
{ {
List<Task<UnityEngine.Object>> loadTasks = new(assetRefs.Count);
foreach (var assetRef in assetRefs) foreach (var assetRef in assetRefs)
{ {
loadTasks.Add(AssetManager.LoadAsset<UnityEngine.Object>(assetRef)); var obj = await AssetManager.LoadAsset<UnityEngine.Object>(assetRef);
}
await Task.WhenAll(loadTasks); if (obj is GameObject prefab)
{
Instantiate(prefab);
}
else
{
Debug.LogWarning($"[ReadyNewFlow] Not a GameObject: {assetRef.RuntimeKey}");
}
}
} }
OpenFlowScene(newFlowState); OpenFlowScene(newFlowState);
@ -96,26 +100,36 @@ public async Task ReadyNewFlow(GameFlowState newFlowState)
StartFlow(); StartFlow();
} }
public void OpenFlowScene(GameFlowState newFlowState) private async void OpenFlowScene(GameFlowState newFlowState)
{
try
{ {
if (GetFlowScene(newFlowState, out var sceneToLoad)) if (GetFlowScene(newFlowState, out var sceneToLoad))
{ {
await FadeManager.Instance.FadeOut();

FadeManager 호출 구조를 변경해주세요.
FlowManager에서 FadeManager를 알고, 호출해야 하는 게 아니라
FadeManager가 알아서 자기가 필요한 타이밍에 불리게끔 등록해야 합니다.
예를 들어, FlowManager의 ReadyForStartNewFlow, WaitUntilAllRegisteredManagerReady 같은 형식으로요.
그리고 FadeManager가 여기서 플로우변경이 아니라 씬에 등록되어 씬 전환 이전-씬전환이후로 가는 게 더 적절할 것 같습니다.

FadeManager 호출 구조를 변경해주세요. FlowManager에서 FadeManager를 알고, 호출해야 하는 게 아니라 FadeManager가 알아서 자기가 필요한 타이밍에 불리게끔 등록해야 합니다. 예를 들어, FlowManager의 ReadyForStartNewFlow, WaitUntilAllRegisteredManagerReady 같은 형식으로요. 그리고 FadeManager가 여기서 플로우변경이 아니라 씬에 등록되어 씬 전환 이전-씬전환이후로 가는 게 더 적절할 것 같습니다.
SceneManager.Instance.ActivateScene(sceneToLoad); SceneManager.Instance.ActivateScene(sceneToLoad);
await Task.Delay(1000);
await FadeManager.Instance.FadeIn();
} }
else else
{ {
Debug.Assert(false, "Scene not found!"); Debug.Assert(false, "Scene not found!");
} }
} }
catch (Exception e)
{
Debug.LogError(e.Message);
}
}
public bool GetFlowScene(GameFlowState flowState, out SceneType sceneType) private bool GetFlowScene(GameFlowState flowState, out SceneType sceneType)
{ {
return GameFlowSceneMappingSo.FlowToSceneMapping.TryGetValue(flowState, out sceneType); return GameFlowSceneMappingSo.FlowToSceneMapping.TryGetValue(flowState, out sceneType);
} }
public void StartFlow() private void StartFlow()
{ {
// Broadcast new flow started
} }
} }
} }

View File

@ -0,0 +1,54 @@
using System.Threading.Tasks;
using DG.Tweening;
using UnityEngine;
namespace DDD
{
public class FadeManager : Singleton<FadeManager>, IManager
{
[SerializeField]
private float _fadeOutDuration = 0.5f;
[SerializeField]
private float _fadeInDuration = 1f;
private CanvasGroup _canvasGroup;
public void Init()
{
_canvasGroup = GetComponent<CanvasGroup>();
}
public void PostInit()
{
_canvasGroup.alpha = 0f;
_canvasGroup.gameObject.SetActive(false);
}
public async Task FadeOut()
{
_canvasGroup.gameObject.SetActive(true);
_canvasGroup.blocksRaycasts = true;
await _canvasGroup.DOFade(1f, _fadeOutDuration)
.SetUpdate(true)
.AsyncWaitForCompletion();
}
public async Task FadeIn()
{
await _canvasGroup.DOFade(0f, _fadeInDuration)
.SetUpdate(true)
.AsyncWaitForCompletion();
_canvasGroup.blocksRaycasts = false;
_canvasGroup.gameObject.SetActive(false);
}
public async Task FadeOutIn()
{
await FadeOut();
await FadeIn();
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 41f0ee0aabb2f954d918caa8d484f646

View File

@ -0,0 +1,206 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &645007492175346922
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 8625885928614466139}
- component: {fileID: 5533625503660040844}
- component: {fileID: 2068856588424138268}
- component: {fileID: 827366504865157138}
- component: {fileID: 8205940526588409056}
- component: {fileID: 5136368050551183548}
m_Layer: 5
m_Name: FadeManager
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &8625885928614466139
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 645007492175346922}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 0, y: 0, z: 0}
m_ConstrainProportionsScale: 1
m_Children:
- {fileID: 2840604718763097518}
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0, y: 0}
--- !u!223 &5533625503660040844
Canvas:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 645007492175346922}
m_Enabled: 1
serializedVersion: 3
m_RenderMode: 0
m_Camera: {fileID: 0}
m_PlaneDistance: 100
m_PixelPerfect: 0
m_ReceivesEvents: 1
m_OverrideSorting: 0
m_OverridePixelPerfect: 0
m_SortingBucketNormalizedSize: 0
m_VertexColorAlwaysGammaSpace: 0
m_AdditionalShaderChannelsFlag: 0
m_UpdateRectTransformForStandalone: 0
m_SortingLayerID: 0
m_SortingOrder: 6
m_TargetDisplay: 0
--- !u!114 &2068856588424138268
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 645007492175346922}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3}
m_Name:
m_EditorClassIdentifier:
m_UiScaleMode: 1
m_ReferencePixelsPerUnit: 100
m_ScaleFactor: 1
m_ReferenceResolution: {x: 1920, y: 1080}
m_ScreenMatchMode: 1
m_MatchWidthOrHeight: 0
m_PhysicalUnit: 3
m_FallbackScreenDPI: 96
m_DefaultSpriteDPI: 96
m_DynamicPixelsPerUnit: 1
m_PresetInfoIsWorld: 0
--- !u!114 &827366504865157138
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 645007492175346922}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3}
m_Name:
m_EditorClassIdentifier:
m_IgnoreReversedGraphics: 1
m_BlockingObjects: 0
m_BlockingMask:
serializedVersion: 2
m_Bits: 55
--- !u!225 &8205940526588409056
CanvasGroup:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 645007492175346922}
m_Enabled: 1
m_Alpha: 0
m_Interactable: 1
m_BlocksRaycasts: 1
m_IgnoreParentGroups: 0
--- !u!114 &5136368050551183548
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 645007492175346922}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 41f0ee0aabb2f954d918caa8d484f646, type: 3}
m_Name:
m_EditorClassIdentifier:
_persistent: 1
--- !u!1 &6954525544416039378
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 2840604718763097518}
- component: {fileID: 8274624108829164416}
- component: {fileID: 4134486114940038904}
m_Layer: 5
m_Name: Image
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &2840604718763097518
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6954525544416039378}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 1
m_Children: []
m_Father: {fileID: 8625885928614466139}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &8274624108829164416
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6954525544416039378}
m_CullTransparentMesh: 1
--- !u!114 &4134486114940038904
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6954525544416039378}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 0, g: 0, b: 0, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_Sprite: {fileID: 0}
m_Type: 0
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 0aa6654feb91ef040b8b99d4f64688fc
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -20,7 +20,6 @@ protected void Start()
return; return;
} }
// Entry Scene에서 뭘 해야할까?
// 매니저 초기화 // 매니저 초기화
_managerInstances = new List<Singleton>(_managerDefinitionSo.ManagerClasses.Count); _managerInstances = new List<Singleton>(_managerDefinitionSo.ManagerClasses.Count);
@ -42,7 +41,6 @@ protected void Start()
manager.PostInit(); manager.PostInit();
} }
} }
// 초기 씬으로 보내주기
} }
} }
} }

View File

@ -17,3 +17,5 @@ MonoBehaviour:
- {fileID: 4889131746858770208, guid: d90fdb17f0162334daadc6fc93e9a0e3, type: 3} - {fileID: 4889131746858770208, guid: d90fdb17f0162334daadc6fc93e9a0e3, type: 3}
- {fileID: 6471498998539637564, guid: fa2ad62c75b1549f09597e47ed5f7cfb, type: 3} - {fileID: 6471498998539637564, guid: fa2ad62c75b1549f09597e47ed5f7cfb, type: 3}
- {fileID: 7665229218737596710, guid: 71b177c2a18314c588da30429451666a, type: 3} - {fileID: 7665229218737596710, guid: 71b177c2a18314c588da30429451666a, type: 3}
- {fileID: 622422277636247943, guid: d95124918e5a4a246abb0d378b14d3fa, type: 3}
- {fileID: 5136368050551183548, guid: 0aa6654feb91ef040b8b99d4f64688fc, type: 3}

View File

@ -35,16 +35,7 @@ public async void PostInit()
{ {
if (sceneType == SceneType.Entry) continue; if (sceneType == SceneType.Entry) continue;
var sceneInstance = await AssetManager.LoadScene(sceneType.ToString()); await PreloadSceneAsync(sceneType);
if (sceneInstance.Scene.IsValid())
{
_loadedScenes[sceneType] = sceneInstance;
foreach (var go in sceneInstance.Scene.GetRootGameObjects())
{
go.SetActive(false);
}
}
} }
} }
catch (Exception e) catch (Exception e)

View File

@ -11,6 +11,7 @@ GameObject:
- component: {fileID: 1761643478070701343} - component: {fileID: 1761643478070701343}
- component: {fileID: 5176902543201676162} - component: {fileID: 5176902543201676162}
- component: {fileID: 5246526151924390639} - component: {fileID: 5246526151924390639}
- component: {fileID: 8352859907019760819}
- component: {fileID: 3365694194251356714} - component: {fileID: 3365694194251356714}
- component: {fileID: 127430239903465757} - component: {fileID: 127430239903465757}
- component: {fileID: 3095965496140440094} - component: {fileID: 3095965496140440094}
@ -87,6 +88,92 @@ CapsuleCollider:
m_Height: 0.1 m_Height: 0.1
m_Direction: 1 m_Direction: 1
m_Center: {x: 0, y: 0.1, z: 0} m_Center: {x: 0, y: 0.1, z: 0}
--- !u!114 &8352859907019760819
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5259510642736920361}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 62899f850307741f2a39c98a8b639597, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Actions: {fileID: -944628639613478452, guid: 052faaac586de48259a63d0c4782560b, type: 3}
m_NotificationBehavior: 2
m_UIInputModule: {fileID: 0}
m_DeviceLostEvent:
m_PersistentCalls:
m_Calls: []
m_DeviceRegainedEvent:
m_PersistentCalls:
m_Calls: []
m_ControlsChangedEvent:
m_PersistentCalls:
m_Calls: []
m_ActionEvents:
- m_PersistentCalls:
m_Calls: []
m_ActionId: 351f2ccd-1f9f-44bf-9bec-d62ac5c5f408
m_ActionName: 'Restaurant/Move[/Keyboard/w,/Keyboard/upArrow,/Keyboard/s,/Keyboard/downArrow,/Keyboard/a,/Keyboard/leftArrow,/Keyboard/d,/Keyboard/rightArrow]'
- m_PersistentCalls:
m_Calls: []
m_ActionId: 6c2ab1b8-8984-453a-af3d-a3c78ae1679a
m_ActionName: 'Restaurant/Attack[/Mouse/leftButton,/Keyboard/enter]'
- m_PersistentCalls:
m_Calls: []
m_ActionId: f1e71b7e-271b-4382-876a-260ea451296a
m_ActionName: 'Restaurant/Dash[/Keyboard/space]'
- m_PersistentCalls:
m_Calls: []
m_ActionId: 852140f2-7766-474d-8707-702459ba45f3
m_ActionName: 'Restaurant/Interact[/Keyboard/e]'
- m_PersistentCalls:
m_Calls: []
m_ActionId: c95b2375-e6d9-4b88-9c4c-c5e76515df4b
m_ActionName: 'Ui/Navigate[/Keyboard/w,/Keyboard/upArrow,/Keyboard/s,/Keyboard/downArrow,/Keyboard/a,/Keyboard/leftArrow,/Keyboard/d,/Keyboard/rightArrow]'
- m_PersistentCalls:
m_Calls: []
m_ActionId: 7607c7b6-cd76-4816-beef-bd0341cfe950
m_ActionName: 'Ui/Submit[/Keyboard/enter]'
- m_PersistentCalls:
m_Calls: []
m_ActionId: 15cef263-9014-4fd5-94d9-4e4a6234a6ef
m_ActionName: 'Ui/Cancel[/Keyboard/escape]'
- m_PersistentCalls:
m_Calls: []
m_ActionId: 32b35790-4ed0-4e9a-aa41-69ac6d629449
m_ActionName: 'Ui/Point[/Mouse/position]'
- m_PersistentCalls:
m_Calls: []
m_ActionId: 3c7022bf-7922-4f7c-a998-c437916075ad
m_ActionName: 'Ui/Click[/Mouse/leftButton]'
- m_PersistentCalls:
m_Calls: []
m_ActionId: 44b200b1-1557-4083-816c-b22cbdf77ddf
m_ActionName: 'Ui/RightClick[/Mouse/rightButton]'
- m_PersistentCalls:
m_Calls: []
m_ActionId: dad70c86-b58c-4b17-88ad-f5e53adf419e
m_ActionName: 'Ui/MiddleClick[/Mouse/middleButton]'
- m_PersistentCalls:
m_Calls: []
m_ActionId: 0489e84a-4833-4c40-bfae-cea84b696689
m_ActionName: 'Ui/ScrollWheel[/Mouse/scroll]'
- m_PersistentCalls:
m_Calls: []
m_ActionId: 24908448-c609-4bc3-a128-ea258674378a
m_ActionName: Ui/TrackedDevicePosition
- m_PersistentCalls:
m_Calls: []
m_ActionId: 9caa3d8a-6b2f-4e8e-8bad-6ede561bd9be
m_ActionName: Ui/TrackedDeviceOrientation
m_NeverAutoSwitchControlSchemes: 0
m_DefaultControlScheme:
m_DefaultActionMap: Restaurant
m_SplitScreenIndex: -1
m_Camera: {fileID: 0}
--- !u!114 &3365694194251356714 --- !u!114 &3365694194251356714
MonoBehaviour: MonoBehaviour:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@ -123,6 +210,14 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: e20368314a3139f4fb4b4e35af9fcf98, type: 3} m_Script: {fileID: 11500000, guid: e20368314a3139f4fb4b4e35af9fcf98, type: 3}
m_Name: m_Name:
m_EditorClassIdentifier: m_EditorClassIdentifier:
_originalMaterial: {fileID: 0}
_replacementMaterial: {fileID: 0}
_isSkinSet: 1
_initialSkinName: default
_isRandomSkin: 0
_isRandomRange: 0
_randomRange: {x: 0, y: 0}
_randomStrings: []
--- !u!1 &6791841979869644848 --- !u!1 &6791841979869644848
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0

View File

@ -0,0 +1,26 @@
using System;
using UnityEngine;
namespace DDD
{
public class CreateRestaurantPlayer : MonoBehaviour
{
[SerializeField]
private Vector3 _spawnPosition;
private async void Start()
{
try
{
var playerPrefab = await AssetManager.LoadAsset<GameObject>("RestaurantPlayer");

리터럴 스트링 제거할 방법이 있을까요?

리터럴 스트링 제거할 방법이 있을까요?
var player = Instantiate(playerPrefab, _spawnPosition, playerPrefab.transform.rotation);
player.name = "RestaurantPlayer";
CameraManager.Instance.GetCameraGameObject("RestaurantBaseCamera").SetFollowAndLookAtTarget(player.transform);

여기도 리터럴 스트링 제거하고 레퍼런스 기반으로 작업할 방법이 있을까요?

여기도 리터럴 스트링 제거하고 레퍼런스 기반으로 작업할 방법이 있을까요?
}
catch (Exception e)
{
Debug.LogError($"Create player failed\n{e.Message}");
}
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 246a7785bd15ac84b9f240005b987f1f

View File

@ -1,9 +0,0 @@
namespace DDD
{
public interface IStateMachine
{
void Enter();
void Update();
void Exit();
}
}

View File

@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: c111bfa40d649ac4c9d401efa650734d

View File

@ -1,19 +0,0 @@
namespace DDD
{
public class PlayerStateMachine
{
private IStateMachine _currentStateMachine;
public void ChangeState(IStateMachine newStateMachine)
{
_currentStateMachine?.Exit();
_currentStateMachine = newStateMachine;
_currentStateMachine.Enter();
}
public void Update()
{
_currentStateMachine?.Update();
}
}
}

View File

@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: 2887dac388e7a244585d84329954e38f

View File

@ -1,191 +1,191 @@
using System.Collections; // using System.Collections;
using UnityEngine; // using UnityEngine;
using UnityEngine.AddressableAssets; // using UnityEngine.AddressableAssets;
using UnityEngine.InputSystem; // using UnityEngine.InputSystem;
using UnityEngine.Serialization; // using UnityEngine.Serialization;
//
namespace DDD // namespace DDD
{ // {
public class RestaurantPlayer : MonoBehaviour // public class RestaurantPlayer : MonoBehaviour
{ // {
#region Variables // #region Variables
//
private RestaurantPlayerDataSo _playerData; // private RestaurantPlayerDataSo _playerData;
private RestaurantPlayerView _playerView; // private RestaurantPlayerView _playerView;
//
private InputAction _moveAction; // private InputAction _moveAction;
private InputAction _dashAction; // private InputAction _dashAction;
private Coroutine _dashInstance; // private Coroutine _dashInstance;
//
private Vector3 _inputDirection; // private Vector3 _inputDirection;
private Vector3 _currentDirection = Vector3.back; // private Vector3 _currentDirection = Vector3.back;
//
public bool IsMoving; // public bool IsMoving;
public bool IsDashing; // public bool IsDashing;
public bool IsDashCoolDownActive; // public bool IsDashCoolDownActive;
//
private float _finalSpeed; // private float _finalSpeed;
//
private PlayerStateMachine _stateMachine; // private PlayerStateMachine _stateMachine;
//
#endregion // #endregion
//
// Unity events // // Unity events
//
#region Unity events // #region Unity events
//
private void Awake() // private void Awake()
{ // {
_playerData = Addressables.LoadAssetAsync<RestaurantPlayerDataSo>("RestaurantPlayerDataSo").WaitForCompletion(); // _playerData = Addressables.LoadAssetAsync<RestaurantPlayerDataSo>("RestaurantPlayerDataSo").WaitForCompletion();
_playerView = GetComponent<RestaurantPlayerView>(); // _playerView = GetComponent<RestaurantPlayerView>();
} // }
//
private void Start() // private void Start()
{ // {
_moveAction = InputManager.Instance.GetAction(InputActionMaps.Restaurant, nameof(RestaurantActions.Move)); // _moveAction = InputManager.Instance.GetAction(InputActionMaps.Restaurant, nameof(RestaurantActions.Move));
_dashAction = InputManager.Instance.GetAction(InputActionMaps.Restaurant, nameof(RestaurantActions.Dash)); // _dashAction = InputManager.Instance.GetAction(InputActionMaps.Restaurant, nameof(RestaurantActions.Dash));
//
_moveAction.performed += OnMove; // _moveAction.performed += OnMove;
_moveAction.canceled += OnMove; // _moveAction.canceled += OnMove;
_dashAction.performed += OnDash; // _dashAction.performed += OnDash;
//
_stateMachine = new PlayerStateMachine(); // _stateMachine = new PlayerStateMachine();
ChangeState(new IdleState(this, _playerView)); // ChangeState(new IdleState(this, _playerView));
} // }
//
//public CellManager cellManager; // //public CellManager cellManager;
private void Update() // private void Update()
{ // {
_stateMachine.Update(); // _stateMachine.Update();
//
FlipVisualLook(); // FlipVisualLook();
//
//UpdateCell // //UpdateCell
//cellManager.SetupCell(transform.position); // //cellManager.SetupCell(transform.position);
} // }
//
private void FixedUpdate() // private void FixedUpdate()
{ // {
if (!CanMove()) return; // if (!CanMove()) return;
//
Move(); // Move();
} // }
//
private void OnDestroy() // private void OnDestroy()
{ // {
_moveAction.performed -= OnMove; // _moveAction.performed -= OnMove;
_moveAction.canceled -= OnMove; // _moveAction.canceled -= OnMove;
_dashAction.performed -= OnDash; // _dashAction.performed -= OnDash;
} // }
//
#endregion // #endregion
//
// Methods // // Methods
#region Methods // #region Methods
//
public void SetCurrentDirection(Vector3 normalDirection) // public void SetCurrentDirection(Vector3 normalDirection)
{ // {
if (normalDirection == Vector3.zero) return; // if (normalDirection == Vector3.zero) return;
//
_currentDirection = normalDirection; // _currentDirection = normalDirection;
} // }
//
private void FlipVisualLook() // private void FlipVisualLook()
{ // {
Vector3 localScale = _playerView.GetLocalScale(); // Vector3 localScale = _playerView.GetLocalScale();
localScale.x = _currentDirection.x switch // localScale.x = _currentDirection.x switch
{ // {
> 0.01f => -Mathf.Abs(localScale.x), // > 0.01f => -Mathf.Abs(localScale.x),
< -0.01f => Mathf.Abs(localScale.x), // < -0.01f => Mathf.Abs(localScale.x),
_ => localScale.x // _ => localScale.x
}; // };
_playerView.SetLocalScale(localScale); // _playerView.SetLocalScale(localScale);
} // }
//
public void OnMove(InputAction.CallbackContext context) // public void OnMove(InputAction.CallbackContext context)
{ // {
var movementInput = _moveAction.ReadValue<Vector2>(); // var movementInput = _moveAction.ReadValue<Vector2>();
_inputDirection = new Vector3(movementInput.x, 0, movementInput.y).normalized; // _inputDirection = new Vector3(movementInput.x, 0, movementInput.y).normalized;
} // }
//
public bool CanMove() // public bool CanMove()
{ // {
return _playerData.IsMoveEnabled && !IsDashing; // return _playerData.IsMoveEnabled && !IsDashing;
} // }
//
public void Move() // public void Move()
{ // {
SetCurrentDirection(_inputDirection); // SetCurrentDirection(_inputDirection);
IsMoving = _inputDirection != Vector3.zero; // IsMoving = _inputDirection != Vector3.zero;
//
var finalVelocity = _inputDirection * _playerData.MoveSpeed; // var finalVelocity = _inputDirection * _playerData.MoveSpeed;
_playerView.SetVelocity(finalVelocity); // _playerView.SetVelocity(finalVelocity);
} // }
//
public void OnDash(InputAction.CallbackContext context) // public void OnDash(InputAction.CallbackContext context)
{ // {
if (!CanDash()) return; // if (!CanDash()) return;
//
Dash(); // Dash();
} // }
//
public bool CanDash() // public bool CanDash()
{ // {
return _playerData.IsDashEnabled && !IsDashing && !IsDashCoolDownActive; // return _playerData.IsDashEnabled && !IsDashing && !IsDashCoolDownActive;
} // }
//
public void Dash() // public void Dash()
{ // {
Utils.StartUniqueCoroutine(this, ref _dashInstance, DashCoroutine()); // Utils.StartUniqueCoroutine(this, ref _dashInstance, DashCoroutine());
} // }
//
private IEnumerator DashCoroutine() // private IEnumerator DashCoroutine()
{ // {
IsDashing = true; // IsDashing = true;
IsDashCoolDownActive = true; // IsDashCoolDownActive = true;
_playerView.PlayDashParticle(); // _playerView.PlayDashParticle();
//
AudioManager.Instance.PlaySfx(_playerData.DashSfxName); // AudioManager.Instance.PlaySfx(_playerData.DashSfxName);
//
var dashDirection = _inputDirection; // var dashDirection = _inputDirection;
if (dashDirection == Vector3.zero) // if (dashDirection == Vector3.zero)
{ // {
dashDirection = _currentDirection; // dashDirection = _currentDirection;
} // }
//
var elapsedTime = 0f; // var elapsedTime = 0f;
while (elapsedTime <= _playerData.DashTime) // while (elapsedTime <= _playerData.DashTime)
{ // {
var finalVelocity = dashDirection * _playerData.DashSpeed; // var finalVelocity = dashDirection * _playerData.DashSpeed;
_playerView.SetVelocity(finalVelocity); // _playerView.SetVelocity(finalVelocity);
//
elapsedTime += Time.fixedDeltaTime; // elapsedTime += Time.fixedDeltaTime;
yield return new WaitForFixedUpdate(); // yield return new WaitForFixedUpdate();
} // }
//
EndDash(_playerData.DashCooldown); // EndDash(_playerData.DashCooldown);
} // }
//
public void EndDash(float dashCooldown = float.PositiveInfinity) // public void EndDash(float dashCooldown = float.PositiveInfinity)
{ // {
Utils.EndUniqueCoroutine(this, ref _dashInstance); // Utils.EndUniqueCoroutine(this, ref _dashInstance);
_playerView.SetVelocity(Vector3.zero); // _playerView.SetVelocity(Vector3.zero);
IsDashing = false; // IsDashing = false;
//
if (float.IsPositiveInfinity(dashCooldown)) // if (float.IsPositiveInfinity(dashCooldown))
{ // {
dashCooldown = _playerData.DashCooldown; // dashCooldown = _playerData.DashCooldown;
} // }
//
// TODO : ui 연동 // // TODO : ui 연동
StartCoroutine(Utils.CoolDownCoroutine(dashCooldown, () => IsDashCoolDownActive = false)); // StartCoroutine(Utils.CoolDownCoroutine(dashCooldown, () => IsDashCoolDownActive = false));
} // }
//
public void ChangeState(IStateMachine stateMachine) // public void ChangeState(IStateMachine stateMachine)
{ // {
_stateMachine.ChangeState(stateMachine); // _stateMachine.ChangeState(stateMachine);
} // }
//
#endregion // #endregion
} // }
} // }

View File

@ -1,4 +1,5 @@
using UnityEngine; using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.Serialization; using UnityEngine.Serialization;
namespace DDD namespace DDD
@ -12,9 +13,12 @@ public class RestaurantPlayerDataSo : ScriptableObject
public bool IsDashEnabled = true; public bool IsDashEnabled = true;
public float DashSpeed = 20f; public float DashSpeed = 20f;
public float DashTime = 0.2f; public float DashTime = 0.2f;
public float DashCooldown = 0.5f; public float DashCooldown = 2f;
public string WalkingSfxName; public string WalkingSfxName;
public string DashSfxName; public string DashSfxName;
public InputActionReference MoveActionReference;
public InputActionReference DashActionReference;
} }
} }

View File

@ -1,57 +1,57 @@
using Spine; // using Spine;
using UnityEngine; // using UnityEngine;
//
namespace DDD // namespace DDD
{ // {
public static class RestaurantSpineAnimation // public static class RestaurantSpineAnimation
{ // {
public const string Idle = "Idle"; // public const string Idle = "Idle";
public const string Walking = "RunFast"; // public const string Walking = "RunFast";
public const string ServingIdle = "Serving/ServingIdle"; // public const string ServingIdle = "Serving/ServingIdle";
public const string Serving = "Serving/ServingFast"; // public const string Serving = "Serving/ServingFast";
public const string Dash = "Dash"; // public const string Dash = "Dash";
public const string CleaningFloor = "Cleaning/CleaningFloor"; // public const string CleaningFloor = "Cleaning/CleaningFloor";
public const string CleaningTable = "Cleaning/CleaningTable"; // public const string CleaningTable = "Cleaning/CleaningTable";
public const string MakingCocktail = "BeerMaker"; // public const string MakingCocktail = "BeerMaker";
public const string Pumping = "Attack/AttackWhip"; // public const string Pumping = "Attack/AttackWhip";
public const string AttackSlime = "Attack/AttackSlime"; // public const string AttackSlime = "Attack/AttackSlime";
public const string AttackLimeTree = "Attack/AttackBat"; // public const string AttackLimeTree = "Attack/AttackBat";
public const string CookingFried = "Cooking/CookingFried"; // public const string CookingFried = "Cooking/CookingFried";
public const string CookingStew = "Cooking/CookingStew"; // public const string CookingStew = "Cooking/CookingStew";
} // }
//
public class RestaurantPlayerView : MonoBehaviour // public class RestaurantPlayerView : MonoBehaviour
{ // {
private Rigidbody _rigidbody; // private Rigidbody _rigidbody;
private Transform _visualLook; // private Transform _visualLook;
private SpineController _spineController; // private SpineController _spineController;
//
private ParticleSystem _dashParticle; // private ParticleSystem _dashParticle;
//
private void Awake() // private void Awake()
{ // {
_rigidbody = GetComponent<Rigidbody>(); // _rigidbody = GetComponent<Rigidbody>();
_visualLook = transform.Find("VisualLook"); // _visualLook = transform.Find("VisualLook");
_spineController = GetComponent<SpineController>(); // _spineController = GetComponent<SpineController>();
} // }
//
public void SetVelocity(Vector3 velocity) => _rigidbody.linearVelocity = velocity; // public void SetVelocity(Vector3 velocity) => _rigidbody.linearVelocity = velocity;
public Vector3 GetLocalScale() => _visualLook.localScale; // public Vector3 GetLocalScale() => _visualLook.localScale;
public void SetLocalScale(Vector3 localScale) => _visualLook.localScale = localScale; // public void SetLocalScale(Vector3 localScale) => _visualLook.localScale = localScale;
//
public void PlayDashParticle() // public void PlayDashParticle()
{ // {
if (_dashParticle) // if (_dashParticle)
{ // {
_dashParticle.Play(); // _dashParticle.Play();
} // }
} // }
//
public TrackEntry PlayAnimation(string animationName, bool isLoopActive, float speed = 1f, bool isReverse = false, int trackIndex = 0) // public TrackEntry PlayAnimation(string animationName, bool isLoopActive, float speed = 1f, bool isReverse = false, int trackIndex = 0)
=> _spineController.PlayAnimation(animationName, isLoopActive, speed, isReverse, trackIndex); // => _spineController.PlayAnimation(animationName, isLoopActive, speed, isReverse, trackIndex);
public TrackEntry PlayAnimationDuration(string animationName, bool isLoopActive, float duration, bool isReverse = false, int trackIndex = 0) => // public TrackEntry PlayAnimationDuration(string animationName, bool isLoopActive, float duration, bool isReverse = false, int trackIndex = 0) =>
_spineController.PlayAnimationDuration(animationName, isLoopActive, duration, isReverse, trackIndex); // _spineController.PlayAnimationDuration(animationName, isLoopActive, duration, isReverse, trackIndex);
public TrackEntry AddAnimation(string animationName, bool isLoopActive, int trackIndex = 0) // public TrackEntry AddAnimation(string animationName, bool isLoopActive, int trackIndex = 0)
=> _spineController.AddAnimation(animationName, isLoopActive, trackIndex); // => _spineController.AddAnimation(animationName, isLoopActive, trackIndex);
} // }
} // }

View File

@ -1,32 +0,0 @@
namespace DDD
{
public class IdleState : IStateMachine
{
private RestaurantPlayer _player;
private RestaurantPlayerView _view;
public IdleState(RestaurantPlayer player, RestaurantPlayerView view)
{
_player = player;
_view = view;
}
public void Enter()
{
_view.PlayAnimation(RestaurantSpineAnimation.Idle, true);
}
public void Update()
{
if (_player.IsMoving)
{
_player.ChangeState(new WalkingState(_player, _view));
}
}
public void Exit()
{
}
}
}

View File

@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: 8dd7a1f24d102af41848ae82fb8f8ca5

View File

@ -1,32 +0,0 @@
namespace DDD
{
public class WalkingState : IStateMachine
{
private RestaurantPlayer _player;
private RestaurantPlayerView _view;
public WalkingState(RestaurantPlayer player, RestaurantPlayerView view)
{
_player = player;
_view = view;
}
public void Enter()
{
_view.PlayAnimation(RestaurantSpineAnimation.Walking, true);
}
public void Update()
{
if (!_player.IsMoving)
{
_player.ChangeState(new IdleState(_player, _view));
}
}
public void Exit()
{
}
}
}

View File

@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: 08926e2ade87cab459e625851316b00c

View File

@ -1,9 +1,264 @@
using System.Collections.Generic;
using Sirenix.OdinInspector;
using Spine;
using Spine.Unity;
using UnityEngine; using UnityEngine;
using AnimationState = Spine.AnimationState;
namespace DDD namespace DDD
{ {
public class RestaurantCharacterAnimation : MonoBehaviour public class RestaurantCharacterAnimation : MonoBehaviour
{ {
// Variables
#region Variables
private SkeletonAnimation _skeletonAnimation;
[SerializeField, ReadOnly]
private Material _originalMaterial;
[SerializeField]
private Material _replacementMaterial;
private AnimationState _animationState;
// Variables
[SerializeField]
private bool _isSkinSet = true;
[SerializeField, ShowIf("@_isSkinSet && !_isRandomSkin")]
private string _initialSkinName = "default";
[SerializeField, ShowIf("@_isSkinSet")]
private bool _isRandomSkin;
[SerializeField, ShowIf("@_isSkinSet && _isRandomSkin")]
private bool _isRandomRange;
[SerializeField, ShowIf("@_isSkinSet && _isRandomSkin && _isRandomRange"), Tooltip("x <= 값 < y")]
private Vector2 _randomRange;
[SerializeField, ShowIf("@_isSkinSet && _isRandomSkin && !_isRandomRange")]
private List<string> _randomStrings;
private bool _customMaterialEnabled;
#endregion
// Unity events
#region Unity events
private void Reset()
{
InitializeComponents();
}
private void Awake()
{
InitializeComponents();
if (!_isSkinSet) return;
if (_isRandomSkin)
{
if (_isRandomRange)
{
SetRandomSkin();
}
else
{
SetRandomStringListSkin();
}
}
else
{
SetSkin(_initialSkinName);
}
}
#endregion
// Initialize methods
#region Initialize methods
private void InitializeComponents()
{
_skeletonAnimation = transform.GetComponentInChildren<SkeletonAnimation>();
if (!_originalMaterial)
{
_originalMaterial = _skeletonAnimation.SkeletonDataAsset.atlasAssets[0].PrimaryMaterial;
}
_animationState = _skeletonAnimation.AnimationState;
}
#endregion
// Methods
#region Methods
/// <param name="animationName">스파인 애니메이션 이름</param>
/// <param name="isLoopActive">반복 여부</param>
/// <param name="speed">애니메이션 속도 양수값</param>
/// <param name="isReverse">true인 경우 자동으로 speed에 음수값(-1)을 넣음</param>
/// <param name="trackIndex"></param>
/// <returns></returns>
public TrackEntry PlayAnimation(string animationName, bool isLoopActive, float speed = 1f, bool isReverse = false, int trackIndex = 0)
{
if (!_skeletonAnimation || _animationState == null) return null;
if (string.IsNullOrEmpty(animationName))
{
Debug.LogError($"{animationName}의 애니메이션은 존재하지 않습니다.");
return null;
}
// 중복 체크
var currentTrackEntry = _animationState.GetCurrent(trackIndex);
if (currentTrackEntry != null && currentTrackEntry.Animation.Name == animationName)
{
return currentTrackEntry;
}
_animationState.TimeScale = isReverse ? -Mathf.Abs(speed) : Mathf.Abs(speed);
var trackEntry = _animationState.SetAnimation(trackIndex, animationName, isLoopActive);
if (isReverse)
{
trackEntry.TrackTime = trackEntry.AnimationEnd;
}
return trackEntry;
}
public TrackEntry PlayAnimationDuration(string animationName, bool isLoopActive, float duration, bool isReverse = false, int trackIndex = 0)
{
if (!_skeletonAnimation || _animationState == null) return null;
if (string.IsNullOrEmpty(animationName))
{
Debug.LogError($"{animationName}의 애니메이션은 존재하지 않습니다.");
return null;
}
// 중복 체크
var currentTrackEntry = _animationState.GetCurrent(trackIndex);
if (currentTrackEntry != null && currentTrackEntry.Animation.Name == animationName)
{
return currentTrackEntry;
}
var findAnimation = _skeletonAnimation.Skeleton.Data.FindAnimation(animationName);
if (findAnimation == null)
{
Debug.LogError($"{animationName} 애니메이션을 찾을 수 없습니다.");
return null;
}
var speed = findAnimation.Duration / duration;
_animationState.TimeScale = isReverse ? -Mathf.Abs(speed) : Mathf.Abs(speed);
var trackEntry = _animationState.SetAnimation(trackIndex, animationName, isLoopActive);
if (isReverse)
{
trackEntry.TrackTime = trackEntry.AnimationEnd;
}
return trackEntry;
}
public TrackEntry AddAnimation(string animationName, bool isLoopActive, int trackIndex = 0)
{
if (!_skeletonAnimation || _animationState == null) return null;
if (string.IsNullOrEmpty(animationName))
{
Debug.LogError($"{animationName} 애니메이션은 존재하지 않습니다.");
return null;
}
var trackEntry = _animationState.AddAnimation(trackIndex, animationName, isLoopActive, 0);
return trackEntry;
}
public string GetCurrentSkin()
{
if (_skeletonAnimation == null) return null;
return _skeletonAnimation.Skeleton.Skin.ToString();
}
public void SetSkin(string skinName)
{
if (_skeletonAnimation == null && _animationState == null) return;
if (string.IsNullOrEmpty(skinName))
{
Debug.LogError($"{skinName}의 스킨 이름은 존재하지 않습니다.");
return;
}
_skeletonAnimation.Skeleton.SetSkin(skinName);
_skeletonAnimation.Skeleton.SetSlotsToSetupPose();
_animationState.Apply(_skeletonAnimation.Skeleton);
}
public void SetRandomSkin()
{
if (_skeletonAnimation == null || _skeletonAnimation.Skeleton == null) return;
var skins = _skeletonAnimation.skeleton.Data.Skins;
var randomSkin = Random.Range((int)_randomRange.x, (int)_randomRange.y);
var randomSkinName = skins.Items[randomSkin].Name;
SetSkin(randomSkinName);
}
public void SetRandomStringListSkin()
{
if (_skeletonAnimation == null || _skeletonAnimation.Skeleton == null) return;
if (_randomStrings == null || _randomStrings.Count <= 0)
{
Debug.LogError("_randomStrings 설정 오류");
return;
}
var randomSkin = Random.Range(0, _randomStrings.Count);
var randomSkinName = _randomStrings[randomSkin];
SetSkin(randomSkinName);
}
public void EnableCustomMaterial()
{
if (_customMaterialEnabled) return;
_skeletonAnimation.CustomMaterialOverride[_originalMaterial] = _replacementMaterial;
_customMaterialEnabled = true;
}
public void DisableCustomMaterial()
{
if (!_customMaterialEnabled) return;
_skeletonAnimation.CustomMaterialOverride.Remove(_originalMaterial);
_customMaterialEnabled = false;
}
public bool IsAnimationComplete(int trackIndex = 0)
{
if (!_skeletonAnimation || _animationState == null) return false;
var currentTrackEntry = _animationState.GetCurrent(trackIndex);
if (currentTrackEntry == null)
{
Debug.LogWarning($"트랙 {trackIndex}에서 재생 중인 애니메이션이 없습니다.");
return false;
}
return currentTrackEntry.IsComplete;
}
#endregion
} }
} }

View File

@ -1,11 +1,150 @@
using System;
using System.Collections;
using UnityEngine; using UnityEngine;
using UnityEngine.InputSystem;
namespace DDD namespace DDD
{ {
public class RestaurantPlayerMovement : RestaurantCharacterMovement public class RestaurantPlayerMovement : RestaurantCharacterMovement
{ {
// TODO : TryMove // 인풋에 등록할 함수 private Rigidbody _rigidbody;
// TODO : CanMove // Check IMovementConstraint private RestaurantCharacterAnimation _animation;
// TODO : Move // 실제 트랜스레이션, 슬라이딩, 충돌 private Transform _visualLook;
private RestaurantPlayerDataSo _playerData;
private Vector3 _inputDirection;
private Vector3 _currentDirection;
private bool _isMoving;
private bool _isDashing;
private bool _isDashCooldown;
private bool _isInitialized;
private void Awake()
{
_rigidbody = GetComponent<Rigidbody>();
_animation = GetComponent<RestaurantCharacterAnimation>();
_visualLook = transform.Find("VisualLook");

리터럴 제거 바랍니다. 다른 방식으로 얻을 수 없을까요?

리터럴 제거 바랍니다. 다른 방식으로 얻을 수 없을까요?
}
private async void Start()
{
try
{
_playerData = await AssetManager.LoadAsset<RestaurantPlayerDataSo>("RestaurantPlayerDataSo");

리터럴 제거

리터럴 제거
_playerData.MoveActionReference.action.performed += OnMove;
_playerData.MoveActionReference.action.canceled += OnMove;
_playerData.DashActionReference.action.performed += OnDash;
_isInitialized = true;
}
catch (Exception e)
{
Debug.LogError($"_playerData load failed\n{e}");
}
}
private void Update()
{
if (_isInitialized == false) return;
FlipVisualLook();
}
private void FixedUpdate()
{
if (_isInitialized == false) return;
if (CanMove())
{
Move();
}
}
private void OnDestroy()
{
if (_playerData)
{
_playerData.MoveActionReference.action.performed -= OnMove;
_playerData.MoveActionReference.action.canceled -= OnMove;
_playerData.DashActionReference.action.performed -= OnDash;
}
}
public void SetCurrentDirection(Vector3 normalDirection)
{
if (_inputDirection == Vector3.zero) return;
_currentDirection = normalDirection;
}
private void FlipVisualLook()
Review

무브먼트에서 다뤄야할 영역이 아님.
다른 컴포넌트로 이관 필요.

무브먼트에서 다뤄야할 영역이 아님. 다른 컴포넌트로 이관 필요.
{
Vector3 localScale = _visualLook.localScale;
localScale.x = _currentDirection.x switch
{
> 0.01f => -Mathf.Abs(localScale.x),
< -0.01f => Mathf.Abs(localScale.x),
_ => localScale.x
};
_visualLook.localScale = localScale;
}
private void OnMove(InputAction.CallbackContext context)
{
Vector2 movementInput = context.ReadValue<Vector2>();
_inputDirection = new Vector3(movementInput.x, 0f, movementInput.y);
}
private bool CanMove()
{
return _playerData.IsMoveEnabled && _isDashing == false;
}
private void Move()
{
SetCurrentDirection(_inputDirection);
_isMoving = _inputDirection != Vector3.zero;
string animationName = _isMoving ? "RunFast" : "Idle";

애니메이션 재생 역시 무브먼트의 소관이 아님.
애니메이션 컴포넌트로 이동해야할듯합니다.

애니메이션 재생 역시 무브먼트의 소관이 아님. 애니메이션 컴포넌트로 이동해야할듯합니다.
_animation.PlayAnimation(animationName, true);
Vector3 finalVelocity = _inputDirection * _playerData.MoveSpeed;
_rigidbody.linearVelocity = finalVelocity;
}
private void OnDash(InputAction.CallbackContext context)
{
if (CanDash())
{
StartCoroutine(DashCoroutine());
}
}
private bool CanDash()
{
return _playerData.IsDashEnabled && _isDashing == false && _isDashCooldown == false;
}
private IEnumerator DashCoroutine()
{
// TODO : ui생기면 연동
_isDashing = true;
_isDashCooldown = true;
_animation.PlayAnimationDuration("Dash", false, _playerData.DashTime);

애니메이션 제거. OnDashStarted나 IsDashing 등으로 처리할 것.

애니메이션 제거. OnDashStarted나 IsDashing 등으로 처리할 것.
Vector3 dashVelocity = _currentDirection.normalized * _playerData.DashSpeed;
_rigidbody.linearVelocity = dashVelocity;
yield return new WaitForSeconds(_playerData.DashTime);
_isDashing = false;
yield return new WaitForSeconds(_playerData.DashCooldown);
_isDashCooldown = false;
}
} }
} }

View File

@ -1,265 +0,0 @@
using System.Collections.Generic;
using Sirenix.OdinInspector;
using Spine;
using Spine.Unity;
using UnityEngine;
using AnimationState = Spine.AnimationState;
using Random = UnityEngine.Random;
namespace DDD
{
public class SpineController : MonoBehaviour
{
// Variables
#region Variables
private SkeletonAnimation _skeletonAnimation;
[SerializeField, ReadOnly]
private Material _originalMaterial;
[SerializeField]
private Material _replacementMaterial;
private AnimationState _animationState;
// Variables
[SerializeField]
private bool _isSkinSet = true;
[SerializeField, ShowIf("@_isSkinSet && !_isRandomSkin")]
private string _initialSkinName = "default";
[SerializeField, ShowIf("@_isSkinSet")]
private bool _isRandomSkin;
[SerializeField, ShowIf("@_isSkinSet && _isRandomSkin")]
private bool _isRandomRange;
[SerializeField, ShowIf("@_isSkinSet && _isRandomSkin && _isRandomRange"), Tooltip("x <= 값 < y")]
private Vector2 _randomRange;
[SerializeField, ShowIf("@_isSkinSet && _isRandomSkin && !_isRandomRange")]
private List<string> _randomStrings;
private bool _customMaterialEnabled;
#endregion
// Unity events
#region Unity events
private void Reset()
{
InitializeComponents();
}
private void Awake()
{
InitializeComponents();
if (!_isSkinSet) return;
if (_isRandomSkin)
{
if (_isRandomRange)
{
SetRandomSkin();
}
else
{
SetRandomStringListSkin();
}
}
else
{
SetSkin(_initialSkinName);
}
}
#endregion
// Initialize methods
#region Initialize methods
private void InitializeComponents()
{
_skeletonAnimation = transform.GetComponentInChildren<SkeletonAnimation>();
if (!_originalMaterial)
{
_originalMaterial = _skeletonAnimation.SkeletonDataAsset.atlasAssets[0].PrimaryMaterial;
}
_animationState = _skeletonAnimation.AnimationState;
}
#endregion
// Methods
#region Methods
/// <param name="animationName">스파인 애니메이션 이름</param>
/// <param name="isLoopActive">반복 여부</param>
/// <param name="speed">애니메이션 속도 양수값</param>
/// <param name="isReverse">true인 경우 자동으로 speed에 음수값(-1)을 넣음</param>
/// <param name="trackIndex"></param>
/// <returns></returns>
public TrackEntry PlayAnimation(string animationName, bool isLoopActive, float speed = 1f, bool isReverse = false, int trackIndex = 0)
{
if (!_skeletonAnimation || _animationState == null) return null;
if (string.IsNullOrEmpty(animationName))
{
Debug.LogError($"{animationName}의 애니메이션은 존재하지 않습니다.");
return null;
}
// 중복 체크
var currentTrackEntry = _animationState.GetCurrent(trackIndex);
if (currentTrackEntry != null && currentTrackEntry.Animation.Name == animationName)
{
return currentTrackEntry;
}
_animationState.TimeScale = isReverse ? -Mathf.Abs(speed) : Mathf.Abs(speed);
var trackEntry = _animationState.SetAnimation(trackIndex, animationName, isLoopActive);
if (isReverse)
{
trackEntry.TrackTime = trackEntry.AnimationEnd;
}
return trackEntry;
}
public TrackEntry PlayAnimationDuration(string animationName, bool isLoopActive, float duration, bool isReverse = false, int trackIndex = 0)
{
if (!_skeletonAnimation || _animationState == null) return null;
if (string.IsNullOrEmpty(animationName))
{
Debug.LogError($"{animationName}의 애니메이션은 존재하지 않습니다.");
return null;
}
// 중복 체크
var currentTrackEntry = _animationState.GetCurrent(trackIndex);
if (currentTrackEntry != null && currentTrackEntry.Animation.Name == animationName)
{
return currentTrackEntry;
}
var findAnimation = _skeletonAnimation.Skeleton.Data.FindAnimation(animationName);
if (findAnimation == null)
{
Debug.LogError($"{animationName} 애니메이션을 찾을 수 없습니다.");
return null;
}
var speed = findAnimation.Duration / duration;
_animationState.TimeScale = isReverse ? -Mathf.Abs(speed) : Mathf.Abs(speed);
var trackEntry = _animationState.SetAnimation(trackIndex, animationName, isLoopActive);
if (isReverse)
{
trackEntry.TrackTime = trackEntry.AnimationEnd;
}
return trackEntry;
}
public TrackEntry AddAnimation(string animationName, bool isLoopActive, int trackIndex = 0)
{
if (!_skeletonAnimation || _animationState == null) return null;
if (string.IsNullOrEmpty(animationName))
{
Debug.LogError($"{animationName} 애니메이션은 존재하지 않습니다.");
return null;
}
var trackEntry = _animationState.AddAnimation(trackIndex, animationName, isLoopActive, 0);
return trackEntry;
}
public string GetCurrentSkin()
{
if (_skeletonAnimation == null) return null;
return _skeletonAnimation.Skeleton.Skin.ToString();
}
public void SetSkin(string skinName)
{
if (_skeletonAnimation == null && _animationState == null) return;
if (string.IsNullOrEmpty(skinName))
{
Debug.LogError($"{skinName}의 스킨 이름은 존재하지 않습니다.");
return;
}
_skeletonAnimation.Skeleton.SetSkin(skinName);
_skeletonAnimation.Skeleton.SetSlotsToSetupPose();
_animationState.Apply(_skeletonAnimation.Skeleton);
}
public void SetRandomSkin()
{
if (_skeletonAnimation == null || _skeletonAnimation.Skeleton == null) return;
var skins = _skeletonAnimation.skeleton.Data.Skins;
var randomSkin = Random.Range((int)_randomRange.x, (int)_randomRange.y);
var randomSkinName = skins.Items[randomSkin].Name;
SetSkin(randomSkinName);
}
public void SetRandomStringListSkin()
{
if (_skeletonAnimation == null || _skeletonAnimation.Skeleton == null) return;
if (_randomStrings == null || _randomStrings.Count <= 0)
{
Debug.LogError("_randomStrings 설정 오류");
return;
}
var randomSkin = Random.Range(0, _randomStrings.Count);
var randomSkinName = _randomStrings[randomSkin];
SetSkin(randomSkinName);
}
public void EnableCustomMaterial()
{
if (_customMaterialEnabled) return;
_skeletonAnimation.CustomMaterialOverride[_originalMaterial] = _replacementMaterial;
_customMaterialEnabled = true;
}
public void DisableCustomMaterial()
{
if (!_customMaterialEnabled) return;
_skeletonAnimation.CustomMaterialOverride.Remove(_originalMaterial);
_customMaterialEnabled = false;
}
public bool IsAnimationComplete(int trackIndex = 0)
{
if (!_skeletonAnimation || _animationState == null) return false;
var currentTrackEntry = _animationState.GetCurrent(trackIndex);
if (currentTrackEntry == null)
{
Debug.LogWarning($"트랙 {trackIndex}에서 재생 중인 애니메이션이 없습니다.");
return false;
}
return currentTrackEntry.IsComplete;
}
#endregion
}
}

View File

@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: 06e836de83eb924449235839869a147c