유니티3D 4강

http://freebox.myqnapcloud.com:8080/share.cgi?ssid=0dICmIN
4강소스


배열은 하나 이상이기때문에 NEW를 선언 해줘야 한다

코딩시 숫자를 넣는것 보다 단어를 넣는것이 좋다.

코루틴은 RETURN을 쓸 수 없다.

*이름 정하는것도 기술이다.(패턴)


ngui -> texture 는 ugui의 image와 같은 기능

ngui -> 3d 모델을 2d 이미지로 만들기
(메인 카메라를 활용하여 ngui 화면에 띄우는 방식)


  3d 모델을 화면에 끌어다 놓는다.(원래 3d 카메라 뷰)

   # 참고)  카메라의 뎁스에 따라 ngui가 보이고 원래 카메라가 보이고...
   레이어 개념으로 이해

   메뉴에서 texture 선택  하이어라키에 TEXTUTRE 오브젝트 생성됨

   프로젝트에서 Render texture 생성

  
  생성된 Render texture를 메인카메라 선택후 타겟 텍스쳐에 드래그앤 드롭
  (카메라가 보이는 뷰를 그린다.) 

 생성된 Render texture를 하이어 라키 텍스쳐에 드래그앤 드롭

  생성된 화면을 볼 수 있다.
   
   

   





















생성된 화면 사이즈는 인스펙터에서 조정


화면의 스카이 박스 끄기




안티 알리아싱 퀄리티 올리기

레이어 적용, 컬링 마스크 적용
NGUI 카메라

메인 카메라

슬라이더 바 만들기

슬라이스 자르는것은 프리팹에서 담당한다.

 일단 아틀라스를 등록 해주고...

스프라이트를 만들어 준다.


해당 프리팹 선택 후 -> 스프라이트 클릭 -> 슬라이스 할 스프라이트 선택

 NGUI  처럼 보더로 잘라 준다.




중심축은 피봇에서 바꾼다.


ngui 슬라이더 컴포넌트 추가

  ngui 슬라이더 컴포넌트에 스프라이트 추가

  ngui 슬라이더 컬러 컴포넌트추가 -> 값이 줄어들수록 컬러 변경가능
  (게임 실행시에 확인 할 수 있음)


   팝업 만들기.
NGUI-> CREATE ->PANEL
하이어 라키 PANEL 밑으로 스프라이트 추가



   스프라이트 타일 방식으로 바꿔서 사용


  스프라이트 타일이 문제가 있을때 해결


버튼추가 방법.
스프라이트 추가 -> 스프라이트 선택
추가된 스프라이트에 박스 콜라이더 컴포넌트 연결


Collider auto~ 체크하여 콜라이더 스프라이트 크기와 같게 맞춰줌.




ngui 버튼 컴포넌트 추가



tween 컴포넌트 추가 ( 애니메이션 가능)




팝업창 띄우기
패널 -> 하위 오브젝트를 묶는개념
패널 생성
패널 아래로 스프라이트 생성
스프라이트 인스펙터-> 스프라이트 선택




안드로이드 sdk 설치

ngui 애니메이션 스크립트 추가
빌드셋팅 -> 안드로이드 선택.
안드로이드는 JAVA 기반의 os이다.
때문에 JAVA SDK가 설치 되어 있어야 한다.

구글 검색 -> JAVA SDK 1.7 
http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260.html



구글 검색 -> android SDK
https://developer.android.com/sdk/index.html#Other
ZIP로 다운



자바 설치 -> 넥스트 넥스트....
C:\Program Files (x86)\Java 폴더에
jdk1.7.0_79 , jre7 설치가 되어 있는지 확인한다.





 유니티 메뉴 -> 에디트 -> 프리퍼런스 -> 폴더 설정
 안드로이드 sdk도 다운받은 폴더를 지정해준다
안드로이드  sdk 매니저 실행


안드로이드SDK 설치
다운받은 파일 압축 해제->SDK Manager 실행 (시간이 몇초 지나야 나옴)
설치할 SDK 버전 체크한다.



빌드를 위한 유니티 설정

고유 아이디 설정(내 어플만의 아이디)
com.Company.ProductName 수정 
Company = 숫자로 시작하면 안됨. 특수기호 안됨 ' _ ' 가능






스크립트.
=====[ 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;
 
    // 플레이어 데미지
    PlayerState playerDamage;
 
    // 애니메이션 컴포넌트 참조 할 변수
    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)
        {
            // 플레이어 damage  메서드 호출
            playerDamage.damage();
 
            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");
        playerDamage = target.GetComponent<PlayerState>(); 
    }
 
 
    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;
 
        }
         */ 
    }
}

===[ PlayerState  ]==================================
using UnityEngine;
using System.Collections;
 
public class PlayerState : MonoBehaviour
{
    //50/100 = 0.5
    // 최대 체력
    const float hpMax = 100;
    public int hp = 100;
    // 캐릭터 사망 확인 불 변수.
    bool isDead = false;
 
    public UISlider hpSlider;
 
    public GameObject PopUp;
 
 
 
    void Start()
    {
 
 
    }
 
 
    void Update()
    {
 
    }
 
    public void damage()
    {
 
        if (isDead) return//_hp 가 -값으로 내려가지 않도록.
        hp -= 5;
        // 비율 계산
        float ratio = (float)hp / hpMax;
        hpSlider.value = ratio;
        if (hp <= 0)
        {
            isDead = true;
            Die();
        }
 
 
        print("현재 체력은 : " + hp);
 
    }
 
    public void Die()
    {
        // 팝업창 띄움
        PopUp.SetActive(true);
        print("죽었어....");
 
    } 
}

===[ UIGameEvent ]=============================

using UnityEngine;
using System.Collections;

public class UIGameEvent : MonoBehaviour {
 
 
    void Awake()
    {
        gameObject.SetActive(false);
    }
 
    public void Replay()
    {
 
        Application.LoadLevel("fps_game");
    }
 
 
    public void Title()
    {
        Application.LoadLevel("TITLE");
    }
}


====[ UTTitleEvent ]==============================================
using UnityEngine;
using System.Collections;
 
public class UTTitleEvent : MonoBehaviour {
 
    // Use this for initialization
    void Start () {
    
    }
    
    // Update is called once per frame
    void Update () {
    
    }
 
    public void SceneMain()
    {
        Application.LoadLevel("fps_game");
 
    }
 
 
}

댓글

이 블로그의 인기 게시물

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

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

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