Publish:

νƒœκ·Έ: , , , , ,

μΉ΄ν…Œκ³ λ¦¬:

πŸ“Œ State Pattern

✏️ μƒνƒœ νŒ¨ν„΄μ΄λž€?

μƒνƒœνŒ¨ν„΄μ΄λž€ 각 μƒνƒœλ³„λ‘œ 슀크립트λ₯Ό 뢄리

즉, μ‹œμŠ€ν…œμ˜ 각 μƒνƒœλ₯Ό 클래슀둜 뢄리해 ν‘œν˜„ν•˜λŠ” 것이닀.

ν•œ μŠ€ν¬λ¦½νŠΈμ— λͺ¨λ‘ 넣을 수 μžˆλŠ” λ‚΄μš©μ„ μ™œ λ‚˜λˆ„λŠ” κ²ƒμΌκΉŒ?

첫쨰둜 ν•œ 객체의 μƒνƒœλ₯Ό μ—¬λŸ¬ 슀크립트둜 λ‚˜λˆ„λŠ” 것이기에 μ½”λ“œμ˜ 가독성이 쒋아진닀.

λ‘˜μ§Έλ‘œ 각 μƒνƒœλ³„λ‘œ μ½”λ“œλ₯Ό κ΄€λ¦¬ν•˜κΈ°μ— κ°œλ°œν•˜λŠ” μž…μž₯μ—μ„œ 관리가 쉽닀. (μƒνƒœ μΆ”κ°€κ°€ 쉽닀.)

ν•˜μ§€λ§Œ 단점은 μ‘΄μž¬ν•œλ‹€.

μƒνƒœκ°€ λ„ˆλ¬΄ λ§Žμ•„μ§€κ²Œ 되면 그만큼 μŠ€ν¬λ¦½νŠΈκ°€ μ¦κ°€ν•˜κΈ°μ— 관리가 μ–΄λ ΅λ‹€.

이 ν•˜λ‚˜κ°€ ꡉμž₯히 큰 단점이 될 수 μžˆλ‹€κ³  μƒκ°ν•œλ‹€.

이제 μ‹€μ œ κ²Œμž„μ—μ„œ μ–΄λ–»κ²Œ μ‚¬μš©λ  수 μžˆλŠ”μ§€ ν•œ 번 μƒκ°ν•΄λ³΄μž.

λ§Œμ•½ κ²Œμž„μ— μ‘΄μž¬ν•˜λŠ” μƒμžμ— μƒνƒœλ₯Ό μ μš©ν•œλ‹€λ©΄ μ–΄λ–»κ²Œ 될까?

μƒμžκ°€ κΈ°λ³Έ μƒνƒœ / 듀렀진 μƒνƒœ / 놓아진 μƒνƒœ / λ˜μ €μ§„ μƒνƒœ λ₯Ό 가진닀고 μƒκ°ν•΄λ³΄μž.

그리고 μƒμž μ˜€λΈŒμ νŠΈλŠ” 이 λͺ¨λ“  슀크립트λ₯Ό κ°€μ§€λŠ” 것이 μ•„λ‹Œ,

이듀을 κ΄€λ¦¬ν•˜λŠ” λ§€λ‹ˆμ € 슀크립트λ₯Ό 가진닀.

그럼 각 μƒνƒœλ³„λ‘œ μ½”λ“œλ₯Ό μ§œμ€€λ‹€.

(μš°μ„  λͺ¨λ“  μƒνƒœλŠ” BaseState μ΄λΌλŠ” 좔상 클래슀λ₯Ό μƒμ†λ°›λŠ”λ‹€.)

πŸ“‹ μ½”λ“œ

πŸ“ BaseState

1
2
3
4
5
6
7
8
using UnityEngine;

public abstract class BoxBaseState
{
	public abstract void EnterState(BoxStateManager box);
	public abstract void UpdateState(BoxStateManager box);
	public abstract void OnCollisionEnter(BoxStateManager box, Collision collision);
}

