Get it on Google Play


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

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

Recent Comment

Archive


2020. 5. 19. 21:26 Unity/C#

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

UGui 관련  (0) 2020.05.19
2D용 LookatTarget  (0) 2020.05.19
충돌 계산 스크립트  (0) 2017.12.17
posted by 모카쨩
2020. 5. 19. 21:22 Unity/C#

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

안드로이드에서 뒤로가기 버튼을 누르면 종료됨  (0) 2020.05.19
충돌 계산 스크립트  (0) 2017.12.17
유니티 각도계산 모음  (0) 2017.11.06
posted by 모카쨩
2017. 12. 17. 21:55

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

2017. 11. 6. 14:54 Unity/C#

좌표계산

https://wmmu.tistory.com/entry/%EC%9C%A0%EB%8B%88%ED%8B%B0-%EC%A2%8C%ED%91%9C%EA%B3%84%EC%82%B0-%EB%AA%A8%EC%9D%8C

 

결과값이 좌표일 경우에는 위 링크로

결과값이 각도일 경우에는 이 글을 이용

 

 

 

pos1에서 pos2에대한 각도

Vector3 relativePos = pos2-pos1; 
Quaternion rotation = Quaternion.LookRotation (relativePos, Vector3.up );

 

 

상대 회전각

dir_speed=target.transform.rotation*Quaternion.Inverse(dir_previous);

 

상대 회전각2

a에서 b에대한 각도(위와 같음)

var a = Quaternion.Euler(0, 15, 0);
var b = Quaternion.Euler(0, 20, 0);
Debug.DrawLine(Vector3.zero, a * Vector3.forward, Color.red);
Debug.DrawLine(Vector3.zero, b * Vector3.forward, Color.blue);
Debug.DrawLine(Vector3.zero, (Quaternion.Inverse(a) * b) * Vector3.forward, Color.green);

 

상대회전각3

테스트는 안 해봄

var rotRel=Quaternion.FromToRotation(fromDir,ToDir);

 

각도 반전

var rotInverse=Quaternion.Inverse(transform.rotation);

 

 

 

 

speed = Quaternion.euler (0,0,0) * new vector3(0,0,0);  //len_vec과 동일

 

 

pDir(pointDirection)

2D계산용
수학계산을 이용한다. 일반적으로는 아래의 SignedAngle사용

    float PointDirection(Vector2 vec2)
    {
        vec2 = vec2.normalized;
        float offset;
        if (vec2.x > 0)
        {
            if (vec2.y > 0)
            {
                offset = 0;
            }
            else
            {
                var t = vec2.x;
                vec2.x = -vec2.y;
                vec2.y = t;

                offset = 270;
            }
        }
        else
        {
            if (vec2.y > 0)
            {
                var t = vec2.x;
                vec2.x = vec2.y;
                vec2.y = -t;

                offset = 90;
            }
            else
            {
                vec2.x = -vec2.x;
                vec2.y = -vec2.y;

                offset = 180;
            }
        }
        if (vec2.x == 0)
        {
            return 0;
        }
        return (Mathf.Atan(vec2.y / vec2.x) * Mathf.Rad2Deg) + offset;
    }

 

 

 

 

PDir

3D계산

var direction = Quaternion.LookRotation(pos2- pos1, Vector3.up);

 

 

PDir2D

좌현이 기준각도라서

Vector2.right를 좌현에 두고 쓰면 겜메랑 똑같이 나온다

Debug.Log(Vector2.SignedAngle(Vector2.zero, Vector2.up)); //0
Debug.Log(Vector2.SignedAngle(Vector2.zero, Vector2.down)); //0
Debug.Log(Vector2.SignedAngle(Vector2.zero, Vector2.left)); //0
Debug.Log(Vector2.SignedAngle(Vector2.zero, Vector2.right)); //0

Debug.Log(Vector2.SignedAngle(Vector2.right, Vector2.up)); //90
Debug.Log(Vector2.SignedAngle(Vector2.right, Vector2.down)); //-90
Debug.Log(Vector2.SignedAngle(Vector2.right, Vector2.left)); //180
Debug.Log(Vector2.SignedAngle(Vector2.right, Vector2.right)); //0

Debug.Log(Vector2.SignedAngle(Vector2.up, Vector2.up)); //0
Debug.Log(Vector2.SignedAngle(Vector2.up, Vector2.down)); //180
Debug.Log(Vector2.SignedAngle(Vector2.up, Vector2.left)); //90
Debug.Log(Vector2.SignedAngle(Vector2.up, Vector2.right)); //-90

 

 

