버튼을 눌렀을 때, 버튼음을 집어넣었다.


그런데, 버튼을 빠르게 누르면 누른 횟수대로 사운드가 재생된다.


어떻게 이 문제를 해결할까?


1. PlayOneShot()함수 앞에 Stop()함수를 먼저 실행한다.


--> 안 된다. 짧아서 그런지 몰라도 .


매우 간단하게 해결 할 수 있다.


바로,


isPlaying을 잘 사용하면 된다.


public AudioSource soundSource;
public AudioClip[] sound;

if (soundSource && sound[3])
if (soundSource.GetComponent<AudioSource>().isPlaying) return;
else soundSource.GetComponent<AudioSource>().PlayOneShot(sound[3]);


핵심은 isPlaying을 사용하는 것이다.


만약(if)현재 플레이 중이라면 return 즉, 아무것도 진행하지 말라는 의미이며,


그렇지 않다면(=플레이 중이 아니라면else) PlayOneShot을 사용하여 1회 플레이하라는 의미이다.


이렇게하면 버튼을 미친듯이 눌러도 이벤트는 발생하지만 isPlaying에 막혀 사운드는 출력되지 않는다.


이상으로 버튼 사운드 중복될 때 해결 방법을 알아봤다.

Posted by sungho88
,

버튼을 1회 클릭 후 더이상 누르지 못 하게 막는 것이 비활성화(disable)이다.



NGUI를 사용하는 경우 스크립트에서 비활성화시키기 위해서는 


버튼을 찾아온 후, isEnabled를 사용한다.



answerObject.GetComponent<UIButton>().isEnabled = false;


이것이 버튼을 눌렀을 때, 버튼을 다시 중복해서 누를 수 없게 비활성화시키는 코드이다.




그런데, 실행해보면 다음과 같이 비활성화되었다고 저렇게 진한 회색으로 표시된다.


이것은 기본적으로 세팅되어있는것이다.


색상을 바꾸고 싶거나, 제거하고 싶으면 UIButton에서 없애면된다.



위에서 Disabled를 수정해주면 된다.


이상으로 NGUI에서 UIButton 사용시, isEnabled = false로 비활성화했을 때 색상 제거하는 것을 알아보았다.

Posted by sungho88
,

개발할 때 평소에는 아무것도 아닌 것 같지만 사용하지 않으면 불편하고 사용하면 매우 효율적일 때가 있다.


인스펙터 잠금에 대해 알아보겠다.


유니티에서 AudioClip 배열을 만들었다.


public AudioClip[] uiSound;


와 같이 선언했더니, 다음과 같이 유니티에서 스크립트에 이렇게 배열이 생겼다.


auio 파일이 만약 50개라면 어떻게 할까?


1개는 드래그해서 넣을 수 있고, 이 창이 닫히지 않는다.


하지만, 여러개를 선택하기 위해 Project 뷰에 마우스를 갖다대면 이 Inspector창은 닫힌다.


그렇다고 하나하나 일일히 드래그 앤 드롭해서 집어넣을 수도 없다.(있긴 하지...)


그래서 찾다보니 잠금 기능을 찾았다.


말 그대로 인스펙터 창을 잠금. 즉 닫히지 않고 고정시켜주는 기능을 갖고 있다.



오른쪽 위쪽에 자물쇠 모양이 존재한다.


이것을 누르면 잠금 다시 누르면 잠금해제된다. 


그림이 작지만 눈 크게 뜨고 자세히보면 모양이 달라진다.


이렇게 잠금모드로 해놓고 50개를 전체 선택 후 드래그해서 위 배열 이름 위(UI Sound) 갖다놓게 되면 50개 모두 삽입!


이상으로 유니티 내 잠금기능에 대해 알아보았다.

Posted by sungho88
,

유니티 게임오브젝트에 애니메이션을 적용하기 위해서는 컴포넌트로  Animation을 추가해주면 된다.


[컴포넌트를 추가하는 방법]


1. 컴포넌트를 붙이길 원하는 게임오브젝트를 선택한다.


2. Add Component를 누른뒤 Animation을 추가한다.


3. Animation 컴포넌트가 추가되었다. 물론, 아무것도 넣지 않았기때문에 None 즉 아무 애니메이션도 존재하지 않는다.


4. death라는 애니메이션을 Animation에다가 집어넣었다. 이 경우 애니메이션 동작을 한 개(death)만 보여줄 경우이다.


5. 한 게임오브젝트에 여러 애니메이션을 재생하려면, Animations에다가 여러개의 애니메이션 파일을 집어넣는다.



그렇다면 Animations에 담긴 애니메이션 파일은 어떻게 사용할까?


일단, 코드에서 애니메이션을 실행하는 코드는 anim.Play("");이다.


그럼, Animations는 배열이므로 string[]배열을 사용해야 할 것이다.


