- 요구조건 


앱 버전을 x.x.x 형식으로 한다


--------------------------------


- 업데이트를 강제 하고 싶지 않은 경우 맨 뒤의 숫자만 바꾸면 업데이트 요구를 하지 않는다



--------------------------------------


bool IsSameVersion = false; //일단은 그냥 같은 버젼으로 취급해준다
bool IsChecked = false;
      
private void GooglePlayVersionCheck()

{
        ////////////////////

        UnsafeSecurityPolicy.Instate(); //이 코드를 안쓸 경우 오류가 뜨더라구요

        string marketVersion = "";

        string url = "https://play.google.com/store/apps/details?id=앱id";

            HtmlWeb web = new HtmlWeb();
            HtmlDocument doc = web.Load(url);
            yield return doc;

        try
        {
            System.Collections.Generic.IEnumerable<HtmlNode> nodes = doc.DocumentNode.Descendants("div").Where(d => d.Attributes["class"].Value.Contains("htlgb"));

            foreach (HtmlNode node in doc.DocumentNode.SelectNodes("//span[@class='htlgb']"))
            {
                string value = node.InnerText.Trim();

               

                /////////
                if (System.Text.RegularExpressions.Regex.IsMatch(value, @"^\d{1}\.\d{1}\.\d{1}$"))
                {
                    
                    marketVersion = value;
                    Debug.Log("market version : " + marketVersion.Trim());



                    if(marketVersion.Split('.')[0] == Application.version.Split('.')[0] && marketVersion.Split('.')[1] == Application.version.Split('.')[1]) // . . 형식중에서 앞의 두 숫자가 바뀌는 경우에만 업데이트 요구 -> 업데이트를 강제할 필요없는 경우에는 맨뒤의 숫자만 바꾸자
                    {
                        Debug.Log("업데이트 필요없음");
                        //버전이 같은 경우 
                        IsSameVersion = true; //일단은 그냥 같은 버젼으로 취급해준다
                        IsChecked = true;
                        yield break; //함수 빠져나감 
                    }
                    else
                    {
                        Debug.Log("업데이트 필요함");
                        //버전이 다른 경우 
                        IsSameVersion = false;
                        IsChecked = true;
                        _DeveloperLogoScene.SetActiveRequestUpdateGameOnGooglePlayPanel(true);
                        yield break; //함수 빠져나감 
                    }

                }


            }

          
        

        }
        catch
        {

            //구글 플레이 쪽에서 코드를 자주 바꾸다 버전을 못가져 올 수 도 있습니다. 이런 경우를 대비하여 exception이 뜬 경우 그냥 버전이 동일한걸로 취급
            IsSameVersion = true; //일단은 그냥 같은 버젼으로 취급해준다
            IsChecked = true;

 
        }

      
      
  }


유니티 라이트맵을 사용하다 보면 위의 사진과 같이 오브젝트에 어색한 얼룩이나 검은 점이 생기는 것을 볼 수 있다

이는 UV가 겹쳐서 생기는 일이다 .

이를 해결하기 위해서는 아래와 같이 Generate Lightmap Uvs를 설정해 주어 라이트 맵을 위한 UV를 만들어 주면 된다


간혹 UV를 생성해준 후에도 얼룩이 그대로 있는 경우가 있다

이는 생성된 UV에서 텍스쳐가 겹치는 부분이 있기 때문이다 이를 해결해 주기 위해서는 PackMargin을 늘려주면 된다. 조금 씩 늘리면서 Overlapping UV가 사라지는 지점까지 PackMargin을 늘려주면 된다. 



https://docs.unity3d.com/kr/2018.1/Manual/RandomNumbers.html

우선 스크롤뷰를 사용하는 방법에는 여러가지가 있다


1. Vertical하게 컨텐츠들을 배치하는 방법




2. Horizontal하게 컨텐츠들을 배치하는 방법




3. Vertical하게 배치하되 한 줄에 여러 컨텐츠를 넣는 방법




등등이 있다


이러한 스크롤뷰 내의 Content와 Content의 child들의 size , position을 일일이 코드로 수정해주려면 매우 힘들다.

그렇기 때문에 유니티는 여러가지 좋은 컴퍼넌트들을 제공해준다. 그 방법을 알아보자.


우선 가장 기본적인 것은 Content의 Child로 들어갈 Ui들에 LayoutElement를 추가해주는 것이다


아래와 같이 Preferred Width와 Height를 체크해주어서 적절한 사이즈를 정해주자....


그 다음에는 Content에 여러 두가지 컴퍼넌트가 각각 필요하다


우선 공통적으로는 Content Size Filtter가 필요하다

