camera_system #5
264
Assets/_DDD/_Scripts/GameCharacter/SpineController.cs
Normal file
264
Assets/_DDD/_Scripts/GameCharacter/SpineController.cs
Normal file
@ -0,0 +1,264 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using Sirenix.OdinInspector;
|
||||||
|
using Spine;
|
||||||
|
using Spine.Unity;
|
||||||
|
using UnityEngine;
|
||||||
|
using AnimationState = Spine.AnimationState;
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 6d7e5480ae1ebf54b8537ad2a08696d2
|
@ -1,264 +1,27 @@
|
|||||||
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
|
private RestaurantPlayerMovement _restaurantPlayerMovement;
|
||||||
#region Variables
|
private SpineController _spineController;
|
||||||
|
|
||||||
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()
|
private void Awake()
|
||||||
{
|
{
|
||||||
InitializeComponents();
|
_restaurantPlayerMovement = GetComponent<RestaurantPlayerMovement>();
|
||||||
|
_spineController = GetComponent<SpineController>();
|
||||||
if (!_isSkinSet) return;
|
|
||||||
|
|
||||||
if (_isRandomSkin)
|
|
||||||
{
|
|
||||||
if (_isRandomRange)
|
|
||||||
{
|
|
||||||
SetRandomSkin();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SetRandomStringListSkin();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SetSkin(_initialSkinName);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
private void OnMove(bool isMoving)
|
||||||
|
|
||||||
// Initialize methods
|
|
||||||
#region Initialize methods
|
|
||||||
|
|
||||||
private void InitializeComponents()
|
|
||||||
{
|
{
|
||||||
_skeletonAnimation = transform.GetComponentInChildren<SkeletonAnimation>();
|
string animationName = isMoving ? RestaurantPlayerAnimation.Walk : RestaurantPlayerAnimation.Idle;
|
||||||
if (!_originalMaterial)
|
_spineController.PlayAnimation(animationName, true);
|
||||||
{
|
|
||||||
_originalMaterial = _skeletonAnimation.SkeletonDataAsset.atlasAssets[0].PrimaryMaterial;
|
|
||||||
}
|
|
||||||
|
|
||||||
_animationState = _skeletonAnimation.AnimationState;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
private void OnDash(float dashTime)
|
||||||
|
|
||||||
// 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;
|
_spineController.PlayAnimationDuration(RestaurantPlayerAnimation.Dash, false, duration:dashTime);
|
||||||
|
|
||||||
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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -4,6 +4,32 @@ namespace DDD
|
|||||||
{
|
{
|
||||||
public class RestaurantPlayerCharacter : RestaurantCharacter
|
public class RestaurantPlayerCharacter : RestaurantCharacter
|
||||||
{
|
{
|
||||||
|
private RestaurantPlayerMovement _movement;
|
||||||
|
|
||||||
|
private Transform _visualLook;
|
||||||
|
|
||||||
|
private void Awake()
|
||||||
|
{
|
||||||
|
_movement = GetComponent<RestaurantPlayerMovement>();
|
||||||
|
|
||||||
|
_visualLook = transform.Find(CommonConstants.VisualLook);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Update()
|
||||||
|
{
|
||||||
|
FlipVisualLook();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void FlipVisualLook()
|
||||||
|
{
|
||||||
|
Vector3 localScale = _visualLook.localScale;
|
||||||
|
localScale.x = _movement.GetCurrentDirection().x switch
|
||||||
|
{
|
||||||
|
> 0.01f => -Mathf.Abs(localScale.x),
|
||||||
|
< -0.01f => Mathf.Abs(localScale.x),
|
||||||
|
_ => localScale.x
|
||||||
|
};
|
||||||
|
_visualLook.localScale = localScale;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -8,8 +8,6 @@ namespace DDD
|
|||||||
public class RestaurantPlayerMovement : RestaurantCharacterMovement
|
public class RestaurantPlayerMovement : RestaurantCharacterMovement
|
||||||
{
|
{
|
||||||
private Rigidbody _rigidbody;
|
private Rigidbody _rigidbody;
|
||||||
private RestaurantCharacterAnimation _animation;
|
|
||||||
private Transform _visualLook;
|
|
||||||
|
|
||||||
private RestaurantPlayerDataSo _playerData;
|
private RestaurantPlayerDataSo _playerData;
|
||||||
|
|
||||||
@ -20,11 +18,12 @@ public class RestaurantPlayerMovement : RestaurantCharacterMovement
|
|||||||
private bool _isDashCooldown;
|
private bool _isDashCooldown;
|
||||||
private bool _isInitialized;
|
private bool _isInitialized;
|
||||||
|
|
||||||
|
public Action<bool> OnMoving;
|
||||||
|
public Action<float> OnDashing;
|
||||||
|
|
||||||
private void Awake()
|
private void Awake()
|
||||||
{
|
{
|
||||||
_rigidbody = GetComponent<Rigidbody>();
|
_rigidbody = GetComponent<Rigidbody>();
|
||||||
_animation = GetComponent<RestaurantCharacterAnimation>();
|
|
||||||
_visualLook = transform.Find(CommonConstants.VisualLook);
|
|
||||||
}
|
}
|
||||||
|
|||||||
|
|
||||||
private async void Start()
|
private async void Start()
|
||||||
@ -45,13 +44,6 @@ private async void Start()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Update()
|
|
||||||
{
|
|
||||||
if (_isInitialized == false) return;
|
|
||||||
|
|
||||||
FlipVisualLook();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void FixedUpdate()
|
private void FixedUpdate()
|
||||||
{
|
{
|
||||||
if (_isInitialized == false) return;
|
if (_isInitialized == false) return;
|
||||||
@ -79,18 +71,6 @@ public void SetCurrentDirection(Vector3 normalDirection)
|
|||||||
_currentDirection = normalDirection;
|
_currentDirection = normalDirection;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void FlipVisualLook()
|
|
||||||
{
|
|
||||||
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)
|
private void OnMove(InputAction.CallbackContext context)
|
||||||
{
|
{
|
||||||
Vector2 movementInput = context.ReadValue<Vector2>();
|
Vector2 movementInput = context.ReadValue<Vector2>();
|
||||||
@ -107,8 +87,7 @@ private void Move()
|
|||||||
SetCurrentDirection(_inputDirection);
|
SetCurrentDirection(_inputDirection);
|
||||||
|
|
||||||
_isMoving = _inputDirection != Vector3.zero;
|
_isMoving = _inputDirection != Vector3.zero;
|
||||||
string animationName = _isMoving ? RestaurantPlayerAnimation.Walk : RestaurantPlayerAnimation.Idle;
|
OnMoving?.Invoke(_isMoving);
|
||||||
_animation.PlayAnimation(animationName, true);
|
|
||||||
|
|
||||||
Vector3 finalVelocity = _inputDirection * _playerData.MoveSpeed;
|
Vector3 finalVelocity = _inputDirection * _playerData.MoveSpeed;
|
||||||
_rigidbody.linearVelocity = finalVelocity;
|
_rigidbody.linearVelocity = finalVelocity;
|
||||||
@ -129,12 +108,10 @@ private bool CanDash()
|
|||||||
|
|
||||||
private IEnumerator DashCoroutine()
|
private IEnumerator DashCoroutine()
|
||||||
{
|
{
|
||||||
Jeonghyeon
commented
애니메이션 재생 역시 무브먼트의 소관이 아님. 애니메이션 재생 역시 무브먼트의 소관이 아님.
애니메이션 컴포넌트로 이동해야할듯합니다.
|
|||||||
// TODO : ui생기면 연동
|
|
||||||
|
|
||||||
_isDashing = true;
|
_isDashing = true;
|
||||||
_isDashCooldown = true;
|
_isDashCooldown = true;
|
||||||
|
|
||||||
_animation.PlayAnimationDuration(RestaurantPlayerAnimation.Dash, false, _playerData.DashTime);
|
OnDashing?.Invoke(_playerData.DashTime);
|
||||||
|
|
||||||
Vector3 dashVelocity = _currentDirection.normalized * _playerData.DashSpeed;
|
Vector3 dashVelocity = _currentDirection.normalized * _playerData.DashSpeed;
|
||||||
_rigidbody.linearVelocity = dashVelocity;
|
_rigidbody.linearVelocity = dashVelocity;
|
||||||
@ -146,5 +123,7 @@ private IEnumerator DashCoroutine()
|
|||||||
yield return new WaitForSeconds(_playerData.DashCooldown);
|
yield return new WaitForSeconds(_playerData.DashCooldown);
|
||||||
_isDashCooldown = false;
|
_isDashCooldown = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Vector3 GetCurrentDirection() => _currentDirection;
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user
리터럴 제거 바랍니다. 다른 방식으로 얻을 수 없을까요?