Vector2.Angle 예제

Debug.Log(Vector2.Angle(Vector2.zero, Vector2.up)); //0
Debug.Log(Vector2.Angle(Vector2.zero, Vector2.down)); //0
Debug.Log(Vector2.Angle(Vector2.zero, Vector2.left)); //0
Debug.Log(Vector2.Angle(Vector2.zero, Vector2.right)); //0

Debug.Log(Vector2.Angle(Vector2.right, Vector2.up)); //90
Debug.Log(Vector2.Angle(Vector2.right, Vector2.down)); //90
Debug.Log(Vector2.Angle(Vector2.right, Vector2.left)); //180
Debug.Log(Vector2.Angle(Vector2.right, Vector2.right)); //0

Debug.Log(Vector2.Angle(Vector2.up, Vector2.up)); //0
Debug.Log(Vector2.Angle(Vector2.up, Vector2.down)); //180
Debug.Log(Vector2.Angle(Vector2.up, Vector2.left)); //90
Debug.Log(Vector2.Angle(Vector2.up, Vector2.right)); //90

 

DeltaAngle예제

-179.9~180각도 Normalize용 (정규화)

일반적으론 좌현을 0으로 두고 쓰면 된다

Debug.Log(Mathf.DeltaAngle(0, -270)); //90
Debug.Log(Mathf.DeltaAngle(0, -180)); //180
Debug.Log(Mathf.DeltaAngle(0, -90)); //-90
Debug.Log(Mathf.DeltaAngle(0, 0)); //0
Debug.Log(Mathf.DeltaAngle(0, 90)); //90
Debug.Log(Mathf.DeltaAngle(0, 180)); //180
Debug.Log(Mathf.DeltaAngle(0, 270)); //-90

Debug.Log(Mathf.DeltaAngle(90, -270)); //0
Debug.Log(Mathf.DeltaAngle(90, -180)); //90
Debug.Log(Mathf.DeltaAngle(90, -90)); //180
Debug.Log(Mathf.DeltaAngle(90, 0)); //-90
Debug.Log(Mathf.DeltaAngle(90, 90)); //0
Debug.Log(Mathf.DeltaAngle(90, 180)); //90
Debug.Log(Mathf.DeltaAngle(90, 270)); //180

 

 

각도정규화 

v1

더보기

 겜메 시절에 썼던거

public double d_set(double _Dir)
{
    if(_Dir<0d)
    {
        _Dir=360d-((-_Dir)%360d);
    }
    if(_Dir>=360d)
    {
        return _Dir%360d;
    }
    return _Dir;
}

 

v2

dir = (dir % 360f + 360f) % 360f;

 

v3

dir = Mathf.Repeat(dir, 360f);

 

 

각도정규화 (쉐이더용)

0~1로 정규화 한다

dir = frac(dir);

 

 

 

 

 

 

Dot예제

각도 연산을 바로 인풋으로 받아들일때 쓰면 편하다

Debug.Log(Vector2.Dot(Vector2.zero, Vector2.up)); //0
Debug.Log(Vector2.Dot(Vector2.zero, Vector2.down)); //0
Debug.Log(Vector2.Dot(Vector2.zero, Vector2.left)); //0
Debug.Log(Vector2.Dot(Vector2.zero, Vector2.right)); //0

Debug.Log(Vector2.Dot(Vector2.right, Vector2.up)); //0
Debug.Log(Vector2.Dot(Vector2.right, Vector2.down)); //0
Debug.Log(Vector2.Dot(Vector2.right, Vector2.left)); //-1
Debug.Log(Vector2.Dot(Vector2.right, Vector2.right)); //1

Debug.Log(Vector2.Dot(Vector2.up, Vector2.up)); //1
Debug.Log(Vector2.Dot(Vector2.up, Vector2.down)); //-1
Debug.Log(Vector2.Dot(Vector2.up, Vector2.left)); //0
Debug.Log(Vector2.Dot(Vector2.up, Vector2.right)); //0

 

 

두 벡터간 각도차이

Vector3.Angle(ray.direction, Camera.main.transform.forward)

 

특정 시야각 안에 들어왔는지 검사


bool IsInFOV(Vector3 position, float fovRatio)
{
    var cam = Camera.main;
    if (cam == null)
    {
        return false;
    }
    var direction = position - cam.transform.position;
    var angle = Vector3.Angle(cam.transform.forward, direction);
    var fov = cam.fieldOfView * fovRatio;
    if (angle > fov)
    {
        return false;
    }
    return true;
}

 