스크롤뷰를 아래위로 당기는지 혹은 좌우로 당기는지에 따라 


아래위로 당기는 경우 Vertical Fit을 Preferred Size로 Horizontal Fit을 Uncontrained로

좌우로 당기는 경우 Vertical Fit을 Uncontrained로 Horizontal Fit을 Preferred Size로 설정한다

Vertical Fit, Horizontal Fit 모두 Preferred Size로 설정한다


그 다음 


1. 아래 위로 당기는 경우에는 Vertical layout Group을


2. 좌 우로 당기는 경우에는 Horizontal layout Group을


3. 한 줄 혹은 한 행에 여러 Content child가 들어가는 경우에는 Grid layout Group을


각 컴포넌트의 설정방법은 아래의 것을 참고하면 된다..



특별하게 Grid Layout Group의 경우에는 


한 줄에 여러 컨텐츠를 넣는 경우에는 Cell Size를 조정, Constraint를 Fixed Column Count를 한 줄에 들어갈 컨텐츠 개수로 정해주면 된다


한 행에 여러 컨텐츠를 넣는 경우에는 Cell Size를 조정, Constraint를 Fixed Row Count를 한 행에 들어갈 컨텐츠 개수로 정해주면 된다




Start Axis는 Content의 Child 순서대로 ScrollView에서 어떤 순서로 배치할지를 결정한다

horizontal은 Child 순서대로 왼쪽에서 오른쪽으로 스크롤뷰를 채워나간다

vertical은 Child 순서대로 위에서 아래로 스크롤뷰를 채워나간다










Content와 Content의 child로 들어갈 오브젝트의 Anchor을 조정해주어서 적절한 위치를 정해주자


  1. GameObject WorldObject;
  2. //this is the ui element
  3. RectTransform UI_Element;
  4. //first you need the RectTransform component of your canvas
  5. RectTransform CanvasRect=Canvas.GetComponent<RectTransform>();
  6. //then you calculate the position of the UI element
  7. //0,0 for the canvas is at the center of the screen, whereas WorldToViewPortPoint treats the lower left corner as 0,0. Because of this, you need to subtract the height / width of the canvas * 0.5 to get the correct position.
  8. Vector2 ViewportPosition=Camara.main.WorldToViewportPoint(WorldObject.transform.position);
  9. Vector2 WorldObject_ScreenPosition=new Vector2(
  10. ((ViewportPosition.x*CanvasRect.sizeDelta.x)-(CanvasRect.sizeDelta.x*0.5f)),
  11. ((ViewportPosition.y*CanvasRect.sizeDelta.y)-(CanvasRect.sizeDelta.y*0.5f)));
  12. //now you can set the position of the ui element
  13. UI_Element.anchoredPosition=WorldObject_ScreenPosition;



- 출처 : https://answers.unity.com/questions/799616/unity-46-beta-19-how-to-convert-from-world-space-t.html

유니티 프로젝트 폴더를 깃에 올리다 보면 .obj 모델 메쉬파일이 깃에 안올라와 있는 것을 알 수 있다

대개 이유는 자신의 gitignore에 *.obj 를 추가 했거나 global ignore list에 *.obj가 올라와 있는 경우이다.

위 두 경우 때문에 obj 확장자의 파일들이 커밋에 추가 되지 않았던 것이다


이를 해결하기 위해서는 해당 깃의 gitignore에 !Assets/**/*.obj 를 추가함으로 해결 할 수 있다

그럼 Assets 폴더 안에 모든 *.obj를 찾아내어서 그 파일들을 전부 허용해줄 것이다




유니티 Raycast를 사용할 때 특정한 오브젝트만 Raycast에 Target되기를 원하는 경우 LayerMask를 사용한다

하지만 LayerMask를 사용할 때 주의해야할 점이 


RaycastHit hitInfo;

Ray ray = Camera.main.ScreenPointToRay(InputManager.GetInputPos());



1.   if (Physics.Raycast(ray, out hitInfo, 1 << LayerMask.NameToLayer("특정 레이어") ))


2.   if (Physics.Raycast(ray, out hitInfo, float.MaxValue, 1 << LayerMask.NameToLayer("특정 레이어") ))



위의 1번과 2번의 차이는 중간에 float.MaxValue 즉 Raycast의 파라미터 중 maxDistance를 넣어주느냐 마냐의 차이이다


1번의 경우에는 Raycast는 1 << LayerMask.NameToLayer("특정 레이어") 를 flaot maxDistance 파라미터에 넣어주는 것으로 인식하여서 LayerMask가 제대로 적용되지 않는다. 함수가 프로그래머가 의도한 바와는 다르게 1 << LayerMask.NameToLayer("특정 레이어") 를 다른 parameter 값으로 인식한 경우다. 게다가 Raycast에는 maxDistance 파라미터가 없이 LayerMask를 파라미터로 넣는 함수형은 없다.


