//구글콘솔 광고 추가가

public class ResourceManager 
{
    public T Load<T>(string path) where T: Object
    {
        return Resources.Load<T>(path);
    }

    public GameObject Instantiate(string path, Transform parent = null)
    {
        GameObject prefab = Load<GameObject>($"Prefabs/{path}");
        if(prefab == null)
        {
            Debug.Log($"Failed to load Prefab : {path}");
            return null;
        }

        return Object.Instantiate(prefab, parent); 

    }

    public void Destroy(GameObject go)
    {
        if(go == null)
            return;

        Object.Destroy(go);
    }
}


return Object.Instantiate(prefab, parent); 

< Object를 붙여준 이유 >

안붙이면 ResourceManager클래스에있는 Instatiate()를 재귀적으로 호출하려 할테니 Object에 있는 instantiate()를 하세요라고 명시를 해준 것.


public class GameManagers : MonoBehaviour
{

    ResourceManager _resource = new ResourceManager();
    public static ResourceManager Resource { get { return Instance._resource; } }

}


게임매니저 클래스에서 ResourceManager 를 만들어 주고


public class PrefabTest : MonoBehaviour
{

    GameObject prefab;

    GameObject item;

 

    private void Start() 

    {

         item = GameManager.Resource.Instantiate("Item");      // 유니티에서 프리팹으로 만들어 둔 Item 생성

         GameManager.Resource.Destroy(item);                         // 제거

    }

}


프리팹사용을 원하는 클래스에서 GameManager를 통해 생성 가능


 

728x90

 


public class InputManager
    {
        public Action KeyAction = null;

        public void OnUpdate()
        {
            if (Input.anyKey == false)
            {
                return;
            }
            if(KeyAction != null)
            {
                KeyAction.Invoke();
            }
        }
    }


input 클래스에서는 플레이어의 키입력을 체크해서 키입력이 되었을 때 다른 클래스에 키입력을 받았다는 것을 알려준다.


public class GameManager : MonoBehaviour
{
    private static GameManager s_instance = null;
    public static GameManager instance { get { return s_instance; } }

    InputManager _input = new InputManager();
    public static InputManager Input { get { return instance._input; } }

    private void Update()
    {
        _input.OnUpdate();
    }

}


GameManager 클래스에선 MonoBehaviour를 상속 받지 않은 inputManager를 새롭게 할당해서 객체를 만들어주고,

Update()함수에서 inputManager 클래스에서 만들어 둔 OnUpdate()함수를 실행시켜준다.


public class PlayerController : MonoBehaviour
    {
        float playerSpeed = 10f;
        private void Start()
        {
            GameManager.Input.KeyAction -= OnKeyBoard;
            GameManager.Input.KeyAction += OnKeyBoard;

        }

        void OnKeyBoard()
        {

            if (Input.GetKey(KeyCode.W))
            {
                transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(Vector3.forward), 0.2f);
                transform.position += Vector3.forward * playerSpeed * Time.deltaTime;
            }
            if (Input.GetKey(KeyCode.S))
            {
                transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(Vector3.back), 0.2f);
                transform.position += Vector3.back * playerSpeed * Time.deltaTime;
            }
            if (Input.GetKey(KeyCode.A))
            {
                transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(Vector3.left), 0.2f);
                transform.position += Vector3.left * playerSpeed * Time.deltaTime;
            }
            if (Input.GetKey(KeyCode.D))
            {
                transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(Vector3.right), 0.2f);
                transform.position += Vector3.right * playerSpeed * Time.deltaTime;
            }

        }
    }


PlayerController 클래스에서는 Start() 함수에서 GameManager클래스에서 만들어뒀던 InputManager의 객체를 통해 KeyAction에 OnKeyBoard()함수를 등록시켜준다.

 

이때 -=를 +=하기전에 먼저 한번 해주는데 이유는, 다른 곳에서 모르고 추가로 등록해줄 경우를 대비해서

제거했다가 등록을 시켜준다. (삭제 해줬을 때 등록된 함수가 발견되지 않아도 예외가 발생하지 않음 )

중복으로 호출되는 것을 막아주기 위해 습관적으로 해두는게 좋을 것 같다.


 

728x90

// 절대값을 입력해서 회전을 하고 싶다면 

transform.eulerAngles를 사용.

ex) transform.eulerAngles = new Vector3(0.0f, Time.deltaTime * 100f, 0.0f);

- 각도가 360도를 초과하면 증가시키지 말고, 대신에 Transform.Rotate를 사용해야된다.

 

// 특정 축을 기준으로 얼마만큼 회전을 시키고 싶다 한다면

transform.Rotate()를 사용.

ex) transform.Rotate(new Vector3(0.0f, Time.deltaTime * 100f, 0.0f));

 

// 원하는 특정방향을 쳐다보고 싶게 하고 싶다면

transform.rotation = Quaternion.LookRotation(벡터방향);

 

// 자연스럽게 회전하면서 쳐다보고 싶다면

Quaternion.Slerp()를 사용.

transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(벡터방향), 0부터 1사이의 float값);

- float 값이 0일경우 transform.rotation = transform.rotation,

  float 값이 1일 경우 transform.rotation = Quaternion.LookRotation(벡터방향)이기 때문에 적절한 중간값으로 대입.

 

// < Quaternion.Slerp() > 구면 선형 보간

- public static Quaternion Slerp (Quaternion a, Quaternion b, float t);

: a와 b 사이에 구형으로 t씩 보간한다. 파라미터 t는 [0, 1] 범위로 고정.

 

// 짐벌락 확인 키워드( 짐벌락이란 : 같은방향으로 오브젝트의 두 회전 축이 겹치는 현상 )

euler(gimbal lock) explained

https://www.youtube.com/watch?v=zc8b2Jo7mno&ab_channel=GuerrillaCG

 

// player 이동키

  1. void playerMove()
        {
            float dirX = Input.GetAxis("Horizontal");
            float dirY = Input.GetAxis("Vertical");

            Vector3 dirXY = (Vector3.right * dirX) + (Vector3.forward * dirY);

            transform.position += dirXY * playerSpeed * Time.deltaTime;
        }
  2.   void playerMove2()
        {
            if (Input.GetKey(KeyCode.W))
            {
                transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(Vector3.forward), 0.2f);
                transform.position += Vector3.forward * playerSpeed * Time.deltaTime;
            }
            if (Input.GetKey(KeyCode.S))
            {
                transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(Vector3.back), 0.2f);
                transform.position += Vector3.back * playerSpeed * Time.deltaTime;
            }
            if (Input.GetKey(KeyCode.A))
            {
                transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(Vector3.left), 0.2f);
                transform.position += Vector3.left * playerSpeed * Time.deltaTime;
            }
            if (Input.GetKey(KeyCode.D))
            {
                transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(Vector3.right), 0.2f);
                transform.position += Vector3.right * playerSpeed * Time.deltaTime;
            }
        }
728x90

+ Recent posts