OldBlueWater/BlueWater/Assets/02.Scripts/Character/Crewmate/Crewmate.cs
NTG c63377124f 슬라임 및 로직 수정(상세내용 아래 참고)
수정 내역
1. 토끼 이미지, 크기 변경
2. 슬라임 이미지(색감), 크기 변경
3. 슬라임 그림자 이미지 변경
4. 슬라임 얼룩자국 이미지(색감) 변경
5. 토끼 슬라임 최대 4단계로 변경
6. 맵 이동 및 재시작 과정에서 전투플레이어 삭제 후 생성하는 로직으로 변경
7. 1단계 슬라임이 점프할 때, 카메라 흔들림 효과 강화
8. 슬라임 시작 또는 분열할 때, 0.5초 무적 기능 추가

버그 수정 내역
1. 일반 슬라임이 본체로 인식되는 버그 수정
2. 간헐적으로 슬라임 얼룩 자국이 남아있는 버그 수정
3. 마지막 보스를 스킬로 잡을 때, 전투플레이어 오류 수정
4. 대쉬 중에 디버프를 받는 버그 수정
2024-05-12 17:41:13 +09:00

562 lines
21 KiB
C#

// using System;
// using System.Collections;
// using BehaviorDesigner.Runtime;
// using Sirenix.OdinInspector;
// using UnityEngine;
// using UnityEngine.AI;
// using UnityEngine.InputSystem;
// using UnityEngine.UI;
//
// // ReSharper disable once CheckNamespace
// namespace BlueWaterProject
// {
// [RequireComponent(typeof(PlayerInput))]
// public abstract class Crewmate : BaseCharacter, IDamageable, IAnimatorBridge, IAiView, INormalAttack, IInIslandPlayer
// {
// #region Properties and variables
//
// // DrawGizmos
// [Title("DrawGizmos")]
// [Tooltip("전체 Gizmos 그리기 여부")]
// [SerializeField] private bool isDrawGizmos = true;
//
// [ShowIf("@isDrawGizmos")]
// [Tooltip("타겟 인식 범위 그리기 여부")]
// [SerializeField] private bool isDrawViewRange = true;
//
// [ShowIf("@isDrawGizmos")]
// [Tooltip("이동제한 범위 그리기 여부")]
// [SerializeField] private bool isDrawDefenseRange = true;
//
// [ShowIf("@isDrawGizmos")]
// [Tooltip("타겟과의 상태 그리기 여부\n빨간색 = 공격 범위 밖\n파란색 = 공격 범위 안")]
// [SerializeField] private bool isDrawTargetRange = true;
//
// // Stat
// [field: Title("Stat")]
// [field: Tooltip("최대 체력 설정")]
// [field: SerializeField] public float MaxHp { get; private set; } = 100f;
//
// [field: Tooltip("현재 체력")]
// [field: SerializeField] public float CurrentHp { get; private set; }
//
// [field: Tooltip("이동 속도 설정")]
// [field: SerializeField] public float MoveSpd { get; set; } = 5f;
//
// [field: Tooltip("공격력 설정")]
// [field: SerializeField] public float Atk { get; private set; } = 10f;
//
// [field: Tooltip("공격 속도(다음 공격 주기)\nAtkCooldown = 2f (2초마다 1번 공격)")]
// [field: SerializeField] public float AtkCooldown { get; private set; } = 1f;
//
// [field: Tooltip("공격 사거리 설정")]
// [field: SerializeField] public float AtkRange { get; set; } = 1.5f;
//
// [field: Tooltip("이동 제한 범위 설정")]
// [field: SerializeField] public float DefenseRange { get; private set; } = 20f;
//
// [field: Tooltip("Idle 상태에서 랜덤으로 이동 여부")]
// [field: SerializeField] public bool IsRandomMove { get; set; }
//
// [field: ShowIf("@IsRandomMove")]
// [field: Tooltip("Idle 상태에서 이동하는 범위 설정")]
// [field: SerializeField] public float RandomMoveRange { get; set; }
//
// // HpSlider
// [Title("HpSlider")]
// [SerializeField] private bool useHpSlider = true;
//
// [ShowIf("@useHpSlider")]
// [Required("HpSlider 프리팹을 넣어주세요.")]
// [SerializeField] private GameObject hpSliderPrefab;
//
// [ShowIf("@useHpSlider")]
// [SerializeField] private Vector3 hpSliderOffset = Vector3.up;
//
// [ShowIf("@useHpSlider")]
// [DisableIf("@true")]
// [SerializeField] private Slider hpSlider;
//
// // Data
// [field: Title("Data")]
// [field: DisableIf("@true")]
// [field: SerializeField] public Vector3 DefensePos { get; set; }
// [field: DisableIf("@true")]
// [field: SerializeField] public bool IsCombated { get; set; }
// [field: DisableIf("@true")]
// [field: SerializeField] public bool BeAttackedInIdle { get; set; }
// [field: DisableIf("@true")]
// [field: SerializeField] public bool UseRigidbody { get; set; }
// [DisableIf("@true")]
// [SerializeField] private bool beAttacked;
// [DisableIf("@true")]
// [SerializeField] protected bool isAttacking;
//
// // 일반 변수
// public int CrewmatePrefabIndex { get; set; } = -1;
//
// protected Vector2 movementInput;
// protected bool usedNormalAttackCoroutine;
// protected WaitForSeconds waitAtkCooldown;
//
// // 컴포넌트
// public GameObject GameObject => gameObject;
// public Transform Transform => transform;
// public Rigidbody Rb { get; set; }
// public Collider MyCollider { get; set; }
// public NavMeshAgent Agent { get; set; }
// private BehaviorTree bt;
// private Transform unitRoot;
// protected Animator myAnimator;
// private Canvas worldSpaceCanvas;
//
// // Hash
// protected static readonly int RunStateHash = Animator.StringToHash("RunState");
// protected static readonly int AttackHash = Animator.StringToHash("Attack");
// protected static readonly int AttackStateHash = Animator.StringToHash("AttackState");
// protected static readonly int NormalStateHash = Animator.StringToHash("NormalState");
// protected static readonly int DieHash = Animator.StringToHash("Die");
//
// // Const
// private static readonly WaitForSeconds BeAttackedWaitTime = new(0.3f);
//
// #endregion
//
// #region abstract
//
// protected abstract IEnumerator NormalAttackCoroutine();
//
// #endregion
//
// #region Unity built-in methods
//
// protected override void Awake()
// {
// base.Awake();
//
// Rb = GetComponent<Rigidbody>();
// MyCollider = GetComponent<Collider>();
// Agent = GetComponent<NavMeshAgent>();
// bt = GetComponent<BehaviorTree>();
//
// unitRoot = transform.Find("UnitRoot");
// if (unitRoot == null)
// {
// print("UnitRoot를 찾을 수 없습니다.");
// }
// else
// {
// myAnimator = unitRoot.GetComponent<Animator>();
// if (myAnimator == null)
// {
// print("myAnimator를 찾을 수 없습니다.");
// }
// }
//
// worldSpaceCanvas = GameObject.Find("WorldSpaceCanvas")?.GetComponent<Canvas>();
// if (worldSpaceCanvas == null)
// {
// print("WorldSpaceCanvas 찾을 수 없습니다.");
// }
// else
// {
// if (useHpSlider)
// {
// hpSlider = Instantiate(hpSliderPrefab, worldSpaceCanvas.transform).GetComponent<Slider>();
// hpSlider.gameObject.name = gameObject.name + " HpSlider";
// hpSlider.transform.rotation = unitRoot.transform.rotation;
// }
// }
// }
//
// protected override void Start()
// {
// base.Start();
//
// TargetLayer = LayerMask.GetMask("Enemy");
//
// waitAtkCooldown = new WaitForSeconds(AtkCooldown);
// Agent.updateRotation = false;
//
// SetAgentSpeed(MoveSpd);
// hpSlider.maxValue = MaxHp;
// SetCurrentHp(MaxHp);
// }
//
// protected override void Update()
// {
// switch (useHpSlider)
// {
// case true when CurrentHp > 0 && CurrentHp < MaxHp:
// {
// if (!hpSlider.gameObject.activeSelf)
// {
// hpSlider.gameObject.SetActive(true);
// }
//
// var localOffset = unitRoot.TransformPoint(hpSliderOffset);
// hpSlider.transform.position = localOffset;
// break;
// }
// case true when CurrentHp <= 0 || CurrentHp >= MaxHp:
// {
// if (hpSlider.gameObject.activeSelf)
// {
// hpSlider.gameObject.SetActive(false);
// }
//
// break;
// }
// }
//
// if (CurrentHp <= 0) return;
//
// if (GameManager.Inst.CurrentInIslandPlayer.GameObject == gameObject)
// {
// // 움직이는 경우
// if (movementInput.x != 0 || movementInput.y != 0)
// {
// // Rigidbody 사용
// if (!UseRigidbody)
// {
// UseRigidbodyMovement();
// }
//
// if (!beAttacked)
// {
// myAnimator.SetFloat(RunStateHash, 0.5f);
// }
// }
// // 멈춰있는 경우
// else
// {
// // NavMeshAgent 사용
// if (UseRigidbody)
// {
// UseAgentMovement();
// }
//
// if (Agent.velocity.x != 0 || Agent.velocity.z != 0)
// {
// myAnimator.SetFloat(RunStateHash, 0.5f);
// }
// else if (!beAttacked)
// {
// myAnimator.SetFloat(RunStateHash, 0f);
// }
// }
// }
// else
// {
// if (GameManager.Inst.CurrentInIslandPlayer.GameObject && GameManager.Inst.CurrentInIslandPlayer.UseRigidbody && !Target)
// {
// if (!UseRigidbody)
// {
// UseRigidbodyMovement();
// }
//
// if (!beAttacked)
// {
// myAnimator.SetFloat(RunStateHash, 0.5f);
// }
// }
// else if (GameManager.Inst.CurrentInIslandPlayer.GameObject && !GameManager.Inst.CurrentInIslandPlayer.UseRigidbody)
// {
// if (UseRigidbody)
// {
// UseAgentMovement();
// }
//
// if (Agent.velocity.x != 0 || Agent.velocity.z != 0)
// {
// myAnimator.SetFloat(RunStateHash, 0.5f);
// }
// else if (!beAttacked)
// {
// myAnimator.SetFloat(RunStateHash, 0f);
// }
// }
// }
//
// var localScale = transform.localScale;
// if (UseRigidbody)
// {
// localScale.x = Rb.velocity.x switch
// {
// > 0 => Mathf.Abs(localScale.x),
// < 0 => -Mathf.Abs(localScale.x),
// _ => localScale.x
// };
// }
// else
// {
// if (Agent.velocity.x != 0)
// {
// localScale.x = Agent.velocity.x switch
// {
// > 0 => Mathf.Abs(localScale.x),
// < 0 => -Mathf.Abs(localScale.x),
// _ => localScale.x
// };
// }
// else
// {
// if (Target)
// {
// var targetToDistanceX = Target.bounds.center.x - MyCollider.bounds.center.x;
// localScale.x = targetToDistanceX switch
// {
// > 0 => Mathf.Abs(localScale.x),
// < 0 => -Mathf.Abs(localScale.x),
// _ => localScale.x
// };
// }
// }
// }
//
// transform.localScale = localScale;
// }
//
// protected override void FixedUpdate()
// {
// if (CurrentHp <= 0) return;
//
// if (UseRigidbody)
// {
// // var movement = GameManager.Inst.InIslandPlayer.Rb.velocity * (MoveSpd / GameManager.Inst.InIslandPlayer.MoveSpd);
// // rb.velocity = new Vector3(movement.x, 0, movement.z);
//
// if (GameManager.Inst.CurrentInIslandPlayer.GameObject == gameObject)
// {
// var localMovement = new Vector3(movementInput.x, 0, movementInput.y);
// var worldDirection = transform.TransformDirection(localMovement);
//
// var movement = worldDirection * MoveSpd;
// Rb.velocity = new Vector3(movement.x, 0, movement.z);
// }
// else
// {
// var predictedPos = GameManager.Inst.CurrentInIslandPlayer.Rb.position + GameManager.Inst.CurrentInIslandPlayer.Rb.velocity;
// var moveDir = (predictedPos - transform.position).normalized;
// Rb.velocity = new Vector3(moveDir.x, 0, moveDir.z) * MoveSpd;
// }
// }
// }
//
// #endregion
//
// #region Interfaces
//
// //IDamageable
// public void TakeDamage(float attackerPower, Vector3? attackPos = null)
// {
// IsCombated = true;
//
// if (!Target)
// {
// BeAttackedInIdle = true;
// bt.SendEvent("BeAttackedInIdle", attackPos);
// }
//
// var changeHp = Mathf.Max(CurrentHp - attackerPower, 0);
// SetCurrentHp(changeHp);
//
// // 죽었는지 체크
// if (changeHp == 0f)
// {
// Die();
// return;
// }
//
// StartCoroutine(nameof(BeAttacked));
// }
//
// public void Die()
// {
// myAnimator.SetTrigger(DieHash);
// MyCollider.enabled = false;
// if (Agent.enabled)
// {
// Agent.isStopped = true;
// }
// else
// {
// Rb.isKinematic = true;
// }
// Agent.enabled = false;
//
// if (GameManager.Inst.CurrentInIslandPlayer == (IInIslandPlayer)this)
// {
// foreach (var crewmate in GameManager.Inst.CurrentCrewmateList)
// {
// if (crewmate == null || !crewmate.gameObject.activeSelf || crewmate.CurrentHp <= 0) continue;
//
// GameManager.Inst.SetCurrentInIslandPlayer(crewmate);
// return;
// }
//
// // 게임 종료
// var overlayCanvas = GameObject.Find("OverlayCanvas");
// overlayCanvas.transform.Find("RestartPopUp").gameObject.SetActive(true);
// return;
// }
//
// Destroy(hpSlider.gameObject, 2f);
// Destroy(gameObject, 2f);
// }
//
// public float GetCurrentHp() => CurrentHp;
//
// // IAnimatorBridge
// public virtual void AttackTiming()
// {
// if (!Target) return;
//
// var myCenterPos = MyCollider.bounds.center;
// var targetDir = (Target.bounds.center - myCenterPos).normalized;
//
// if (!Physics.Raycast(MyCollider.bounds.center, targetDir, out var hit, AtkRange, TargetLayer)) return;
//
// var iDamageable = hit.transform.GetComponent<IDamageable>();
// iDamageable.TakeDamage(Atk);
// }
//
// public void SetIsAttacking(int boolValue) => isAttacking = boolValue == 1;
//
// // IAiView
// [field: Title("IAiView")]
// [field: SerializeField] public float ViewRadius { get; set; } = 15f;
// [field: SerializeField] public Collider[] Targets { get; set; } = new Collider[MAX_COLLIDERS];
// [field: SerializeField] public Collider Target { get; set; }
// [field: SerializeField] public LayerMask TargetLayer { get; set; }
//
// private const int MAX_COLLIDERS = 30;
//
// public void FindNearestTargetInRange(Vector3 centerPos, bool targetIsTrigger = true)
// {
// Array.Clear(Targets, 0, MAX_COLLIDERS);
//
// var numResults = Physics.OverlapSphereNonAlloc(centerPos, ViewRadius, Targets, TargetLayer,
// targetIsTrigger ? QueryTriggerInteraction.Collide : QueryTriggerInteraction.Ignore);
//
// if (numResults <= 0)
// {
// SetTarget(null);
// return;
// }
//
// var nearestDistance = ViewRadius * ViewRadius;
// Collider nearestTargetCollider = null;
//
// for (var i = 0; i < numResults; i++)
// {
// var distanceSqrToTarget = (centerPos - Targets[i].bounds.center).sqrMagnitude;
//
// if (distanceSqrToTarget >= nearestDistance) continue;
//
// nearestDistance = distanceSqrToTarget;
// nearestTargetCollider = Targets[i];
// }
//
// SetTarget(nearestTargetCollider);
// }
//
// public void SetTarget(Collider value)
// {
// Target = value;
//
// if (value != null)
// {
// IsCombated = true;
// BeAttackedInIdle = false;
// }
// }
//
// public bool IsTargetWithinRange(Vector3 centerPos, float range)
// {
// var inRange = Vector3.Distance(centerPos, Target.bounds.center) <= AtkRange;
// return inRange;
// }
//
// public bool GoOutOfBounds()
// {
// var defensePosInRange = Vector3.Distance(transform.position, DefensePos) <= DefenseRange;
// return !defensePosInRange;
// }
//
// public void MoveTarget(Vector3 targetPos, float speed, float stopDistance = float.MaxValue)
// {
// if (Vector3.Distance(Agent.destination, targetPos) < 0.1f) return;
//
// SetAgentSpeed(speed);
// Agent.stoppingDistance = stopDistance;
// Agent.isStopped = false;
// Agent.SetDestination(targetPos);
// }
//
// // INormalAttack
// public void NormalAttack()
// {
// StartCoroutine(nameof(NormalAttackCoroutine));
// }
//
// public void StopNormalAttackCoroutine() => StopCoroutine(nameof(NormalAttackCoroutine));
// public bool GetUsedNormalAttackCoroutine() => usedNormalAttackCoroutine;
//
// #endregion
//
// #region Player input system
//
// public void OnMove(InputValue value)
// {
// if (CurrentHp <= 0) return;
//
// movementInput = value.Get<Vector2>();
// }
//
// #endregion
//
// #region Custom methods
//
// private void UseRigidbodyMovement()
// {
// UseRigidbody = true;
// Rb.isKinematic = false;
// Agent.enabled = false;
// }
//
// private void UseAgentMovement()
// {
// UseRigidbody = false;
// Rb.isKinematic = true;
// Agent.enabled = true;
//
// if (Target) return;
//
// MoveTarget(GameManager.Inst.CurrentInIslandPlayer.Transform.position, MoveSpd, GlobalValue.MAXIMUM_STOP_DISTANCE);
// }
//
// private IEnumerator BeAttacked()
// {
// beAttacked = true;
// myAnimator.SetFloat(RunStateHash, 1f);
// yield return BeAttackedWaitTime;
//
// beAttacked = false;
// }
//
// private void SetCurrentHp(float value)
// {
// CurrentHp = value;
//
// if (useHpSlider)
// {
// hpSlider.value = value;
// }
// }
//
// private void SetAgentSpeed(float value) => Agent.speed = value;
//
// #endregion
// }
// }