티스토리 툴바


엔진/unity3d2012/02/14 12:41
               
월드 좌표계를 지역 좌표계로 옮겨서 회전값을 구함.

                Transform from,  Transform to

// 1. 현재 오브젝트에서 타켓 오브젝트까지의 Vector를 구하기(월드 좌표계에서 지역 좌표계로 이동시키기)
Vector3 objToTargetVec = to.position - from.position; 
objToTargetVec = from.InverseTransformDirection(objToTargetVec);   
objToTargetVec.Normalize();   // 노말라이즈
// 2. 지역 좌표계에서 기준 Vector(여기서는 Up)로 해서 회전값 구하기 
Vector2 objToTargetProj = new Vector2(objToTargetVec.x, objToTargetVec.y); 
float angleToRot = Vector2.Angle(Vector2.up, objToTargetProj); 
// 3. x값이 음수이면 회전은 반대 방향
if(objToTargetProj.x > 0){ 
angleToRot *= -1; 

               // 4. 쿼터니언 구하기 
   Quaternion quat = Quaternion.AngleAxis( angleToRot, Vector3.forward);



 
저작자 표시
Posted by 붉은용기병
엔진/unity3d2011/09/17 16:43
일반적으로 오브젝트의 위치값을 가져올려고 하면.
gameObject.transform.position 또는 localPosition을 가져오면 된다.

그런데, 애니매이션 중인 오브젝트는 그렇게 하면 되지 원하는 결과값을 가져오지 않습니다.
그래서 열심히 구글링을 하였는데, 원하는 정보를 얻지 못하였습니다. 이놈의 짧디, 짧은 외국어 능력.... 난 학력고사 세대란 말야.. T.T

 그런데, 우연히 Bounds가 있고 그 아래에 Center가 있는 것을 보았다.
혹시 이것을 가져오면 되지 않을까 했지만 못 가져왔다. OTL
이것저것 만지기 시작하였다.
Update When Offscreen을 enabled했더니, 오~~~웃~~~ Bounds의 값이 변했다. 와우...심봤다.



Bounds 값을 가져오는 코드

public void setTarget(GameObject _target) {
SkinnedMeshRenderer renderer = _target.GetComponent<SkinnedMeshRenderer>();
m_targetPosition = renderer.bounds.center;

 
저작자 표시
Posted by 붉은용기병
엔진/unity3d2011/08/04 15:33
http://forum.unity3d.com/threads/98315-Using-Unity-Android-In-a-Sub-View
저작자 표시
Posted by 붉은용기병
엔진/unity3d2011/05/18 19:12

다음 사이트를 참조하였습니다.

http://www.youtube.com/watch?v=IX041ZvgQKE&feature=related

동영상에 나오는 소스 코드를 정리한 것입니다.
상세한 설명은 동영상을 참조하세요.

using UnityEngine;
// using System;  <- 이것이 있으면 object vs Object가 헷갈려합니다. (Java와 UnityEngine사이에서 혼동)
using System.Collections;
using System.Collections.Generic;
using System.Linq;


public class ObjectRecycler
{

    public    delegate void    ObjectRecyclerChangedEventHandler(int available, int total);
    public    event    ObjectRecyclerChangedEventHandler onObjectRecylerChanged;

    private    List<GameObject>    objectList;
    private    GameObject    objectToRecycle;

   
    public ObjectRecycler (GameObject obj, int totalObjectsAtStart)
    {
        objectList = new List<GameObject>(totalObjectsAtStart);
        objectToRecycle = obj;

        for (int i = 0; i < totalObjectsAtStart; i++) {
            GameObject newObject = Object.Instantiate(obj) as GameObject;
            newObject.gameObject.active = false;
            objectList.Add(newObject);
        }
    }
   
 
    private    void    InfoChangedEvent() {

        if (onObjectRecylerChanged != null) {

      var allFree =     from item in objectList
                                        where item.active == false
                                        select item;

            onObjectRecylerChanged(allFree.Count(), objectList.Count);
        }
    }

   
    public    GameObject    NextFree{

        get {
                var freeObject = ( from item in objectList
                                         where item.active == false
                                         select item).FirstOrDefault();
 

            if (freeObject == null) {
                freeObject = Object.Instantiate( objectToRecycle ) as GameObject;
                objectList.Add(freeObject);
            }

            freeObject.active = true;

            InfoChangedEvent();
            return freeObject;
        }
    }

   

    public    void    FreeObject(GameObject objectTorFree) {

                 objectTorFree.gameObject.active = false;
                 InfoChangedEvent();
    }

}





저작자 표시
Posted by 붉은용기병
TAG LINQ, Unity3D
엔진/unity3d2011/05/04 11:27

다음 동영상에 있는 소스 코드를 옮겨둔 것임.
http://www.youtube.com/watch?v=7KBmZvpguWk&feature=player_profilepage



AudioSourceExtensions.cs

using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;



public    static    class    AudioSourceExtensions
{

    public    stataic    void    playClip(this AudioSource audioSource, AudioClip audioClip)
    {
        audioSource.clip = audioClip;
        auidoSource.Play();
    }


    public    static    IEnumerator    playClip(this AudioSource audioSource, AuidoClip audioClip, Action onComplete)
    {
        audioSource.playClip(audioClip);

        while(audioSource.isPlaying)
            yield return null;

        onComplete();
    }


    public    static    void    playRandomClip(this AudioSource audioSource, AudioClip[] clips)
    {
        int clipIndex = UnityEngine.Random.Range(0, clips.Length);
        audioSource.playClip(clips[clipIndex]);
    }


    public    static    IEnumerator    fadeOut(this AudioSource audioSource, AudioClip audioClip, float duration, Action onComplete)
    {
        audioSource.playClip(audioClip);

        var startingVolume = audioSource.volume;
   
        // fade out the volume
        while(audioSource.volume > 0.0f)
        {
            audioSource.volume -= Time.deltaTime * startingVolume / duration;
            yield return null;
        }       

        // done fading out
        if ( onComplete != null )
            onCompelte();

    }

}




ExtensionsCUI.cs


using UnityEngine;
using System.Collections;


public    class    ExtensionsGUI : MoneBehaviour
{
    public    AudioClip    explosion;
    public    AudioClip    wind;
    public    AudioClip[]     clips;

    private    AudioSource    _audioSource;

    void    Start()
    {

        _audioSource = GetComponent<AudioSource>();
    }

    void    OnGUI()
    {
        if( GUI.Button( new Rect(5,5,200,40), "String Append"))
        {
            var theString = "Hi. In a string.";
            thsString.printWithLotsOfLettersAppended();
        }

        float x = Screen.width - 210;
        if ( GUI.Button( new Rect(x,5, 200, 40), "Play Explosion"))
        {
            _audioSource.playClip(explosion);
        }


        if ( GUI.Button( new Rect(x, 55, 200, 40), "Play Explosion with Completion"))
        {
            StartCoroutine
            {
                _audioSource.playClip(explosion, () =>
                {
                    Debug.Log("audio clip finished");
                })
            }
        }


        if ( GUI.Button( new Rect(x, 105, 200, 40), "Play Random Clip"))
        {
            _audioSource.playRandomClip( clips );
        }



        if ( GUI.Button( new Rect(x, 155, 200, 40), "Fade Audio Clip"))
        {
            StartCoroutine
            {
                _audioSource.fadeOut( wind, 3.0f, () =>
                {
                    Debug.Log("all done fading");
                })
            }
        }


    }
}


저작자 표시
Posted by 붉은용기병
TAG Unity3D
엔진/unity3d2011/04/28 15:24

참고 : 이 사이트에 내용을 거의 차용하였습니다.


Scene에 3D GUI contorls를 출력할 때에 사용하면 된다.

OnSceneGUI()에서 Handles, HandlesUtility를 이용해서 각종 콘드롤러를 뿌려주면 된다.


using UnityEngine;
using UnityEditor;  // 커스텀 Inspector를 만들기 위해는 포함시켜야 한다.
using System.Collections;


// CustomEditor() 애트리뷰트를 사용해서 어떤 타입(클라스)를 사용자화 할 것인지 명시해야한다.
[CustomEditor(typeof(TestUI2))]

// Inspector를 사용자화시킬려고 하면 Editor를 상속받아야 한다.
public class TestUIInspector2 : Editor {

    // 사용자화 대상의 레퍼런스를 선언
    TestUI2    m_testUi;
    float        sphereSize = 1.0f;
   

    // TestUIInspector가 인스턴스화가 될 때에 호출
    void    OnEnable() {
        // target은 Editor의 멤버 변수으로 CustomEditor() 애트리뷰트에서 설정해 준 타입의 객처에 대한
        // 레퍼런스 object형이므로 실제 클라스(타입)으로 캐스팅해서 명확하게 해서 사용하기 용이하게한다.
        m_testUi = target as TestUI2;


    }

   // Scene 화면에 뿌리지는 것
    public void OnSceneGUI()
    {
        // 원 출력
        Handles.color = Color.red;
        Handles.SphereCap(0,    m_testUi.transform.position + new Vector3(5,0,0),    m_testUi.transform.rotation,     sphereSize);

        Handles.color = Color.green;
        Handles.SphereCap(0,    m_testUi.transform.position + new Vector3(0,5,0),    m_testUi.transform.rotation,    sphereSize);
       
        Handles.color = Color.blue;
        Handles.SphereCap(0,    m_testUi.transform.position + new Vector3(0,0,5),    m_testUi.transform.rotation,    sphereSize);

       
        // 사각 출력
        Handles.color = Color.red;
        Handles.CubeCap(0, m_testUi.m_targetPosition, Quaternion.identity, 1.0f);
 
        Handles.color = Color.green;
        Handles.DrawLine(m_testUi.gameObject.transform.position, m_testUi.m_targetPosition);
 
        // GUI 출력의 시작
        Handles.BeginGUI();
        {
            if (m_testUi.gameObject.transform.position != m_testUi.m_targetPosition)
            {
                // 3D좌표를 2D좌표 변경
                Vector2 button_positoin = HandleUtility.WorldToGUIPoint(m_testUi.m_targetPosition);
                Rect button_rect = new Rect(button_positoin.x-100, button_positoin.y - 50, 200, 20);
                // 에티딩 중 (Pop PlayButton)에 눌러도 반응을 함. ^^;
                if (GUI.Button(button_rect, "Move To Target Position"))
                    m_testUi.transform.position = m_testUi.m_targetPosition;
            }
        }

        // GUI 출력의 끝
        Handles.EndGUI();
       
        // 동작(Push PlayButton) 중에 버튼을 클릭하면 반응을 함. ^^;
        m_testUi.m_checkButton = Handles.Button(    m_testUi.transform.position + new Vector3(0,2,0),
                                                                    Quaternion.identity,
                                                                    3.0f,
                                                                    3.0f,
                                                                    Handles.RectangleCap );

        // 이렇게 사용하면 화면 갱신 속도가 느려진다.
        // Event e = Event.current;
        // Debug.Log("Current detected event: " + e);
    }
   


    // Inspector에서 표시되어지는 것들은 이 메소드 안에서 코딩해야한다.
    // EditorGUILayout에서 제공하는 콘드롤을 이용한다.
    // GUILayout을 이용해서 할수도 있다.
    public override void OnInspectorGUI()  {

 
        // 수평으로 구성한다.
        EditorGUILayout.BeginVertical ();

            // 버튼을 구성
            if (GUILayout.Button("Reset") == true)
            {
                m_testUi.Reset();
            }

            // 레이블과 드롭리스트 콘드롤
            EditorGUILayout.LabelField("AI Type", null);
            string[] aiNames = new string[] { "보통", "순찰", "공격"};
            int[] aiValues = new int[] { 0, 1, 2 };
            m_testUi.m_aiType = EditorGUILayout.IntPopup(m_testUi.m_aiType, aiNames, aiValues);

            // 레이블과 슬라이드
            EditorGUILayout.PrefixLabel("Speed");
            m_testUi.m_speed = EditorGUILayout.Slider(m_testUi.m_speed, 0, 100, null);

           
           
        EditorGUILayout.EndVertical ();

        // x,y,z값을 표시하는 콘드롤
        m_testUi.m_targetPosition = EditorGUILayout.Vector3Field("Target Position", m_testUi.m_targetPosition);


        // GUI가 변경이 되면 타켓을 다시 렌더링하기 위해서는 Dirty상태를 마크한다.
        if (GUI.changed) {
            EditorUtility.SetDirty(target);
        }
   
    }


}








fwfwfw
저작자 표시
Posted by 붉은용기병
엔진/unity3d2011/04/27 18:06
주의
Assets 아래에 Editor 라는 폴더를 만들어서 그안에 스크립터를 넣어야 제대로 동작한다.
즉, Assets/Editor/TestUIInspecto.cs가 되어야 한다.

Editor, EditorWindows를 상속 받은 경우가 해당된다.


참고
한글로 친절하게 잘 설명되어 있음.(아주 많이 참조하였음. 거의 복사한 수준. ^^;)

            QuadUI인데, c#으로만 구성되어서 참고하기에는 좋음.

순서
   1. 레퍼런스를 추가한다.
          
            using UnityEditor
  
    2. 애트리뷰트를 선언한다.
           클라스 앞에 한다. 
           Typeof으로 선언한 클라스와 커스텀 클라스 간에 연동이 되어진다.
          
           [CustomEditor(typeof(TestUI))]

    3. Editor를 상속 받은 자식 클라스를 선언한다.
           실제 사용할 클라스이다. 

           public class TestUIInspector : Editor {}

    4.  target을 실제 class와 연결한다.
           보기 쉽게 하기 위해서 하는 것임.  안해도 됨.
           target는 Editor의 멤버이다.
           
            void OnEnable() {
                   m_testUi = target as TestUI;
            }
            
     5. OnInspectorGUI()를 override한다.
           UI가 보여지는 부분이다.


참고 : "한글"은 제대로 안보이는 것 같음.(UTF-8이 제대로 안 먹은 것 같음.)

using UnityEngine;

using System.Collections;


public class TestUI : MonoBehaviour {


    public  float       m_speed = 0;

    public  int         m_aiType = 0;

    public  Vector3     m_targetPosition = Vector3.zero;


// Use this for initialization

void Start () {

}

// Update is called once per frame

void Update () {

}



    public void Reset()   {

        m_speed = 0;

        m_aiType = 0;

        m_targetPosition = Vector3.zero;

    }

}



           

using UnityEngine;

using UnityEditor;  // 커스텀 Inspector를 만들기 위해는 포함시켜야 한다.

using System.Collections;



// CustomEditor() 애트리뷰트를 사용해서 어떤 타입(클라스)를 사용자화 할 것인지 명시해야한다.

[CustomEditor(typeof(TestUI))]


// Inspector를 사용자화시킬려고 하면 Editor를 상속받아야 한다.

public class TestUIInspector : Editor {


    // 사용자화 대상의 레퍼런스를 선언

TestUI m_testUi;




    // TestUIInspector가 인스턴스화가 될 때에 호출

void OnEnable() {

        // target은 Editor의 멤버 변수으로 CustomEditor() 애트리뷰트에서 설정해 준 타입의 객처에 대한 

        // 레퍼런스 object형이므로 실제 클라스(타입)으로 캐스팅해서 명확하게 해서 사용하기 용이하게한다.

m_testUi = target as TestUI;



}


    // Inspector에서 표시되어지는 것들은 이 메소드 안에서 코딩해야한다.

    // EditorGUILayout에서 제공하는 콘드롤을 이용한다.

    // GUILayout을 이용해서 할수도 있다.

    public override void OnInspectorGUI()  {


  

        // 수평으로 구성한다.

        EditorGUILayout.BeginVertical ();


            // 버튼을 구성

            if (GUILayout.Button("Reset") == true)

            {

                m_testUi.Reset();

            }


            // 레이블과 드롭리스트 콘드롤

            EditorGUILayout.LabelField("AI Type", null);

            string[] aiNames = new string[] { "normal", "patrol", "attack"};

            int[] aiValues = new int[] { 0, 1, 2 };

            m_testUi.m_aiType = EditorGUILayout.IntPopup(m_testUi.m_aiType, aiNames, aiValues);


            // 레이블과 슬라이드

            EditorGUILayout.PrefixLabel("Speed");

            m_testUi.m_speed = EditorGUILayout.Slider(m_testUi.m_speed, 0, 100, null);


            

            

        EditorGUILayout.EndVertical ();


        // x,y,z값을 표시하는 콘드롤

        m_testUi.m_targetPosition = EditorGUILayout.Vector3Field("Target Position", m_testUi.m_targetPosition);



        // GUI가 변경이 되면 타켓을 다시 렌더링하기 위해서는 Dirty상태를 마크한다.

        if (GUI.changed) {

            EditorUtility.SetDirty(target);

        }

    

    }



}



           



 
저작자 표시
Posted by 붉은용기병