πŸ“ IdleState

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
using UnityEngine;

public class BoxIdle : BoxBaseState
{
	public override void EnterState(BoxStateManager box) { }
	
	public override void UpdateState(BoxStateManager box)
	{
		if(box.player != null && box.player._yes)
		{
			box.player._yes = false;
			box.SwitchState(box._pickState);
		}
	}
	
	public override void OnCollisionEnter(BoxStateManager box, Collision collision)
	{
		GameObject other = collision.gameObject;
		if(other.CompareTag("Player"))
		{
			if(box.player == null) box.player = other.GetComponent<PlayerController>();
			box.player.DrawUI();
		}
	}
}

πŸ“ PickedupState

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
using UnityEngine;

public class BoxPickedUp : BoxBaseState
{
	public override void EnterState(BoxStateManager box)
	{
		box.transform.position = box.player.transform.position + new Vector3(0, 2f, 0);
		box.transform.SetParent(box.player.transform);
		box.GetComponent<Rigidbody>().isKinematic = true;
	}
	
	public override void UpdateState(BoxStateManager box)
	{
		if(box.player._putDown)
		{
			box.player._putDown = false;
			box.SwitchState(box._putDownState);
		}
		else if(box.player._throwAway)
		{
			box.player._throwAway = false;
			box.SwitchState(box._throwAwayState);
		}
	}
	
	public override void OnCollisionEnter(BoxStateManager box, Collision collision) { }
}

πŸ“ PutDownState

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
using UnityEngine;

public class BoxPutdown : BoxBaseState
{
	float _countdown = 1.0f;
	
	public override void EnterState(BoxStateManager box)
	{
		box.transform.SetParent(null);
		box.transform.position = box.player.transform.position + new Vector3(2, 0, 0);
		box.GetComponent<Rigidbody>().isKinematic = false;
	}
	
	public override void UpdateState(BoxStateManager box)
	{
		if(_countdown > 0)
			_countdown -= Time.deltaTime;
		else
			box.SwitchState(box._idleState);
	}
	
	public override void OnCollisionEnter(BoxStateManager box, Collision collision) { }
}

πŸ“ ThrowedAwayState

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
using UnityEngine;

public class BoxThrowedAway : BoxBaseState
{
	float _countdown = 2.0f;
	
	public override void EnterState(BoxStateManager box)
	{
		box.transform.SetParent(null);
		box.GetComponent<Rigidbody>().isKinematic = false;
		box.GetComponent<Rigidbody>().AddForce(Vector3.right * 10, ForceMode.Impulse);
	}
	
	public override void UpdateState(BoxStateManager box)
	{
		if(_countdown > 0)
			_countdown -= Time.deltaTime;
		else
			box.SwitchState(box._idleState);
	}
	
	public override void OnCollisionEnter(BoxStateManager box, Collision collision) { }
}

πŸ“ StateManager

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
using UnityEngine;

public class BoxStateManager : MonoBehaviour
{
	BoxBaseState _currentState;
	
	public PlayerController player;
	public BoxIdle _idleState = new BoxIdle();
	public BoxPickedUp _pickState = new BoxPickedUp();
	public BoxPutdown _putDownState = new BoxPutdown();
	public BoxThrowedAway _throwAwayState = new BoxThrowedAway();
	
	private void Start()
	{
		_currentState = _idleState;
		_currentState.EnterState(this);
	}
	
	protected void Update()
	{
		_currentState.UpdateState(this);
	}
	
	public void SwitchState(BoxBaseState state)
	{
		_currentState = state;
		_currentState.EnterState(this);
	}
	
	void OnCollisionEnter(Collision collision)
	{
		_currentState.OnCollisionEnter(this, collision);
	}
}

πŸ’» μ‹€ν–‰

1

λ°©λ¬Έν•΄ μ£Όμ…”μ„œ κ°μ‚¬ν•©λ‹ˆλ‹€!😊

μ—…λ°μ΄νŠΈ:

λŒ“κΈ€λ‚¨κΈ°κΈ°