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


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


실수로 삭제해버린 브런치를 복구하는 방법


다행히 깃은 삭제한 브런치라도 커밋을 한 모든 기록을 보관하고 있다

그러니 해당 커밋을 찾아서 복구를 해주면 된다


우선 git reflog로 이제까지 커밋한 목록을 전부가져온다


그럼 위의 사진과 같이 내가 원하는 커밋인 b243685 HEAD@[15] : commit : 2018.02.14 오후 11:06 을 찾을 수 있다


숫자 15는 해당 커밋의 순서이다


그럼 이 커밋을 체크아웃 하여 복구를 해주면 된다


git checkout -b 새로체크아웃할브런치 HEAD@{15} 로 복구할 커밋을 체크아웃하여 복구할 수 있다



- 간단 정리 -


1. git reflog로 커밋 기록 가져옴

2. git checkout -b 새로체크아웃할브런치 HEAD@{커밋 숫자}



  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

git : https://github.com/SungJJinKang/Unity-3DTile-Object-Placement-Wall-Constructer


example video : https://youtu.be/stzQYF4xpbc

Grid m_Grid;


Vector3 world = Camera.main.ScreenToWorldPoint(Input.mousePosition); //현재 마우스의 위치를 Vector3로 가져옴

Vector3Int gridPos = m_Grid.WorldToCell(world); //Vector3 position을 Vector3Int로 바꿔줌

가끔 ctrl+z나 g키 같은 단축키가 안먹는 경우가 있다.

이 경우 한영키를 눌러서 혹시 현재 한글키로 설정되어 있지 않은지 확인하자.

애드몹과 구글 플레이 게임 서비스를 같이 한 프로젝트에 넣으면 거의 99%의 확률로 빌드 에러가 뜬다

여러 원인들이 있지만 필자가 4~5개의 게임을 개발하면서 거의 99%의 확률로 원인은 한가지 였다

애드몹과 구글 플레이 게임 서비스의 gms 버전이 각기 다르기 때문이다


해결책 : 

GoogleMobileAds의 ~~dependencies xml 파일과
GooglePlayGames의  ~~dependencies xml 파일안에

<androidPackage spec="com.google.android.gms:~~~ : 11.~~ 이 숫자부분을 한쪽 버전으로 통일 시켜주자
그 후 유니티의 asset->play service resolver -> android -> resolve를 클릭해주자
그리고 play service resolver setting에서 auto resolve는 꺼주 것이 좋다


대개 유니티를 사용할 때 세이브 파일을 저장할 경로로 Application.persistentDataPath를 많이 사용한다


그런데 이것이 안드로이드 플랫폼에서는 일부 기기에서 문제를 일으킨다


일부 기기에서 이 Application.persistentDataPath 값을 임의로 바꾸기 때문이다.


다른 기기와 달리 특정 기기에서 다른 Application.persistentDataPath를 사용하는건 큰 문제가 되지 않는다


어차피 그 기기에서는 다른 기기들과 다른 특정한 Application.persistentDataPath에 계속 저장하면 되기 때문이다.


그런데 문제는 일부 기기에서는 Application.persistentDataPath 값이 어떠한 요인에 의해 계속 바뀐다는 것이다.


즉 게임을 키고 세이브 파일을 저장하고 게임을 끈 후 다시 그 게임을 실행하면 Application.persistentDataPath이 바뀌어 있는 것이다.


이러면 당연히 게임은 세이브 파일을 찾지 못하고 세이브 파일을 날린 것과 같이 보이게 된다


해결책 : "/data/data/com.mycompany.mygame/files/세이브파일명" 과 같이 세이브 파일을 저장할 경로를 개발자가 지정해주자



1. 너무 잦은 업데이트, 한꺼번에 너무 많은 업데이트는 독이다!!!!!

 : 너무 잦은 업데이트는 유저들의 짜증을 유발하여 앱 제거율을 높인다, 한꺼번에 너무 많은 업데이트는 역량 부족으로 미처 전부 테스트를 해보지 못할 가능성이 많아 버그가 있을 가능성!!!!!!이 매우 높다. -> 충분한 테스트 후 업데이트를 배포하자. 버그가 있으면 업데이트를 안하느니만 못하다


2. 인앱 결제 시스템의 신중함

 : 인앱 결제 시스템을 넣으려면 최소한 클라우드 서버를 통해 모든 결제 내역을 저장해두어야한다. 혹시나 데이터가 날라갈 시 인앱 결제를 전부 환불해야하는 사태가 생길 수 있다(킬러를 찾아라 11/28 인앱 결제 전부 환불해줌)


3. 유저들의 데이터는 매우 소중히 보관해야한다 

 : 클라우드 서버를 이용해서 무조건 유저들의 데이터를 따로 저장해두자. 잘못해서 세이브 파일이 날라가면 진짜 돌이킬 수 없는 비난을 받는다.


4. 과도한 소통은 독이다 

 : 과도하게 소통을 하여 모든 유저들의 요구를 일일이 들여주다 보면 게임의 방향성을 잃는다. 물론 유저의 말도 중요하지만 과연 그 유저들이 정말 게임의 방향성, 핵심을 이해하고 아이디어를 내는 것일까? 


5. 섯부른 출시는 독이다

 : 게임의 버그가 없는지 충분히 확인하고!!!!!!! 출시하자


6. 확장성 있게 코드를 짜자(!!!!)

 : 모드를 추가하거나 맵을 추가할 때 미리 확장성 있는 코드를 짜두지 않으면 다시 리팩토링 해야하고 이 과정에서 또 버그가 생길 가능성이 높다


7. 유저의 의견이 무조건 좋은 것만은 아니다

: 물론 좋은 의견들을 제시해 주는 분들도 있지만 그렇지 않고 아이디어를 제시하거나 게임에 대한 재미보다는 오직 자신의 재미만을 위해 의견을 제시하는 사람들도 많다. 과연 개발자 만큼이나 게임에 대한 이해를 가지고 있고 게임에 대해 많은 시간을 생각해보았을까?? 유저의 아이디어를 고려하되 무조건 따르다 보면 밸런스도 깨지고 오히려 게임은 더 재미없어진다.


8. 다시 강조하지만 유저들의 피드백에 휘둘리지 말자 특히 밸런스는!!


9. 디자인, 음악 등 외주를 쓸때는 내가 원하는 것을 구체적으로 확정지어두고 내가 상상하는 그대로를 외주가 만들게해야한다. 

: 구체적인 요구없이 그냥 알아서 잘 해달라는건 진짜 돈만 버리는거다(아이콘 외주 맡기다 망함).  정말 내가 상상하는 이미지, 음악을 구체적으로 그려두고 요구를 해야한다. 외주는 내가 상상한걸 그대로 구현하게 만들어야된다. 외주의 의견이 들어가서 만들면 절대 안된다. 오직 내가 원하는걸 그대로 만드렉 시키는 것이다 -> 외주를 맡기기 전에 원하는 그림,음악을 구체적으로 확정지어두자


10. 게임을 완성한 후 출시하자. 어중간하게 게임이 완성된 후 출시하면 가장 유저 유입이 많은 초반시기에 유저들을 잃게 된다. 그러니깐 최소한 충분히 즐길 수 있고 재밌고 버그가 없는 게임을 완성한 후 출시하자. 출시 후 버그 수정하겠다고 하면 이미 늦었다


+ Recent posts