I think documenting is very important In programming
To cooperate with colleague, documenting is necessary.
as programmer, I expect that this book will help me improve cooperating skill

The subject of chapter one is understanding reader.
this chapter says that knowledge is difference between developer and user.
this book call this as "curse of knowledge"
when i see the sentence, i thought document is made up based on user perspective
however it is difficult more than i think.
so this book suggests more specific measure
one of these measure is to make user personsa.
So I could think a document should be sparated for each user.


-------------------------------------------------------------------- after reading point

The document should be sperated for reader.

 

레이어 잠금 해제

비율 변경

기본 선택(m) -> 편집 ->자유 변경(ctrl+r)

 

레이어에 이미지 추가

중급 프로그래머 가는 길 재미있게 가보자!

안녕하세요. 프로그래머 JD입니다. 

이번글은 BuildManager 클래스를 설명하는 시간을 갖겠습니다.

거두절미하고 BuildManager 클래스 확인해 보겠습니다.

using UnityEngine;

public class BuildManager : MonoBehaviour
{
    public static BuildManager instance;

    private void Awake()
    {
        if(instance != null)
        {
            Debug.LogError("More than one BuildManager in scene!");
            return;
        }
        instance = this;
    }

    public GameObject standardTurretPrefab;
    private GameObject turretToBuild;

    private void Start()
    {
        turretToBuild = standardTurretPrefab;
    }

    public GameObject GetTurretToBuild()
    {
        return turretToBuild;
    }
}

멤버변수인 instance가 있습니다. 

static으로 설정한이유는 모든 객체가 같은 속성으로 되기위해(공유하기위해) 설정했습니다.

Awake()문입니다.

    private void Awake()
    {
        if(instance != null)
        {
            Debug.LogError("More than one BuildManager in scene!");
            return;
        }
        instance = this;
    }

조건문 instance 가 있는경우 즉 이 클래스가 두번 선언한경우 입니다.

싱글턴 패턴은 객체를 공유하기위한 패턴이라서 이 클래스가 두개이상있는경우 객체들은 어떤것을 공유해야할줄 몰라 에러가 생깁니다. 

그래서 두개이상 생성될경우의 예외를 방지하기위해 예외처리했습니다.

조건문을 빠져나와서 자신의 주소값을 instance에 대입합니다. 

여기까지가 싱글턴 패턴에 기본 틀 입니다. 

 

그런다음 public 으로 할당된 object를 private 로 할당된 object에 대입합니다.

 

유니티 에디트 화면으로 돌아가 public으로선언한 변수들을 대입해줍니다.

www.youtube.com/watch?v=OjvNfuOZI-I

여기까지 해서 타워건설 프로젝트는 마무리됩니다. 

포스트 양조절을 실패해서 오늘은 여기까지해서 마무리 하겠습니다.

다음시간에는 Camera 이동하는 프로젝트로 찾아오겠습니다.

읽어주셔서 감사하고 Brackeys에게 감사합니다. 

출처 www.youtube.com/watch?v=t7GuWvP_IEQ&list=PLPV2KyIb3jR4u5jX8za5iU1cqnQPmbzG0&index=6

 

중급 프로그래머 가는 길 재미있게 가보자!

안녕하세요. 프로그래머 JD입니다. 

이번 글은 타워 디펜스 타워 건설 두 번째 시간입니다.

저번 시간에는 Node클래스의 멤버 변수를 설명했습니다. 이번 글은 본격적으로 메서드에 대한 설명을 하겠습니다.

    private void Start()
    {
        rend = GetComponent<Renderer>();
        startColor = rend.material.color;
    }

start() 문입니다.

이함수의 역할은 private로 선언한 startColor의 값을 기본색으로 대입하는 것입니다. 

 

그다음 함수는 OnMousDown(),OnMousEnter(),OnMouseExit()함수가 있는데 

모두 공통으로 OnMous가 들어가있는 함수로 마우스와 관련 있는 함수입니다.

