본문 바로가기
IT

[Unity/Zepeto] 개발하면서 해결한 오류 및 정리

by 배애앰이 좋아 2023. 6. 9.
반응형

 

1. Property 'x' has no initializer and is not definitely assigned in the constructor 오류

 

새로운 클래스에 맞는 변수를 선언했는데 아래처럼 오류가 뜬 경우가 발생했습니다.

 

Property 'x' has no initializer and is not definitely assigned in the constructor.

 

https://velog.io/@gingaminga/%EB%AC%B8%EC%A0%9C-%ED%95%B4%EA%B2%B0-has-no-initializer-and-is-not-definitely-assigned-in-the-constructor

 

 

has no initializer and is not definitely assigned in the constructor

Typescript가 나를 괴롭히는구나..!

velog.io

 

위 글의 참고해서 선택적 사항으로 아래 사진과 같이 처리해줬고 그 결과 해결 되었습니다.

 

 

2. 플레이어 동기화 및 멀티 게임에서 충돌 처리할 때 (예 : 좀비 게임)

 

- host player 판별해서 host 일 시 npc 들의 nav agent 실행 후 매 시간 npc 위치 값을 서버로 전송

- 그 외 플레이어는 sever 로부터 매 시간 npc 위치 값을 받아와서 위치 동기화 실행

 

3. 오브젝트 움직이는 방식

 

오브젝트 위치 동기화를 시킬 때는 어떤 방식을 사용하는지에 따라 자연스럽게 움직이는지 아닌지가 달라지기 때문에 여러 방법을 테스트하면서 고려해보아야 합니다.

 

room.AddMessageHandler<ZombiePos[]>("SendZombiePosData", message => { 
                //console.log("매시간 좀비 pos data 요청해서 좀비 위치 조정하기");
                //for (const ZombiePos of message) {
                //    let gameObject : UnityEngine.GameObject = UnityEngine.GameObject.Find("Zombie" + ZombiePos.index.toString());
                //    gameObject.transform.position = new UnityEngine.Vector3(ZombiePos.x, ZombiePos.y, ZombiePos.z);
                //}
                for (let index = 0; index < this.ZombieNum; index++) {
                    let gameObject : UnityEngine.GameObject = UnityEngine.GameObject.Find("Zombie" + message[index].index.toString());
                    //let newVelocity : UnityEngine.Vector3 = new UnityEngine.Vector3(message[index].x - gameObject.transform.position.x, message[index].y - gameObject.transform.position.y, message[index].z - gameObject.transform.position.z);
                    //gameObject.GetComponent<UnityEngine.Rigidbody>().velocity = newVelocity;
                    gameObject.transform.position = UnityEngine.Vector3.MoveTowards(gameObject.transform.position, new UnityEngine.Vector3(message[index].x, message[index].y, message[index].z),1);
                    //gameObject.transform.Translate(new UnityEngine.Vector3(message[index].x, message[index].y, message[index].z));
                    //gameObject.transform.position = new UnityEngine.Vector3(message[index].x, message[index].y, message[index].z);
                    // UnityEngine.Vector3.MoveTowards();
                    //console.log(`first zombie pos : ${message[index].index} ${message[index].x}
                    //            ${message[index].y} ${message[index].z} `);
                }
            });

 

4. 멀티 플레이어에서 해줘야하는 예외 처리들

 

1) 다른 유저의 위치가 서버에 있는 그 사람의 위치랑 너무 많이 차이났을 때 서버 위치 값 로컬 위치 값 리셋 아래 코드 참고 ( OnUpdatePlayer 함수에 넣어줌 )

 

if (UnityEngine.Vector3.Distance(zepetoPlayer.character.transform.position, position) > 2) {
            zepetoPlayer.character.transform.position = position;
            zepetoPlayer.character.transform.rotation = UnityEngine.Quaternion.Euler(rotation.x, rotation.y, rotation.z);
        }

 

5. 위치 동기화 할 때 할 수 있는 방법

 

- 서버에서 시작 시간이랑 다른 사람 들어올 때 시간 받아서 차이값을 클라이언트에게 보내기

- 해당 시간 값을 가지고 플랫폼 또는 장애물의 이미 이동된 위치를 계산해서 옮겨주기

- 현 시간 받아올 수 있는 코드

 

