유니티3D 3강


3강 소스자료
http://freebox.myqnapcloud.com:8080/share.cgi?ssid=0976X1B

애니메이션 리셋 트리거. 찾아볼것.
MoveNext() 찾아보기

NGUI
UI편집할때는 화면을  2D로 본다.

아틀라스 선행작업. 속도와 안정성 때문에 사용한다.


UI Root 는 NGUI의 캔버스라고 생각...

해상도 설정

Scaling Style 
 - flexible : 원래 이미지 크기 
 - Constrained (pc작업시) : 해상도 사이즈에 맞게 늘어나고 줄어듬 (가장 많이 쓰는 타입)
 - Constrained Mobil (모바일 작업시) : 















버튼 스프라이트 추가하고 버튼 스크립트 컴포넌트 연결
눌렀을때 크기 조절
==[ delgate ]=====

using UnityEngine;
using System.Collections;
 
public class delgate : MonoBehaviour {
    // 델리게이트
    // 같은 매개변수를 가지고 있는 메서드를 대입 할 수 있다. 몇개라도.
    delegate void Calc(int a, int b);
 
    void Add(int a, int b)
    {
        // 스트링 변수 선언한 뒤에 들어오는 숫자는 문자가 된다.
        
        string result = "add :" + (a + b);
        print(result);
    }
 
    void Mul(int a, int b)
    {
        print("mul : " + (a * b));
    }
 
    // Use this for initialization
    void Start () 
    {
        /*
        Calc calc = Add;
        calc(10, 30);
        */
        /*
        Calc calc = Add;
        calc = Mul;
        Mul(10, 10);
         */
 
        /*
        Calc calc = Add;
        calc += Mul;
        calc(5, 5);
         */
 
        /*
        Calc calc = Add;
        calc = Mul;
        Mul(10, 10);
        Add(15, 10);
         */
 
        // 델리게이트형 배열 변수 calc생성 
        Calc[] calc = new Calc[2];
        // calc에 메서드 대입
        calc[0] = Add;
        calc[1] = Mul;
 
        /*
        for (int i = 0; i < calc.Length; i++)
        {
            calc[i](5, 5);
        }
        */
 
        foreach (Calc n in calc)
        {
            n(5,5);
        }    
    }
}

======[ Spider ]===========

using UnityEngine;
using System.Collections;
 
public class Spider : MonoBehaviour
{
 
    //델리게이트 선언
    delegate void State();
 
 
 
    // enum 코드의 효율성을 주고 싶을때. 문자로 표시 할 수 있음 가독성을 높일 수 있음.
    public enum SpiderState
    {
        // 첫번째 변수에 0을 대입하면 순차적으로 Move = 1, Attack = 2, Damage = 3 순으로 올라간다
        None = -1,// 생성되어 있지 않고 아무것도 아닌 대기상태
        Idle,
        Move,
        Attack,
        Damage,
        Dead,
        Max
    }
 
    //델리게이트 형 배열 선언
    //(int)SpiderState.Max = enum 의 마지막.(int(숫자))형으로 변환
    //배열을 맴버변수로 선언할때 메소드 위에 선언하면 메소드의 주소를 찾을 수 없다.
    State[] funState = null;
 
    
 
    // 애니메이션 컴포넌트 참조 할 변수
    Animation monAni = null;
    GameObject target = null;
 
    //대기 시간 변수
    float interVal = 0;
    //const 를 선언하면 값을 변할 수 없게 한다.
    const float attackRange = 3; //공격범위
    const float attackTime = 2;  //공격시간
 
    int hp = 5;
 
    // enum 참조
    // enum SpiderState를 변수 state에 대입    
    // 무브를 실행 하려면 = SpiderState state = SpiderState.Move;
 
    SpiderState state = SpiderState.Idle;
 
    //상태처리 함수 생성   
    void Idle() // 대기
    {
 
        // monAni.Play("idle");
 
        //타이머 설정 
        interVal += Time.deltaTime; //interVal변수에 현재 시간의 흐름(float)을 더해준다.
        if (interVal > attackRange) //2초 지난뒤 실행
        {
            //2초 지난뒤 SpiderState.Move 호출
            state = SpiderState.Move;
            interVal = 0; // 재활용을 위해 초기화 시킨다
        }
    }
 
