후들후들

foodybug.egloos.com

포토로그



GameObject의 Hierarchy 상의 경로 얻기 Unity


디버그를 위해 코드에 로그를 삽입할 때 어느 오브젝트에 attach됐는지 알면 편리한 경우가 많습니다.

Unity3d에서 따로 제공하는 함수는 없고 직접 코드를 작성해야 합니다.

아래와 같은 코드로 Hierarchy상에 존재하는 오브젝트의 경로(상위 오브젝트의 이름들)를 얻을 수 있습니다.


public static string GetGameObjectPath(GameObject obj)
{
    string path = "/" + obj.name;
    while (obj.transform.parent != null)
    {
        obj = obj.transform.parent.gameObject;
        path = "/" + obj.name + path;
    }
    return path;
}


출처는 아래의 사이트입니다.


위의 코드를 확장메소드를 이용하면 좀 더 전역적으로 사용할 수 있습니다. 저는 아래와 같이 사용합니다.


public static string GetFullPath(this Transform trn)
{
string path = "/" + trn.name;
while (trn.transform.parent != null)
{
trn = trn.parent;
path = "/" + trn.name + path;
}
return path;
}



Script Execution Order 변경사항의 저장 Unity


Script Execution Order는 각 클래스의 콜백함수들의 호출 순서를 조정할 수 있는 편리한 기능입니다.

별도로 코드에서 초기화 순서를 관리할 필요가 없기 때문입니다.

다만 코드가 Unity3D에 종속되기 때문에 개인적으로는 사용을 자제하는 편입니다.

Script Execution Order를 변경할 경우 변경사항은 따로 프로젝트세팅 파일에 저장되지 않습니다.

해당 스크립트의 메타 파일에 변경사항이 저장됩니다.

SVN에 commit하기 위해 프로젝트세팅 쪽을 살펴봐도 변화가 없길래 검색을 해보니 그렇게 구성돼있더군요.


유니티 공홈의 설명입니다.

크게 중요한 내용은 아니지만 혹시 헤매는 분들이 있을 수 있으니 작성해봅니다.

drag가 적용된 Rigidbody의 이동 궤도를 예측하는 코드 Unity


포트리스같은 게임을 구현할 때 발사된 강체의 궤도를 미리 예측해서 보여줘야 하는 상황이 있습니다.



아래와 같이 프레임당 위치를 구할 수 있습니다.

List<Vector3> list = new List<Vector3>();
float unitTime = 1f / 50f; //초당 50프레임으로 계산
int steps = 50 * 10; // 10초 계산(총 500프레임)
for (int i = 0; i < steps; i++) {
velocity.y += Physics.gravity * unitTime; 
position += velocity * unitTime;
list.Add(position);
}


하지만 공기의 저항같은 상황을 구현하려면 drag를 이용해야 합니다.

위의 코드는 강체의 drag값이 0일 경우에만 해당합니다.

강체의 drag가 크면 시간이 지날수록 강체의 속도는 더욱 빠르게 느려집니다.


List<Vector3> results = new List<Vector3>();
Vector3 pos = origin;

float timestep = Time.fixedDeltaTime * Physics.defaultSolverVelocityIterations; // 실제 단위시간
Vector3 gravityAccel = Physics.gravity * timestep * timestep; // 단위시간당 중력가속도
float drag = 1f - timestep * rbBall.drag; // 실제 적용될 저항값
Vector3 moveStep = velocity * timestep; // 단위시간당 이동량

for (int i = 0; i < steps; ++i)
{
moveStep += gravityAccel;
moveStep *= drag;
pos += moveStep;
results.Add(pos); // 실제 경로 저장
}


위의 코드를 살펴보면 중력가속도가 적용된 moveStep에 drag가 곱해짐을 알 수 있습니다.

이것은 drag가 클수록 낙하하는 속도도 느려진다는 것을 의미합니다.

경험상 drag는 2를 넘어가면 강체의 낙하속도가 금방 느려져서 매우 비현실적으로 느껴졌습니다.

(우주 공간 같은 느낌을 원하신다면 오히려 좋을 수도 있습니다.)

개인적으로 1을 넘지 않도록 하는 편입니다.


VR 환경에서의 카메라 로테이션 참조 Unity


Unity3d는 PlayerSetting에서 Virtual Reality Supported 옵션을 켜주면

별다른 조치없이 자동으로 카메라에 HMD의 위치와 방향같은 트래킹 정보가 적용됩니다.

만약 이러한 카메라의 움직임과는 별도로 HMD의 위치나 방향을 알고 싶은 경우는

InputTracking.GetLocalPosition과 InputTracking.GetLocalRotation을 이용하시면 됩니다.

함수의 인자로 들어가는 VRNode는 머리나 눈과 같은 부위를 의미합니다.

아마 VRNode.Head를 주로 이용하게 될 듯 합니다.


Quaternion qDir = InputTracking.GetLocalRotation(VRNode.Head);
dir = qDir * Vector3.forward;


위의 코드는 HMD의 Vector3 방향을 알아내는 코드입니다.




카드보드(GoogleVR) 마그네틱 버튼 입력 Unity


현재 GoogleVR 에서 제공하는 마그네틱 버튼을 입력받는 Api 는 따로 없는 듯 합니다.

그래서 직접 해당 기능을 구현해야 하는 상황입니다.

마그네틱 버튼 기능은 코드로 구현돼있습니다.




디바이스의 움직임(Input.acceleration)이 거의 없는 상황에서

지자기장의 변화(Input.Compass.rawVector)가 클 경우에는

마그네틱 버튼이 눌렸다고 판정하는 원리입니다.

간편하게 함수로 구현돼있지 않다는 건 좀 의외네요.

GoogleVR 은 아직 보완해야 할 점이 많아 보입니다.




1 2 3 4 5 6 7 8