OnMousDown() 함수는 마우스를 클릭했을 때 호출되는 함수입니다.

OnMousEnter() 함수는 마우스 커서가 있을 때 호출되는 함수입니다.

OnMousExit() 함수는 마우스 커서가 있다가 없어질 때 호출되는 함수입니다.,

 

우선 OnMousEnter()함수와 OnMousEnter() 함수부터 확인해보겠습니다.

OnMousDown() 함수는 singleton 패턴을 설명해야 할 것 같아서 마지막에 설명하겠습니다.

    private void OnMouseEnter()
    {
        rend.material.color = hoverColor;
    }

마우스를 댄 노드에 hoverColor색을 대입합니다.

기본색은 회색이고 저희는 추후에 진한 회색을 대입할것입니다.

    private void OnMouseExit()
    {
        rend.material.color = startColor;
    }

마우스 커서가 노드에서 Exit(탈출하다)하게 되면 기본색을 대입합니다.

 

OnMousDown() 함수입니다.

    private void OnMouseDown()
    {
        if(turret!=null)
        {
            Debug.Log("Can't build there! -TODO: Display on screen.");
            return;
        }
        GameObject turretToBuild = BuildManager.instance.GetTurretToBuild();
        turret = Instantiate(turretToBuild, transform.position + positionOffset, transform.rotation);
    }

조건문은 turret이 날이 아닐 때 발생합니다.

저희가 해당 노드에 타워를 설치한 후 다시 노드를 클릭했을 때 생기는 에러를 예외 처리한 것입니다. 

그다음 BuildManager의 GetTurretToBuild() 함수를 호출한 뒤 turretToBuild에 대입합니다. 

나중에 설명하겠지만 GetTurretToBuild() 함수는 Turret object를 반환합니다.

그런 후 Turret object를 생성합니다.

저희가 중요하게 봐야 할부분은 6번째 줄인 BuildManager.instance.GetTurretToBuild() 부분입니다.

싱글턴 패턴을 사용하는 부분인데 이것은 저희가 생성할 Turret object가 공유하고 있다는 부분으로 생각하시면 될 것 같아요. 

예를 들면 1번 노드에 타워를 생성하고 2번 노드에 타워를 생성했을 때 

2번 노드의 타워의 속도를 10에서 15로 수정했을 경우 1번 노드의 타워의 속도도 15로 자동 수정된다는 뜻입니다.

이것이 싱글턴 패턴을 사용하는 이유입니다.

싱글턴 패턴의 핵심은 static이라고 할 수있는데 기본 멤버변수는 객체의 속성이라고 할수있다면 static은 클래스 속성이라고 할수 있죠. 

이번 글은 여기서 마무리하고 다음 글에는 BuildManager클래스를 설명하는 시간을 갖겠습니다. 

읽어주셔서 감사합니다. 소스를 공유해준 유튜버 Brackeys 감사합니다.

출처 -www.youtube.com/watch?v=t7GuWvP_IEQ&list=PLPV2KyIb3jR4u5jX8za5iU1cqnQPmbzG0&index=6

 

중급 프로그래머 가는 길 재미있게 가보자!

안녕하세요. 프로그래머 JD입니다. 

이번 글은 타워 건설 프로젝트로 시작합니다. 

일주일에 3개씩 포스팅해보자는 목표를 가지니까 금방금방 진행되는 느낌이 드네요.

역시 사람은 목표의식이 있어야 하는 것 같아요.

이번 프로젝트는 마우스를 사용한 타워 건설인데요 마우스를 이용해서 동적으로 타워를 생성할 수 있게 됩니다.

uml 확인하겠습니다.

 

 

uml(class Diaglam)을 확인해보면 두 가지 클래스가 추가된 것을 볼 수 있습니다.

Node클래스와 BuildManager클래스이죠.

근대 BuildManager클래스를 확인해보면 다른 클래스랑 모습이 다른 것을 확인할 수 있습니다.

클래스 이름 위에 <<Singleton>>이라고 적혀있죠. ㄷㄷ

