#165 전투 플레이어 스크립트 분리 및 로직 수정
+ 메인 컨트롤러(CombatPlayerController) 와 움직임 컨트롤러(PhysicsMovement)로 기능 분할 + rigidbody를 이용한 움직임으로 전체 로직 수정 + Dash 애니메이션 변경 + Dash, Attack 공격 속도에 따라서 애니메이션 동기화 + 03.CombatTest Scene 에셋 맵 전체 수정(Layer, Collider 등)
This commit is contained in:
parent
0dfe61b81a
commit
419259c5f4
File diff suppressed because it is too large
Load Diff
@ -1,337 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections;
|
|
||||||
using Sirenix.OdinInspector;
|
|
||||||
using UnityEngine;
|
|
||||||
using UnityEngine.InputSystem;
|
|
||||||
using UnityEngine.Serialization;
|
|
||||||
|
|
||||||
// ReSharper disable once CheckNamespace
|
|
||||||
namespace BlueWaterProject
|
|
||||||
{
|
|
||||||
public class CombatPlayer : MonoBehaviour, IDamageable
|
|
||||||
{
|
|
||||||
[Title("초기화 방식")]
|
|
||||||
[SerializeField] private bool autoInit = true;
|
|
||||||
|
|
||||||
[Title("캐릭터 변수")]
|
|
||||||
[SerializeField] private float maxHp = 100f;
|
|
||||||
[SerializeField] private float currentHp;
|
|
||||||
[SerializeField] private float moveSpeed = 5f;
|
|
||||||
[SerializeField] private float maxSlopeAngle = 50f;
|
|
||||||
|
|
||||||
[field: Title("대쉬")]
|
|
||||||
[field: SerializeField] public float DashForce { get; set; } = 20f;
|
|
||||||
[field: SerializeField] public float DashCooldown { get; set; } = 0.5f;
|
|
||||||
[field: DisableIf("@true")]
|
|
||||||
[field: SerializeField] public bool IsDashing { get; set; }
|
|
||||||
[field: DisableIf("@true")]
|
|
||||||
[field: SerializeField] public bool EnableDash { get; set; } = true;
|
|
||||||
|
|
||||||
[field: Title("공격")]
|
|
||||||
[field: SerializeField] public int MaxHitNum { get; set; } = 10;
|
|
||||||
[field: SerializeField] public float AttackDamage { get; set; } = 10f;
|
|
||||||
[field: SerializeField] public float AttackRange { get; set; } = 1.5f;
|
|
||||||
[field: SerializeField] public float AttackAngle { get; set; } = 180f;
|
|
||||||
[field: SerializeField] public float ComboTime { get; set; } = 0.5f;
|
|
||||||
[field: SerializeField] public LayerMask TargetLayer { get; set; }
|
|
||||||
[field: DisableIf("@true")]
|
|
||||||
[field: SerializeField] public bool IsAttacking { get; set; }
|
|
||||||
[field: DisableIf("@true")]
|
|
||||||
[field: SerializeField] public bool IsComboAttacking { get; set; }
|
|
||||||
[field: DisableIf("@true")]
|
|
||||||
[field: SerializeField] public bool IsComboPossible { get; set; }
|
|
||||||
|
|
||||||
[Title("컴포넌트")]
|
|
||||||
[SerializeField] private PlayerInput playerInput;
|
|
||||||
[field: SerializeField] public Rigidbody Rb { get; set; }
|
|
||||||
[SerializeField] private Transform visualLook;
|
|
||||||
[field: SerializeField] public Animator Animator { get; set; }
|
|
||||||
[SerializeField] private Transform groundCheck;
|
|
||||||
|
|
||||||
[Title("Extensions Data")]
|
|
||||||
[SerializeField] private float nextFrameCoefficient = 3f;
|
|
||||||
|
|
||||||
private Vector2 movementInput;
|
|
||||||
private Vector3 currentDirection = Vector3.back;
|
|
||||||
public Vector3 PreviousDirection { get; set; } = Vector3.back;
|
|
||||||
[field: SerializeField] public Collider[] HitColliders { get; set; }
|
|
||||||
private RaycastHit slopeHit;
|
|
||||||
private int groundLayer;
|
|
||||||
private bool isOnSlope;
|
|
||||||
private bool isGrounded;
|
|
||||||
|
|
||||||
private const float RAY_DISTANCE = 3f;
|
|
||||||
|
|
||||||
private static readonly int XDirectionHash = Animator.StringToHash("xDirection");
|
|
||||||
private static readonly int ZDirectionHash = Animator.StringToHash("zDirection");
|
|
||||||
private static readonly int IsMovingHash = Animator.StringToHash("isMoving");
|
|
||||||
public readonly int isDashingHash = Animator.StringToHash("isDashing");
|
|
||||||
public readonly int isAttackingHash = Animator.StringToHash("isAttacking");
|
|
||||||
|
|
||||||
private void OnDrawGizmosSelected()
|
|
||||||
{
|
|
||||||
var lossyScale = transform.lossyScale;
|
|
||||||
var boxSize = new Vector3(lossyScale.x, 0.4f, lossyScale.z * 0.5f);
|
|
||||||
Gizmos.color = IsGrounded() ? Color.blue : Color.red;
|
|
||||||
Gizmos.DrawWireCube(groundCheck.position, boxSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Button("셋팅 초기화")]
|
|
||||||
private void Init()
|
|
||||||
{
|
|
||||||
playerInput = GetComponent<PlayerInput>();
|
|
||||||
Rb = GetComponent<Rigidbody>();
|
|
||||||
visualLook = transform.Find("VisualLook");
|
|
||||||
Animator = visualLook.GetComponent<Animator>();
|
|
||||||
groundCheck = transform.Find("GroundCheck");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Awake()
|
|
||||||
{
|
|
||||||
if (autoInit)
|
|
||||||
{
|
|
||||||
Init();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Start()
|
|
||||||
{
|
|
||||||
HitColliders = new Collider[MaxHitNum];
|
|
||||||
groundLayer = 1 << LayerMask.NameToLayer("Ground");
|
|
||||||
|
|
||||||
SetCurrentHp(maxHp);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnEnable()
|
|
||||||
{
|
|
||||||
playerInput.actions.FindAction("Attack").performed += OnAttackEvent;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnDisable()
|
|
||||||
{
|
|
||||||
playerInput.actions.FindAction("Attack").performed -= OnAttackEvent;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Update()
|
|
||||||
{
|
|
||||||
var isMoving = currentDirection.magnitude > 0.01f;
|
|
||||||
if (isMoving)
|
|
||||||
{
|
|
||||||
PreviousDirection = currentDirection.normalized;
|
|
||||||
Animator.SetFloat(XDirectionHash, PreviousDirection.x);
|
|
||||||
Animator.SetFloat(ZDirectionHash, PreviousDirection.z);
|
|
||||||
}
|
|
||||||
Animator.SetBool(IsMovingHash, isMoving);
|
|
||||||
|
|
||||||
var localScale = visualLook.localScale;
|
|
||||||
localScale.x = PreviousDirection.x switch
|
|
||||||
{
|
|
||||||
> 0.01f => Mathf.Abs(localScale.x),
|
|
||||||
< -0.01f => -Mathf.Abs(localScale.x),
|
|
||||||
_ => localScale.x
|
|
||||||
};
|
|
||||||
visualLook.localScale = localScale;
|
|
||||||
|
|
||||||
isOnSlope = IsOnSlope();
|
|
||||||
isGrounded = IsGrounded();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void FixedUpdate()
|
|
||||||
{
|
|
||||||
HandleMovement();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void TakeDamage(float attackerPower, Vector3? attackPos = null)
|
|
||||||
{
|
|
||||||
if (IsDashing) return;
|
|
||||||
|
|
||||||
var changeHp = Mathf.Max(currentHp - attackerPower, 0);
|
|
||||||
SetCurrentHp(changeHp);
|
|
||||||
|
|
||||||
if (InIslandCamera.Inst.InIslandCam)
|
|
||||||
{
|
|
||||||
VisualFeedbackManager.Inst.CameraShake(InIslandCamera.Inst.InIslandCam);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 죽었는지 체크
|
|
||||||
if (changeHp == 0f)
|
|
||||||
{
|
|
||||||
Die();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Die()
|
|
||||||
{
|
|
||||||
print("Combat Player Die");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnMove(InputValue value)
|
|
||||||
{
|
|
||||||
movementInput = value.Get<Vector2>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnDash()
|
|
||||||
{
|
|
||||||
if (!EnableDash || IsDashing) return;
|
|
||||||
|
|
||||||
Animator.SetBool(isDashingHash, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnAttackEvent(InputAction.CallbackContext context)
|
|
||||||
{
|
|
||||||
if (IsAttacking && !IsComboPossible) return;
|
|
||||||
|
|
||||||
// var control = context.control;
|
|
||||||
//
|
|
||||||
// if (control.name.Equals("leftButton"))
|
|
||||||
// {
|
|
||||||
// UseMouseAttack = true;
|
|
||||||
// }
|
|
||||||
// else if (control.name.Equals("k"))
|
|
||||||
// {
|
|
||||||
// UseMouseAttack = false;
|
|
||||||
// }
|
|
||||||
|
|
||||||
if (IsComboPossible)
|
|
||||||
{
|
|
||||||
IsComboAttacking = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Animator.SetBool(isAttackingHash, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void HandleMovement()
|
|
||||||
{
|
|
||||||
currentDirection = new Vector3(movementInput.x, 0, movementInput.y).normalized;
|
|
||||||
//var currentDirection = IsDashing ? PreviousDirection : currentMovement.normalized;
|
|
||||||
|
|
||||||
if (isOnSlope && isGrounded)
|
|
||||||
{
|
|
||||||
currentDirection = Vector3.ProjectOnPlane(currentDirection, slopeHit.normal).normalized;
|
|
||||||
}
|
|
||||||
|
|
||||||
var moveValue = IsDashing ? DashForce : moveSpeed;
|
|
||||||
var newPosition = Rb.position + currentDirection * (moveValue * Time.fixedDeltaTime);
|
|
||||||
|
|
||||||
Rb.MovePosition(newPosition);
|
|
||||||
|
|
||||||
// var currentMovement = new Vector3(movementInput.x, 0, movementInput.y);
|
|
||||||
// var currentDirection = IsDashing ? PreviousDirection : currentMovement.normalized;
|
|
||||||
// var isNextFrameInAngle = CalculateNextFrameGroundAngle(currentDirection) < maxSlopeAngle;
|
|
||||||
// var velocity = isNextFrameInAngle ? currentDirection : Vector3.zero;
|
|
||||||
// var gravity = Vector3.down * Mathf.Abs(Rb.velocity.y);
|
|
||||||
//
|
|
||||||
// if (IsOnSlope() && IsGrounded())
|
|
||||||
// {
|
|
||||||
// velocity = Vector3.ProjectOnPlane(currentDirection, slopeHit.normal).normalized;
|
|
||||||
// gravity = Vector3.zero;
|
|
||||||
// Rb.useGravity = false;
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// Rb.useGravity = true;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// var moveValue = IsDashing ? DashForce : moveSpeed;
|
|
||||||
// Rb.velocity = velocity * moveValue + gravity;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsOnSlope()
|
|
||||||
{
|
|
||||||
var ray = new Ray(transform.position, Vector3.down);
|
|
||||||
|
|
||||||
if (Physics.Raycast(ray, out slopeHit, RAY_DISTANCE, groundLayer))
|
|
||||||
{
|
|
||||||
var angle = Vector3.Angle(Vector3.up, slopeHit.normal);
|
|
||||||
Debug.DrawRay(transform.position, Vector3.down, angle != 0f && angle < maxSlopeAngle ? Color.blue : Color.red);
|
|
||||||
return angle != 0f && angle < maxSlopeAngle;
|
|
||||||
}
|
|
||||||
Debug.DrawRay(transform.position, Vector3.down, Color.red);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool IsGrounded()
|
|
||||||
{
|
|
||||||
var lossyScale = transform.lossyScale;
|
|
||||||
var boxSize = new Vector3(lossyScale.x, 0.4f, lossyScale.z * 0.5f);
|
|
||||||
return Physics.CheckBox(groundCheck.position, boxSize, Quaternion.identity, groundLayer);
|
|
||||||
}
|
|
||||||
|
|
||||||
private float CalculateNextFrameGroundAngle(Vector3 direction)
|
|
||||||
{
|
|
||||||
var nextFramePlayerPosition = transform.position + direction * (nextFrameCoefficient * moveSpeed * Time.fixedDeltaTime);
|
|
||||||
|
|
||||||
if (Physics.Raycast(nextFramePlayerPosition, Vector3.down, out var hitInfo, RAY_DISTANCE, groundLayer))
|
|
||||||
{
|
|
||||||
if (Vector3.Angle(Vector3.up, hitInfo.normal) > maxSlopeAngle)
|
|
||||||
{
|
|
||||||
Debug.DrawRay(hitInfo.point, hitInfo.normal, Color.red);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Debug.DrawRay(hitInfo.point, hitInfo.normal, Color.cyan);
|
|
||||||
}
|
|
||||||
Debug.DrawRay(nextFramePlayerPosition, Vector3.down, Color.green);
|
|
||||||
return Vector3.Angle(Vector3.up, hitInfo.normal);
|
|
||||||
}
|
|
||||||
Debug.DrawRay(nextFramePlayerPosition, Vector3.down, Color.magenta);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void AttackTiming()
|
|
||||||
{
|
|
||||||
var attackDirection = PreviousDirection;
|
|
||||||
|
|
||||||
Array.Clear(HitColliders, 0, MaxHitNum);
|
|
||||||
|
|
||||||
var size = Physics.OverlapSphereNonAlloc(transform.position, AttackRange, HitColliders, TargetLayer);
|
|
||||||
|
|
||||||
for (var i = 0; i < size; i++)
|
|
||||||
{
|
|
||||||
var targetDirection = (HitColliders[i].transform.position - transform.position).normalized;
|
|
||||||
var angleBetween = Vector3.Angle(attackDirection, targetDirection);
|
|
||||||
|
|
||||||
if (angleBetween >= AttackAngle * 0.5f) continue;
|
|
||||||
|
|
||||||
if (HitColliders[i].gameObject.layer == LayerMask.NameToLayer("Enemy"))
|
|
||||||
{
|
|
||||||
var iDamageable = HitColliders[i].transform.GetComponent<IDamageable>();
|
|
||||||
iDamageable.TakeDamage(AttackDamage);
|
|
||||||
VisualFeedbackManager.Inst.TriggerHitStop(0.1f);
|
|
||||||
}
|
|
||||||
else if (HitColliders[i].gameObject.layer == LayerMask.NameToLayer("Skill") &&
|
|
||||||
HitColliders[i].CompareTag("DestructiveSkill"))
|
|
||||||
{
|
|
||||||
var iDamageable = HitColliders[i].transform.GetComponent<IDamageable>();
|
|
||||||
iDamageable.TakeDamage(AttackDamage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void CoolDown(float waitTime, Action onCooldownComplete = null)
|
|
||||||
{
|
|
||||||
StartCoroutine(CoolDownCoroutine(waitTime, onCooldownComplete));
|
|
||||||
}
|
|
||||||
|
|
||||||
private IEnumerator CoolDownCoroutine(float waitTime, Action onCooldownComplete = null)
|
|
||||||
{
|
|
||||||
var time = 0f;
|
|
||||||
|
|
||||||
while (time <= waitTime)
|
|
||||||
{
|
|
||||||
time += Time.deltaTime;
|
|
||||||
yield return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
onCooldownComplete?.Invoke();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SetCurrentHp(float value)
|
|
||||||
{
|
|
||||||
currentHp = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public RaycastHit GetSlopeHit() => slopeHit;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,2 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 5258cddac7934c1469d147dddbdb5023
|
|
@ -5,23 +5,27 @@ namespace BlueWaterProject
|
|||||||
{
|
{
|
||||||
public class CombatPlayerAnimationEventController : MonoBehaviour
|
public class CombatPlayerAnimationEventController : MonoBehaviour
|
||||||
{
|
{
|
||||||
private CombatPlayer combatPlayer;
|
private CombatPlayerController combatPlayerController;
|
||||||
|
|
||||||
private void Awake()
|
private void Awake()
|
||||||
{
|
{
|
||||||
combatPlayer = GetComponentInParent<CombatPlayer>();
|
combatPlayerController = GetComponentInParent<CombatPlayerController>();
|
||||||
|
if (!combatPlayerController)
|
||||||
|
{
|
||||||
|
print("애니메이션 이벤트 컨트롤러가 없습니다.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CheckComboAttack()
|
public void CheckComboAttack()
|
||||||
{
|
{
|
||||||
if (combatPlayer.IsComboAttacking) return;
|
if (combatPlayerController.GetIsComboAttacking()) return;
|
||||||
|
|
||||||
combatPlayer.Animator.SetBool(combatPlayer.isAttackingHash, false);
|
combatPlayerController.MyComponents.animator.SetBool(CombatPlayerController.IsAttackingHash, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AttackTiming()
|
public void AttackTiming()
|
||||||
{
|
{
|
||||||
combatPlayer.AttackTiming();
|
combatPlayerController.AttackTiming();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -0,0 +1,298 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using Sirenix.OdinInspector;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.InputSystem;
|
||||||
|
|
||||||
|
// ReSharper disable once CheckNamespace
|
||||||
|
namespace BlueWaterProject
|
||||||
|
{
|
||||||
|
public class CombatPlayerController : MonoBehaviour, IDamageable
|
||||||
|
{
|
||||||
|
/***********************************************************************
|
||||||
|
* Definitions
|
||||||
|
***********************************************************************/
|
||||||
|
#region Class
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public class Components
|
||||||
|
{
|
||||||
|
public PlayerInput playerInput;
|
||||||
|
public Transform visualLook;
|
||||||
|
public Animator animator;
|
||||||
|
public PhysicsMovement movement;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public class CharacterOption
|
||||||
|
{
|
||||||
|
[Range(0f, 1000f), Tooltip("최대 체력")]
|
||||||
|
public float maxHp = 100f;
|
||||||
|
|
||||||
|
[Title("공격")]
|
||||||
|
[Range(1, 21), Tooltip("한 번에 공격 가능한 개체 수")]
|
||||||
|
public int maxHitNum = 10;
|
||||||
|
|
||||||
|
[Range(0f, 100f), Tooltip("공격 데미지")]
|
||||||
|
public float attackDamage = 10f;
|
||||||
|
|
||||||
|
[Range(0.1f, 2f), Tooltip("콤보 공격 포함 총 걸리는 시간")]
|
||||||
|
public float attackTime = 0.7f;
|
||||||
|
|
||||||
|
[Range(0.1f, 5f), Tooltip("공격 범위 사거리(반지름)")]
|
||||||
|
public float attackRange = 1.5f;
|
||||||
|
|
||||||
|
[Range(0f, 360f), Tooltip("공격 범위 각도")]
|
||||||
|
public float attackAngle = 180f;
|
||||||
|
|
||||||
|
[Tooltip("공격할 레이어 설정")]
|
||||||
|
public LayerMask targetLayer = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
[DisableIf("@true")]
|
||||||
|
public class CurrentState
|
||||||
|
{
|
||||||
|
public bool isAttacking;
|
||||||
|
public bool isComboPossible;
|
||||||
|
public bool isComboAttacking;
|
||||||
|
}
|
||||||
|
|
||||||
|
[DisableIf("@true")]
|
||||||
|
[Serializable]
|
||||||
|
public class CurrentValue
|
||||||
|
{
|
||||||
|
[Tooltip("현재 체력")]
|
||||||
|
public float currentHp;
|
||||||
|
|
||||||
|
[Tooltip("최근에 공격 받은 충돌체 배열")]
|
||||||
|
public Collider[] hitColliders;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* Variables
|
||||||
|
***********************************************************************/
|
||||||
|
#region Variables
|
||||||
|
|
||||||
|
[field: SerializeField] public Components MyComponents { get; private set; }
|
||||||
|
[field: SerializeField] public CharacterOption MyCharacterOption { get; private set; }
|
||||||
|
[field: SerializeField] public CurrentState MyCurrentState { get; set; }
|
||||||
|
[field: SerializeField] public CurrentValue MyCurrentValue { get; set; }
|
||||||
|
|
||||||
|
public static readonly int IsMovingHash = Animator.StringToHash("isMoving");
|
||||||
|
public static readonly int XDirectionHash = Animator.StringToHash("xDirection");
|
||||||
|
public static readonly int ZDirectionHash = Animator.StringToHash("zDirection");
|
||||||
|
public static readonly int IsAttackingHash = Animator.StringToHash("isAttacking");
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* Unity Events
|
||||||
|
***********************************************************************/
|
||||||
|
#region Unity Events
|
||||||
|
|
||||||
|
private void OnEnable()
|
||||||
|
{
|
||||||
|
MyComponents.playerInput.actions.FindAction("Attack").performed += OnAttackEvent;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnDisable()
|
||||||
|
{
|
||||||
|
MyComponents.playerInput.actions.FindAction("Attack").performed -= OnAttackEvent;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Start()
|
||||||
|
{
|
||||||
|
InitComponents();
|
||||||
|
InitStartValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Update()
|
||||||
|
{
|
||||||
|
MoveAnimation();
|
||||||
|
FlipVisualLook(MyComponents.movement.GetPreviousMoveDirection().x);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* Init Methods
|
||||||
|
***********************************************************************/
|
||||||
|
#region Unity Events
|
||||||
|
|
||||||
|
private void InitComponents()
|
||||||
|
{
|
||||||
|
if (!TryGetComponent(out MyComponents.movement))
|
||||||
|
{
|
||||||
|
MyComponents.movement = gameObject.AddComponent<PhysicsMovement>();
|
||||||
|
}
|
||||||
|
|
||||||
|
MyComponents.movement.SetAnimator(MyComponents.animator);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitStartValue()
|
||||||
|
{
|
||||||
|
MyCurrentValue.hitColliders = new Collider[MyCharacterOption.maxHitNum];
|
||||||
|
SetCurrentHp(MyCharacterOption.maxHp);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* Player Input
|
||||||
|
***********************************************************************/
|
||||||
|
#region Unity Events
|
||||||
|
|
||||||
|
private void OnAttackEvent(InputAction.CallbackContext context)
|
||||||
|
{
|
||||||
|
if (MyCurrentState.isAttacking && !MyCurrentState.isComboPossible) return;
|
||||||
|
|
||||||
|
// var control = context.control;
|
||||||
|
//
|
||||||
|
// if (control.name.Equals("leftButton"))
|
||||||
|
// {
|
||||||
|
// UseMouseAttack = true;
|
||||||
|
// }
|
||||||
|
// else if (control.name.Equals("k"))
|
||||||
|
// {
|
||||||
|
// UseMouseAttack = false;
|
||||||
|
// }
|
||||||
|
|
||||||
|
if (MyCurrentState.isComboPossible)
|
||||||
|
{
|
||||||
|
MyCurrentState.isComboAttacking = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
MyComponents.animator.SetBool(IsAttackingHash, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* Interfaces
|
||||||
|
***********************************************************************/
|
||||||
|
#region Interfaces
|
||||||
|
|
||||||
|
// IDamageable
|
||||||
|
public void TakeDamage(float attackerPower, Vector3? attackPos = null)
|
||||||
|
{
|
||||||
|
if (MyComponents.movement.GetIsDashing()) return;
|
||||||
|
|
||||||
|
var changeHp = Mathf.Max(MyCurrentValue.currentHp - attackerPower, 0);
|
||||||
|
SetCurrentHp(changeHp);
|
||||||
|
|
||||||
|
if (InIslandCamera.Inst.InIslandCam)
|
||||||
|
{
|
||||||
|
VisualFeedbackManager.Inst.CameraShake(InIslandCamera.Inst.InIslandCam);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 죽었는지 체크
|
||||||
|
if (changeHp == 0f)
|
||||||
|
{
|
||||||
|
Die();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Die()
|
||||||
|
{
|
||||||
|
print("Combat Player Die");
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* Methods
|
||||||
|
***********************************************************************/
|
||||||
|
#region Methods
|
||||||
|
|
||||||
|
public void AttackTiming()
|
||||||
|
{
|
||||||
|
var attackDirection = MyComponents.movement.GetPreviousMoveDirection();
|
||||||
|
|
||||||
|
Array.Clear(MyCurrentValue.hitColliders, 0, MyCharacterOption.maxHitNum);
|
||||||
|
|
||||||
|
var size = Physics.OverlapSphereNonAlloc(transform.position, MyCharacterOption.attackRange, MyCurrentValue.hitColliders, MyCharacterOption.targetLayer);
|
||||||
|
|
||||||
|
for (var i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
var targetDirection = (MyCurrentValue.hitColliders[i].transform.position - transform.position).normalized;
|
||||||
|
var angleBetween = Vector3.Angle(attackDirection, targetDirection);
|
||||||
|
|
||||||
|
if (angleBetween >= MyCharacterOption.attackAngle * 0.5f) continue;
|
||||||
|
|
||||||
|
if (MyCurrentValue.hitColliders[i].gameObject.layer == LayerMask.NameToLayer("Enemy"))
|
||||||
|
{
|
||||||
|
var iDamageable = MyCurrentValue.hitColliders[i].transform.GetComponent<IDamageable>();
|
||||||
|
iDamageable.TakeDamage(MyCharacterOption.attackDamage);
|
||||||
|
VisualFeedbackManager.Inst.TriggerHitStop(0.1f);
|
||||||
|
}
|
||||||
|
else if (MyCurrentValue.hitColliders[i].gameObject.layer == LayerMask.NameToLayer("Skill") &&
|
||||||
|
MyCurrentValue.hitColliders[i].CompareTag("DestructiveSkill"))
|
||||||
|
{
|
||||||
|
var iDamageable = MyCurrentValue.hitColliders[i].transform.GetComponent<IDamageable>();
|
||||||
|
iDamageable.TakeDamage(MyCharacterOption.attackDamage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MoveAnimation()
|
||||||
|
{
|
||||||
|
var isMoving = MyComponents.movement.GetIsMoving();
|
||||||
|
var previousDirection = MyComponents.movement.GetPreviousMoveDirection();
|
||||||
|
MyComponents.animator.SetBool(IsMovingHash, isMoving);
|
||||||
|
if (isMoving)
|
||||||
|
{
|
||||||
|
MyComponents.animator.SetFloat(XDirectionHash, previousDirection.x);
|
||||||
|
MyComponents.animator.SetFloat(ZDirectionHash, previousDirection.z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void FlipVisualLook(float previousDirectionX)
|
||||||
|
{
|
||||||
|
var localScale = MyComponents.visualLook.localScale;
|
||||||
|
localScale.x = previousDirectionX switch
|
||||||
|
{
|
||||||
|
> 0.01f => Mathf.Abs(localScale.x),
|
||||||
|
< -0.01f => -Mathf.Abs(localScale.x),
|
||||||
|
_ => localScale.x
|
||||||
|
};
|
||||||
|
MyComponents.visualLook.localScale = localScale;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CoolDown(float waitTime, Action onCooldownComplete = null)
|
||||||
|
{
|
||||||
|
StartCoroutine(CoolDownCoroutine(waitTime, onCooldownComplete));
|
||||||
|
}
|
||||||
|
|
||||||
|
private IEnumerator CoolDownCoroutine(float waitTime, Action onCooldownComplete = null)
|
||||||
|
{
|
||||||
|
var time = 0f;
|
||||||
|
|
||||||
|
while (time <= waitTime)
|
||||||
|
{
|
||||||
|
time += Time.deltaTime;
|
||||||
|
yield return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
onCooldownComplete?.Invoke();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Button("현재 체력 변경")]
|
||||||
|
private void SetCurrentHp(float value) => MyCurrentValue.currentHp = value;
|
||||||
|
public bool GetIsAttacking() => MyCurrentState.isAttacking;
|
||||||
|
public bool GetIsComboAttacking() => MyCurrentState.isComboAttacking;
|
||||||
|
public float GetDashCooldown() => MyComponents.movement.GetDashCooldown();
|
||||||
|
public float GetDashTime() => MyComponents.movement.GetDashTime();
|
||||||
|
public float GetAttackTime() => MyCharacterOption.attackTime;
|
||||||
|
public void SetIsAttacking(bool value) => MyCurrentState.isAttacking = value;
|
||||||
|
public void SetIsComboAttacking(bool value) => MyCurrentState.isComboAttacking = value;
|
||||||
|
public void SetIsComboPossible(bool value) => MyCurrentState.isComboPossible = value;
|
||||||
|
public void SetIsDashing(bool value) => MyComponents.movement.SetIsDashing(value);
|
||||||
|
public void SetEnableDashing(bool value) => MyComponents.movement.SetEnableDashing(value);
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: d85ab5237d86f7a43a553f00be353476
|
@ -1,600 +0,0 @@
|
|||||||
using System;
|
|
||||||
using UnityEngine;
|
|
||||||
using UnityEngine.InputSystem;
|
|
||||||
|
|
||||||
// ReSharper disable once CheckNamespace
|
|
||||||
namespace BlueWaterProject
|
|
||||||
{
|
|
||||||
public class NewCombatPlayer : MonoBehaviour, IMovement3D
|
|
||||||
{
|
|
||||||
/***********************************************************************
|
|
||||||
* Definitions
|
|
||||||
***********************************************************************/
|
|
||||||
|
|
||||||
#region Class
|
|
||||||
|
|
||||||
[Serializable]
|
|
||||||
public class Components
|
|
||||||
{
|
|
||||||
public PlayerInput playerInput;
|
|
||||||
public CapsuleCollider capsuleCollider;
|
|
||||||
public Rigidbody rb;
|
|
||||||
public Transform visualLook;
|
|
||||||
public Animator animator;
|
|
||||||
public Transform groundCheck;
|
|
||||||
}
|
|
||||||
|
|
||||||
[Serializable]
|
|
||||||
public class CheckOption
|
|
||||||
{
|
|
||||||
[Tooltip("지면으로 체크할 레이어 설정")] public LayerMask groundLayerMask = -1;
|
|
||||||
|
|
||||||
[Range(0.01f, 0.5f), Tooltip("전방 감지 거리")]
|
|
||||||
public float forwardCheckDistance = 0.1f;
|
|
||||||
|
|
||||||
[Range(0.1f, 10.0f), Tooltip("지면 감지 거리")]
|
|
||||||
public float groundCheckDistance = 2.0f;
|
|
||||||
|
|
||||||
[Range(0.0f, 0.1f), Tooltip("지면 인식 허용 거리")]
|
|
||||||
public float groundCheckThreshold = 0.01f;
|
|
||||||
}
|
|
||||||
|
|
||||||
[Serializable]
|
|
||||||
public class MovementOption
|
|
||||||
{
|
|
||||||
[Range(1f, 10f), Tooltip("이동속도")] public float speed = 10f;
|
|
||||||
|
|
||||||
[Range(1f, 3f), Tooltip("달리기 이동속도 증가 계수")]
|
|
||||||
public float runningCoefficient = 1.5f;
|
|
||||||
|
|
||||||
[Range(1f, 75f), Tooltip("등반 가능한 경사각")]
|
|
||||||
public float maxSlopeAngle = 50f;
|
|
||||||
|
|
||||||
[Range(0f, 4f), Tooltip("경사로 이동속도 변화율(가속/감속)")]
|
|
||||||
public float slopeAccel = 1f;
|
|
||||||
|
|
||||||
[Range(-9.81f, 0f), Tooltip("중력")] public float gravity = -9.81f;
|
|
||||||
}
|
|
||||||
|
|
||||||
[Serializable]
|
|
||||||
public class CurrentState
|
|
||||||
{
|
|
||||||
public bool isMoving;
|
|
||||||
public bool isRunning;
|
|
||||||
public bool isGrounded;
|
|
||||||
public bool isOnSteepSlope; // 등반 불가능한 경사로에 올라와 있음
|
|
||||||
public bool isForwardBlocked; // 전방에 장애물 존재
|
|
||||||
public bool isOutOfControl; // 제어 불가 상태
|
|
||||||
}
|
|
||||||
|
|
||||||
[Serializable]
|
|
||||||
public class CurrentValue
|
|
||||||
{
|
|
||||||
public Vector2 movementInput;
|
|
||||||
public Vector3 worldMoveDirection;
|
|
||||||
public Vector3 groundNormal;
|
|
||||||
public Vector3 groundCross;
|
|
||||||
public Vector3 horizontalVelocity;
|
|
||||||
|
|
||||||
[Space] public float outOfControlDuration;
|
|
||||||
|
|
||||||
[Space] public float groundDistance;
|
|
||||||
public float groundSlopeAngle; // 현재 바닥의 경사각
|
|
||||||
public float groundVerticalSlopeAngle; // 수직으로 재측정한 경사각
|
|
||||||
public float forwardSlopeAngle; // 캐릭터가 바라보는 방향의 경사각
|
|
||||||
public float slopeAccel; // 경사로 인한 가속/감속 비율
|
|
||||||
|
|
||||||
[Space] public float gravity;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* Variables
|
|
||||||
***********************************************************************/
|
|
||||||
|
|
||||||
#region Variables
|
|
||||||
|
|
||||||
// [SerializeField] private Components components = new();
|
|
||||||
// [SerializeField] private CheckOption checkOptions = new();
|
|
||||||
// [SerializeField] private MovementOption moveOptions = new();
|
|
||||||
// [SerializeField] private CurrentState currentStates = new();
|
|
||||||
// [SerializeField] private CurrentValue currentValues = new();
|
|
||||||
|
|
||||||
[field: SerializeField] public Components PlayerComponents { get; private set; } = new();
|
|
||||||
[field: SerializeField] public CheckOption PlayerCheckOption { get; private set; } = new();
|
|
||||||
[field: SerializeField] public MovementOption PlayerMovementOption { get; private set; } = new();
|
|
||||||
[field: SerializeField] public CurrentState PlayerCurrentState { get; set; } = new();
|
|
||||||
[field: SerializeField] public CurrentValue PlayerCurrentValue { get; set; } = new();
|
|
||||||
|
|
||||||
private float capsuleRadiusDifferent;
|
|
||||||
private float fixedDeltaTime;
|
|
||||||
|
|
||||||
private float castRadius; // Sphere, Capsule 레이캐스트 반지름
|
|
||||||
|
|
||||||
private Vector3 CapsuleTopCenterPoint => new(transform.position.x,
|
|
||||||
transform.position.y + PlayerComponents.capsuleCollider.height - PlayerComponents.capsuleCollider.radius,
|
|
||||||
transform.position.z);
|
|
||||||
|
|
||||||
private Vector3 CapsuleBottomCenterPoint => new(transform.position.x,
|
|
||||||
transform.position.y + PlayerComponents.capsuleCollider.radius, transform.position.z);
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* Unity Events
|
|
||||||
***********************************************************************/
|
|
||||||
|
|
||||||
#region Unity Events
|
|
||||||
|
|
||||||
private void Start()
|
|
||||||
{
|
|
||||||
InitRigidbody();
|
|
||||||
InitCapsuleCollider();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Update()
|
|
||||||
{
|
|
||||||
Move();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void FixedUpdate()
|
|
||||||
{
|
|
||||||
fixedDeltaTime = Time.fixedDeltaTime;
|
|
||||||
|
|
||||||
CheckGround();
|
|
||||||
CheckForward();
|
|
||||||
|
|
||||||
UpdatePhysics();
|
|
||||||
UpdateValues();
|
|
||||||
|
|
||||||
CalculateMovements();
|
|
||||||
ApplyMovementsToRigidbody();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* Init Methods
|
|
||||||
***********************************************************************/
|
|
||||||
|
|
||||||
#region Init Methods
|
|
||||||
|
|
||||||
private void InitRigidbody()
|
|
||||||
{
|
|
||||||
TryGetComponent(out PlayerComponents.rb);
|
|
||||||
if (PlayerComponents.rb == null)
|
|
||||||
{
|
|
||||||
PlayerComponents.rb = gameObject.AddComponent<Rigidbody>();
|
|
||||||
}
|
|
||||||
|
|
||||||
PlayerComponents.rb.constraints = RigidbodyConstraints.FreezeRotation;
|
|
||||||
PlayerComponents.rb.interpolation = RigidbodyInterpolation.Interpolate;
|
|
||||||
PlayerComponents.rb.collisionDetectionMode = CollisionDetectionMode.ContinuousDynamic;
|
|
||||||
PlayerComponents.rb.useGravity = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void InitCapsuleCollider()
|
|
||||||
{
|
|
||||||
TryGetComponent(out PlayerComponents.capsuleCollider);
|
|
||||||
if (PlayerComponents.capsuleCollider == null)
|
|
||||||
{
|
|
||||||
PlayerComponents.capsuleCollider = gameObject.AddComponent<CapsuleCollider>();
|
|
||||||
|
|
||||||
// 렌더러를 모두 탐색하여 높이 결정
|
|
||||||
var maxHeight = -1f;
|
|
||||||
|
|
||||||
// // 1. SMR 확인
|
|
||||||
// var smrArr = GetComponentsInChildren<SkinnedMeshRenderer>();
|
|
||||||
// if (smrArr.Length > 0)
|
|
||||||
// {
|
|
||||||
// foreach (var smr in smrArr)
|
|
||||||
// {
|
|
||||||
// foreach (var vertex in smr.sharedMesh.vertices)
|
|
||||||
// {
|
|
||||||
// if(maxHeight < vertex.y)
|
|
||||||
// maxHeight = vertex.y;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// // 2. MR 확인
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// var mfArr = GetComponentsInChildren<MeshFilter>();
|
|
||||||
// if (mfArr.Length > 0)
|
|
||||||
// {
|
|
||||||
// foreach (var mf in mfArr)
|
|
||||||
// {
|
|
||||||
// foreach (var vertex in mf.mesh.vertices)
|
|
||||||
// {
|
|
||||||
// if (maxHeight < vertex.y)
|
|
||||||
// maxHeight = vertex.y;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// 3. 캡슐 콜라이더 값 설정
|
|
||||||
if (maxHeight <= 0)
|
|
||||||
{
|
|
||||||
maxHeight = 1f;
|
|
||||||
}
|
|
||||||
|
|
||||||
var center = maxHeight * 0.5f;
|
|
||||||
|
|
||||||
PlayerComponents.capsuleCollider.height = maxHeight;
|
|
||||||
PlayerComponents.capsuleCollider.center = Vector3.up * center;
|
|
||||||
PlayerComponents.capsuleCollider.radius = 0.5f;
|
|
||||||
}
|
|
||||||
|
|
||||||
var capsuleColliderRadius = PlayerComponents.capsuleCollider.radius;
|
|
||||||
castRadius = capsuleColliderRadius * 0.9f;
|
|
||||||
capsuleRadiusDifferent = capsuleColliderRadius - castRadius + 0.05f;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* PlayerInput
|
|
||||||
***********************************************************************/
|
|
||||||
|
|
||||||
#region PlayerInput
|
|
||||||
|
|
||||||
private void OnMove(InputValue value)
|
|
||||||
{
|
|
||||||
PlayerCurrentValue.movementInput = value.Get<Vector2>();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* IMovement3D interface
|
|
||||||
***********************************************************************/
|
|
||||||
|
|
||||||
#region IMovement3D interface
|
|
||||||
|
|
||||||
public bool IsMoving() => PlayerCurrentState.isMoving;
|
|
||||||
public bool IsGrounded() => PlayerCurrentState.isGrounded;
|
|
||||||
public float GetDistanceFromGround() => PlayerCurrentValue.groundDistance;
|
|
||||||
|
|
||||||
public void SetMovement(in Vector3 worldMoveDirection, bool isRunning)
|
|
||||||
{
|
|
||||||
PlayerCurrentValue.worldMoveDirection = worldMoveDirection;
|
|
||||||
PlayerCurrentState.isMoving = worldMoveDirection.sqrMagnitude > 0.01f;
|
|
||||||
PlayerCurrentState.isRunning = isRunning;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void StopMoving()
|
|
||||||
{
|
|
||||||
PlayerCurrentValue.worldMoveDirection = Vector3.zero;
|
|
||||||
PlayerCurrentState.isMoving = false;
|
|
||||||
PlayerCurrentState.isRunning = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void KnockBack(in Vector3 force, float time)
|
|
||||||
{
|
|
||||||
SetOutOfControl(time);
|
|
||||||
PlayerComponents.rb.AddForce(force, ForceMode.Impulse);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetOutOfControl(float time)
|
|
||||||
{
|
|
||||||
PlayerCurrentValue.outOfControlDuration = time;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* Methods
|
|
||||||
***********************************************************************/
|
|
||||||
|
|
||||||
#region Methods
|
|
||||||
|
|
||||||
private void Move()
|
|
||||||
{
|
|
||||||
// 이동하지 않는 경우, 미끄럼 방지
|
|
||||||
if (PlayerCurrentState.isMoving == false)
|
|
||||||
{
|
|
||||||
PlayerComponents.rb.velocity = new Vector3(0f, PlayerComponents.rb.velocity.y, 0f);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 실제 이동 벡터 계산
|
|
||||||
var worldMove = new Vector3(PlayerCurrentValue.movementInput.x, 0, PlayerCurrentValue.movementInput.y).normalized;
|
|
||||||
worldMove *= (PlayerMovementOption.speed) * (PlayerCurrentState.isRunning ? PlayerMovementOption.runningCoefficient : 1f);
|
|
||||||
|
|
||||||
// Y축 속도는 유지하면서 XZ평면 이동
|
|
||||||
PlayerComponents.rb.velocity = new Vector3(worldMove.x, PlayerComponents.rb.velocity.y, worldMove.z);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary> 하단 지면 검사 </summary>
|
|
||||||
private void CheckGround()
|
|
||||||
{
|
|
||||||
PlayerCurrentValue.groundDistance = float.MaxValue;
|
|
||||||
PlayerCurrentValue.groundNormal = Vector3.up;
|
|
||||||
PlayerCurrentValue.groundSlopeAngle = 0f;
|
|
||||||
PlayerCurrentValue.forwardSlopeAngle = 0f;
|
|
||||||
|
|
||||||
var cast = Physics.SphereCast(CapsuleBottomCenterPoint, castRadius,
|
|
||||||
Vector3.down, out var hit, PlayerCheckOption.groundCheckDistance, PlayerCheckOption.groundLayerMask,
|
|
||||||
QueryTriggerInteraction.Ignore);
|
|
||||||
|
|
||||||
PlayerCurrentState.isGrounded = false;
|
|
||||||
|
|
||||||
if (cast)
|
|
||||||
{
|
|
||||||
// 지면 노멀벡터 초기화
|
|
||||||
PlayerCurrentValue.groundNormal = hit.normal;
|
|
||||||
|
|
||||||
// 현재 위치한 지면의 경사각 구하기(캐릭터 이동방향 고려)
|
|
||||||
PlayerCurrentValue.groundSlopeAngle = Vector3.Angle(PlayerCurrentValue.groundNormal, Vector3.up);
|
|
||||||
PlayerCurrentValue.forwardSlopeAngle =
|
|
||||||
Vector3.Angle(PlayerCurrentValue.groundNormal, PlayerCurrentValue.worldMoveDirection) - 90f;
|
|
||||||
|
|
||||||
PlayerCurrentState.isOnSteepSlope =
|
|
||||||
PlayerCurrentValue.groundSlopeAngle >= PlayerMovementOption.maxSlopeAngle;
|
|
||||||
|
|
||||||
// 경사각 이중검증 (수직 레이캐스트) : 뾰족하거나 각진 부분 체크
|
|
||||||
//if (State.isOnSteepSlope)
|
|
||||||
//{
|
|
||||||
// Vector3 ro = hit.point + Vector3.up * 0.1f;
|
|
||||||
// Vector3 rd = Vector3.down;
|
|
||||||
// bool rayD =
|
|
||||||
// Physics.SphereCast(ro, 0.09f, rd, out var hitRayD, 0.2f, COption.groundLayerMask, QueryTriggerInteraction.Ignore);
|
|
||||||
|
|
||||||
// Current.groundVerticalSlopeAngle = rayD ? Vector3.Angle(hitRayD.normal, Vector3.up) : Current.groundSlopeAngle;
|
|
||||||
|
|
||||||
// State.isOnSteepSlope = Current.groundVerticalSlopeAngle >= MOption.maxSlopeAngle;
|
|
||||||
//}
|
|
||||||
|
|
||||||
PlayerCurrentValue.groundDistance =
|
|
||||||
Mathf.Max(hit.distance - capsuleRadiusDifferent - PlayerCheckOption.groundCheckThreshold, 0f);
|
|
||||||
|
|
||||||
PlayerCurrentState.isGrounded =
|
|
||||||
(PlayerCurrentValue.groundDistance <= 0.0001f) && !PlayerCurrentState.isOnSteepSlope;
|
|
||||||
|
|
||||||
GzUpdateValue(ref gzGroundTouch, hit.point);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 월드 이동벡터 회전축
|
|
||||||
PlayerCurrentValue.groundCross = Vector3.Cross(PlayerCurrentValue.groundNormal, Vector3.up);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary> 전방 장애물 검사 : 레이어 관계 없이 trigger가 아닌 모든 장애물 검사 </summary>
|
|
||||||
private void CheckForward()
|
|
||||||
{
|
|
||||||
bool cast =
|
|
||||||
Physics.CapsuleCast(CapsuleBottomCenterPoint, CapsuleTopCenterPoint, castRadius,
|
|
||||||
PlayerCurrentValue.worldMoveDirection + Vector3.down * 0.1f,
|
|
||||||
out var hit, PlayerCheckOption.forwardCheckDistance, -1, QueryTriggerInteraction.Ignore);
|
|
||||||
|
|
||||||
PlayerCurrentState.isForwardBlocked = false;
|
|
||||||
if (cast)
|
|
||||||
{
|
|
||||||
float forwardObstacleAngle = Vector3.Angle(hit.normal, Vector3.up);
|
|
||||||
PlayerCurrentState.isForwardBlocked = forwardObstacleAngle >= PlayerMovementOption.maxSlopeAngle;
|
|
||||||
|
|
||||||
GzUpdateValue(ref gzForwardTouch, hit.point);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdatePhysics()
|
|
||||||
{
|
|
||||||
// Custom Gravity, Jumping State
|
|
||||||
if (PlayerCurrentState.isGrounded)
|
|
||||||
{
|
|
||||||
PlayerCurrentValue.gravity = 0f;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PlayerCurrentValue.gravity += fixedDeltaTime * PlayerMovementOption.gravity;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateValues()
|
|
||||||
{
|
|
||||||
// Out Of Control
|
|
||||||
PlayerCurrentState.isOutOfControl = PlayerCurrentValue.outOfControlDuration > 0f;
|
|
||||||
|
|
||||||
if (PlayerCurrentState.isOutOfControl)
|
|
||||||
{
|
|
||||||
PlayerCurrentValue.outOfControlDuration -= fixedDeltaTime;
|
|
||||||
PlayerCurrentValue.worldMoveDirection = Vector3.zero;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void CalculateMovements()
|
|
||||||
{
|
|
||||||
if (PlayerCurrentState.isOutOfControl)
|
|
||||||
{
|
|
||||||
PlayerCurrentValue.horizontalVelocity = Vector3.zero;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 0. 가파른 경사면에 있는 경우 : 꼼짝말고 미끄럼틀 타기
|
|
||||||
//if (State.isOnSteepSlope && Current.groundDistance < 0.1f)
|
|
||||||
//{
|
|
||||||
// DebugMark(0);
|
|
||||||
|
|
||||||
// Current.horizontalVelocity =
|
|
||||||
// Quaternion.AngleAxis(90f - Current.groundSlopeAngle, Current.groundCross) * (Vector3.up * Current.gravity);
|
|
||||||
|
|
||||||
// Com.rBody.velocity = Current.horizontalVelocity;
|
|
||||||
|
|
||||||
// return;
|
|
||||||
//}
|
|
||||||
|
|
||||||
// 2. XZ 이동속도 계산
|
|
||||||
// 공중에서 전방이 막힌 경우 제한 (지상에서는 벽에 붙어서 이동할 수 있도록 허용)
|
|
||||||
if (PlayerCurrentState.isForwardBlocked && !PlayerCurrentState.isGrounded)
|
|
||||||
{
|
|
||||||
PlayerCurrentValue.horizontalVelocity = Vector3.zero;
|
|
||||||
}
|
|
||||||
else // 이동 가능한 경우 : 지상 or 전방이 막히지 않음
|
|
||||||
{
|
|
||||||
float speed = !PlayerCurrentState.isMoving ? 0f :
|
|
||||||
!PlayerCurrentState.isRunning ? PlayerMovementOption.speed :
|
|
||||||
PlayerMovementOption.speed * PlayerMovementOption.runningCoefficient;
|
|
||||||
|
|
||||||
PlayerCurrentValue.horizontalVelocity = PlayerCurrentValue.worldMoveDirection * speed;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. XZ 벡터 회전
|
|
||||||
// 지상이거나 지면에 가까운 높이
|
|
||||||
if (PlayerCurrentState.isGrounded ||
|
|
||||||
PlayerCurrentValue.groundDistance < PlayerCheckOption.groundCheckDistance)
|
|
||||||
{
|
|
||||||
if (PlayerCurrentState.isMoving && !PlayerCurrentState.isForwardBlocked)
|
|
||||||
{
|
|
||||||
// 경사로 인한 가속/감속
|
|
||||||
if (PlayerMovementOption.slopeAccel > 0f)
|
|
||||||
{
|
|
||||||
bool isPlus = PlayerCurrentValue.forwardSlopeAngle >= 0f;
|
|
||||||
float absFsAngle = isPlus
|
|
||||||
? PlayerCurrentValue.forwardSlopeAngle
|
|
||||||
: -PlayerCurrentValue.forwardSlopeAngle;
|
|
||||||
float accel = PlayerMovementOption.slopeAccel * absFsAngle * 0.01111f + 1f;
|
|
||||||
PlayerCurrentValue.slopeAccel = !isPlus ? accel : 1.0f / accel;
|
|
||||||
|
|
||||||
PlayerCurrentValue.horizontalVelocity *= PlayerCurrentValue.slopeAccel;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 벡터 회전 (경사로)
|
|
||||||
PlayerCurrentValue.horizontalVelocity =
|
|
||||||
Quaternion.AngleAxis(-PlayerCurrentValue.groundSlopeAngle, PlayerCurrentValue.groundCross) *
|
|
||||||
PlayerCurrentValue.horizontalVelocity;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GzUpdateValue(ref gzRotatedWorldMoveDirection, PlayerCurrentValue.horizontalVelocity * 0.2f);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary> 리지드바디 최종 속도 적용 </summary>
|
|
||||||
private void ApplyMovementsToRigidbody()
|
|
||||||
{
|
|
||||||
if (PlayerCurrentState.isOutOfControl)
|
|
||||||
{
|
|
||||||
PlayerComponents.rb.velocity = new Vector3(PlayerComponents.rb.velocity.x, PlayerCurrentValue.gravity,
|
|
||||||
PlayerComponents.rb.velocity.z);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
PlayerComponents.rb.velocity =
|
|
||||||
PlayerCurrentValue.horizontalVelocity + Vector3.up * (PlayerCurrentValue.gravity);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* Gizmos, GUI
|
|
||||||
***********************************************************************/
|
|
||||||
|
|
||||||
#region .
|
|
||||||
|
|
||||||
private Vector3 gzGroundTouch;
|
|
||||||
private Vector3 gzForwardTouch;
|
|
||||||
private Vector3 gzRotatedWorldMoveDirection;
|
|
||||||
|
|
||||||
[Header("Gizmos Option")] public bool showGizmos = true;
|
|
||||||
|
|
||||||
[SerializeField, Range(0.01f, 2f)] private float gizmoRadius = 0.05f;
|
|
||||||
|
|
||||||
[System.Diagnostics.Conditional("UNITY_EDITOR")]
|
|
||||||
private void OnDrawGizmos()
|
|
||||||
{
|
|
||||||
if (Application.isPlaying == false) return;
|
|
||||||
if (!showGizmos) return;
|
|
||||||
if (!enabled) return;
|
|
||||||
|
|
||||||
Gizmos.color = Color.red;
|
|
||||||
Gizmos.DrawSphere(gzGroundTouch, gizmoRadius);
|
|
||||||
|
|
||||||
if (PlayerCurrentState.isForwardBlocked)
|
|
||||||
{
|
|
||||||
Gizmos.color = Color.blue;
|
|
||||||
Gizmos.DrawSphere(gzForwardTouch, gizmoRadius);
|
|
||||||
}
|
|
||||||
|
|
||||||
Gizmos.color = Color.blue;
|
|
||||||
Gizmos.DrawLine(gzGroundTouch - PlayerCurrentValue.groundCross,
|
|
||||||
gzGroundTouch + PlayerCurrentValue.groundCross);
|
|
||||||
|
|
||||||
Gizmos.color = Color.black;
|
|
||||||
Gizmos.DrawLine(transform.position, transform.position + gzRotatedWorldMoveDirection);
|
|
||||||
|
|
||||||
Gizmos.color = new Color(0.5f, 1.0f, 0.8f, 0.8f);
|
|
||||||
Gizmos.DrawWireSphere(CapsuleTopCenterPoint, castRadius);
|
|
||||||
Gizmos.DrawWireSphere(CapsuleBottomCenterPoint, castRadius);
|
|
||||||
}
|
|
||||||
|
|
||||||
[System.Diagnostics.Conditional("UNITY_EDITOR")]
|
|
||||||
private void GzUpdateValue<T>(ref T variable, in T value)
|
|
||||||
{
|
|
||||||
variable = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
[SerializeField, Space] private bool showGUI = true;
|
|
||||||
[SerializeField] private int guiTextSize = 28;
|
|
||||||
|
|
||||||
private float prevForwardSlopeAngle;
|
|
||||||
|
|
||||||
private void OnGUI()
|
|
||||||
{
|
|
||||||
if (Application.isPlaying == false) return;
|
|
||||||
if (!showGUI) return;
|
|
||||||
if (!enabled) return;
|
|
||||||
|
|
||||||
GUIStyle labelStyle = GUI.skin.label;
|
|
||||||
labelStyle.normal.textColor = Color.yellow;
|
|
||||||
labelStyle.fontSize = Math.Max(guiTextSize, 20);
|
|
||||||
|
|
||||||
prevForwardSlopeAngle = PlayerCurrentValue.forwardSlopeAngle == -90f
|
|
||||||
? prevForwardSlopeAngle
|
|
||||||
: PlayerCurrentValue.forwardSlopeAngle;
|
|
||||||
|
|
||||||
var oldColor = GUI.color;
|
|
||||||
GUI.color = new Color(0f, 0f, 0f, 0.5f);
|
|
||||||
GUI.Box(new Rect(40, 40, 420, 260), "");
|
|
||||||
GUI.color = oldColor;
|
|
||||||
|
|
||||||
GUILayout.BeginArea(new Rect(50, 50, 1000, 500));
|
|
||||||
GUILayout.Label($"Ground Height : {Mathf.Min(PlayerCurrentValue.groundDistance, 99.99f): 00.00}",
|
|
||||||
labelStyle);
|
|
||||||
GUILayout.Label($"Slope Angle(Ground) : {PlayerCurrentValue.groundSlopeAngle: 00.00}", labelStyle);
|
|
||||||
GUILayout.Label($"Slope Angle(Forward) : {prevForwardSlopeAngle: 00.00}", labelStyle);
|
|
||||||
GUILayout.Label($"Allowed Slope Angle : {PlayerMovementOption.maxSlopeAngle: 00.00}", labelStyle);
|
|
||||||
GUILayout.Label($"Current Slope Accel : {PlayerCurrentValue.slopeAccel: 00.00}", labelStyle);
|
|
||||||
GUILayout.Label($"Current Speed Mag : {PlayerCurrentValue.horizontalVelocity.magnitude: 00.00}",
|
|
||||||
labelStyle);
|
|
||||||
GUILayout.EndArea();
|
|
||||||
|
|
||||||
float sWidth = Screen.width;
|
|
||||||
float sHeight = Screen.height;
|
|
||||||
|
|
||||||
GUIStyle RTLabelStyle = GUI.skin.label;
|
|
||||||
RTLabelStyle.fontSize = 20;
|
|
||||||
RTLabelStyle.normal.textColor = Color.green;
|
|
||||||
|
|
||||||
oldColor = GUI.color;
|
|
||||||
GUI.color = new Color(1f, 1f, 1f, 0.5f);
|
|
||||||
GUI.Box(new Rect(sWidth - 355f, 5f, 340f, 100f), "");
|
|
||||||
GUI.color = oldColor;
|
|
||||||
|
|
||||||
var yPos = 10f;
|
|
||||||
GUI.Label(new Rect(sWidth - 350f, yPos, 150f, 30f), $"Speed : {PlayerMovementOption.speed: 00.00}",
|
|
||||||
RTLabelStyle);
|
|
||||||
PlayerMovementOption.speed = GUI.HorizontalSlider(new Rect(sWidth - 200f, yPos + 10f, 180f, 20f),
|
|
||||||
PlayerMovementOption.speed, 1f, 10f);
|
|
||||||
|
|
||||||
yPos += 20f;
|
|
||||||
GUI.Label(new Rect(sWidth - 350f, yPos, 150f, 30f), $"Max Slope : {PlayerMovementOption.maxSlopeAngle: 00}",
|
|
||||||
RTLabelStyle);
|
|
||||||
PlayerMovementOption.maxSlopeAngle = (int)GUI.HorizontalSlider(
|
|
||||||
new Rect(sWidth - 200f, yPos + 10f, 180f, 20f), PlayerMovementOption.maxSlopeAngle, 1f, 75f);
|
|
||||||
|
|
||||||
labelStyle.fontSize = Math.Max(guiTextSize, 20);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,486 @@
|
|||||||
|
using System;
|
||||||
|
using Sirenix.OdinInspector;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.InputSystem;
|
||||||
|
using UnityEngine.Serialization;
|
||||||
|
|
||||||
|
// ReSharper disable once CheckNamespace
|
||||||
|
namespace BlueWaterProject
|
||||||
|
{
|
||||||
|
public class PhysicsMovement : MonoBehaviour
|
||||||
|
{
|
||||||
|
/***********************************************************************
|
||||||
|
* Definitions
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#region Class
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public class Components
|
||||||
|
{
|
||||||
|
public CapsuleCollider capsuleCollider;
|
||||||
|
public Rigidbody rb;
|
||||||
|
[ShowIf("@false")]
|
||||||
|
public Animator animator;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public class CheckOption
|
||||||
|
{
|
||||||
|
[Tooltip("지면으로 체크할 레이어 설정")]
|
||||||
|
public LayerMask groundLayer = -1;
|
||||||
|
|
||||||
|
[Range(0.01f, 0.5f), Tooltip("전방 감지 거리")]
|
||||||
|
public float forwardCheckDistance = 0.1f;
|
||||||
|
|
||||||
|
[Range(0.1f, 10.0f), Tooltip("지면 감지 거리")]
|
||||||
|
public float groundCheckDistance = 2.0f;
|
||||||
|
|
||||||
|
[Range(0.0f, 0.5f), Tooltip("지면 인식 허용 거리")]
|
||||||
|
public float groundCheckThreshold = 0.01f;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public class MovementOption
|
||||||
|
{
|
||||||
|
[Range(1f, 10f), Tooltip("이동 속도")]
|
||||||
|
public float moveSpeed = 10f;
|
||||||
|
|
||||||
|
[Range(1f, 75f), Tooltip("등반 가능한 경사각")]
|
||||||
|
public float maxSlopeAngle = 50f;
|
||||||
|
|
||||||
|
[Range(1f, 50f), Tooltip("대쉬 속도")]
|
||||||
|
public float dashSpeed = 30f;
|
||||||
|
|
||||||
|
[Range(0.1f, 1f), Tooltip("대쉬 시간")]
|
||||||
|
public float dashTime = 0.2f;
|
||||||
|
|
||||||
|
[Range(0f, 5f), Tooltip("대쉬 쿨타임")]
|
||||||
|
public float dashCooldown = 0.5f;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
[DisableIf("@true")]
|
||||||
|
public class CurrentState
|
||||||
|
{
|
||||||
|
public bool isMoving;
|
||||||
|
public bool isGrounded;
|
||||||
|
public bool isOnSlope;
|
||||||
|
public bool isOnSteepSlope;
|
||||||
|
public bool isForwardBlocked;
|
||||||
|
public bool isOutOfControl;
|
||||||
|
public bool isDashing;
|
||||||
|
public bool enableDash = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
[DisableIf("@true")]
|
||||||
|
public class CurrentValue
|
||||||
|
{
|
||||||
|
public Vector2 movementInput;
|
||||||
|
public Vector3 currentMoveDirection;
|
||||||
|
public Vector3 previousMoveDirection = Vector3.back;
|
||||||
|
public Vector3 groundNormal;
|
||||||
|
public Vector3 groundCross;
|
||||||
|
public Vector3 horizontalVelocity;
|
||||||
|
|
||||||
|
[Space]
|
||||||
|
public float outOfControlDuration;
|
||||||
|
|
||||||
|
[Space]
|
||||||
|
public float groundDistance;
|
||||||
|
public float groundSlopeAngle; // 현재 바닥의 경사각
|
||||||
|
public float forwardSlopeAngle; // 캐릭터가 바라보는 방향의 경사각
|
||||||
|
|
||||||
|
[Space]
|
||||||
|
public Vector3 gravity;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* Variables
|
||||||
|
***********************************************************************/
|
||||||
|
#region Variables
|
||||||
|
|
||||||
|
[field: SerializeField] public Components MyComponents { get; private set; } = new();
|
||||||
|
[field: SerializeField] public CheckOption MyCheckOption { get; private set; } = new();
|
||||||
|
[field: SerializeField] public MovementOption MyMovementOption { get; private set; } = new();
|
||||||
|
[field: SerializeField] public CurrentState MyCurrentState { get; set; } = new();
|
||||||
|
[field: SerializeField] public CurrentValue MyCurrentValue { get; set; } = new();
|
||||||
|
|
||||||
|
private float capsuleRadiusDifferent;
|
||||||
|
private float castRadius;
|
||||||
|
|
||||||
|
private Vector3 CapsuleTopCenterPoint => new(transform.position.x,
|
||||||
|
transform.position.y + MyComponents.capsuleCollider.height - MyComponents.capsuleCollider.radius,
|
||||||
|
transform.position.z);
|
||||||
|
|
||||||
|
private Vector3 CapsuleBottomCenterPoint => new(transform.position.x,
|
||||||
|
transform.position.y + MyComponents.capsuleCollider.radius,
|
||||||
|
transform.position.z);
|
||||||
|
|
||||||
|
public static readonly int IsDashingHash = Animator.StringToHash("isDashing");
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* Unity Events
|
||||||
|
***********************************************************************/
|
||||||
|
#region Unity Events
|
||||||
|
|
||||||
|
private void Start()
|
||||||
|
{
|
||||||
|
InitRigidbody();
|
||||||
|
InitCapsuleCollider();
|
||||||
|
InitStartValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void FixedUpdate()
|
||||||
|
{
|
||||||
|
InputMove();
|
||||||
|
CheckGround();
|
||||||
|
CheckForward();
|
||||||
|
|
||||||
|
UpdateValues();
|
||||||
|
|
||||||
|
CalculateMovements();
|
||||||
|
ApplyMovementsToRigidbody();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* Init Methods
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#region Init Methods
|
||||||
|
|
||||||
|
private void InitRigidbody()
|
||||||
|
{
|
||||||
|
if (TryGetComponent(out MyComponents.rb)) return;
|
||||||
|
|
||||||
|
MyComponents.rb = gameObject.AddComponent<Rigidbody>();
|
||||||
|
|
||||||
|
MyComponents.rb.constraints = RigidbodyConstraints.FreezeRotation;
|
||||||
|
MyComponents.rb.interpolation = RigidbodyInterpolation.Interpolate;
|
||||||
|
MyComponents.rb.collisionDetectionMode = CollisionDetectionMode.ContinuousDynamic;
|
||||||
|
MyComponents.rb.useGravity = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitCapsuleCollider()
|
||||||
|
{
|
||||||
|
if (!TryGetComponent(out MyComponents.capsuleCollider))
|
||||||
|
{
|
||||||
|
MyComponents.capsuleCollider = gameObject.AddComponent<CapsuleCollider>();
|
||||||
|
|
||||||
|
MyComponents.capsuleCollider.height = 2f;
|
||||||
|
MyComponents.capsuleCollider.center = Vector3.up;
|
||||||
|
MyComponents.capsuleCollider.radius = 0.5f;
|
||||||
|
}
|
||||||
|
|
||||||
|
var capsuleColliderRadius = MyComponents.capsuleCollider.radius;
|
||||||
|
castRadius = capsuleColliderRadius * 0.9f;
|
||||||
|
capsuleRadiusDifferent = capsuleColliderRadius - castRadius + 0.05f;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitStartValue()
|
||||||
|
{
|
||||||
|
MyCurrentValue.gravity = Physics.gravity;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* PlayerInput
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#region PlayerInput
|
||||||
|
|
||||||
|
private void OnMove(InputValue value)
|
||||||
|
{
|
||||||
|
MyCurrentValue.movementInput = value.Get<Vector2>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnDash()
|
||||||
|
{
|
||||||
|
if (!MyCurrentState.enableDash || MyCurrentState.isDashing) return;
|
||||||
|
|
||||||
|
MyComponents.animator.SetBool(IsDashingHash, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* Methods
|
||||||
|
***********************************************************************/
|
||||||
|
#region Methods
|
||||||
|
|
||||||
|
private void InputMove()
|
||||||
|
{
|
||||||
|
if (MyCurrentValue.currentMoveDirection != Vector3.zero)
|
||||||
|
{
|
||||||
|
MyCurrentValue.previousMoveDirection = MyCurrentValue.currentMoveDirection;
|
||||||
|
}
|
||||||
|
MyCurrentValue.currentMoveDirection = MyCurrentState.isDashing
|
||||||
|
? MyCurrentValue.previousMoveDirection
|
||||||
|
: new Vector3(MyCurrentValue.movementInput.x, 0,MyCurrentValue.movementInput.y).normalized;
|
||||||
|
MyCurrentState.isMoving = MyCurrentValue.currentMoveDirection != Vector3.zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary> 하단 지면 검사 </summary>
|
||||||
|
private void CheckGround()
|
||||||
|
{
|
||||||
|
MyCurrentValue.groundDistance = float.MaxValue;
|
||||||
|
MyCurrentValue.groundNormal = Vector3.up;
|
||||||
|
MyCurrentValue.groundSlopeAngle = 0f;
|
||||||
|
MyCurrentValue.forwardSlopeAngle = 0f;
|
||||||
|
|
||||||
|
var groundRaycast = Physics.SphereCast(CapsuleBottomCenterPoint, castRadius,Vector3.down,
|
||||||
|
out var hit, MyCheckOption.groundCheckDistance, MyCheckOption.groundLayer, QueryTriggerInteraction.Ignore);
|
||||||
|
|
||||||
|
MyCurrentState.isGrounded = false;
|
||||||
|
|
||||||
|
if (groundRaycast)
|
||||||
|
{
|
||||||
|
MyCurrentValue.groundNormal = hit.normal;
|
||||||
|
MyCurrentValue.groundSlopeAngle = Vector3.Angle(MyCurrentValue.groundNormal, Vector3.up);
|
||||||
|
MyCurrentValue.forwardSlopeAngle = Vector3.Angle(MyCurrentValue.groundNormal, MyCurrentValue.currentMoveDirection) - 90f;
|
||||||
|
MyCurrentState.isOnSlope = MyCurrentValue.groundSlopeAngle > 0f && MyCurrentValue.groundSlopeAngle < MyMovementOption.maxSlopeAngle;
|
||||||
|
MyCurrentState.isOnSteepSlope = MyCurrentValue.groundSlopeAngle >= MyMovementOption.maxSlopeAngle;
|
||||||
|
|
||||||
|
// 경사각 이중검증 (수직 레이캐스트) : 뾰족하거나 각진 부분 체크
|
||||||
|
//if (State.isOnSteepSlope)
|
||||||
|
//{
|
||||||
|
// Vector3 ro = hit.point + Vector3.up * 0.1f;
|
||||||
|
// Vector3 rd = Vector3.down;
|
||||||
|
// bool rayD =
|
||||||
|
// Physics.SphereCast(ro, 0.09f, rd, out var hitRayD, 0.2f, COption.groundLayerMask, QueryTriggerInteraction.Ignore);
|
||||||
|
|
||||||
|
// Current.groundVerticalSlopeAngle = rayD ? Vector3.Angle(hitRayD.normal, Vector3.up) : Current.groundSlopeAngle;
|
||||||
|
|
||||||
|
// State.isOnSteepSlope = Current.groundVerticalSlopeAngle >= MOption.maxSlopeAngle;
|
||||||
|
//}
|
||||||
|
|
||||||
|
MyCurrentValue.groundDistance = Mathf.Max(hit.distance - capsuleRadiusDifferent - MyCheckOption.groundCheckThreshold, 0f);
|
||||||
|
MyCurrentState.isGrounded = (MyCurrentValue.groundDistance <= 0.0001f) && !MyCurrentState.isOnSteepSlope;
|
||||||
|
|
||||||
|
GizmosUpdateValue(ref gzGroundTouch, hit.point);
|
||||||
|
}
|
||||||
|
|
||||||
|
MyCurrentValue.groundCross = Vector3.Cross(MyCurrentValue.groundNormal, Vector3.up);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary> 전방 장애물 검사 : 레이어 관계 없이 trigger가 아닌 모든 장애물 검사 </summary>
|
||||||
|
private void CheckForward()
|
||||||
|
{
|
||||||
|
var obstacleRaycast = Physics.CapsuleCast(CapsuleBottomCenterPoint, CapsuleTopCenterPoint, castRadius,
|
||||||
|
MyCurrentValue.currentMoveDirection + Vector3.down * 0.1f,
|
||||||
|
out var hit, MyCheckOption.forwardCheckDistance, -1, QueryTriggerInteraction.Ignore);
|
||||||
|
|
||||||
|
MyCurrentState.isForwardBlocked = false;
|
||||||
|
if (obstacleRaycast)
|
||||||
|
{
|
||||||
|
var forwardObstacleAngle = Vector3.Angle(hit.normal, Vector3.up);
|
||||||
|
MyCurrentState.isForwardBlocked = forwardObstacleAngle >= MyMovementOption.maxSlopeAngle;
|
||||||
|
|
||||||
|
GizmosUpdateValue(ref gzForwardTouch, hit.point);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateValues()
|
||||||
|
{
|
||||||
|
MyCurrentState.isOutOfControl = MyCurrentValue.outOfControlDuration > 0f;
|
||||||
|
|
||||||
|
if (MyCurrentState.isOutOfControl)
|
||||||
|
{
|
||||||
|
MyCurrentValue.outOfControlDuration -= Time.fixedDeltaTime;
|
||||||
|
MyCurrentValue.currentMoveDirection = Vector3.zero;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CalculateMovements()
|
||||||
|
{
|
||||||
|
if (MyCurrentState.isOutOfControl)
|
||||||
|
{
|
||||||
|
MyComponents.rb.useGravity = true;
|
||||||
|
MyCurrentValue.horizontalVelocity = Vector3.zero;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var speed = 0f;
|
||||||
|
if (MyCurrentState.isDashing)
|
||||||
|
{
|
||||||
|
speed = MyMovementOption.dashSpeed;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
speed = MyCurrentState.isMoving ? MyMovementOption.moveSpeed : 0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MyCurrentState.isOnSlope)
|
||||||
|
{
|
||||||
|
MyComponents.rb.useGravity = false;
|
||||||
|
|
||||||
|
if (MyCurrentState.isMoving)
|
||||||
|
{
|
||||||
|
var changeMoveDirection = Vector3.ProjectOnPlane(MyCurrentValue.currentMoveDirection, MyCurrentValue.groundNormal).normalized;
|
||||||
|
MyCurrentValue.horizontalVelocity = changeMoveDirection * speed;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MyCurrentValue.horizontalVelocity = Vector3.zero;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MyComponents.rb.useGravity = true;
|
||||||
|
if (MyCurrentState.isForwardBlocked || !MyCurrentState.isGrounded)
|
||||||
|
{
|
||||||
|
MyCurrentValue.horizontalVelocity = Vector3.zero;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MyCurrentValue.horizontalVelocity = MyCurrentValue.currentMoveDirection * speed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary> 리지드바디 최종 속도 적용 </summary>
|
||||||
|
private void ApplyMovementsToRigidbody()
|
||||||
|
{
|
||||||
|
Vector3 finalVelocity;
|
||||||
|
if (MyCurrentState.isOutOfControl || MyCurrentState.isOnSteepSlope || !MyCurrentState.isGrounded)
|
||||||
|
{
|
||||||
|
var velocity = MyComponents.rb.velocity;
|
||||||
|
finalVelocity = MyComponents.rb.position + new Vector3(velocity.x, MyCurrentValue.gravity.y, velocity.z) * Time.fixedDeltaTime;
|
||||||
|
MyComponents.rb.MovePosition(finalVelocity);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (MyCurrentValue.horizontalVelocity == Vector3.zero)
|
||||||
|
{
|
||||||
|
MyComponents.rb.velocity = Vector3.zero;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
finalVelocity = MyComponents.rb.position + MyCurrentValue.horizontalVelocity * Time.fixedDeltaTime;
|
||||||
|
MyComponents.rb.MovePosition(finalVelocity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool GetIsMoving() => MyCurrentState.isMoving;
|
||||||
|
public bool GetIsDashing() => MyCurrentState.isDashing;
|
||||||
|
public float GetDashCooldown() => MyMovementOption.dashCooldown;
|
||||||
|
public float GetDashTime() => MyMovementOption.dashTime;
|
||||||
|
public void SetIsDashing(bool value) => MyCurrentState.isDashing = value;
|
||||||
|
public void SetEnableDashing(bool value) => MyCurrentState.enableDash = value;
|
||||||
|
public Vector3 GetPreviousMoveDirection() => MyCurrentValue.previousMoveDirection;
|
||||||
|
public void SetAnimator(Animator animator) => MyComponents.animator = animator;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* Gizmos, GUI
|
||||||
|
***********************************************************************/
|
||||||
|
#region Gizmos, GUI
|
||||||
|
|
||||||
|
private Vector3 gzGroundTouch;
|
||||||
|
private Vector3 gzForwardTouch;
|
||||||
|
|
||||||
|
[Header("Gizmos Option")] public bool showGizmos = true;
|
||||||
|
|
||||||
|
[SerializeField, Range(0.01f, 2f)] private float gizmoRadius = 0.05f;
|
||||||
|
|
||||||
|
[System.Diagnostics.Conditional("UNITY_EDITOR")]
|
||||||
|
private void OnDrawGizmos()
|
||||||
|
{
|
||||||
|
if (Application.isPlaying == false) return;
|
||||||
|
if (!showGizmos) return;
|
||||||
|
if (!enabled) return;
|
||||||
|
|
||||||
|
Gizmos.color = Color.red;
|
||||||
|
Gizmos.DrawSphere(gzGroundTouch, gizmoRadius);
|
||||||
|
|
||||||
|
if (MyCurrentState.isForwardBlocked)
|
||||||
|
{
|
||||||
|
Gizmos.color = Color.blue;
|
||||||
|
Gizmos.DrawSphere(gzForwardTouch, gizmoRadius);
|
||||||
|
}
|
||||||
|
|
||||||
|
Gizmos.color = Color.blue;
|
||||||
|
Gizmos.DrawLine(gzGroundTouch - MyCurrentValue.groundCross,
|
||||||
|
gzGroundTouch + MyCurrentValue.groundCross);
|
||||||
|
|
||||||
|
Gizmos.color = new Color(0.5f, 1.0f, 0.8f, 0.8f);
|
||||||
|
Gizmos.DrawWireSphere(CapsuleTopCenterPoint, castRadius);
|
||||||
|
Gizmos.DrawWireSphere(CapsuleBottomCenterPoint, castRadius);
|
||||||
|
}
|
||||||
|
|
||||||
|
[System.Diagnostics.Conditional("UNITY_EDITOR")]
|
||||||
|
private void GizmosUpdateValue<T>(ref T variable, in T value)
|
||||||
|
{
|
||||||
|
variable = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
[SerializeField, Space] private bool showGUI = true;
|
||||||
|
[SerializeField] private int guiTextSize = 28;
|
||||||
|
|
||||||
|
private float prevForwardSlopeAngle;
|
||||||
|
|
||||||
|
private void OnGUI()
|
||||||
|
{
|
||||||
|
if (Application.isPlaying == false) return;
|
||||||
|
if (!showGUI) return;
|
||||||
|
if (!enabled) return;
|
||||||
|
|
||||||
|
GUIStyle labelStyle = GUI.skin.label;
|
||||||
|
labelStyle.normal.textColor = Color.yellow;
|
||||||
|
labelStyle.fontSize = Math.Max(guiTextSize, 20);
|
||||||
|
|
||||||
|
prevForwardSlopeAngle = MyCurrentValue.forwardSlopeAngle == -90f
|
||||||
|
? prevForwardSlopeAngle
|
||||||
|
: MyCurrentValue.forwardSlopeAngle;
|
||||||
|
|
||||||
|
var oldColor = GUI.color;
|
||||||
|
GUI.color = new Color(0f, 0f, 0f, 0.5f);
|
||||||
|
GUI.Box(new Rect(40, 40, 420, 240), "");
|
||||||
|
GUI.color = oldColor;
|
||||||
|
|
||||||
|
GUILayout.BeginArea(new Rect(50, 50, 1000, 500));
|
||||||
|
GUILayout.Label($"Ground Height : {Mathf.Min(MyCurrentValue.groundDistance, 99.99f): 00.00}",
|
||||||
|
labelStyle);
|
||||||
|
GUILayout.Label($"Slope Angle(Ground) : {MyCurrentValue.groundSlopeAngle: 00.00}", labelStyle);
|
||||||
|
GUILayout.Label($"Slope Angle(Forward) : {prevForwardSlopeAngle: 00.00}", labelStyle);
|
||||||
|
GUILayout.Label($"Allowed Slope Angle : {MyMovementOption.maxSlopeAngle: 00.00}", labelStyle);
|
||||||
|
GUILayout.Label($"Current Speed Mag : {MyCurrentValue.horizontalVelocity.magnitude: 00.00}",
|
||||||
|
labelStyle);
|
||||||
|
GUILayout.EndArea();
|
||||||
|
|
||||||
|
float sWidth = Screen.width;
|
||||||
|
float sHeight = Screen.height;
|
||||||
|
|
||||||
|
GUIStyle RTLabelStyle = GUI.skin.label;
|
||||||
|
RTLabelStyle.fontSize = 20;
|
||||||
|
RTLabelStyle.normal.textColor = Color.green;
|
||||||
|
|
||||||
|
oldColor = GUI.color;
|
||||||
|
GUI.color = new Color(1f, 1f, 1f, 0.5f);
|
||||||
|
GUI.Box(new Rect(sWidth - 355f, 5f, 340f, 100f), "");
|
||||||
|
GUI.color = oldColor;
|
||||||
|
|
||||||
|
var yPos = 10f;
|
||||||
|
GUI.Label(new Rect(sWidth - 350f, yPos, 150f, 30f), $"Speed : {MyMovementOption.moveSpeed: 00.00}",
|
||||||
|
RTLabelStyle);
|
||||||
|
MyMovementOption.moveSpeed = GUI.HorizontalSlider(new Rect(sWidth - 200f, yPos + 10f, 180f, 20f),
|
||||||
|
MyMovementOption.moveSpeed, 1f, 10f);
|
||||||
|
|
||||||
|
yPos += 20f;
|
||||||
|
GUI.Label(new Rect(sWidth - 350f, yPos, 150f, 30f), $"Max Slope : {MyMovementOption.maxSlopeAngle: 00}",
|
||||||
|
RTLabelStyle);
|
||||||
|
MyMovementOption.maxSlopeAngle = (int)GUI.HorizontalSlider(
|
||||||
|
new Rect(sWidth - 200f, yPos + 10f, 180f, 20f), MyMovementOption.maxSlopeAngle, 1f, 75f);
|
||||||
|
|
||||||
|
labelStyle.fontSize = Math.Max(guiTextSize, 20);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
@ -5,32 +5,36 @@ namespace BlueWaterProject
|
|||||||
{
|
{
|
||||||
public class ComboAttack : StateMachineBehaviour
|
public class ComboAttack : StateMachineBehaviour
|
||||||
{
|
{
|
||||||
private CombatPlayer combatPlayer;
|
private CombatPlayerController combatPlayerController;
|
||||||
|
|
||||||
public override void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
|
public override void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
|
||||||
{
|
{
|
||||||
if (combatPlayer == null)
|
if (combatPlayerController == null)
|
||||||
{
|
{
|
||||||
combatPlayer = animator.GetComponentInParent<CombatPlayer>();
|
combatPlayerController = animator.GetComponentInParent<CombatPlayerController>();
|
||||||
}
|
}
|
||||||
combatPlayer.IsAttacking = true;
|
var animationLength = stateInfo.length;
|
||||||
combatPlayer.IsComboPossible = true;
|
animator.speed = animationLength / combatPlayerController.GetAttackTime();
|
||||||
|
|
||||||
|
combatPlayerController.SetIsAttacking(true);
|
||||||
|
combatPlayerController.SetIsComboPossible(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
|
public override void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
|
||||||
{
|
{
|
||||||
if (stateInfo.normalizedTime >= 1f)
|
if (stateInfo.normalizedTime >= 1f)
|
||||||
{
|
{
|
||||||
animator.SetBool(combatPlayer.isAttackingHash, false);
|
animator.SetBool(CombatPlayerController.IsAttackingHash, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
|
public override void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
|
||||||
{
|
{
|
||||||
combatPlayer.IsComboPossible = false;
|
animator.speed = 1f;
|
||||||
combatPlayer.IsComboAttacking = false;
|
combatPlayerController.SetIsComboPossible(false);
|
||||||
combatPlayer.IsAttacking = false;
|
combatPlayerController.SetIsComboAttacking(false);
|
||||||
animator.SetBool(combatPlayer.isAttackingHash, false);
|
combatPlayerController.SetIsAttacking(false);
|
||||||
|
animator.SetBool(CombatPlayerController.IsAttackingHash, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -5,41 +5,36 @@ namespace BlueWaterProject
|
|||||||
{
|
{
|
||||||
public class Dash : StateMachineBehaviour
|
public class Dash : StateMachineBehaviour
|
||||||
{
|
{
|
||||||
private CombatPlayer combatPlayer;
|
private CombatPlayerController combatPlayerController;
|
||||||
|
|
||||||
public override void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
|
public override void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
|
||||||
{
|
{
|
||||||
if (combatPlayer == null)
|
if (combatPlayerController == null)
|
||||||
{
|
{
|
||||||
combatPlayer = animator.GetComponentInParent<CombatPlayer>();
|
combatPlayerController = animator.GetComponentInParent<CombatPlayerController>();
|
||||||
}
|
}
|
||||||
combatPlayer.IsDashing = true;
|
var animationLength = stateInfo.length;
|
||||||
combatPlayer.EnableDash = false;
|
animator.speed = animationLength / combatPlayerController.GetDashTime();
|
||||||
|
|
||||||
|
combatPlayerController.SetIsDashing(true);
|
||||||
|
combatPlayerController.SetEnableDashing(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
|
public override void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
|
||||||
{
|
{
|
||||||
// var dashDirection = combatPlayer.PreviousDirection;
|
|
||||||
//
|
|
||||||
// if (combatPlayer.IsOnSlope())
|
|
||||||
// {
|
|
||||||
// dashDirection = Vector3.ProjectOnPlane(dashDirection, combatPlayer.GetSlopeHit().normal).normalized;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// combatPlayer.Rb.velocity = dashDirection * combatPlayer.DashForce;
|
|
||||||
|
|
||||||
if (stateInfo.normalizedTime >= 1.0f)
|
if (stateInfo.normalizedTime >= 1.0f)
|
||||||
{
|
{
|
||||||
animator.SetBool(combatPlayer.isDashingHash, false);
|
animator.SetBool(PhysicsMovement.IsDashingHash, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
|
public override void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
|
||||||
{
|
{
|
||||||
combatPlayer.IsDashing = false;
|
animator.speed = 1f;
|
||||||
animator.SetBool(combatPlayer.isDashingHash, false);
|
combatPlayerController.SetIsDashing(false);
|
||||||
|
animator.SetBool(PhysicsMovement.IsDashingHash, false);
|
||||||
|
|
||||||
combatPlayer.CoolDown(combatPlayer.DashCooldown, () => combatPlayer.EnableDash = true);
|
combatPlayerController.CoolDown(combatPlayerController.GetDashCooldown(), () => combatPlayerController.SetEnableDashing(true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -0,0 +1,101 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!74 &7400000
|
||||||
|
AnimationClip:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_Name: BackDash
|
||||||
|
serializedVersion: 7
|
||||||
|
m_Legacy: 0
|
||||||
|
m_Compressed: 0
|
||||||
|
m_UseHighQualityCurve: 1
|
||||||
|
m_RotationCurves: []
|
||||||
|
m_CompressedRotationCurves: []
|
||||||
|
m_EulerCurves: []
|
||||||
|
m_PositionCurves: []
|
||||||
|
m_ScaleCurves: []
|
||||||
|
m_FloatCurves: []
|
||||||
|
m_PPtrCurves:
|
||||||
|
- serializedVersion: 2
|
||||||
|
curve:
|
||||||
|
- time: 0
|
||||||
|
value: {fileID: 4010818287206423529, guid: 3799083e0fb2447b58c45499eaf37bd0,
|
||||||
|
type: 3}
|
||||||
|
- time: 0.08
|
||||||
|
value: {fileID: -4053654354307959872, guid: 3799083e0fb2447b58c45499eaf37bd0,
|
||||||
|
type: 3}
|
||||||
|
- time: 0.16
|
||||||
|
value: {fileID: 4124850773902862070, guid: 3799083e0fb2447b58c45499eaf37bd0,
|
||||||
|
type: 3}
|
||||||
|
- time: 0.24
|
||||||
|
value: {fileID: -4366721053727917600, guid: 3799083e0fb2447b58c45499eaf37bd0,
|
||||||
|
type: 3}
|
||||||
|
- time: 0.32
|
||||||
|
value: {fileID: -3589362433014018674, guid: 3799083e0fb2447b58c45499eaf37bd0,
|
||||||
|
type: 3}
|
||||||
|
- time: 0.4
|
||||||
|
value: {fileID: 1363422056328517653, guid: 3799083e0fb2447b58c45499eaf37bd0,
|
||||||
|
type: 3}
|
||||||
|
- time: 0.48
|
||||||
|
value: {fileID: -3862805103302402338, guid: 3799083e0fb2447b58c45499eaf37bd0,
|
||||||
|
type: 3}
|
||||||
|
- time: 0.56
|
||||||
|
value: {fileID: -3862805103302402338, guid: 3799083e0fb2447b58c45499eaf37bd0,
|
||||||
|
type: 3}
|
||||||
|
attribute: m_Sprite
|
||||||
|
path:
|
||||||
|
classID: 212
|
||||||
|
script: {fileID: 0}
|
||||||
|
flags: 2
|
||||||
|
m_SampleRate: 100
|
||||||
|
m_WrapMode: 0
|
||||||
|
m_Bounds:
|
||||||
|
m_Center: {x: 0, y: 0, z: 0}
|
||||||
|
m_Extent: {x: 0, y: 0, z: 0}
|
||||||
|
m_ClipBindingConstant:
|
||||||
|
genericBindings:
|
||||||
|
- serializedVersion: 2
|
||||||
|
path: 0
|
||||||
|
attribute: 0
|
||||||
|
script: {fileID: 0}
|
||||||
|
typeID: 212
|
||||||
|
customType: 23
|
||||||
|
isPPtrCurve: 1
|
||||||
|
isIntCurve: 0
|
||||||
|
isSerializeReferenceCurve: 0
|
||||||
|
pptrCurveMapping:
|
||||||
|
- {fileID: 4010818287206423529, guid: 3799083e0fb2447b58c45499eaf37bd0, type: 3}
|
||||||
|
- {fileID: -4053654354307959872, guid: 3799083e0fb2447b58c45499eaf37bd0, type: 3}
|
||||||
|
- {fileID: 4124850773902862070, guid: 3799083e0fb2447b58c45499eaf37bd0, type: 3}
|
||||||
|
- {fileID: -4366721053727917600, guid: 3799083e0fb2447b58c45499eaf37bd0, type: 3}
|
||||||
|
- {fileID: -3589362433014018674, guid: 3799083e0fb2447b58c45499eaf37bd0, type: 3}
|
||||||
|
- {fileID: 1363422056328517653, guid: 3799083e0fb2447b58c45499eaf37bd0, type: 3}
|
||||||
|
- {fileID: -3862805103302402338, guid: 3799083e0fb2447b58c45499eaf37bd0, type: 3}
|
||||||
|
- {fileID: -3862805103302402338, guid: 3799083e0fb2447b58c45499eaf37bd0, type: 3}
|
||||||
|
m_AnimationClipSettings:
|
||||||
|
serializedVersion: 2
|
||||||
|
m_AdditiveReferencePoseClip: {fileID: 0}
|
||||||
|
m_AdditiveReferencePoseTime: 0
|
||||||
|
m_StartTime: 0
|
||||||
|
m_StopTime: 0.57
|
||||||
|
m_OrientationOffsetY: 0
|
||||||
|
m_Level: 0
|
||||||
|
m_CycleOffset: 0
|
||||||
|
m_HasAdditiveReferencePose: 0
|
||||||
|
m_LoopTime: 1
|
||||||
|
m_LoopBlend: 0
|
||||||
|
m_LoopBlendOrientation: 0
|
||||||
|
m_LoopBlendPositionY: 0
|
||||||
|
m_LoopBlendPositionXZ: 0
|
||||||
|
m_KeepOriginalOrientation: 0
|
||||||
|
m_KeepOriginalPositionY: 0
|
||||||
|
m_KeepOriginalPositionXZ: 0
|
||||||
|
m_HeightFromFeet: 0
|
||||||
|
m_Mirror: 0
|
||||||
|
m_EditorCurves: []
|
||||||
|
m_EulerEditorCurves: []
|
||||||
|
m_HasGenericRootTransform: 0
|
||||||
|
m_HasMotionFloatCurves: 0
|
||||||
|
m_Events: []
|
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 8fe0fe11deca7064aaba73b53537cbb8
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 7400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,101 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!74 &7400000
|
||||||
|
AnimationClip:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_Name: FrontDash
|
||||||
|
serializedVersion: 7
|
||||||
|
m_Legacy: 0
|
||||||
|
m_Compressed: 0
|
||||||
|
m_UseHighQualityCurve: 1
|
||||||
|
m_RotationCurves: []
|
||||||
|
m_CompressedRotationCurves: []
|
||||||
|
m_EulerCurves: []
|
||||||
|
m_PositionCurves: []
|
||||||
|
m_ScaleCurves: []
|
||||||
|
m_FloatCurves: []
|
||||||
|
m_PPtrCurves:
|
||||||
|
- serializedVersion: 2
|
||||||
|
curve:
|
||||||
|
- time: 0
|
||||||
|
value: {fileID: -9154204961782164589, guid: 88b84319f88e542e495fc1f6338dc3ab,
|
||||||
|
type: 3}
|
||||||
|
- time: 0.08
|
||||||
|
value: {fileID: -3658744280763577496, guid: 88b84319f88e542e495fc1f6338dc3ab,
|
||||||
|
type: 3}
|
||||||
|
- time: 0.16
|
||||||
|
value: {fileID: -2197278150333076600, guid: 88b84319f88e542e495fc1f6338dc3ab,
|
||||||
|
type: 3}
|
||||||
|
- time: 0.24
|
||||||
|
value: {fileID: 5445867137363800702, guid: 88b84319f88e542e495fc1f6338dc3ab,
|
||||||
|
type: 3}
|
||||||
|
- time: 0.32
|
||||||
|
value: {fileID: -8674120543164084762, guid: 88b84319f88e542e495fc1f6338dc3ab,
|
||||||
|
type: 3}
|
||||||
|
- time: 0.4
|
||||||
|
value: {fileID: 7659963852650702022, guid: 88b84319f88e542e495fc1f6338dc3ab,
|
||||||
|
type: 3}
|
||||||
|
- time: 0.48
|
||||||
|
value: {fileID: -604151334296838673, guid: 88b84319f88e542e495fc1f6338dc3ab,
|
||||||
|
type: 3}
|
||||||
|
- time: 0.56
|
||||||
|
value: {fileID: -604151334296838673, guid: 88b84319f88e542e495fc1f6338dc3ab,
|
||||||
|
type: 3}
|
||||||
|
attribute: m_Sprite
|
||||||
|
path:
|
||||||
|
classID: 212
|
||||||
|
script: {fileID: 0}
|
||||||
|
flags: 2
|
||||||
|
m_SampleRate: 100
|
||||||
|
m_WrapMode: 0
|
||||||
|
m_Bounds:
|
||||||
|
m_Center: {x: 0, y: 0, z: 0}
|
||||||
|
m_Extent: {x: 0, y: 0, z: 0}
|
||||||
|
m_ClipBindingConstant:
|
||||||
|
genericBindings:
|
||||||
|
- serializedVersion: 2
|
||||||
|
path: 0
|
||||||
|
attribute: 0
|
||||||
|
script: {fileID: 0}
|
||||||
|
typeID: 212
|
||||||
|
customType: 23
|
||||||
|
isPPtrCurve: 1
|
||||||
|
isIntCurve: 0
|
||||||
|
isSerializeReferenceCurve: 0
|
||||||
|
pptrCurveMapping:
|
||||||
|
- {fileID: -9154204961782164589, guid: 88b84319f88e542e495fc1f6338dc3ab, type: 3}
|
||||||
|
- {fileID: -3658744280763577496, guid: 88b84319f88e542e495fc1f6338dc3ab, type: 3}
|
||||||
|
- {fileID: -2197278150333076600, guid: 88b84319f88e542e495fc1f6338dc3ab, type: 3}
|
||||||
|
- {fileID: 5445867137363800702, guid: 88b84319f88e542e495fc1f6338dc3ab, type: 3}
|
||||||
|
- {fileID: -8674120543164084762, guid: 88b84319f88e542e495fc1f6338dc3ab, type: 3}
|
||||||
|
- {fileID: 7659963852650702022, guid: 88b84319f88e542e495fc1f6338dc3ab, type: 3}
|
||||||
|
- {fileID: -604151334296838673, guid: 88b84319f88e542e495fc1f6338dc3ab, type: 3}
|
||||||
|
- {fileID: -604151334296838673, guid: 88b84319f88e542e495fc1f6338dc3ab, type: 3}
|
||||||
|
m_AnimationClipSettings:
|
||||||
|
serializedVersion: 2
|
||||||
|
m_AdditiveReferencePoseClip: {fileID: 0}
|
||||||
|
m_AdditiveReferencePoseTime: 0
|
||||||
|
m_StartTime: 0
|
||||||
|
m_StopTime: 0.57
|
||||||
|
m_OrientationOffsetY: 0
|
||||||
|
m_Level: 0
|
||||||
|
m_CycleOffset: 0
|
||||||
|
m_HasAdditiveReferencePose: 0
|
||||||
|
m_LoopTime: 1
|
||||||
|
m_LoopBlend: 0
|
||||||
|
m_LoopBlendOrientation: 0
|
||||||
|
m_LoopBlendPositionY: 0
|
||||||
|
m_LoopBlendPositionXZ: 0
|
||||||
|
m_KeepOriginalOrientation: 0
|
||||||
|
m_KeepOriginalPositionY: 0
|
||||||
|
m_KeepOriginalPositionXZ: 0
|
||||||
|
m_HeightFromFeet: 0
|
||||||
|
m_Mirror: 0
|
||||||
|
m_EditorCurves: []
|
||||||
|
m_EulerEditorCurves: []
|
||||||
|
m_HasGenericRootTransform: 0
|
||||||
|
m_HasMotionFloatCurves: 0
|
||||||
|
m_Events: []
|
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: ca3c514e04cb41a48816d372ab1e9071
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 7400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,101 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!74 &7400000
|
||||||
|
AnimationClip:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_Name: SideDash
|
||||||
|
serializedVersion: 7
|
||||||
|
m_Legacy: 0
|
||||||
|
m_Compressed: 0
|
||||||
|
m_UseHighQualityCurve: 1
|
||||||
|
m_RotationCurves: []
|
||||||
|
m_CompressedRotationCurves: []
|
||||||
|
m_EulerCurves: []
|
||||||
|
m_PositionCurves: []
|
||||||
|
m_ScaleCurves: []
|
||||||
|
m_FloatCurves: []
|
||||||
|
m_PPtrCurves:
|
||||||
|
- serializedVersion: 2
|
||||||
|
curve:
|
||||||
|
- time: 0
|
||||||
|
value: {fileID: 3033537662187923395, guid: defcc8125c9264ebc9dc3d4026bcb572,
|
||||||
|
type: 3}
|
||||||
|
- time: 0.08
|
||||||
|
value: {fileID: -2693056187368311098, guid: defcc8125c9264ebc9dc3d4026bcb572,
|
||||||
|
type: 3}
|
||||||
|
- time: 0.16
|
||||||
|
value: {fileID: 5184523171927287766, guid: defcc8125c9264ebc9dc3d4026bcb572,
|
||||||
|
type: 3}
|
||||||
|
- time: 0.24
|
||||||
|
value: {fileID: -8235170841148880371, guid: defcc8125c9264ebc9dc3d4026bcb572,
|
||||||
|
type: 3}
|
||||||
|
- time: 0.32
|
||||||
|
value: {fileID: -1750194370219178006, guid: defcc8125c9264ebc9dc3d4026bcb572,
|
||||||
|
type: 3}
|
||||||
|
- time: 0.4
|
||||||
|
value: {fileID: 4756864213286410935, guid: defcc8125c9264ebc9dc3d4026bcb572,
|
||||||
|
type: 3}
|
||||||
|
- time: 0.48
|
||||||
|
value: {fileID: 4040061753010727598, guid: defcc8125c9264ebc9dc3d4026bcb572,
|
||||||
|
type: 3}
|
||||||
|
- time: 0.56
|
||||||
|
value: {fileID: 6229803037504010689, guid: defcc8125c9264ebc9dc3d4026bcb572,
|
||||||
|
type: 3}
|
||||||
|
attribute: m_Sprite
|
||||||
|
path:
|
||||||
|
classID: 212
|
||||||
|
script: {fileID: 0}
|
||||||
|
flags: 2
|
||||||
|
m_SampleRate: 100
|
||||||
|
m_WrapMode: 0
|
||||||
|
m_Bounds:
|
||||||
|
m_Center: {x: 0, y: 0, z: 0}
|
||||||
|
m_Extent: {x: 0, y: 0, z: 0}
|
||||||
|
m_ClipBindingConstant:
|
||||||
|
genericBindings:
|
||||||
|
- serializedVersion: 2
|
||||||
|
path: 0
|
||||||
|
attribute: 0
|
||||||
|
script: {fileID: 0}
|
||||||
|
typeID: 212
|
||||||
|
customType: 23
|
||||||
|
isPPtrCurve: 1
|
||||||
|
isIntCurve: 0
|
||||||
|
isSerializeReferenceCurve: 0
|
||||||
|
pptrCurveMapping:
|
||||||
|
- {fileID: 3033537662187923395, guid: defcc8125c9264ebc9dc3d4026bcb572, type: 3}
|
||||||
|
- {fileID: -2693056187368311098, guid: defcc8125c9264ebc9dc3d4026bcb572, type: 3}
|
||||||
|
- {fileID: 5184523171927287766, guid: defcc8125c9264ebc9dc3d4026bcb572, type: 3}
|
||||||
|
- {fileID: -8235170841148880371, guid: defcc8125c9264ebc9dc3d4026bcb572, type: 3}
|
||||||
|
- {fileID: -1750194370219178006, guid: defcc8125c9264ebc9dc3d4026bcb572, type: 3}
|
||||||
|
- {fileID: 4756864213286410935, guid: defcc8125c9264ebc9dc3d4026bcb572, type: 3}
|
||||||
|
- {fileID: 4040061753010727598, guid: defcc8125c9264ebc9dc3d4026bcb572, type: 3}
|
||||||
|
- {fileID: 6229803037504010689, guid: defcc8125c9264ebc9dc3d4026bcb572, type: 3}
|
||||||
|
m_AnimationClipSettings:
|
||||||
|
serializedVersion: 2
|
||||||
|
m_AdditiveReferencePoseClip: {fileID: 0}
|
||||||
|
m_AdditiveReferencePoseTime: 0
|
||||||
|
m_StartTime: 0
|
||||||
|
m_StopTime: 0.57
|
||||||
|
m_OrientationOffsetY: 0
|
||||||
|
m_Level: 0
|
||||||
|
m_CycleOffset: 0
|
||||||
|
m_HasAdditiveReferencePose: 0
|
||||||
|
m_LoopTime: 1
|
||||||
|
m_LoopBlend: 0
|
||||||
|
m_LoopBlendOrientation: 0
|
||||||
|
m_LoopBlendPositionY: 0
|
||||||
|
m_LoopBlendPositionXZ: 0
|
||||||
|
m_KeepOriginalOrientation: 0
|
||||||
|
m_KeepOriginalPositionY: 0
|
||||||
|
m_KeepOriginalPositionXZ: 0
|
||||||
|
m_HeightFromFeet: 0
|
||||||
|
m_Mirror: 0
|
||||||
|
m_EditorCurves: []
|
||||||
|
m_EulerEditorCurves: []
|
||||||
|
m_HasGenericRootTransform: 0
|
||||||
|
m_HasMotionFloatCurves: 0
|
||||||
|
m_Events: []
|
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 9f05bb89ed7085e43a607922b7f14ae9
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 7400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -12,7 +12,6 @@ GameObject:
|
|||||||
- component: {fileID: 1564585232883027199}
|
- component: {fileID: 1564585232883027199}
|
||||||
- component: {fileID: 3138574858532492034}
|
- component: {fileID: 3138574858532492034}
|
||||||
- component: {fileID: 6230115818254112785}
|
- component: {fileID: 6230115818254112785}
|
||||||
- component: {fileID: 6407473152449951742}
|
|
||||||
m_Layer: 0
|
m_Layer: 0
|
||||||
m_Name: VisualLook
|
m_Name: VisualLook
|
||||||
m_TagString: Untagged
|
m_TagString: Untagged
|
||||||
@ -124,28 +123,6 @@ MonoBehaviour:
|
|||||||
m_Script: {fileID: 11500000, guid: e16f62f7d451b504fae5474be03a6da7, type: 3}
|
m_Script: {fileID: 11500000, guid: e16f62f7d451b504fae5474be03a6da7, type: 3}
|
||||||
m_Name:
|
m_Name:
|
||||||
m_EditorClassIdentifier:
|
m_EditorClassIdentifier:
|
||||||
--- !u!64 &6407473152449951742
|
|
||||||
MeshCollider:
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
|
||||||
m_PrefabInstance: {fileID: 0}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
m_GameObject: {fileID: 87732673861481097}
|
|
||||||
m_Material: {fileID: 0}
|
|
||||||
m_IncludeLayers:
|
|
||||||
serializedVersion: 2
|
|
||||||
m_Bits: 0
|
|
||||||
m_ExcludeLayers:
|
|
||||||
serializedVersion: 2
|
|
||||||
m_Bits: 0
|
|
||||||
m_LayerOverridePriority: 0
|
|
||||||
m_IsTrigger: 0
|
|
||||||
m_ProvidesContacts: 0
|
|
||||||
m_Enabled: 1
|
|
||||||
serializedVersion: 5
|
|
||||||
m_Convex: 0
|
|
||||||
m_CookingOptions: 30
|
|
||||||
m_Mesh: {fileID: 0}
|
|
||||||
--- !u!1 &2391945466483065398
|
--- !u!1 &2391945466483065398
|
||||||
GameObject:
|
GameObject:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
@ -158,8 +135,8 @@ GameObject:
|
|||||||
- component: {fileID: 6858674358337067996}
|
- component: {fileID: 6858674358337067996}
|
||||||
- component: {fileID: 7729150195808218711}
|
- component: {fileID: 7729150195808218711}
|
||||||
- component: {fileID: 6121288256300454469}
|
- component: {fileID: 6121288256300454469}
|
||||||
- component: {fileID: 4906016173319036404}
|
- component: {fileID: 5799904028004926704}
|
||||||
- component: {fileID: 1096317451054001340}
|
- component: {fileID: 803982772767150407}
|
||||||
m_Layer: 9
|
m_Layer: 9
|
||||||
m_Name: CombatPlayer
|
m_Name: CombatPlayer
|
||||||
m_TagString: Untagged
|
m_TagString: Untagged
|
||||||
@ -181,7 +158,6 @@ Transform:
|
|||||||
m_ConstrainProportionsScale: 0
|
m_ConstrainProportionsScale: 0
|
||||||
m_Children:
|
m_Children:
|
||||||
- {fileID: 8557381169392297019}
|
- {fileID: 8557381169392297019}
|
||||||
- {fileID: 7407663186225048994}
|
|
||||||
m_Father: {fileID: 0}
|
m_Father: {fileID: 0}
|
||||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
--- !u!136 &6858674358337067996
|
--- !u!136 &6858674358337067996
|
||||||
@ -265,46 +241,41 @@ MonoBehaviour:
|
|||||||
m_DefaultActionMap: Player
|
m_DefaultActionMap: Player
|
||||||
m_SplitScreenIndex: -1
|
m_SplitScreenIndex: -1
|
||||||
m_Camera: {fileID: 0}
|
m_Camera: {fileID: 0}
|
||||||
--- !u!114 &4906016173319036404
|
--- !u!114 &5799904028004926704
|
||||||
MonoBehaviour:
|
MonoBehaviour:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
m_PrefabInstance: {fileID: 0}
|
m_PrefabInstance: {fileID: 0}
|
||||||
m_PrefabAsset: {fileID: 0}
|
m_PrefabAsset: {fileID: 0}
|
||||||
m_GameObject: {fileID: 2391945466483065398}
|
m_GameObject: {fileID: 2391945466483065398}
|
||||||
m_Enabled: 0
|
m_Enabled: 1
|
||||||
m_EditorHideFlags: 0
|
m_EditorHideFlags: 0
|
||||||
m_Script: {fileID: 11500000, guid: 5258cddac7934c1469d147dddbdb5023, type: 3}
|
m_Script: {fileID: 11500000, guid: d85ab5237d86f7a43a553f00be353476, type: 3}
|
||||||
m_Name:
|
m_Name:
|
||||||
m_EditorClassIdentifier:
|
m_EditorClassIdentifier:
|
||||||
autoInit: 0
|
<MyComponents>k__BackingField:
|
||||||
maxHp: 100
|
playerInput: {fileID: 6121288256300454469}
|
||||||
currentHp: 0
|
visualLook: {fileID: 8557381169392297019}
|
||||||
moveSpeed: 10
|
animator: {fileID: 3138574858532492034}
|
||||||
maxSlopeAngle: 50
|
movement: {fileID: 803982772767150407}
|
||||||
<DashForce>k__BackingField: 20
|
<MyCharacterOption>k__BackingField:
|
||||||
<DashCooldown>k__BackingField: 0.5
|
maxHp: 100
|
||||||
<IsDashing>k__BackingField: 0
|
maxHitNum: 10
|
||||||
<EnableDash>k__BackingField: 1
|
attackDamage: 10
|
||||||
<MaxHitNum>k__BackingField: 10
|
attackRange: 1.5
|
||||||
<AttackDamage>k__BackingField: 10
|
attackAngle: 180
|
||||||
<AttackRange>k__BackingField: 1.5
|
comboTime: 0.5
|
||||||
<AttackAngle>k__BackingField: 180
|
targetLayer:
|
||||||
<ComboTime>k__BackingField: 0.5
|
serializedVersion: 2
|
||||||
<TargetLayer>k__BackingField:
|
m_Bits: 512
|
||||||
serializedVersion: 2
|
<MyCurrentState>k__BackingField:
|
||||||
m_Bits: 8192
|
isAttacking: 0
|
||||||
<IsAttacking>k__BackingField: 0
|
isComboPossible: 0
|
||||||
<IsComboAttacking>k__BackingField: 0
|
isComboAttacking: 0
|
||||||
<IsComboPossible>k__BackingField: 0
|
<MyCurrentValue>k__BackingField:
|
||||||
playerInput: {fileID: 6121288256300454469}
|
currentHp: 0
|
||||||
<Rb>k__BackingField: {fileID: 7729150195808218711}
|
hitColliders: []
|
||||||
visualLook: {fileID: 8557381169392297019}
|
--- !u!114 &803982772767150407
|
||||||
<Animator>k__BackingField: {fileID: 3138574858532492034}
|
|
||||||
groundCheck: {fileID: 7407663186225048994}
|
|
||||||
nextFrameCoefficient: 3
|
|
||||||
<HitColliders>k__BackingField: []
|
|
||||||
--- !u!114 &1096317451054001340
|
|
||||||
MonoBehaviour:
|
MonoBehaviour:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
@ -316,77 +287,45 @@ MonoBehaviour:
|
|||||||
m_Script: {fileID: 11500000, guid: 01fef22c346a235499c530436f7c9c53, type: 3}
|
m_Script: {fileID: 11500000, guid: 01fef22c346a235499c530436f7c9c53, type: 3}
|
||||||
m_Name:
|
m_Name:
|
||||||
m_EditorClassIdentifier:
|
m_EditorClassIdentifier:
|
||||||
<PlayerComponents>k__BackingField:
|
<MyComponents>k__BackingField:
|
||||||
playerInput: {fileID: 6121288256300454469}
|
|
||||||
capsuleCollider: {fileID: 6858674358337067996}
|
capsuleCollider: {fileID: 6858674358337067996}
|
||||||
rb: {fileID: 7729150195808218711}
|
rb: {fileID: 7729150195808218711}
|
||||||
visualLook: {fileID: 8557381169392297019}
|
animator: {fileID: 0}
|
||||||
animator: {fileID: 3138574858532492034}
|
<MyCheckOption>k__BackingField:
|
||||||
groundCheck: {fileID: 7407663186225048994}
|
groundLayer:
|
||||||
<PlayerCheckOption>k__BackingField:
|
|
||||||
groundLayerMask:
|
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
m_Bits: 8
|
m_Bits: 8
|
||||||
forwardCheckDistance: 0.1
|
forwardCheckDistance: 0.1
|
||||||
groundCheckDistance: 2
|
groundCheckDistance: 2
|
||||||
groundCheckThreshold: 0.01
|
groundCheckThreshold: 0.01
|
||||||
<PlayerMovementOption>k__BackingField:
|
<MyMovementOption>k__BackingField:
|
||||||
speed: 10
|
moveSpeed: 10
|
||||||
runningCoefficient: 1.5
|
|
||||||
maxSlopeAngle: 50
|
maxSlopeAngle: 50
|
||||||
slopeAccel: 1
|
dashSpeed: 30
|
||||||
gravity: -9.81
|
dashTime: 0.2
|
||||||
<PlayerCurrentState>k__BackingField:
|
dashCooldown: 0.5
|
||||||
|
<MyCurrentState>k__BackingField:
|
||||||
isMoving: 0
|
isMoving: 0
|
||||||
isRunning: 0
|
|
||||||
isGrounded: 0
|
isGrounded: 0
|
||||||
|
isOnSlope: 0
|
||||||
isOnSteepSlope: 0
|
isOnSteepSlope: 0
|
||||||
isForwardBlocked: 0
|
isForwardBlocked: 0
|
||||||
isOutOfControl: 0
|
isOutOfControl: 0
|
||||||
<PlayerCurrentValue>k__BackingField:
|
isDashing: 0
|
||||||
worldMoveDirection: {x: 0, y: 0, z: 0}
|
enableDash: 1
|
||||||
|
<MyCurrentValue>k__BackingField:
|
||||||
|
movementInput: {x: 0, y: 0}
|
||||||
|
currentMoveDirection: {x: 0, y: 0, z: 0}
|
||||||
|
previousMoveDirection: {x: 0, y: 0, z: -1}
|
||||||
groundNormal: {x: 0, y: 0, z: 0}
|
groundNormal: {x: 0, y: 0, z: 0}
|
||||||
groundCross: {x: 0, y: 0, z: 0}
|
groundCross: {x: 0, y: 0, z: 0}
|
||||||
horizontalVelocity: {x: 0, y: 0, z: 0}
|
horizontalVelocity: {x: 0, y: 0, z: 0}
|
||||||
outOfControlDuration: 0
|
outOfControlDuration: 0
|
||||||
groundDistance: 0
|
groundDistance: 0
|
||||||
groundSlopeAngle: 0
|
groundSlopeAngle: 0
|
||||||
groundVerticalSlopeAngle: 0
|
|
||||||
forwardSlopeAngle: 0
|
forwardSlopeAngle: 0
|
||||||
slopeAccel: 0
|
gravity: {x: 0, y: 0, z: 0}
|
||||||
gravity: 0
|
|
||||||
showGizmos: 1
|
showGizmos: 1
|
||||||
gizmoRadius: 0.05
|
gizmoRadius: 0.05
|
||||||
showGUI: 1
|
showGUI: 1
|
||||||
guiTextSize: 28
|
guiTextSize: 28
|
||||||
--- !u!1 &3669261844365681366
|
|
||||||
GameObject:
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
|
||||||
m_PrefabInstance: {fileID: 0}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
serializedVersion: 6
|
|
||||||
m_Component:
|
|
||||||
- component: {fileID: 7407663186225048994}
|
|
||||||
m_Layer: 9
|
|
||||||
m_Name: GroundCheck
|
|
||||||
m_TagString: Untagged
|
|
||||||
m_Icon: {fileID: 0}
|
|
||||||
m_NavMeshLayer: 0
|
|
||||||
m_StaticEditorFlags: 0
|
|
||||||
m_IsActive: 1
|
|
||||||
--- !u!4 &7407663186225048994
|
|
||||||
Transform:
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
|
||||||
m_PrefabInstance: {fileID: 0}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
m_GameObject: {fileID: 3669261844365681366}
|
|
||||||
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: 0
|
|
||||||
m_Children: []
|
|
||||||
m_Father: {fileID: 8934240191915016273}
|
|
||||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
|
||||||
|
@ -697,8 +697,7 @@ BlendTree:
|
|||||||
m_Name: Blend Tree
|
m_Name: Blend Tree
|
||||||
m_Childs:
|
m_Childs:
|
||||||
- serializedVersion: 2
|
- serializedVersion: 2
|
||||||
m_Motion: {fileID: -8444228808809566427, guid: 88b84319f88e542e495fc1f6338dc3ab,
|
m_Motion: {fileID: 7400000, guid: ca3c514e04cb41a48816d372ab1e9071, type: 2}
|
||||||
type: 3}
|
|
||||||
m_Threshold: 0
|
m_Threshold: 0
|
||||||
m_Position: {x: 0, y: -1}
|
m_Position: {x: 0, y: -1}
|
||||||
m_TimeScale: 1
|
m_TimeScale: 1
|
||||||
@ -706,8 +705,7 @@ BlendTree:
|
|||||||
m_DirectBlendParameter: Blend
|
m_DirectBlendParameter: Blend
|
||||||
m_Mirror: 0
|
m_Mirror: 0
|
||||||
- serializedVersion: 2
|
- serializedVersion: 2
|
||||||
m_Motion: {fileID: -8444228808809566427, guid: defcc8125c9264ebc9dc3d4026bcb572,
|
m_Motion: {fileID: 7400000, guid: 9f05bb89ed7085e43a607922b7f14ae9, type: 2}
|
||||||
type: 3}
|
|
||||||
m_Threshold: 0.33333334
|
m_Threshold: 0.33333334
|
||||||
m_Position: {x: -0.9, y: 0}
|
m_Position: {x: -0.9, y: 0}
|
||||||
m_TimeScale: 1
|
m_TimeScale: 1
|
||||||
@ -715,8 +713,7 @@ BlendTree:
|
|||||||
m_DirectBlendParameter: Blend
|
m_DirectBlendParameter: Blend
|
||||||
m_Mirror: 0
|
m_Mirror: 0
|
||||||
- serializedVersion: 2
|
- serializedVersion: 2
|
||||||
m_Motion: {fileID: -8444228808809566427, guid: defcc8125c9264ebc9dc3d4026bcb572,
|
m_Motion: {fileID: 7400000, guid: 9f05bb89ed7085e43a607922b7f14ae9, type: 2}
|
||||||
type: 3}
|
|
||||||
m_Threshold: 0.6666667
|
m_Threshold: 0.6666667
|
||||||
m_Position: {x: 0.9, y: 0}
|
m_Position: {x: 0.9, y: 0}
|
||||||
m_TimeScale: 1
|
m_TimeScale: 1
|
||||||
@ -724,8 +721,7 @@ BlendTree:
|
|||||||
m_DirectBlendParameter: Blend
|
m_DirectBlendParameter: Blend
|
||||||
m_Mirror: 0
|
m_Mirror: 0
|
||||||
- serializedVersion: 2
|
- serializedVersion: 2
|
||||||
m_Motion: {fileID: -8444228808809566427, guid: 3799083e0fb2447b58c45499eaf37bd0,
|
m_Motion: {fileID: 7400000, guid: 8fe0fe11deca7064aaba73b53537cbb8, type: 2}
|
||||||
type: 3}
|
|
||||||
m_Threshold: 1
|
m_Threshold: 1
|
||||||
m_Position: {x: 0, y: 1}
|
m_Position: {x: 0, y: 1}
|
||||||
m_TimeScale: 1
|
m_TimeScale: 1
|
||||||
@ -759,7 +755,7 @@ AnimatorState:
|
|||||||
m_PrefabInstance: {fileID: 0}
|
m_PrefabInstance: {fileID: 0}
|
||||||
m_PrefabAsset: {fileID: 0}
|
m_PrefabAsset: {fileID: 0}
|
||||||
m_Name: DashState
|
m_Name: DashState
|
||||||
m_Speed: 3
|
m_Speed: 1
|
||||||
m_CycleOffset: 0
|
m_CycleOffset: 0
|
||||||
m_Transitions:
|
m_Transitions:
|
||||||
- {fileID: -4120808473508093546}
|
- {fileID: -4120808473508093546}
|
||||||
|
Loading…
Reference in New Issue
Block a user