그래서 프로그래머는 maxDistance에 float.MaxValue를 넣어주어야만 뒤의 1 << LayerMask.NameToLayer("특정 레이어")를 프로그래머가 의도한대로 LayerMask의 값으로 인식한다

사진과 같이 Button에 Event Trigger이라는 컴포넌트를 추가하여 준다

 그 다음 Add New EventType에서 원하는 Event를 추가하여 주면 된다


누르고 있는 상태를 체크하려면 Pointer Down를 추가하여 주면 된다

그 후 스크립트에서 


priavte bool ButtonDown;


public void PointerDown()

{

ButtonDown=true;

}


이 코드를 추가 후 Pointer Down의 유니티 이벤트 List에 PointerDown() 함수를 추가하면 버튼을 누르고 있는 상태일때 PointerDown() 함수가 실행된다



대개 유니티에서 2D 캐릭터 에니메이션을 만들면 왼쪽을 바라보고 있는 경우 오른쪽을 바라보고 있는 경우를 각각 따로 만들어야 한다 생각하는데 사실 그러지 않아도 된다.


캐릭터 스프라이트가 있는 Object의 Scale을 (-1 , 1, 1) 로 설정하면 Sprite의 좌우 반전이 된다. 이는 에니메이션에도 모두 적용되어 손쉽게 좌우 반전을 구현할 수 있다.

  1. using UnityEngine;
  2. using UnityEngine;
  3. using System.Collections;
  4. public class DragMouseOrbit : MonoBehaviour
  5. {
  6. public Transform target;
  7. public float distance = 2.0f;
  8. public float xSpeed = 20.0f;
  9. public float ySpeed = 20.0f;
  10. public float yMinLimit = -90f;
  11. public float yMaxLimit = 90f;
  12. public float distanceMin = 10f;
  13. public float distanceMax = 10f;
  14. public float smoothTime = 2f;
  15. float rotationYAxis = 0.0f;
  16. float rotationXAxis = 0.0f;
  17. float velocityX = 0.0f;
  18. float velocityY = 0.0f;
  19. // Use this for initialization
  20. void Start()
  21. {
  22. Vector3 angles = transform.eulerAngles;
  23. rotationYAxis = angles.y;
  24. rotationXAxis = angles.x;
  25. // Make the rigid body not change rotation
  26. if (GetComponent<Rigidbody>())
  27. {
  28. GetComponent<Rigidbody>().freezeRotation = true;
  29. }
  30. }
  31. void LateUpdate()
  32. {
  33. if (target)
  34. {
  35. if (Input.GetMouseButton(0))
  36. {
  37. velocityX += xSpeed * Input.GetAxis("Mouse X") * distance * 0.02f;
  38. velocityY += ySpeed * Input.GetAxis("Mouse Y") * 0.02f;
  39. }
  40. rotationYAxis += velocityX;
  41. rotationXAxis -= velocityY;
  42. rotationXAxis = ClampAngle(rotationXAxis, yMinLimit, yMaxLimit);
  43. Quaternion fromRotation = Quaternion.Euler(transform.rotation.eulerAngles.x, transform.rotation.eulerAngles.y, 0);
  44. Quaternion toRotation = Quaternion.Euler(rotationXAxis, rotationYAxis, 0);
  45. Quaternion rotation = toRotation;
  46. //distance = Mathf.Clamp(distance - Input.GetAxis("Mouse ScrollWheel") * 5, distanceMin, distanceMax);
  47. //RaycastHit hit;
  48. //if (Physics.Linecast(target.position, transform.position, out hit))
  49. //{
  50. //distance -= hit.distance;
  51. //}
  52. //Vector3 negDistance = new Vector3(0.0f, 0.0f, -distance);
  53. //Vector3 position = rotation * negDistance + target.position;
  54. transform.rotation = rotation;
  55. //transform.position = position;
  56. velocityX = Mathf.Lerp(velocityX, 0, Time.deltaTime * smoothTime);
  57. velocityY = Mathf.Lerp(velocityY, 0, Time.deltaTime * smoothTime);
  58. }
  59. }
  60. public static float ClampAngle(float angle, float min, float max)
  61. {
  62. if (angle < -360F)
  63. angle += 360F;
  64. if (angle > 360F)
  65. angle -= 360F;
  66. return Mathf.Clamp(angle, min, max);
  67. }
  68. }




from https://answers.unity.com/questions/1257281/how-to-rotate-camera-orbit-around-a-game-object-on.html

+ Recent posts