์ฐ์ ์ด ์ฝ๋๋ฅผ ์ง๊ฒ ๋ ์คํ ๋ฆฌ๋ ์ด๋ ์ต๋๋ค.
์ก์ ๊ฒ์์ ๋ง๋ค์ด ๋ณด๊ณ ์ถ์๋ฐ ์ฒ์์๋ ๊ทธ๋ฅ if๋ฌธ์ ๋ง ์จ์ ์ง๋ค๊ฐ ์์ธ์ํฉ์ด ๋๋ฌด ๋ง์ด ๋ฐ์ํ๊ณ
๊ตฌ์กฐ๊ฐ ์ด์ํด์ง๋๊ฒ ๋๊ปด์ ธ์ ๋ฐฉ๋ฒ์ ์์ ๋ฐ๊พธ๊ณ ์ด๋ฐ์ ๋ฐ๊ฒ๋ค์ ์ฐธ๊ณ ํด์ ์ง๊ธ์ ์ฝ๋๋ฅผ ๋ง๋ค์์ต๋๋ค.
์ฐ์ ActorController ์คํฌ๋ฆฝํธ์ ๋ชฉ์ ์ ๋ชจ๋ ์ ๋ ฅ์ ๋ฐ๊ณ ์ฒ๋ฆฌํ๋ ๊ณณ์ผ๋ก ์ง์ ํ์ต๋๋ค.
๊ทธ๋ฆฌ๊ณ ๊ทธ ์ ๋ ฅ๊ฐ๋ค์ Actor๋ก ๋๊ฒจ์ฃผ์์ต๋๋ค.
๊ทธ๋์ Actor ์คํฌ๋ฆฝํธ๋ ์ค์ง ActorController์์ ์ ๋ ฅ๊ฐ์ ๋ฐ๋ ์ญํ ๋ง ํฉ๋๋ค.
๊ทธ๋ฆฌ๊ณ CharacterManager์์๋ Actor๋ฅผ ์์๋ฐ๊ณ Actor์์ ๋ฐ์ ๊ฐ๋ค์ ๋ค์ BaseAction์ผ๋ก ๋๊ฒจ์ฃผ๋ ์ญํ ์ ํฉ๋๋ค.
๊ทธ๋ฌ๋ฉด BaseAction์์ ๊ทธ ๊ฐ๋ค์ ๋ฐ๊ณ ์ค์ ๋์์ ํ Idle ์คํฌ๋ฆฝํธ๋ Run ์คํฌ๋ฆฝํธ ์๋๋ฉด Attack ์คํฌ๋ฆฝํธ์ ์ต์ข ์ ์ผ๋ก ๋๊ฒจ์ค๋๋ค.
๊ทธ๋ฆฌ๊ณ ์๋๋ BaseAction ์ฝ๋์ CharacterManager ์ฝ๋์ ๋๋ค.
public class CharacterManager : Actor
{
BaseAction _nowAction; (์ถ์ํด๋์ค๋ผ์ new๋ก๋ ์๋๊ณ null์ ์ง์ด๋ฃ์ด๋ ์ ์ด๋ก์์ด ์์ฌ๋ผ์ง๊น์ ใ )
public override void MovingCheck(Vector3 moveDir) =>
_nowAction.CheckMoveDir(moveDir);
public override void OnNormalAtk(ActorController.InputKey key, ActorController.InputState state) =>
_nowAction.CheckInputKeys(key, state);
public override void OnDodge(ActorController.InputKey key, ActorController.InputState state) =>
_nowAction.CheckInputKeys(key, state);
public void ChangeAction(string name) => _nowAction.ChangeAction(name);
void Update()
{
}
}
๋ฐ์๋ BaseAction ์ฝ๋์
๋๋ค
public abstract class BaseAction : MonoBehaviour
{
[Header("Managers")]
[SerializeField] protected CharacterManager _owner;
[SerializeField] protected Animator _animator;
public virtual void StartAction() { }
public abstract void UpdateAction();
public virtual void EndAction() { }
public abstract void ChangeAction(string name);
public virtual void CheckInputKeys(ActorController.InputKey key, ActorController.InputState state) { }
public virtual void CheckMoveDir(Vector3 dir) { }
void Start()
{
}
void Update()
{
}
}
๊ทธ๋ฆฌ๊ณ ์ต์ข ์ ์ผ๋ก ๊ฐ์ ๋ฐ์์ ์คํ๋๋ ์คํฌ๋ฆฝํธ ์ ๋๋ค (์๋ฅผ๋ค์ด Idle)
public class Idle : BaseAction
{
public override void CheckInputKeys(ActorController.InputKey key, ActorController.InputState state)
{
if (key == ActorController.InputKey.NORMALATK && state == ActorController.InputState.PRESSED)
_owner.ChangeAction("Atk");
if (key == ActorController.InputKey.DODGE && state == ActorController.InputState.PRESSED)
_owner.ChangeAction("Dodge");
}
public override void CheckMoveDir(Vector3 dir)
{
if (dir != Vector3.zero)
_owner.ChangeAction("Moving");
}
public override void UpdateAction()
{
}
public override void ChangeAction(string name)
{
_animator.SetBool(name, true);
}
void Start()
{
}
void Update()
{
}
}
์ฝ๋๊ฐ ์์ ํด์ผ ํ ๊ฒ์ด ์๊ฑฐ๋ ํ๋ฉด ์ง์ ์ข ํด์ฃผ์ธ์. ํ๋ค๊ฐ ๋ณต์กํด์ ๋ฉํ์ด ๋ง์ด ๋๊ฐ๊ธฐ๋ ํ๊ณ ์ด์ํ ์ค๋ฅ๋ ๋ง์๊ฒ ๊ฐ์์ ใ ใ
์ง๋ฌธ๊ธ์ ๋ต๋ณ์๋ฅผ ํน์ ์ง์ง๋ ๋ง์์ค
์ ๋ค ์ฃ์กํฉ๋๋ค ์์ ํ ๊ฒ์ ใ ใ
1. CharacterManager๋ผ๋ ์ด๋ฆ์ ๋ถ์ ์ .
๋ต ์์ ํ ๊ฒ์
2. BaseAction์ ์ถ์ํด๋์ค์ด๊ธฐ ๋๋ฌธ์ ์ธ์คํด์ค ์์ฑ์ด ๋ถ๊ฐ๋ฅ. [serializeField]๋ฅผ ํตํด ์๋ํฐ์์ ํด๋น ํด๋์ค๋ฅผ ์์๋ฐ์ ์ปดํฌ๋ํธ๋ฅผ ํ ๋น์์ผ์ค์ผํจ.
๋ค ๊ทธ๋ ๊ฒ๋ ํด๋ดค๋๋ฐ์. ๊ทผ๋ฐ ์ง๊ธ ์ ๊ฐ ๋ง๋ ์คํฌ๋ฆฝํธ์์๋ ์ค์ ๋ก BaseAction์ ์์๋ฐ์ ์ ๋ค์ด ๋ค Idle,Run,Attack ์ด๋ฐ์ ๋ค์ด๋ผ์์. ๊ทธ๋ฅ BaseAction ์์๋ฐ์ ์คํฌ๋ฆฝํธ ์๋ฌด๊ฑฐ๋ ๋ง๋ค์ด์ ๊ทธ๊ฑฐ ๋ฃ์๊น์? ์๋๋ฉด Idle์ ๋ฃ์๊น์??
3. ๊ตฌ์กฐ ์์ฒด๊ฐ Commandํจํด์ ํ์ฉํ๊ณ ์์ด์ ์์ ์ฝ๋ ๋จ์์ ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ฑฐ๋ ScriptableObject๋ฅผ ํ์ฉํ๋๊ฒ ๋ ์ ๋ฆฌํ ๋ฐฉ์์ธ๋ฐ ์ด์ํ๊ฒ ๋ง๋ค๊ณ ์์
ํ๋ฒ ๋ค์ ์์๋ณด๊ฒ ์ต๋๋ค ๊ฐ์ฌํฉ๋๋ค
๋ ์๋ ค์ฃผ๊ธฐ์๋ ์กธ๋ฆฌ๋ ์์ธํ ์ค๋ช ์ ์๋ตํ๋ค
๋ด๊ฐ ๋ณด๊ธฐ์๋ ์ ํ์ ์ธ ๋์์ธํจํด์ถฉ(์ถ์ํ์ถฉ)์ ๋ชจ์ต์ ๋ณด์ด๋ ๊ฒ ๊ฐ๋ค. ์ผ๋จ ์ถ์ํ๊ฐ ๋ ๋๋๋ผ๋ ๋์๊ฐ๋ ์ฝ๋๋ฅผ ์์ฑํ๊ณ ๋์ค์ ๋จ๊ณ์ ์ผ๋ก ์ถ์ํํ์
์ผ๋จ ์ด๋ป๊ฒ๋ ์ด๋ฐ๋ฐฉ์์ ์ฐ๊ณ ์ถ๋ค๋ฉด FSM์ ๋จผ์ ์์๋ด.
๋ค ์๊ฒ ์ต๋๋ค!
BaseAction์ด ์ถ์ํด๋์ค๋ผ์ ์ธ์คํด์ค ์์ฑ ๋ถ๊ฐ๋ฅ...์ธ๊ฒ ๋ฌธ์ ๊ฐ ์๋๋ผ BaseAction์ ๋ชจ๋ ธ๋นํค์ด๋น์ด๋ฅผ ์์๋ฐ๋์ ๋๊น new๋ก ์ธ์คํด์ค ์์ฑ์ด ์๋๋๊ฒ ๋ฌธ์ ์.. GetComponentํด์ ๋ฃ์ด์ฃผ์๋ฉด ๋จ
์๋๋ฉด ๋ ๋ณด๋๊น BaseActionํ๊ณ Idleํ๊ณ ๋ค start update ์์ฐ๋๋ฐ ๋ชจ๋ ธ๋นํค์ด๋น์ด ์์ ์๋ฐ์๋ ๋์ง์์? ๊ทธ๋ฌ๋ฉด new๋ก ๋จ