특정 시야각 안에 들어왔는지 검사2

targetingCircle.GetComponent<Image>().color = Color.white;
targetingCircle.GetComponent<FovToRectsize>().fov = GetWeapon().GetComponent<Gun>().spread * 2;
var fov = targetingCircle.GetComponent<FovToRectsize>().fov;
var targets = GameSystem.GetInGameOtherCharacters();
var cam = Camera.main;
var targeting = false;
foreach (var target in targets)
{
    Debug.DrawLine(transform.position, target.transform.position, Color.cyan);
    var directionToTarget = target.transform.position - cam.transform.position;
    var angle = Vector3.Angle(cam.transform.forward, directionToTarget);
    if (angle > fov)
    {
        continue;
    }

    var humanoidAnimatorController = target.GetComponentInChildren<HumanoidAnimatorController>();


    //디버깅이 원활하도록 배열로 한번에 안 만들고 하나씩 추가함
    var targetPoses = new List<Vector3>();
    targetPoses.Add(target.transform.position);
    targetPoses.Add(humanoidAnimatorController.GetBoneTransform(HumanBodyBones.Hips).position);
    targetPoses.Add(humanoidAnimatorController.GetBoneTransform(HumanBodyBones.Head).position);

    foreach (var targetPos in targetPoses)
    {
        if (Physics.Raycast(cam.transform.position, targetPos - cam.transform.position, out RaycastHit hit, maxDistance: 100))
        {
            Debug.DrawRay(cam.transform.position, targetPos - cam.transform.position, Color.red);
            if (hit.transform.tag == "Player")
            {
                Debug.DrawLine(targetPos, targetPos + Vector3.up, Color.red);
                targeting = true;
                break;
            }
        }
    }
    if (targeting)
    {
        break;
    }
}
{
    //정중앙에 보고 있는게 닿았는지 검사
    if (Physics.Raycast(cam.transform.position, cam.transform.forward, out RaycastHit hit))
    {
        Debug.DrawRay(cam.transform.position, cam.transform.forward, Color.red);
        if (hit.transform.tag == "Player")
        {
            targeting = true;
        }
    }
}
if (targeting)
{
    targetingCircle.GetComponent<Image>().color = new Color(1, 0.5f, 0.5f);
}

 

 

 

맞은 각도 표시

firePosition은 발사지점

var relativePosition = Quaternion.Inverse(transform.rotation) * (firePosition - transform.position);
var relativePosition2D = new Vector2(relativePosition.x, -relativePosition.z);

var rot = Quaternion.Euler(0, 0, Vector2.SignedAngle(relativePosition2D, Vector2.right));
damageUI.transform.rotation = rot;

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

충돌 계산 스크립트  (0) 2017.12.17
유니티 함수 정리  (0) 2017.07.02
c# list(리스트) 관련  (0) 2017.03.23
posted by 모카쨩
2017. 7. 2. 22:48 Unity/C#
Application.targetFrameRate=60;  //룸스피드를 60프레임으로 맞춤
Application.runInBackground=true;   //백그라운드상에서도 동작하게 한다
DontDestroyOnLoad(this.gameObject);   //룸을 이동해도 오브젝트가 지워지지 않는다
UnityEngine.SceneManagement.SceneManager.LoadScene(룸);   //Application.LoadLevel대신 들어온 녀석, 룸을 이동한다
Application.Quit (); //종료



월드 좌표: 게임내 가상좌표, 편의를 위해 기본좌표계라고 사용
스크린상 좌표: 좌x0, 우x픽셀길이, 상y픽셀높이, 하y0 
Input.GetKey (키보드 번호): 키보드가 눌렸는지를 반환한다. 키보드 번호는 KeyCode에 따라 좌우된다.
Input.GetMouseButton(버튼 번호): 마우스가 클릭했는지를 반환한다. 0은 왼쪽 1은 오른쪽 2는 가운데
Input.GetAxis("Vertical") : 정의된 방향키의 위아래 값을 반환한다 -1이 위쪽
Input.GetAxis("Horizontal") : 정의된 방향키의 좌우 값을 반환한다 -1이 왼쪽
Input.mousePosition : 마우스의 스크린상좌표를 반환한다
Camera.main.ScreenToWorldPoint(좌표) : 스크린상 좌표를 기본좌표계로 변환
Camera.main.WorldToScreenPoint(좌표) : 기본좌표를 스크린상 좌표로 변환

