* Skybox에 이미지를 적용할 때 Wrap Mode를 Repeat가 아닌 Clamp로
바꿔줘야 연결 부분이 깔끔하게 이어짐을 알게 되다.
* Hierarchy에 마우스 우클릭 UI-Canvas를 눌러 캔버스를 생성하면 EventSystem도 따라
생성된다. Canvas 하위에 Panel, Raw Image, Button 등 만들어 넣고 설정 테스트.
* Hierarchy에 마우스 우클릭 UI-Canvas를 눌러 캔버스를 생성, EventSystem도 따라 생성.
Canvas 하위에 Panel 추가, 'PanelScore'라 명명, Image 컴포넌트 Source Image에
04.Images-UI Textures(UI_Textures.unitypackage로 프로젝트에 추가한 것)-textures
and Sprites 폴더의 Button-Tab.psd를 드래그. Color는 푸른색으로 설정. 패널 크기 조정하고
위치는 화면 좌상으로 배치. PanelScore 아래에 UI-Text 추가. Text-Text에 'SCORE <color=#ff0000>0000</color>'
입력하여 숫자 빨간색으로. Text 컬러는 연녹색.
Canvas의 Pixel Perfect의 체크를 해제하면 안티알리아싱 기능을 해제하여 외곽선이 뚜렷해 진다.
빈 게임 오브젝트 생성, 'GameUI'라 명명, 'csGameUI.cs' 스크립트 새로 만들어 적 죽일 때 마다
점수 오르게 하는 기능 추가. 스크립트에
//UI 컴포넌트에 접근하기위해 추가한 네임 스페이스
using UnityEngine.UI;
를 추가해 줘야 한다.
*PlayerPrefs메서드를 이용한 게임자료 저장, 불러오기:
//스코어 저장
PlayerPrefs.SetInt("TOT_SCORE", totScore);
//저장된 스코어 정보 불러와 변수에 저장
totScore = PlayerPrefs.GetInt ("TOT_SCORE", 0);
*생명 게이지 구현하기:
위에 만든 패널을 Ctrl-D로 복제한 뒤 조금 아래로 내리고 하위 Text는 제거.
\Resource\Images\hpbar.psd 불러오기. Texture Type: Sprite(2D
and UI)로 변경, Apply.
패널 하위에 UI-Image 추가. Source Image에 hpbar.psd 드래그.
Image Type: Filled, Fill Method: Horizontal로 설정.
csPlayerCtrl.cs 스크립트 중 적에게 공격 받을 때(OnTriggerEnter(Collider col){})
아래 내용 추가, 공격 받아 체력이 줄면 체력 게이지도 줄어들게 처리.
public Image imgHpbar; //플레이어의 Health Bar 이미지
//Image UI항목의 fillAmount 속성을 조절하여 생명 게이지값 조정
imgHpbar.fillAmount = (float)hp / (float)initHp;
7장 유니티UI 따라하기 완료.
* 빈 게임 오브젝트들로 스폰 포인트들 만들고 역시 빈 게임 오브젝트 생성, 'GameManager'라 명명,
csGameMgr.cs 스크립트 만들어 게임오버가 아닌 동안 최대 몬스터 갯수만큼 랜덤한 스폰 포인트에 몬스터
생성시키기. 몬스터 추적거리: 10 에서 40으로 변경. csMonsterCtrl.cs에서 몬스터 죽을 경우 태그를
Untagged로 변경하여 죽은 몬스터를 제외하고 최대 몬스터 수 유지하게 처리.
csPlayerCtrl.cs 스크립트에 주인공 사망시
//게임 매니저의 isGameOver 변수값을 변경, 몬스터 출현을 중지시킴
gameMgr.isGameOver = true;
csGameMgr.cs 스크립트 내 게임오버 여부 변수값 변경시켜 몬스터 출현 중지.
* 싱글턴: 매번 변수 선언 뒤 할당하는 번거러운 초기화 대체 가능 기술
//싱글턴 패턴을 위한 인스턴스 변수 선언
public static csGameMgrSingle instance = null;
void Awake(){
instance = this; //csGameMgrSingle 클래스를 인스턴스에
대입
}
//csGameMgrSingle의 싱글턴 인스턴스로 접근, isGameOver 변수값을 변경, 몬스터 출현을 중지시킴
csGameMgrSingle.instance.isGameOver = true;
*오브젝트 풀: 게임오브젝트, 프리팹등을 처음 로드시 모두 생성하여 담아 두고 필요할 때 가져다
사용하는 방식.
//List 자료형을 사용하기 위해 추가해야하는 네임스페이스
using System.Collections.Generic;
//몬스터를 미리 생성, 저장할 리스트 자료형
public List<GameObject> monsterPool = new
List<GameObject>();
void Start () {
//몬스터 생성, 오브젝트 풀에 저장
for (int i = 0; i < maxMonster; i++) {
//몬스터 프리팹 생성
GameObject monster = (GameObject)Instantiate(monsterPrefab);
//생성한 몬스터 이름 설정
monster.name = "Monster_"+i.ToString();
//생성한 몬스터 비활성화
monster.SetActive(false);
//생성한 몬스터 오브젝트 풀에 추가
monsterPool.Add(monster);
} }
*공용함수-사운드 처리: 사운드 처리 한 곳에서 처리하기.
csGameMgr.cs 스크립트 수정
//사운드의 볼륨 설정 변수
public float sfxVolumn = 1.0f; //사운드 뮤트 기능
public bool isSfxMute = false; //사운드 공용 함수
public void PlaySfx(Vector3 pos, AudioClip sfx){
//음소거 옵션이 설정되면 바로 빠져나가기
if (isSfxMute) return;
//게임오브젝트 동적 생성
GameObject soundObj = new GameObject ("Sfx");
//사운드 발생 위치 지정
soundObj.transform.position = pos;
//생성한 게임오브젝트에 AudioSource 컴포넌트 추가
AudioSource audioSource = soundObj.AddComponent ();
//AudioSource 속성 설정
audioSource.clip = sfx;
audioSource.minDistance = 10.0f;
audioSource.maxDistance = 30.0f;
//sfxVolumn 변수로 게임의 전체적 볼륨 설정 기능
audioSource.volume = sfxVolumn;
//사운드 실행
audioSource.Play ();
//사운드 플레이 종료시 동적 생성한 게임오브젝트 삭제
Destroy (soundObj, sfx.length);
}
csFireCtrl.cs 스크립트 수정
void Fire(){ csGameMgrPool.instance.PlaySfx (firePos.position,
fireSfx); }
8장 게임 매니저 예제 따라하기 완료.
* 9장 레이캐스트 활용
csFireCtrl2.cs에 추가
void Update () {
//Ray를 시각적으로 표시하기 위해 사용
Debug.DrawRay(firePos.position, firePos.forward * 10.0f, Color.green);
if (Input.GetMouseButtonDown (0)){ //마우스 좌클릭시
Fire();
//Ray에 맞은 게임오브젝트 정보를 받아올 변수
RaycastHit hit;
//Raycast 함수로 Ray를 발사, 맍은 게임 오브젝트가 있을 때 true 반환
if(Physics.Raycast(firePos.position, firePos.forward, out hit, 10.0f)){
//Ray에 맞은 게임오브젝트의 Tag 값을 비교, 몬스터 여부 체크
if(hit.collider.tag == "MONSTER"){
//SendMessage를 이용, 전달받은 인자를 배열에 담기
object[] _params = new object[2];
_params[0] = hit.point; //Ray에 맞은 정확한 위치값(Vector3)
_params[1] = 20; //몬스터에 입힐 데미지 값
//몬스터에 데미지 입히는 함수 호출
hit.collider.gameObject.SendMessage("OnDamage", _params,
SendMessageOptions.DontRequireReceiver);
}
}
}}
csMonsterCtrl2.cs에 추가
//몬스터가 Ray에 맞았을 때 호출되는 함수
void OnDamage(object[] _params){
Debug.Log(string.Format("Hit Ray {0}:{1}", _params [0],_params[1]));
//혈흔 효과 함수 호출
CreateBloodEffect ((Vector3)_params [0]);
//맞은 총알의 Damage 추출해 몬스터 hp 차감
hp -= (int)_params [1];
if (hp <= 0) {
MonsterDie();
}
//IsHit Trigger를 발생, Any State > gothit로 전이
animator.SetTrigger ("IsHit");
}
pfBarrel에 'BARREL'이란 새 tag 추가, csBarrelCtrl.cs 스크립트에 추가
//Barrel이 Ray에 맞았을 때 호출되는 함수
void OnDamage(object[] _params){
//발사위치
Vector3 firePos = (Vector3)_params [0];
//드럼통에 맞은 hit 위치
Vector3 hitPos = (Vector3)_params [1];
//입사벡터(Ray의 각도) = 맞은 좌표 - 발사 원점
Vector3 incomeVector = hitPos - firePos;
//입사벡터를 정규화 벡터로 변경
incomeVector = incomeVector.normalized;
//Ray의 hit 좌표에 입사벡터 각도로 힘 생성
GetComponent ().AddForceAtPosition (incomeVector * 1000f, hitPos);
//총알 맞은 횟수 증가 시키고 3회 이상이면 폭발 처리
if (++hitCount >= 3) {
ExpBarrel();
}
}
*레이저빔 구현: Hierarchy-PlayerNew-FirePos 아래 빈 게임오브젝트 만들고 'LaserBeam'이라
명명, 메뉴 Component-Effects-Line Renderer 컴포넌트 추가, Use World Space
체크 해제(해제 안하면 피봇 위치에 레이저가 생성). Materials-Element0에 03.Images-Materials-BulletTrail
매터리얼 적용.
csLaserBeam.cs 스크립트 만들어 LaserBeam에 적용하고 레이저가 눈에 보이게 처리. 9장 레이캐스트
활용 따라하기 완료. |