하지만 배열은 선언할 때 반드시 크기를 명시해줘야 한다.


즉, 배열에 저장할 데이터의 크기를 확실히 모르거나 데이터가 도중에 추가될 가능성이 있다면 배열을 사용하면 안 된다.


List를 사용한다.

 


    List<string> animArray;
    Animation anim;     
int index = 0;

void Start()
{
        anim = gameObject.GetComponent<Animation>();
        animArray = new List<string>();
            AnimationArray();

            anim.Play(animArray[randomNum]);
            anim.wrapMode = WrapMode.Once;
}

public void AnimationArray()
{
        foreach (AnimationState state in anim)
{
            animArray.Add(state.name);          
           index++;
}
        randomNum = Random.Range(0,index);
}



이렇게하면 된다.



중요한 함수는 AnimationArray()함수이다.


여기서, foreach문을 사용하여 AnimationState형으로 꺼내온 뒤, list에 저장한다(Add)


나는 항목들 중 랜덤으로 1회 플레이하기 위해서 Random.Range를 사용했고,


Play안에 난수를 집어넣었다. 이렇게 함으로써 랜덤한 애니메이션이 1회 플레이 될 것이다.



이상으로 애니메이션(Animation) 컴포넌트 안에 Animations 배열을 가져오는 방법에 대해 알아보았다.



Posted by sungho88
,

루프(loop)를 설정하여 무한 반복할 것인지, 한 번만 실행할 것인지(once)를 설정해야 할 때가 있다.


물론 유니티 내에서 설정이 가능하지만, 코드로 동적으로 변경하고 싶다면 어떻게 할까.


순간 Audio Source와 헷갈려서 , anim.loop = true로 작성했는데 안된다.


정신차리고...


애니메이션 loop나 once는 어떻게 설정할까?



위와같이 death 애니메이션 파일을 클릭하면, 아래와 같이 나온다.


Wrap Mode라고 씌여있다.


왠지 이것을 스크립트에서 사용하면 될 것 같아서 wrapmode를 입력해봤다.


역시. 


anim.wrapMode가 존재했다. 이것 키워드로 구글에 검색을 해보니 정답을 얻을 수 있었다.


아래와 같이 하면, 애니메이션을 제어할 수 있다.


anim.wrapMode = WrapMode.Once;


이렇게 작성하면 한번(once) 실행되고 중지된다.


anim.wrapMode = WrapMode.Loop;


이렇게 작성하면 무한 반복된다.


이상으로 유니티에서 애니메이션 반복 여부를 설정하는 코드에 대해 알아봤다.


Posted by sungho88
,

유니티 개발할 때, 사운드 두 개를 이어서 나오게 하고 싶다면 어떻게 할까?


일단, 사운드를 위해서는 AudioSource와 AudioClip 두 개가 필요하다.


public AudioClip[] intro_music;
AudioSource soundSource;


오디오 클립은 각각의 사운드 파일을 의미하며, AudioSource를 통해 플레이 한다고 할 수 있다.


사운드를 넣기 위해 public으로 선언했다. AudioSource는 GetComponent로 호출할 수 있으므로 안 해도 된다.


    void Start () {
        soundSource = GetComponent<AudioSource>();
        StartCoroutine("Playlist");
    }


이것처럼, 해당 오브젝트에서 AudioSource를 선언한 뒤, 코루틴을 호출한다.


   
 IEnumerator Playlist() {
        soundSource.clip = intro_music[0];
        soundSource.Play();
        while (true)
        {
            yield return new WaitForSeconds(1.0f);
            if(!soundSource.isPlaying) {
                soundSource.clip = intro_music[1];
                soundSource.Play();
                soundSource.loop = true;
            }
        }
    }


먼저, 


배열 0번째를 실행한다. 


실행 방법은 AudioSource의 객체 audioSource를 이용한다. 그래서 AudioSource가 필요한 것이다.


audioSource.clip을 통해 어떤 사운드 데이터를 사용할 것인지 설정한다(배열 첫 번째)

audioSource.Play();를 통해 먼저 사운드를 재상한다. 따라서, 0번째 사운드가 실행된다.


그 다음 while문이 실행된다. true이므로 무한 반복.


yield를 통해 1.0초 대기 후 아래 코드를 수행한다.


만약 사운드가 진행이 되지 않는다면, -> isPlaying


 audioSource.isPlaying의 경우 bool형이다. 실행되고 있다면 True, 재생되고 있지 않다면 False


!가 붙었으므로 멈췄으면 if를 실행하라는 의미가 된다.


즉, 1초마다 체크 후 0번째 사운드가 종료되었으면 if문을 실행하라는 의미이다.


다시 audioSource.clip을 통해 1번째 사운드를 플레이한다.


audioSource.Play()을 통해 사운드를 재생한다.


