using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TopDownAnimationController : TopDownAnimations
{
private static readonly int IsWalking = Animator.StringToHash("IsWalking");
private static readonly int Attack = Animator.StringToHash("Attack");
private static readonly int IsHit = Animator.StringToHash("IsHit");
//string의 비교는 비용이 높아 Hash값으로 비교하도록 처리하한다.
//같은 이름은 더이상 사용 불가능
protected override void Awake()
{
base.Awake();
}
private void Start()
{
controller.OnMoveEvent += Move;
}
private void Move(Vector2 directionVector)
{
animator.SetBool(IsWalking, directionVector.magnitude > 0.5);
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TopDownAnimations : MonoBehaviour
{
protected Animator animator;
protected TopDownCharacterController controller;
protected virtual void Awake()
{
animator = GetComponentInChildren<Animator>();
controller = GetComponent<TopDownCharacterController>();
}
}
TopDownAnimationController 은 TopDownAnimations를 상속받아 사용한다.
후자의 Cs에서 움직임을 관리하는 TopDownCharacterController을 할당받아 이를 이용해 움짐임이 있을때 Action을 통해 움직임 상태를 받아올 수 있다.
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TopDownCharacterController : MonoBehaviour
{
public event Action<Vector2> OnMoveEvent;
public event Action<Vector2> OnLookEvent;
protected virtual void Awake()
{
}
public void CallMoveEvent(Vector2 direction)
{
if (OnMoveEvent == null)
{
Debug.Log("Null");
}
OnMoveEvent?.Invoke(direction);
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TopDownMovement : MonoBehaviour
{
private TopDownCharacterController _controller;
private Rigidbody2D _rigidbody;
Vector2 newDirection = Vector2.zero;
private void Awake()
{
_controller = GetComponent<TopDownCharacterController>();
_rigidbody = GetComponent<Rigidbody2D>();
}
private void Start()
{
_controller.OnMoveEvent += Move;
}
private void FixedUpdate()
{
ApplyMovement(newDirection);
}
private void Move(Vector2 dir)
{
newDirection = dir;
}
private void ApplyMovement(Vector2 dir)
{
dir = dir * 5; // 5= 속도
_rigidbody.velocity = dir;
}
}
위의 두 스크립트를 이용해 오브젝트의 이동을 관리한다. 어딘가의 스크립트에서 TopDownMovement.cs의 CallMoveEvent가 실행되면, TopDownMovement.cs의 Move함수가 실행되게 된다. Move는 이동하고자 하는 방향으로의 방향백터를 인자로 받아 이동을 하게 해준다. 이 경우 어떤 오브젝트던 간에 이동하고자 하는 방향백터, CallMoveEvent함수만 있다면 이동을 할 수 있다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyController : TopDownCharacterController
{
protected Transform ClosestTarget { get; private set; }
protected override void Awake()
{
base.Awake();
}
protected virtual void Start()
{
ClosestTarget = GameManager.Instance.Player;
}
protected virtual void FixedUpdate()
{
}
protected float DistancetoTarget()
{
Debug.Log(Vector3.Distance(transform.position, ClosestTarget.position));
return Vector3.Distance(transform.position, ClosestTarget.position);
}
protected Vector2 DirectionTotarget()
{
return (ClosestTarget.position - transform.position).normalized;
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ContactEnemyController : EnemyController
{
[SerializeField][Range(0, 100)] private float followRange;
[SerializeField] private string targetTag = "Player";
protected override void Start()
{
base.Start();
}
protected override void FixedUpdate()
{
base.FixedUpdate();
Vector2 direction = Vector2.zero;
if(DistancetoTarget() < followRange)
{
direction = DirectionTotarget();
}
CallMoveEvent(direction);
}
}
EnemyController.cs 는 TopDownCharacterController을 상속받는다. ContactEnemyController.cs는 EnemyController을 상속 받으며, 무언가 물체의 이동의 방향백터의 인풋이 필요할때 TopDownCharacterController을 상속받아 사용한다.