    void Move()
    {
        // 거리값 계간 함수 Vector3.Distance(a의 위치 , b의 위치);
        float distance = Vector3.Distance(target.transform.position, this.transform.position);
        //거리값으로 공격 호출       
        if (distance < attackRange)
        {
            state = SpiderState.Attack;
            // 인터벌 어택타임 3초로 대입하여 플레이어와 가까워 졌을때 바로 공격
            interVal = attackRange;
 
        }
 
        else
        {
            // 이동
            // 타겟 - 자기 자신 ( 방향 설정 ) * 이동 공식 외울것.
            // dir에 플레이어의 위지를 대입하고 자기 자신의 위치값을 뺀다.
            Vector3 dir = target.transform.position - this.transform.position;
            //normalized = ??? 벡터를 만들기 위해 실행 한 함수.
            dir.Normalize();
            dir.y = 0;
            //이동 코드 = 자기 자신의 위치 += 이동방향 * 속도 * 시간
            this.transform.position += dir * 5 * Time.deltaTime;
 
            // 플레이어의 회전 방향 대입
            Quaternion to = Quaternion.LookRotation(dir);
            // 회전  Lerp() = 시간에 따라 부드러운 처리 사용
            // Quaternion.Lerp(자기자신의 회전 방향(값), 바라보고 싶은 방향(값 플레이어),시간(회전할 시간 각) );
            // 10 * Time.deltaTime 매 프레임마다 각을 계산
            //this.transform.rotation = Quaternion.Lerp(this.transform.rotation,to, 10 * Time.deltaTime);
            this.transform.rotation = Quaternion.Lerp(this.transform.rotation, to, 0.05f);
 
            monAni.Play("walk"); // 이동 애니메이션 호출
        }
 
 
 
 
    }
 
    void Attack() // 공격
    {
 
        interVal += Time.deltaTime;
        // 2초에 한번 공격
        if (interVal > attackTime)
        {
            monAni.Play("attack"); // 공격 애메니이션 호출
            // PlayQueued : attack(이전 attack은 루프가 되면 안됨) 애니메이션 뒤에 idle 애니메이션을 추가 함.
            monAni.PlayQueued("idle");
 
            interVal = 0;
        }
 
        //플레이어와 거리가 멀어지면 다시 idel 호출
        if (Vector3.Distance(target.transform.position, this.transform.position) > attackRange)
        {
            state = SpiderState.Idle;
            interVal = 0;
        }
 
 
    }
 
    void Damage() // 데미지
    {
        monAni.Play("damage");
        monAni.PlayQueued("idle");
 
        interVal = 0;
        state = SpiderState.Idle;
        hp--;
        if (hp <= 0)
        {
            state = SpiderState.Dead;
        }
 
    }
    void Dead() // 죽음
    {
 
        state = SpiderState.None; // 코루틴 작동 안됨
        StartCoroutine(DeadProcess()); // 
        //Destroy(this.gameObject, 0.5f);
        
 
    }
 
    void Reset()
    {
        hp = 5;
        state = SpiderState.Idle;
        monAni.Play("idle");
    }
 