audioSource.loop를 통해 반복 재생을 할 지 설정한다. true면 반복, false면 반복하지 않는다는 뜻이다.


이렇게 하게 되면


0번째 사운드는 1회 실행되고 1번째 사운드는 루프가 체크되어 무한반복된다.


이상으로 사운드를 이용하여 연속적으로 재생하는 방법을 알아보았다.


여러개의 사운드를 재생하는 것도 동일할 것이다. for문으로 i번 순서대로 돌릴 수도 있고,


랜덤으로 재생하고 싶다면 [i] 대신 Random.Range(0,xx)으로 하면 될 것이다.
















Posted by sungho88
,

transform.RotateAround는 구버전으로, 사용되지 않는다.


에러가 발생하지는 않지만, 녹색으로 경고창이 뜬다.


경고는 다음과 같다.


'Transform.RotateAround(Vector3, float)' is obsolete: 'use Transform.Rotate instead.' [Assembly-CSharp]


쉽게 말하면,


transform.RotateAround은 구식이다. transform.Rotate을 대신 사용해라.



Posted by sungho88
,

public class Test01 : MonoBehaviour 

    public float testNum = 0; 


이라는 클래스가 존재한다고 할 때, testNum 변수를 어떻게 불러올까?


물론... public으로 선언되어 있다고 가정한다. 


private를 사용했거나, 아무것도 작성하지 않을 경우 모두 외부에서 보이지 않는다.



public class MainClas : MonoBehaviour 

    void Start() 

    { 

        Test01 call = GameObject.Find("Test01 컴포넌트 붙은 오브젝트").GetComponent< Test01 >(); 

        call. testNum = 5; // 접근해서 값을 수정할 수 있다. (주의해야함)

    } 


이렇게, Find()함수를 이용하여 오브젝트를 검색한 뒤, 그 오브젝트에 Test01 스크립트 컴포넌트를 불러온다.


그런뒤에 변수(call)에 저장한다.


이제, 이 변수를 이용하여 public된 함수 및 변수에 자유롭게 접근할 수 있다.

Posted by sungho88
,

게임을 개발중에 라이트와 관련된 문제를 하나 발견했다.



원래 이렇게 흰색 배경으로 프로젝트를 진행 중이었다.


그런데, 게임 오버 되서 다시 게임을 시작할때... 현재 화면 그리고 메인화면으로 이동할때...메인 화면도 


아래와 같이 뭔가 어두운 색상으로 변했다. 처음에는 라이트 적용이 안 되었다고 생각을 했다.



예상과 달리 라이트는 체크되어 있었다. 라이트 체크를 끄게 되면 다음과 같이 아예 검은색으로 변하는 것을 알았다. 



그렇다면 어떻게 흰색으로 유지할 수 있을까?


이러한 현상은 게임을 빌드해서 실행했을 경우에는 발생하지 않는다고 한다.


하지만, 개발할 때 매우 찝찝하다.


해결 방법은 다음과 같다.


상단 메뉴 - Windows - Lighting - Settings에 들어간다.



Lighting Setting 창이 열리는데, 가장 아래쪽에서 Auto Generate가 체크되어 있는 것을 볼 수 있다.


이 체크를 해제하면 옆의 Generate Lighting 버튼이 활성화가 된다.

 

이 버튼을 클릭하면 유니티 에디터에서 테스트를 진행할 때에도 빛이 제대로 들어오는 것을 확인할 수 있다.


씬이 여러개라면 해당 씬에 가서 위 작업을 반복해야 한다.



참고로, 씬이 있는 프로젝트 뷰를 보면 씬과 동일한 이름의 폴더가 생성된다.


Generate했으니...뭔가 라이트(Lighting) 관련된 설정이 담긴 폴더인 듯 하다. 


이상한 게 만들어져서 신경쓰이지만, 이 폴더를 지우게 되면 다시 원상 복귀되므로 냅둬야한다.


Posted by sungho88
,

UGUI에서는 Button 컴포넌트에 존재한다.


Button 컴포넌트를 추가하면  interactable라는 속성이 추가되어 있다.


이것은 기본적으로 버튼이 클릭될 수 있도록 미리 체크해서 설정해놓은 것이다.


이 체크를 해제하면, 버튼을 클릭할 수 없게 된다.


이것을 스크립트 코드에서 작성하려면, 


버튼 오브젝트 객체.interactable 로 쉽게 할 수 있다.


NGUI에서는 이 interactable라는 용어가 없어 찾았더니.


isEnabled라는 것이 존재한다.


버튼 오브젝트 객체.isEnabled으로 사용할 수 있으며 false일 경우 비활성화, true일 경우 활성화가 된다.


이렇게


UGUI에서, NGUI에서의 버튼 비활성화하는 방법에 대해 알아보았다.



Posted by sungho88
,