let time = new Date();
startTime = time.getTime();
console.log(`startTime ${startTime}`)

 

시작 시간은 OnCreate 에 넣어줘야 하며 다른 사람 들어올 때 시간은 OnJoin 에 넣어줘야한다.

 

6. 변수 타입 출력하고 싶을 때

 

console.log(`${typeof zombieNum}`);

 

7. 그 밖에

 

- has 있는지 체크 / get 가져와주는 기능

- canvas sort order 로 캔버스 그려지는 순서 조정 가능

- raw image raycast target false 로 체크하면 ui interation 작동됨

- AddMessageHandler 받을 때 너무 많은 코드가 들어간 반복문을 집어넣으면 제대로 작동하지 않음 예를 들어 5번 돌면서 작동해야하는 거 1번 작동하거나 아예 안하거나

 

8. 오브젝트 스크립트 참조할 때

 

- ZombieController.Instance.Zombies[message.index].GetComponent<Zombie>().SetHp(message.hp); : 작동 안됨

ZombieController.GetInstance().ChangeHP(message.index-1, message.hp); : 작동됨

제페토 오류 때문에 유니티에서 되는 문법들이 안될 수 있음. 특히나 getcomponent 두 번 참고 같은 부분은 제페토 내에서 작동 안되기 때문에 참고해서 따로 함수를 만들어주거나 해야함

 

9. Navagent 사용 중에 아래와 같은 오류 발생 : "Stop" can only be called on an active agent that has been placed on a NavMesh.

 

 

this.pathFinder.isStopped = true; // 이 코드에서 해당 오류가 발생하는데 없애고
this.pathFinder.enabled = false; // 이 코드 써서 원하는 동작 해결 가능

 

10. 제페토 Client 에서 구할 수 있는 Id 종류들

 

 

위 중에서 많이 쓰이는 Id는

1) this.player.sessionId : 현재 씬에서 로컬 플레이어의 아이디

2) this.room.Sessionid : 해당 룸 아이디

3) this.zepetoPlayer.Charater.name : 해당 장면에서 로컬 플레이어의 캐릭터 이름

 

11. sever 로 받은 sessionId를 이용하여 캐릭터 호출할 때 주의점

 

SetReloadGesture(){
        this.room.Send("SetReloadGesture", this.player.sessionId);
    }

private * ReloadGesture(sessionId : string, tick:number){
	const zepetoPlayer = ZepetoPlayers.instance.GetPlayer(sessionId); // 작동안됨
    	const zepetoPlayer = ZepetoPlayers.instance.GetPlayer(sessionId.toString()); // 작동됨
        // 해당 플레이어의 애니메이션 실행 코드
        zepetoPlayer.character.Context.GetComponent<UnityEngine.Animator>().SetBool("isReload", true);
  }

 

sessionId를 string으로 읽어들었기 때문에 실제로 작동되어야 하지만(로그 찍었을 때도 잘 나온다) 오류가 난다. 이상하게도 다시 한 번 toString()을 안 붙여주면 같은 string임에도 player를 못 찾아온다.

 

12. 제페토 내에서 코루틴 사용하기

 

// 호출하고 싶은 위치에 넣기
this.StartCoroutine(this.ReloadGesture(message, 2));

private * ReloadGesture(sessionId : string, tick:number){
        yield new UnityEngine.WaitForSeconds(tick);
}

 

13. TypeError: Cannot read property 'push' of null 오류

 

분명 이론상 잘 들어가서 작동해야하는데 안되는 부분에서 저런 오류가 떳다. 형식도 체크했는데 안되서 30분 넘게 붙잡고 있었는데 알고보니 씬 안에 들어가는 스크립트 뿐만 아닌 모든 스크립트에서의 이름이 겹치면 안되는 것 같다. 예를 들어 Zombie 라는 GameObject 형식의 배열을 만들고 다른 스크립트에 Zombie 라는 number 배열을 만들어서 push 하면 스크립트 상에서 어떤 것을 지칭하는지 헷갈려서 되었다가 안되고 위의 오류나던가 둘 중에 하나 일어나는 것 같다. 다음부터 스크립트 작성할 때는 같은 변수여도 이름은 스크립트 별로 다 다르게 지정해야할 것 같다.

 

반응형

댓글