네... gof design 패턴 중 하나인 싱글톤 패턴입니다.

정보처리기사 공부하시는 분들을 많이 들어보셨을 거예요. 

<<,>> 문자가 보이는데요 이것은 guillemets이라고 uml에서는 스테레오 타입을 표현할 때 사용되는 것입니다.

class Diaglam을 확인하면 Node클래스가 Turret클래스를 생성하고 BuildManager를 의존하는 것을 볼 수 있어요.

BuildManager는 Turret을 연관 짖고 있습니다.

저희 목적은 Node에다가 turret을 생성하는 것인데 이런 관계를 가진 이유는 Node에 Turret을 생성할 때 BuildManager가 가지고 있는 Turret정보(instance)를 확인하고 생성하기 때문입니다. 

그럼 소스코드 확인해보겠습니다.

 

Node 클래스입니다.

using UnityEngine;

public class Node : MonoBehaviour
{
    public Color hoverColor;
    public Vector3 positionOffset; 

    private GameObject turret;
    private Renderer rend;
    private Color startColor;

    private void Start()
    {
        rend = GetComponent<Renderer>();
        startColor = rend.material.color;
    }

    private void OnMouseDown()
    {
        if(turret!=null)
        {
            Debug.Log("Can't build there! -TODO: Display on screen.");
            return;
        }
        GameObject turretToBuild = BuildManager.instance.GetTurretToBuild();
        turret = Instantiate(turretToBuild, transform.position + positionOffset, transform.rotation);
    }

    private void OnMouseEnter()
    {
        rend.material.color = hoverColor;
    }

    private void OnMouseExit()
    {
        rend.material.color = startColor;
    }
}

 

멤버 변수는 hoverColor는 마우스가 node에 갔을 때 변하는 색깔입니다.

positionOffset은 생성되는 타워의 이동하는 값입니다. node의 좌표값과 타워의 좌표값이 계산되지 않을 경우 깔끔하게 작업할 수 있습니다. 

turret은 타워 객체입니다.

rend는 

이것인데 저희는 마우스가 Node object에 가면 색이 변하는데 이것을 원상 복구해야 합니다. 그래서 Node object의 기본 색을 접근하기 위해 사용했습니다.

만약 이 변수를 사용하지 않는다면 저희가 손댄 Node색은 모두 검은색으로 변할 것입니다.

 

startColor는 Mesh Renderer의 Element0의 색입니다.

오늘은 멤버 변수에 대한 설명으로 이번 글 마치겠습니다.

다음 시간에는 소스 설명과 BuildManager 클래스를 설명해보겠습니다.

 

읽어주셔서 감사합니다. 소스를 공유해준 유튜버 Brackeys 감사합니다.

출처 -www.youtube.com/watch?v=t7GuWvP_IEQ&list=PLPV2KyIb3jR4u5jX8za5iU1cqnQPmbzG0&index=6

 

중급 프로그래머 가는 길 재미있게 가보자!

안녕하세요. 프로그래머 JD입니다. 

오늘은 저번 시간에 이야기했던 Bullet.Seek() 함수부터 시작해보겠습니다.

저번에 Seek() 함수를 UML(Unified Modeling Language)을 이용해서 설명한다고 했습니다.

우선 프로젝트 UML부터 확인해 보겠습니다.

 

현재 저희 프로젝트 UML입니다. 

저희가 확인해야 할 부분은 Turret과 Bullet의 연관 부분인데 

파워포인트로 작업해서 집약 관계 표현이 애매한 점 양해 부탁드립니다.

집약 관계는 초록색,  합성 관계는 빨간색으로 표현했습니다.

저는 집약과 합성 관계의 차이점은 그냥 생성자 호출로 기준을 나누었습니다.

사실 UML을 제대로 공부하고 싶어서 게임 만들기를 시작했어요. 

혹시 문제가 있거나 부족한 부분은 바로 지적해주시면 감사하겠습니다.

 

