Get it on Google Play


Wm뮤 :: 'Unity' 카테고리의 글 목록 (11 Page)

블로그 이미지
가끔 그림그리거나 3D모델링하거나
취미로 로봇만드는
전자과 게임프로그래머 (퇴사함)
2022.3.22f1 주로 사용
모카쨩
@Ahzkwid

Recent Comment

Archive


2021. 10. 16. 13:23 Unity/C#

 


float canvasHei = GetComponentInParent<Canvas>().GetComponent<RectTransform>().rect.height; //현재 캔버스의 높이를 반환
float oneCentimeterPixelCount = (1 / screenHeightCentimeter) * canvasHei //1센치에 대한 캔버스 픽셀사이즈를 반환


//RectTransform계열
float wid = GetComponent<RectTransform>().sizeDelta.x; //rect.width와 동일
float wid = GetComponent<RectTransform>().rect.width; //sizeDelta.x와 동일
textUI.rectTransform.anchoredPosition.x //일반적으로 생각하는 rectTransform의 x좌표
textUI.rectTransform.localPosition.x //Anchors가 미적용된 x좌표, 가급적 사용자제
textUI.rectTransform.rect.x //작동안함, anchoredPosition써라

 

 

사이즈 조정

public GameObject board;
var rectTransform = board.GetComponent<RectTransform>();
var sizeDelta = rectTransform.sizeDelta;
sizeDelta.y = 400;
rectTransform.sizeDelta = sizeDelta;

 

 

 

Rect 사이즈를 표시

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

public class DrawRectSize : MonoBehaviour
{
    public Color gizmoColor=Color.white;
    void OnDrawGizmos()
    {

        // Draw a semitransparent blue cube at the transforms position
        var rectTransform = GetComponent<RectTransform>();
        if (rectTransform == null)
        {
            return;
        }
        var lossyScale = rectTransform.lossyScale;
        float wid = rectTransform.rect.width;
        float hei = rectTransform.rect.height;
        var pivot = rectTransform.pivot;

        Vector3 downPos = transform.up * lossyScale.y * hei * (pivot.y - 1);
        Vector3 upPos = transform.up * lossyScale.y * hei * pivot.y;
        Vector3 leftPos = transform.right * lossyScale.x * wid * (pivot.x - 1);
        Vector3 rightPos = transform.right * lossyScale.x * wid * pivot.x;

        Gizmos.color = gizmoColor;

        Gizmos.DrawLine(transform.position + downPos + leftPos, transform.position + upPos + leftPos);
        Gizmos.DrawLine(transform.position + downPos + rightPos, transform.position + upPos + rightPos);
        Gizmos.DrawLine(transform.position + downPos + leftPos, transform.position + downPos + rightPos);
        Gizmos.DrawLine(transform.position + upPos + leftPos, transform.position + upPos + rightPos);
    }
}

 

 

 

 

 

특정 시야각만큼 차지하는 RectSize를 가져옴


 (Canvas, Camera) GetCanvasCamera()
{
    var canvas = GetComponentInParent<Canvas>();
    var camera = canvas.worldCamera;
    if (camera == null)
    {
        camera = Camera.main;
    }
    return (canvas,camera);

}
Vector2 GetRectSize(float angle)
{
    (Canvas canvas, Camera camera) = GetCanvasCamera();
    if (camera == null)
    {
        return Vector2.zero;
    }


    var canvasSize = canvas.GetComponent<RectTransform>().rect.size;



    var worldPos = camera.transform.position + camera.transform.rotation * (Quaternion.Euler(angle, 0, 0) * Vector3.forward * 2);
    {
        //debug
        var worldPosb = camera.transform.position + camera.transform.rotation * (Quaternion.Euler(-angle, 0, 0) * Vector3.forward * 2);
        Debug.DrawLine(camera.transform.position, worldPos, Color.yellow);
        Debug.DrawLine(camera.transform.position, worldPosb, Color.yellow);
        Debug.DrawLine(worldPos, worldPosb, Color.yellow);
    }
    var screenPos = camera.WorldToScreenPoint(worldPos);
    var center = camera.ViewportToScreenPoint(Vector2.one * 0.5f);
    var screenSize = camera.ViewportToScreenPoint(Vector2.one);
    var newSize = Vector2.one * Mathf.Abs(center.y - screenPos.y) * 2;

    newSize *= canvasSize.y / screenSize.y;
    return newSize;
}

 

 

 