Screen.width //화면가로해상도를 반환
Screen.height //화면세로해상도를 반환
screenHeightCentimeter = Display.main.systemHeight / ((Screen.dpi==0? 96:Screen.dpi) / 2.54f); //화면 세로 Cm높이를 반환
Screen.currentResolution.height //모니터 높이 해상도를 반환(Screen.height와 다른점은 창이 작아져도 최대값을 반환함)
Display.main.renderingWidth //현재 렌더링 되는 디스플레이 사이즈, screen.width랑 같다고 보면 된다
Display.main.systemWidth //물리적인 디스플레이 사이즈, 스크린 사이즈가 바뀌어도 기기레퍼런스값을 가져오므로 불변이다.


float canvasHei = GetComponentInParent<Canvas>().GetComponent<RectTransform>().rect.height; //현재 캔버스의 높이를 반환
(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써라




Physics2D.CircleCast(위치(vector2), 반지름, 각도(Vector2)) :  원충돌 검사 RaycastHit2D를 반환하고, (RaycastHit2D.transform!=null) 검사로 충돌했는지 확인가능

GetComponent<Rigidbody2D> ().AddRelativeForce (Vector2.right*1000f); //상대적인 정면을 향해 힘을 줌, 질량에 따라 바뀜
GetComponent<Rigidbody2D> ().velocity //속력을 반환



GetComponent<Rigidbody2D>().AddForce( (transform.position-target.position).normalized*-gravity); //특정방향으로 힘을 줌



Vector2.Distance(Vec2_A,Vec2_B); //벡터간의 길이값을 반환

Vector3.Distance(Vec3_A,Vec3_B); //벡터간의 길이값을 반환 3D


this.GetComponent<Renderer>().material.mainTexture  //렌더러의 텍스처

this.GetComponent<SpriteRenderer>().sprite  //렌더러의 스프라이트



GetComponent<AudioSource>().volume //게임오브젝트의 사운드 볼륨조절



GUI.Label (new Rect(x,y,wid,hei),text); draw_text와 같다



void OnGUI(){} //GUI계층의 함수를 사용할수 있다

void OnCollisionEnter2D(Collision2D col) //리지드바디2D가 충돌을 시작했을때 작동한다 OnCollisionStay2D는 항상 OnCollisionExit2D는 종료시,Collision을 Trigger로 바꾸면 트리거 작동 인수는 그대로

{

}

void OnCollisionStay(Collision col) //Enter와 다르게 항상 작동한다

{

}

GetComponent<Collider2D>().IsTouchingLayers() //충돌했는지 반환



Mathf.Clamp(value,min,max) //median함수와 동일함

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

유니티 각도계산 모음  (0) 2017.11.06
c# list(리스트) 관련  (0) 2017.03.23
c# list와 array속도 비교  (3) 2017.01.25
posted by 모카쨩
2017. 3. 23. 00:22 Unity/C#

내부값과 검색하여 하나라도 맞는지 검사하여 bool 반환 x는 내부값을 나타냄 반드시 x로 써야함

if (nameList.Exists(x => x.ToString() == "name"))

 

해당하는 값이 존재하는지 bool 반환함 위 코드와 같음

nameList.Contains("name")

 

해당 하는 조건에 맞는 항목들을 전부 지움, 아래의 경우는 ".meta"가 포함된경우 전부 지운다.

x는 내부값이고 무조건 x로 써야함

fileNames.RemoveAll(x => x.Contains(".meta"));

 

 

리스트 복제(깊은복사)

List<int> DNA_copy = DNA.GetRange(0, DNA.Count);

 

리스트복제 2

var list2 = new List<int>(list);

 

 

 

중간삽입

DNAcopy.Insert(index, mScript.irandom(random_value));
 
중간삽입(배열 및 리스트)
 list.InsertRange(index, 배열 혹은 리스트);
 
다중추가(배열 및 리스트)
 list.AddRange(배열 혹은 리스트);

 

 

Linq계열

using System.Linq;

//중복제거
//앞글자 3글자가 같은녀석들만 제거함, x => x.Substring(0,3) 이부분만 수정해서 쓰면 됨
list = list.GroupBy(x => x.Substring(0,3)).Select(x=>x.First()).ToList();

//중복제거2
//완벽히 동일한것만 제거
list = list.GroupBy(x => x).Select(x=>x.First()).ToList();

//그룹리스트 (같은값끼리 짝지어서 나온다)
List<int> list=new int[] { 1,1,1,2,2,3,4,4}.ToList();
var groupList = list.GroupBy(x => x).ToList();

for (int i = 0; i < groupList.Count; i++)
{
    var group = groupList[i].ToList();
    for (int j = 0; j < group.Count; j++)
    {
        Debug.Log(group[j]);
    }

}

//중복제거 심플버전 구조체만 가능(예를들어 게임오브젝트는 안된다)
list.Distinct();

//전부 더하기
list.Sum();



//슬라이스(자르기)
var list = new List<int>(new int[] { 1, 2, 3, 4, 5 });
var length = 3;
var sliceList =  list.Take(length).ToList();
Debug.Log(string.Join(", ", sliceList));
//결과: 1,2,3



//슬라이스2 (중간부터)
var list = new List<int>(new int[] { 1, 2, 3, 4, 5 });
var startIndex = 1;
var length = 3;
var sliceList =  list.Skip(startIndex).Take(length).ToList();
Debug.Log(string.Join(", ", sliceList));
//결과: 2,3,4

 

 

 

 

 

 

최댓값 (맥스)

double dividendMax = list.Max(x => x.dividend);

 

최댓값'들'

var timeMax = saves.Max(save => save.time);
var timeMaxSaves = saves.FindAll(save => save.time == timeMax);

 

 

 

셔플(미세한 편향, 비둘기집문제)

하지만 구조가 간단하므로 중요로직이 아니면 이걸로 처리한다 

using System.Linq;

//유니티버전
list = list.OrderBy(a => Random.value).ToList();

//닷넷버전
System.Random seed = new System.Random((Int32)DateTime.Now.Ticks);
list = list.OrderBy(a => seed.Next()).ToList();

 

셔플(완전한)

    public static void ShuffleList<T>(ref List<T> targetList)
    {
        for (int i = 0; i < targetList.Count; i++)
        {
            int j = Random.Range(0, targetList.Count);
            T t = targetList[i];
            targetList[i] = targetList[j];
            targetList[j] = t;
        }
    }

 

정렬//오름차순

creature_list.Sort();

 

정렬//내림차순 정렬

list.Sort((x, y) => y.CompareTo(x));

이것과 동일함

List<double> A;
List<double> B;

//동일버전
list.Sort((A, B) => B.CompareTo(A));

//람다 긴버전
list.Sort(delegate (var a, var b)
{
    return b.CompareTo(a);

});

//if방식
list.Sort(delegate (var a, var b)
{
    if (a > b)
    {
        return -1;
    }
    if (a < b)
    {
        return 1;
    }
    return 0;
});

//for방식
for (int i = 0; i < list.Count; i++)
{
    for (int j = i + 1; j < list.Count; j++)
    {
    	var a=list[i];
    	var b=list[j];
        if (a > b)
        {
            var t=a;
            a=b;
            b=t;
        }
    }
}

 

 

 

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

유니티 각도계산 모음  (0) 2017.11.06
유니티 함수 정리  (0) 2017.07.02
c# list와 array속도 비교  (3) 2017.01.25
posted by 모카쨩
2017. 1. 25. 01:56 Unity/C#

중계서버 코딩할일이 생겨서 가장 부하가 많이 걸리는 array에 접근해봤습니다

타입은 앞으로 가장 많이 쓰이게될 long형


비교항목은 다음과 같습니다

1. 초기화속도 비교

2. 입력속도 비교

3. 일반 Add 속도 비교

4. 일반 Delete 속도 비교




결론

1. 초기화속도 비교 = array가 list보다 40배 빠름

2. 입력속도 비교 = array가 list보다 2배 빠름

3. 일반 Add 속도 비교 =  array가 list보다 1.07배 빠름

4. 일반 Delete 속도 비교 =  동일함


=이 일로 mBuffer라고 해서 전용 구조체 하나 만들어 뒀습니다 ㅡ_ㅡ;;

  array가 가장 맨 처음에 나온거니 당연하다고 하면 당연하지만 설마 Delete에서 비효율적인 코드와 동일하게 측정될줄은 몰랐네요

  

여기에 쓰인 코드는 프로그램에서 구동하에 상용이든 비상용이든 자유롭게 가져다 쓰셔도 됩니다

다만 스크랩이나 재게시는 안 되여~

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

유니티 각도계산 모음  (0) 2017.11.06
유니티 함수 정리  (0) 2017.07.02
c# list(리스트) 관련  (0) 2017.03.23
posted by 모카쨩

  • total
  • today
  • yesterday

Recent Post

저사양 유저용 블로그 진입