'Unity/C#'에 해당되는 글 63건
- 2021.12.16 유니티 ScriptableObject
- 2021.11.30 유니티 트랜스 폼 (Transform)
- 2021.11.18 C# 메일
- 2021.11.06 A Star
- 2021.10.23 유니티 기울기 관련
- 2021.10.16 유니티 RectTransform
- 2021.10.11 C# 시리얼
- 2021.10.11 C# Delegate와 IEnumerator
공통부모들을 반환
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 |
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 |
가속도센서 중력
//가속도센서 중력
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 |
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 |
받을때
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 |
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();
}
}
그외에 이것들을 쓴다는건 비동기계열을 다룬다는 소리인데
스레드나 태스크계열도 참조할 필요가 생긴다 (링크참조)
'Unity > C#' 카테고리의 다른 글
C# 시리얼 (0) | 2021.10.11 |
---|---|
c# 해쉬테이블 (0) | 2021.09.13 |
자주쓰는 c# 소켓 통신 모음 (0) | 2021.09.08 |