화면상 RectTransform의 위치

GetComponent<RectTransform>().position //절대적
GetComponent<RectTransform>().localPosition //상대적

 

'Unity > C#' 카테고리의 다른 글

유니티 기울기 관련  (0) 2021.10.23
C# 시리얼  (0) 2021.10.11
C# Delegate와 IEnumerator  (0) 2021.10.11
posted by 모카쨩
2021. 10. 16. 12:00 Unity

 

 

 

 

 

에셋폴더에 우클릭해서 믹서를 만든다

 

 

 

 

DefaultMixer라고 지었다

Resources폴더 하위로 한 이유는 에셋번들 미포함이기 때문

 

AudioMixer창을 연다

 

 

아까 만든 믹서를 선택하고 그룹 생성을 누른다

 

BGM과 SE를 할당해준다

Music과 Effect라고 해줘도 된다

 

 

에셋폴더에서 방금 만든 그룹을 인스펙터에서 볼륨에 대고 우클릭하면

저렇게 뜨는데 Expose해준다

대강 스크립트에서 볼륨을 조작해주겠다는 의미이다

 

 

다시 오디오 믹서 오른쪽 위로 가면 Expose해준 파라미터들이 보인다

 

 

가급적 그룹명과 동일하게 해주자

변수를 이용하여 조작할것이므로 소문자로 했다 (C# 표준규약)

 

 

 

다음과 같은 컴포넌트를 만든다

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



public class MixerTest : MonoBehaviour
{
    public AudioMixer mixer;


    [Range(-80,0)]
    public float master = 0;

    [Range(-80, 0)]
    public float bgm = 0;

    [Range(-80, 0)]
    public float se = 0;

    public void MixerControl()
    {
        mixer.SetFloat(nameof(master), master);
        mixer.SetFloat(nameof(bgm), bgm);
        mixer.SetFloat(nameof(se), se);
    }
    // Start is called before the first frame update
    void Start()
    {
    }

    // Update is called once per frame
    void Update()
    {
        MixerControl();
    }
}

 

 

 

이제 사운드에다가 믹서를 할당해줄차례다

아까만든 컴포넌트를 얹고 믹서를 할당해주자

DnD가 안 먹히니까 옆에 땡글뱅이 눌러서 할당해야한다

 

 

실행하고 인스펙터를 만지면 쭈왑하고 볼륨이 조정된다

'Unity' 카테고리의 다른 글

유니티 구글 스프레드 시트 연동  (0) 2021.11.04
유니티 GPGS 연동  (0) 2021.10.07
구글플레이에 앱 등록하기 2021  (0) 2021.10.05
posted by 모카쨩
2021. 10. 11. 19:08 Unity/C#

 

 

 


받을때
if (serialport.BytesToRead > 0)
{
    string t = serialport.ReadExisting().Trim();//좌우공백지움
    if (t.IndexOf("P3RR") >= 0)//문자열있는지 검색하고 있으면 해당위치 없으면 -1
    {
        ping = 0;
    }
}


보낼때
serialport.Write("문자열");
serialport.Write(바이트배열,offset,길이);

'Unity > C#' 카테고리의 다른 글

유니티 RectTransform  (0) 2021.10.16
C# Delegate와 IEnumerator  (0) 2021.10.11
c# 해쉬테이블  (0) 2021.09.13
posted by 모카쨩
2021. 10. 11. 19:05 Unity/C#

Delegate = 대리자
말그대로 대신 실행시켜주는것
invoke나 event를 쓰기위해선 필수

 

그외에도 비동기 계열들을 동기 계열처럼 쓸 수 있게 해준다


예제1

namespace namespace1
{
    public delegate void delegate_sender(string text_buff);
    public static class class1
    {

        void Main()
        {
            class2 cl = new class2(); //클래스 생성
            cl.delegate_handle = new delegate_sender(text_set); //대리시킬 함수 명시
        }
        set_text(string text)
        {
            messagebox.show(text);
        }
    }
    class class2 //이벤트를 실행할 클래스2
    {
        public static delegate_sender delegate_handle;
        void main()
        {
            delegate_handle("test");//델리게이트 동작
        }
    }
}

 

 

 

 

 

 

이벤트

용도: 이벤트가 발생하면 이벤트 리스너에 등록된 곳에서 모두 동작을 실시합니다

namespace namespace1
{
    public delegate void delegate_sender(string text_buff);
    public static class class1
    {

        void Main()
        {
            class2 cl = new class2(); //클래스 생성
            cl.event_handle += new delegate_sender(show_text); //이벤트 등록
        }
        show_text(string text)
        {
            messagebox.show(text);
        }
    }
    class class2 //이벤트를 실행할 클래스2
    {
        public event delegate_sender event_handle; //이벤트 리스너 생성
        void main()
        {
            event_handle("test");//이벤트 동작
        }
        public void CallEvent(string text)//이벤트 핸들은 반드시 해당 클래스에서 호출해야 하기 때문에 외부에서 호출시 이런식으로 호출
        {
            event_handle("test");//이벤트 동작
        }
    }
}

 

 

 

 

Invoke함수

존나 옛날에 내가 다 정리해놨었네;

요새 프로그래밍 다시 시작하면서 복습중이다

Invoke(Delegate) 
//컨트롤의 내부 창 핸들이 있는 스레드에서 지정된 대리자를 실행합니다.

Invoke(Delegate, Object[]) 
//컨트롤의 내부 창 핸들이 있는 스레드에서 특정 인수 목록을 사용하여 지정된 대리자를 실행합니다.
private void SetText(string text)
{
    // InvokeRequired required compares the thread ID of the
    // calling thread to the thread ID of the creating thread.
    // If these threads are different, it returns true.
    if (this.textBox_log.InvokeRequired)
    {
        //delegate_sender d = new delegate_sender (SetText);
        //this.Invoke(new delegate_sender (SetText), new object[] { text });
        //this.Invoke(new Action(delegate () {할일 }));
        //string _return ="";
        //this.Invoke(new Action(delegate () { _return = this.textBox.Text; }));
        this.Invoke(new delegate_sender(SetText), text);
    }
    else
    {
        this.textBox.Text = text;
    }
}

 

 

이건 윈폼예제

간단한 요약

멀티스레드에서 가장 문제가 되는 클립보드 접근에 대한것

핸들이 static이므로 그냥 막 쓸수 있다

    public delegate void de_set_clip(string text); //입력예제
    public delegate string de_get_clip(); //출력예제
    public partial class Form1: Form
    {
        public void set_clip(string input)  //입력함수
        {
            this.Invoke(new Action(delegate () {
                Clipboard.SetText(input);
            }));
        }
        public string get_clip()  //출력함수
        {
            String _return ="";
            this.Invoke(new Action(delegate () {
                _return=Clipboard.GetText();
            }));
            return _return;
        }
        public Form1() //사용할 폼
        {
            clip.de_set_clip_handle = new de_set_clip(set_clip);
            clip.de_get_clip_handle = new de_get_clip(get_clip);

            InitializeComponent();
}

    public static class clip
    {
        public static de_set_clip de_set_clip_handle; //이걸 다른 폼에서 사용
        public static de_get_clip de_get_clip_handle;
    }
}

 

 

 

 

존나 옛날에 짠거들이라 리메이크 해야할듯

 

 

 

 

 

 

 

 

 

 

 

delegate기반 계열로 Action이 있다

위쪽이 이벤트 기반이라면 이쪽은 비동기 리턴에 사용

 

 

비동기 리턴 예제

    public void Login() //외부에서 리턴안쓰고 호출할때 사용
    {
        Login(success=> { });
    }
    public void Login(System.Action<bool> successCallback)
    {
        if (로그인 하는데 성공)
        {
            successCallback.Invoke(true);
        }
        else
        {
            successCallback.Invoke(false);
        }
    }
    public void Start()
    {
        Login(success =>
        {

            if (success)
            {
            	//성공했을경우 처리
            }
            else
            {
            	//실패했을경우 처리
            }

        });
    }

 

 

 

 

 

 

 

이벤트 핸들러 예제

    
    public event System.EventHandler StateChanged;
    public void OnStateChanged()
    {
        //sender는 누가 발생시켰는지, System.EventArgs.Empty는 리턴밸류를 할당하지 않겠다는 뜻
        StateChanged?.Invoke(sender:this, System.EventArgs.Empty);
        Debug.Log("상태가 전환됨");
    }
    public void Start()
    {
    	StateChanged+=OnStateChanged;
    }

 

 

 

 

 

 

 

 

유니티 전용 이벤트가 있다

유니티 이벤트 기능

public class CustomInteface
{


    [System.Serializable]
	public class Vector3Event : UnityEngine.Events.UnityEvent<Vector3> { }
	//public class VoidEvent : UnityEngine.Events.UnityEvent { }
    
    //public UnityEvent OnEvent; //void 타입
    public Vector3Event OnEvent;
    
    
    void Start()
    {
    	//함수를 붙일때
        OnEvent.AddListener (Draw);
    
    	//호출
        OnEvent.Invoke(transform.position);
    }

	//붙일함수
    void Draw(Vector3 pos)
    {
		Debug.Log ("pos:"+pos);
    }


}

 

 

MonoBehaviour.Invoke

특정 함수를 0.4초 딜레이후에 호출

코루틴과 달리 오프된 상태에서도 사용가능해서 트리거 만들때 유용해보인다

유니티 함수도 쓸수있다

Invoke(nameof(Logout),0.4f);

 

위랑 같은데 일정시간마다 반복함

커스텀 업데이트만들때 유용해보이나 중단점을 잘 맞춰야 할것이다

InvokeRepeating(nameof(methodName),delay : 3,repeatTime : 1);



CancelInvoke(nameof(methodName)); //해당 Invoke메소드를 중단
CancelInvoke(); //모든 Invoke메소드를 중단

 

 

 

 

-코루틴 계열들

IEnumerator = 열거자

코루틴은 IEnumerator기반으로 동작함

 

코루틴이 동작중인지 체크

    IEnumerator preCoroutine;
    void StartMusic()
    {
            if (preCoroutine != null)
            {
                StopCoroutine(preCoroutine);
            }
            preCoroutine = MusicEnd();
        Debug.Log("음악시작");
            StartCoroutine(preCoroutine);
    }
    IEnumerator MusicEnd()
    {
        yield return new WaitForSeconds(10f);
        Debug.Log("음악이 종료됨");
        preCoroutine =null;
    }

 

코루틴이 동작중인지 체크2

위 1번이 그냥 일반상황에서 쓴다면

2번은 코루틴내의 코루틴을 동작시킬때 씀

v1

더보기

 

IEnumerator preReset;
void Reset()
{
    if ((preReset == null)||((preReset.Current.GetType()==typeof(int)) &&((int)preReset.Current == 0)))//Current의 타입검사도 필요함
    {
        preReset = ResetCo();
        StartCoroutine(preReset);
    }
}
IEnumerator ResetCo()
{
    yield return 0;//종료
}

 

 

v2

더보기

 

IEnumerator preReset;
void Reset()
{
    if ((preReset == null) || ((preReset.Current is int current) && (current == 0)))//Current의 타입검사도 필요함
    {
        preReset = ResetCo();
        StartCoroutine(preReset);
    }
}
IEnumerator ResetCo()
{
    yield return 0;//종료
}

 

 

v3 일반

IEnumerator preReset;
void Reset()
{
    if (preReset?.Current as string == "End")//Current의 타입검사도 필요함
    {
        preReset = ResetCo();
        StartCoroutine(preReset);
    }
}
IEnumerator ResetCo()
{
    yield return "End";//종료
}

 

 

v3 코루틴

이 버전의 강점은 지역변수만으로도 체크 가능하단것

IEnumerator RoutineAllAria()
{
    var preAria = aria;
    for (int i = 0; i < System.Enum.GetValues(typeof(Aria)).Length; i++)
    {
        var co = Routine((Aria)i);
        StartCoroutine(co);
        yield return new WaitUntil(()=>co?.Current as string == "end"); //Current의 타입검사도 필요함
    }
    aria = preAria;
}
IEnumerator Routine(Aria aria)
{
	//실행로직
    yield return "end";//종료
}

 

v3 리스트

스킬관리할때 썼음

    public void Skill(int index)
    {
        var delaySkillSpawn = DelaySkillSpawn(skillPrefab);
        StartCoroutine(delaySkillSpawn);
        delaySkillSpawns.Add(delaySkillSpawn);
        delaySkillSpawns = delaySkillSpawns.FindAll(x => (x?.Current as string == "End")==false);
    }
    public List<IEnumerator> delaySkillSpawns = new List<IEnumerator>();
    public void SkillCancel()
    {
        delaySkillSpawns = delaySkillSpawns.FindAll(x => (x?.Current as string == "End") == false);
        foreach (var delaySkillSpawn in delaySkillSpawns)
        {
            StopCoroutine(delaySkillSpawn);
        }
        delaySkillSpawns.Clear();
    }
    private IEnumerator DelaySkillSpawn(SkillSystem.SkillPrefab skillPrefab)
    {
        yield return new WaitForSeconds(skillPrefab.spawnDelay);
        if (hp<0)
        {
            yield return "End";//종료
            yield break; //반환하지않고 중단
        }
        
        
        //동작코드들
        
        
        yield return "End";//종료
    }

 

 

 

 

 

frame이 10 이상이 될때까지 대기

    IEnumerator Example()
    {
        yield return new WaitUntil(() => frame >= 10);
        Debug.Log("프레임이 10 이상임");
    }

 

비동기 함수가 끝날때까지 대기

v1

더보기
    IEnumerator LoadSpritesCo()
    {
        {
            var co = GetFolderToSpriteFilesCo(folderPath);
            StartCoroutine(co);
            yield return new WaitUntil(() => co.Current.GetType() == typeof(Sprite[]));
            sprites = (Sprite[])co.Current;
        }
    }

v2

    IEnumerator LoadSpritesCo()
    {
        {
            var co = GetFolderToSpriteFilesCo(folderPath);
            StartCoroutine(co);
            yield return new WaitUntil(() => co?.Current as Sprite[] != null);
            sprites = (Sprite[])co.Current;
        }
    }

 

IEnumerator 내부에서 코루틴 종료

IEnumerator SampleCo()
{
    Debug.Log("코루틴 실행중");
    yield break;
    Debug.Log("코루틴이 종료되어 실행할수 없는 문구");
}

 

 

IEnumerator 반환값 예제

    IEnumerator TestCo()
    {
        //반환값 null
        yield return new WaitForSeconds(10);

        //반환값 UnityEngine.WaitForSeconds

        yield return 0;

        //반환값 0

        yield break;

        //반환값 0
    }

 

 

변수가 변경될경우 이벤트 호출

    public IEnumerator IndexChengedChecker()
    {
        while (true)
        {
            var indexPrevious = index;
            yield return new WaitUntil(() => index != indexPrevious);


            //상태 변경됨
            //event.Invoke();
        }
    }

 

 

 

 

 

 

 

 

 

 

그외에 이것들을 쓴다는건 비동기계열을 다룬다는 소리인데

스레드나 태스크계열도 참조할 필요가 생긴다 (링크참조)

https://wmmu.tistory.com/entry/c-%EB%A9%80%ED%8B%B0%EC%8A%A4%EB%A0%88%EB%93%9C%ED%92%80-%EA%B8%B0%EB%B3%B8%EC%86%8C%EC%8A%A4

 

c# 멀티스레드 기본소스

c# 멀티스레드풀 기본소스 using System.Collections; public bool multi_threadpool_MC(float[,] img1f) { int img1wid = img1f.GetLength(0); // 기준 이미지 너비 int img1hei = img1f.GetLength(1); //기준..

wmmu.tistory.com

 

'Unity > C#' 카테고리의 다른 글

C# 시리얼  (0) 2021.10.11
c# 해쉬테이블  (0) 2021.09.13
자주쓰는 c# 소켓 통신 모음  (0) 2021.09.08
posted by 모카쨩
2021. 10. 7. 10:42

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.

2021. 10. 5. 08:52 Unity

 

 

 

 

 

 

쉬밤바 aab만 업로드 가능하게 바뀌었더라

심지어 키스토어도 앱별로 관리해야 한단다 귀찮게

 

 

이후에 나오는 빨간문구 전부 쳐주자

'Unity' 카테고리의 다른 글

유니티 GPGS 연동  (0) 2021.10.07
LogError 뜰때마다 pause 되는현상 수정  (0) 2021.09.24
유니티 이벤트 모음  (0) 2021.06.22
posted by 모카쨩
2021. 9. 24. 10:38 Unity

 

 

 

 

누른거 풀어라

 

'Unity' 카테고리의 다른 글

구글플레이에 앱 등록하기 2021  (0) 2021.10.05
유니티 이벤트 모음  (0) 2021.06.22
유니티 VR 세팅관련  (0) 2021.05.15
posted by 모카쨩
2021. 9. 13. 11:32 Unity/C#

 

 

 

쓰기

var hashtable = new Hashtable();
hashtable["intValue"]=1;
hashtable["stringValue"]="2";

 

 

 

읽기

var intValue=(int)hashtable["intValue"];
var stringValue=(string)hashtable["stringValue"];

 

 

매우 쉽다

 

 

 

하지만 해쉬테이블을 쓴다는건 넘겨받는 값이 모호하기 때문일것이다.

따라서 아래같은 상황도 자주 쓰이게 된다

 

 

null체크 후 없으면 생성후 읽기

int intValue;
if(hashtable[nameof(intValue)] == null)
{
    hashtable[nameof(intValue)]=1;
}
intValue=(int)hashtable[nameof(intValue)];


string stringValue;
if(hashtable[nameof(stringValue)] == null)
{
    hashtable[nameof(stringValue)]="2";
}
stringValue=(string)hashtable[nameof(stringValue)];

 

 

간소화버전

int intValue;
intValue=hashtable[nameof(intValue)]??1;

string stringValue;
stringValue=hashtable[nameof(stringValue)]??"2";

 

 

리플과 섞어쓰면 좋다

 

'Unity > C#' 카테고리의 다른 글

C# Delegate와 IEnumerator  (0) 2021.10.11
자주쓰는 c# 소켓 통신 모음  (0) 2021.09.08
자주쓰는 변수명 모음  (0) 2021.08.18
posted by 모카쨩

저사양 유저용 블로그 진입