다시 돌아와서 Bullet은 Turret에 합성 관계,

Turret은 Bullet에 집약 관계에 있습니다. 

일단 둘은 연관관계에 있고 두 개의 클래스는 서로를 알고 있습니다.

여기서 Seek() 함수는 Bullet의 멤버 함수인 target을 nearestEnemy(Enemy Object)에 대입하기 위한 함수로 사용된 것입니다.

이런 관계를 사용한 이유는 Turret은 Bullet클래스를 생성하고 Bullet클래스는 Turret클래스와 의존관계에 있는 Enemy를 제거하기 위해서입니다. 

우선 Bullet클래스는 Bullet object의 컴포넌트 스크립트입니다.

Bullet object가 생성돼야 Bullet 클래스가 실행되는 것입니다.

Bullet object는 Turret클래스에서 shoot함수가 호츨될때 생성됍니다.

    void Shoot()
    {
        GameObject bulletGO = Instantiate(bulletPrefab, firePoint.position, firePoint.rotation);
        Bullet bullet = bulletGO.GetComponent<Bullet>();

        if (bullet != null)
            bullet.Seek(target);
    }

Turret.Shoot() 함수입니다. --

bulletPrefab은 public으로 선언한 멤버 변수이고 저희는 Bullet prefab을 대입할 계획입니다.

결국 Bullet클래스가 실행되고 private으로 선언한 Bullet.target은 bullet.Seek() 함수를 이용해서  Turret.target으로 대입됩니다.

 

그다음 Update문입니다.

     if(target ==null)
        {
            Destroy(gameObject);
            return;
        }

이조 건문은 저희가 다음 사용할 

Vector3 dir = target.position - transform.position;

여기서 target이 할당되지 않으면 컴파일 에러를 예방하기 위한 예외처리입니다. 

distanceThisFram은 bullet object가 움직이는 속도입니다. speed/sec의 속력을 가지게 됩니다.

        if(dir.magnitude <= distanceThisFram)
        {
            HitTarget();
            return;
        }

        transform.Translate(dir.normalized * distanceThisFram, Space.World);

조건문 dir.magnitude 이 distanceThisFram 보다 작거나 같은 상황은 bullet object의 속력이 거리보다 작은 경우

즉 속력이 빠르다면 범위 안에 있는 모든 enemy들을 제거할것이고 , 속력이 느리다면 범위안에 있더라도 enemy들을 제거하지 못할 것입니다.   

그렇게 조건문이 참인 경우 즉 Bullet object가 enemy와 만났을 경우 HitTarget() 함수를 실행하고 Update문을 빠져나옵니다.

아닌 경우 bullet object를 이동합니다.

 

    void HitTarget()
    {
        GameObject effectIns= Instantiate(impactEffect, transform.position, transform.rotation);
        Destroy(effectIns, 2f);
        Destroy(target.gameObject);
        Destroy(gameObject);
    }

HitTarget() 함수는 impactEffect object를 생성한 후

2초 뒤 제거하고

enemy object를 제거하고,

bullet object를 제거합니다.

이렇게 하고 

unity edite로 돌아가서 public object를 드래그해주기 위해 effect를 제작해서 넣어야 하는데

effect제작은 복잡하고 제가 잘 몰라서 이 블로그에서는 자세히 다루지 않고 기본적인 것만 넣어서 제작하겠습니다. 

www.youtube.com/watch?v=1fp97pDZm_o

이렇게 작업하면 타워가 enemy를 제거하는 작업이 완료됩니다.

이것으로 타워 생성 프로젝트는 완료하고 다음은 게임에서 블록을 클릭하면 타워가 생성되는 타워 건설 프로젝트로 돌아오겠습니다.

읽어주셔서 감사하고 유튜버 brackeys에게 감사합니다.

출처- www.youtube.com/watch?v=oqidgRQAMB8&list=PLPV2KyIb3jR4u5jX8za5iU1cqnQPmbzG0&index=5

 

+ Recent posts