State Pattern

Design Patterns 2021. 10. 18. 23:56
반응형

 

using UnityEngine;

public class Test2 : MonoBehaviour
{
    public SiegeTank tank;
    
    void Start()
    {
        tank.onMoveComplete = () => {
            tank.ChangeSiegeMode();

            tank.Move(new Vector3(0, 0, 0));
        };

        tank.Init();
        tank.Move(new Vector3(7f, 0, 7f));
    }
}
public interface ISiegeTankState
{
    int GetDamage();

    bool CanMove();

    void Move(Vector3 tpos);
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;

public class TankState : ISiegeTankState
{
    private SiegeTank tank;
    private UnityEvent moveComplete;
    public TankState(SiegeTank tank)
    {
        this.tank = tank;
    }

    public int GetDamage()
    {
        return 10;
    }

    public bool CanMove()
    {
        return true;
    }

    public void Move(Vector3 tpos)
    {
        Debug.LogFormat("{0}로 이동 합니다.", tpos);
        this.tank.StartCoroutine(this.MoveImpl(tpos));
    }

    IEnumerator MoveImpl(Vector3 tpos) {

        var dir = (tpos - this.tank.transform.position).normalized;
        var angle = Mathf.Atan2(dir.z, dir.x) * Mathf.Rad2Deg;
        this.tank.transform.rotation = Quaternion.AngleAxis(angle, Vector3.up);

        while (true) {
            this.tank.transform.Translate(Vector3.forward * this.tank.moveSpeed * Time.deltaTime);
            var dis = (tpos - this.tank.transform.position).magnitude;
            if (dis < 0.1f) break;
            yield return null;
        }
        Debug.Log("move complete!");
        tank.onMoveComplete();
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;

public class SiegeState : ISiegeTankState
{
    private SiegeTank tank;
    public SiegeState(SiegeTank tank)
    {
        this.tank = tank;
    }

    public int GetDamage()
    {
        return 20;
    }

    public bool CanMove()
    {
        return false;
    }

    public void Move(Vector3 tpos)
    {
        Debug.Log("이동 할수 없습니다.");
    }

}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SiegeTank : MonoBehaviour
{
    TankState tankState;
    SiegeState siegeState;
    ISiegeTankState iState;
    public float moveSpeed = 1f;
    public System.Action onMoveComplete;

    //private void Awake()
    //{
    //    this.Init();
    //}

    //IEnumerator Start() {
    //    yield return new WaitForSeconds(1.0f);
    //    this.Move(new Vector3(7f, 0, 7f));
    //}

    public void Init()
    {
        this.tankState = new TankState(this);
        this.siegeState = new SiegeState(this);
        this.iState = this.tankState;
    }

    public void ChangeTankMode()
    {
        Debug.Log("탱크모드로 변경합니다.");
        this.iState = this.tankState;
    }
    public void ChangeSiegeMode() 
    {
        Debug.Log("시즈모드로 변경합니다.");
        this.iState = this.siegeState;
    }

    public void Move(Vector3 tpos) 
    {
        this.iState.Move(tpos);
    }

}

 

 

 

반응형
: