using System.Collections;

using System.Collections.Generic;

using UnityEngine;


public class MaterialTest : MonoBehaviour {

public SkinnedMeshRenderer skin;

// Use this for initialization

void Start () {

  skin.GetComponent<SkinnedMeshRenderer>().material.color = Color.black;  // 첫 번째 방법


for (int i = 0; i < 2; i++) {                                                                                    // 두 번째 방법

skin.GetComponent<SkinnedMeshRenderer> ().materials [i].color = Color.black;

}

}

}



1. 첫번째 방법  


skin.GetComponent<SkinnedMeshRenderer>().material.color = Color.black;

쉽게 말하면, material이 한 개일 경우에 이렇게 사용한다. 그냥 material을 호출하면 자동으로 인식되는 경우이다.


2. 두번째 방법


for (int i = 0; i < 2; i++) {                                                                                    // 두 번째 방법

skin.GetComponent<SkinnedMeshRenderer> ().materials [i].color = Color.black;

}


쉽게 말하면, material이 여래 개일 경우에 이렇게 사용한다. 


유니티에서는 보통 materials라 나오며 배열로 표기된다. 

 

이럴 경우에는 for문을 사용해서 material의 갯수만큼 반복하며 material을 조작할 수 있다.


위 코드의 경우 매티러얼이 2개이므로 materials [0] 과 materials [1]을 각각 반복하였다.


이상으로 스크립트에서 material을 사용하는 방법에 대해 알아봤다.

Posted by sungho88
,

버튼에 애니메이션을 실행(Play)시킬 때 발생하는 문제가 하나 있었다.


같은 버튼을 계속 누를 때 최초 1회만 애니메이션이 재생되고, 그 이후 두번 다시 Play되지 않은 문제였다.

 

그래서 틀렸을 때 흔들리는 애니메이션이 1번만 보여지고 그 이후는 무반응이므로 뭔가 어색하게 되었다.


오브젝트를 껐다가 켜야하나 생각도 해보고 구글을 찾아봤지만 한국어 검색으로는 비슷한 문제가 발견되지 않았다.


그래서 형편없는 영어 실력으로 영어 검색을 시작했다.


검색어 : unity animator play once reset


그결과 유니티 커뮤니티에서 어떤 한 외국인님이 나와 완전히 동일한 문제를 질문했고, 답을 얻을 수 있었다.


생각보다 별 것 아니었다. 몰라서 못 쓴 것이지만,,]


내가 사용했던 Play("AnimationName"); 에서 확장된...아니 오버로딩된



public void Play(string stateName, int layer = -1, float normalizedTime = float.NegativeInfinity);


을 사용하라고 한다.



아래 코드가 내가 사용한 기본적인 코드이다. 이렇게 하면 플레이는 된다.


buttonObject.GetComponent<Animator>().Play("ButtonWrong");


하지만,


buttonObject.GetComponent<Animator>().Play("ButtonWrong", -1, 0f);



첫 번째 매개변수 : stateName

두 번째 매개변수 : layer

세 번쨰 매개변수 :normalizedTime


첫 번쨰 매개변수로는 Play할 애니메이션 state의 이름을 적는다.


두 번째 매개변수로는 layer를 설정한다. -1일 경우 첫 state를 재생한다.


세 번째 매개변수로는 normalizedTime를 적는다.


normalizedTime란,


표준화된(normalized) 애니메이션 시간아다. 


값 1은 애니메이션의 끝을 의미하며 값 0.5는 애니메이션의 중간을 의미한다.


Posted by sungho88
,

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


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


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


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
,

List 선언하는 방법


public List<string> strlist;

   strlist = new List<string>();




<>은 제네릭(Generic)으로 자료형을 넣는다. 이러한 해당 자료형만 넣겠다는 의미이다.

위 코드는 GameObject만을 넣겠다는 의미이다.


LIst 추가하는 방법


strlist.Add()를 사용한다. 추가할 값을 Add의 매개변수로 넣는다.


strlist.Add("Hello");

strlist.Add("Hi");

strlist.Add("Good Bye");



LIst 제거하는 방법



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
,