Get it on Google Play


Wm뮤 :: 'Unity/C#' 카테고리의 글 목록 (2 Page)

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

Recent Comment

Archive


'Unity/C#'에 해당되는 글 63건

  1. 2021.12.16 유니티 ScriptableObject
  2. 2021.11.30 유니티 트랜스 폼 (Transform)
  3. 2021.11.18 C# 메일
  4. 2021.11.06 A Star
  5. 2021.10.23 유니티 기울기 관련
  6. 2021.10.16 유니티 RectTransform
  7. 2021.10.11 C# 시리얼
  8. 2021.10.11 C# Delegate와 IEnumerator
2021. 12. 16. 14:43

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

2021. 11. 30. 01:54 Unity/C#

 

 

 

공통부모들을 반환

        Transform[] GetCommonParents(params Transform[] targetTransforms)
        {
            if ((targetTransforms == null) || (targetTransforms.Length == 0))
            {
                return null;
            }
            var parentsArray = System.Array.ConvertAll(targetTransforms, x => x.GetComponentsInParent<Transform>());
            var commonParents = parentsArray[0];
            for (int i = 1; i < parentsArray.Length; i++)
            {
                commonParents = System.Array.FindAll(commonParents, x => parentsArray[i].Contains(x));
            }
            return commonParents;
        }

 

 

부모와 자식사이의 노드들을 반환

앞쪽에 있을수록 부모에 가까움

        Transform[] GetNodes(Transform parent,Transform child)
        {
            if ((parent == null) || (child == null))
            {
                return null;
            }
            var parents = child.GetComponentsInParent<Transform>();
            var parentIndex = System.Array.FindIndex(parents, x=>x==parent);
            if (parentIndex < 0)
            {
                return null;
            }
            if (parentIndex == 0)
            {
                return new Transform[] { } ;
            }
            return parents.Take(parentIndex).Reverse().ToArray();
        }

 

 

 

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

유니티 ScriptableObject  (0) 2021.12.16
C# 메일  (0) 2021.11.18
A Star  (0) 2021.11.06
posted by 모카쨩
2021. 11. 18. 13:06

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

2021. 11. 6. 00:22 Unity/C#

 


    private int[,] _node_checker;
    private float[,] _worth_p_worth2 ;
    private Vector2 _now_pos;
    private int[,] _parent_dir ;
    private int map_wid = 1000;
    private float[] _check_pos_len;
    void Awake()
    {
        _worth_p_worth2 = new float[map_wid, map_wid];
        _node_checker = new int[map_wid, map_wid];
        _check_pos_len = new float[] { 1, 1.41421f, 1, 1.41421f, 1, 1.41421f, 1, 1.41421f };
        
        _parent_dir = new int[map_wid, map_wid];
        _now_pos = transform.position;
    }
    public int sc_8search(Vector2 pos)
    {//sc_8search(x,y);
        int _return = 0, _x = (int)pos.x, _y = (int)pos.y;
        int check_x, check_y, i, _t;


        for (i = 0; i < 8; i++)
        {
            check_x = _x + _check_pos_x[i];
            check_y = _y + _check_pos_y[i];
            if ((check_x < 0) || (check_x >= map_wid)
            || (check_y < 0) || (check_y >= map_wid))
            {
                continue;
            }

            if ((check_x == (int)move_point.x) && (check_y == (int)move_point.y))
            {
                _parent_dir[check_x, check_y] = i;
                return 2;
            }
            if (_node_checker[check_x, check_y] <= 0)
            {
                float f_t = _worth[_x, _y] + _check_pos_len[i];
                if (f_t < _worth[check_x, check_y])
                {
                    _worth[check_x, check_y] = f_t;
                    if (_worth2[check_x, check_y] == -4)
                    {
                        _worth2[check_x, check_y] = Vector2.Distance(new Vector2(check_x, check_y), move_point);
                    }
                    _worth_p_worth2[check_x, check_y] = _worth[check_x, check_y] + _worth2[check_x, check_y];

                    _parent_dir[check_x, check_y] = i;
                    _return = 1;
                }
                _node_checker[check_x, check_y] = -1;
            }
        }
        _node_checker[_x, _y] = 2;
        return _return;
    }
    public void a_star(Vector2 pos)
    {
        for (int k = 0; k < 10000; k++)
        {
            //if(sc_8search_len(_now_x,_now_y,8)==2)
            if (sc_8search(pos) == 2)
            {
                break;
            }
            bool _t = true;
            for (int i = 0; i < map_wid; i++)
            {
                for (int j = 0; j < map_wid; j++)
                {
                    if (_node_checker[i, j] == -1)
                    {
                        if (_t)
                        {
                            _now_pos.x = i;
                            _now_pos.y = j;
                            _t = false;
                        }
                        else
                        {
                            if (_worth_p_worth2[i, j] < _worth_p_worth2[(int)_now_pos.x, (int)_now_pos.y])
                            {
                                _now_pos.x = i;
                                _now_pos.y = j;
                            }
                        }
                    }
                }
            }
            //if (_t)
            {
                //break;
            }
        }
    }

 

 

너무 오래전에 짜서 개 난잡하게 되어있다... 후 언제 정리하지

구조가 거지같아서 그렇지 성능은 꽤나 최적화 되어있던걸로 기억한다

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

C# 메일  (0) 2021.11.18
유니티 기울기 관련  (0) 2021.10.23
유니티 RectTransform  (0) 2021.10.16
posted by 모카쨩
2021. 10. 23. 19:40 Unity/C#

가속도센서 중력

//가속도센서 중력
Physics.gravity = Input.acceleration;

//가속도센서 2D중력
Physics2D.gravity = (Vector2)Input.acceleration;

 

핸드폰 방향

if (Input.deviceOrientation == DeviceOrientation.FaceUp)
{
    //바닥에 놓은상태
}
else
{
    //세워둔 상태
}

 

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

A Star  (0) 2021.11.06
유니티 RectTransform  (0) 2021.10.16
C# 시리얼  (0) 2021.10.11
posted by 모카쨩
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. 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 모카쨩

  • total
  • today
  • yesterday

Recent Post

저사양 유저용 블로그 진입