    //public AnimationClip[] clip = null;
    
 
    IEnumerator DeadProcess()
    {
 
        monAni.Play("death");
 
        //애니메이션 시간 구하기(레거시용)
        float length = monAni["death"].length;
        yield return new WaitForSeconds(length + 1); // 애니메이션 시간 + 1초 
 
        // 몬스터 사망시 아래로 내려가는 코드
        while (this.transform.position.y > -2)
        {
            Vector3 temp = this.transform.position;
            //this.transform.position.y = .y로 바로 접근 할 수 없음.
            temp.y -= 0.5f * Time.deltaTime;// 매프레임마다 0.5f만큼 뺀다
            this.transform.position = temp;
            
            // 코루틴 대기 ,일정 프레임에 한번씩 대기 동시 작업 가능
            // 코루틴에서 while문을 사용 할 때 사용
            yield return new WaitForEndOfFrame();
        }
 
 
        Reset();
        this.gameObject.SetActive(false);
        
 
    }
 
 
 
 
    void OnCollisionEnter(Collision col)
    {
 
        if (state == SpiderState.None || state == SpiderState.Dead) return;
        // 레이어 인덱스는 문자로 넣어도 숫자로 반환된다.
        // 레이어 인덱스는 int형 변수에 대입된다
        int layerIndex = col.gameObject.layer;
        //레이어 마스크로 부딪히는 오브젝트 이름 가져옴
        if (layerIndex == LayerMask.NameToLayer("ball")) 
        {
            state = SpiderState.Damage;
        }
        
        /*
        if (col.gameObject.tag == "bullet")
        {
            state = SpiderState.Damage;
 
        }
        */
    }
 
 
    void Start()
    {
        // 델리게이트 배열 대입 한줄로 선언.   
        funState = new State[(int)SpiderState.Max] { Idle, Move, Attack, Damage, Dead };
        
        // 델리게이트 배열에 각 메소드 대입 초기화        
        /*
        funState[(int)SpiderState.Idle] = Idle;
        funState[(int)SpiderState.Move] = Move;
        funState[(int)SpiderState.Attack] = Attack;
        funState[(int)SpiderState.Damage] = Damage;
        funState[(int)SpiderState.Dead] = Dead;
        */
 
        // 매카닉(new) 애니메이션 방식은 Animator 레거시(old) 방식은 Animation
        // 몬스터 애니메이션에서 idle 애니메이션을 플레이 시킨다. 레거시 방식은 초기 루프가 기본이 아니다.
        monAni = GetComponent<Animation>();
        // 태그로 플레이어 검색
        target = GameObject.FindGameObjectWithTag("myPlayer");
 
 
    }
 
 
    void Update()
    {
        // enum 의 메소드 호출 방법 delegate사용
        if (state == SpiderState.None) return;
        funState[(int)state]();
 
 
        // enum 의 메소드 호출 방법 swich사용
        /*
        switch (state)
        {
            case SpiderState.Idle:
                {
                    Idle();
                }
                break;
            case SpiderState.Move:
                {
                    Move();
                }
                break;
            case SpiderState.Attack:
                {
                    Attack();
                }
                break;
            case SpiderState.Damage:
                {
                    Damage();
                }
                break;
            case SpiderState.Dead:
                {
                    Dead();
                }
                break;
 
        }
         */
 
    }
}



===== [ MonsterGen ] =========

using UnityEngine;
using System.Collections;
 
public class MonsterGen : MonoBehaviour
{
 
    float randX;
    float randZ;
    Vector3 genPos;
 
    public GameObject monster = null;
 
    //몬스터를 담아놓을 공간.  배열 생성 ( 배열을 생성할때 new를 붙인다)
    //const 절대 변하지 않는 변수 선언 , 배열에 변수를 대입할때는 const 선언을 해준다.
    const int poolArraySize = 10;
    GameObject[] enemyPool = new GameObject[poolArraySize];
 
 
    void Start()
    {
        /*
        IEnumerator f = Factoy();
        StartCoroutine(f);
         */
        for (int i = 0; i < poolArraySize; ++i)
        {
            // 몬스터를 배열에 담음
            enemyPool[i] = Instantiate(monster); //enemyPool[0]  = monster0번이됨.
            enemyPool[i].SetActive(false); //SetActive는 업데이트에서 사용하면 느려진다.
        }
 
        StartCoroutine(Factoy());
    }
 
 
 
 
    // 몬스터 생성
    IEnumerator Factoy()
    {
        //몬스터 이름 인덱스 설정
        //int index = 0;
        while (true)
        {
 
            yield return new WaitForSeconds(3);
 
            for (int i = 0; i < poolArraySize; ++i)
            {
                // enemyPool[i] 배열에 담긴 게임오브젝트를 mom 게임오브젝트 변수에 담는다
                GameObject mon = enemyPool[i];
                //activeSelf 게임오브젝트 자신의 active에 대한 반환값 (true of flase)
                if (mon.activeSelf == true//배열에 담긴 게임오브젝트의 activeSelf 가 true라면
                {
                    continue//true라면 재실행 false 라면 아래 코드 실행
                }
                randX = Random.Range(20, -20);
                randZ = Random.Range(20, -20);
                genPos = new Vector3(randX, 0, randZ);
                mon.transform.position = genPos;
                mon.SetActive(true);
                break// for 코드 종료 yield return new WaitForSeconds(3); 실행
            }
 
 
 
            /*
            randX = Random.Range(20, -20);
            randZ = Random.Range(20, -20);
            genPos = new Vector3(randX, 0, randZ);
 
            GameObject mon = Instantiate(monster);
            
            mon.transform.position = genPos;
            // 몬스터의 이름 설정
            mon.name = "Monster" + index;
            index++;
            */
        }
 
 
    }
 
}






댓글

이 블로그의 인기 게시물

날짜 시간 시간차 시간 계산 하기

코루틴에서 CallBack 함수 적용하기

C++ 언어 퍼센트 구하는 방법 / 기본 언어 퍼센트 구하는 방법