위키북스 출판사 이재현 저자님의 '절대강좌! 유니티' 책을 참고하여 필기한 내용입니다.트
특정 레어 간의 충돌 감지
지금까지 동작들이 문제 업어보이지만 몬스터는 추적하는 동안에도 충돌 이벤트가 발생하는 것을 확인할 수 있음
물리 엔진 설정은 레이어로 판단하기 때문에 각 Collider 를 서로 다른 레이어로 지정해야 함
Layer 에 MONSTER_BODY, MONSTER_PUNCH 를 추가해준다.
Monster 오브젝트에 Layer를 MonsterBody로 설정하는데 이때 무조건 No the object only로 선택해야된다.
이때 몬스터 손인 wrist 를 찾아서 둘의 레이어를 MONSTER_PUNCH로 변경한다.
Project Settings 에 들어가서 서로 물리적인 충돌을 처리하지 않는다
Layer Collision Matrix 설정은 아군의 레이어와 적군의 레이어를 서로 분리해 적용하고 Layer Collision Matrix에서 서로 충돌하지 않게 언체크하면 물리 엔진의 부하도 줄일 수 있고 로직도 간결하게 구현할 수 있다.
본 구조의 최적화
3D 모델이 가진 많은 Transform 컴포넌트의 이동 및 회전 처리는 런타임 시 내부적으로 다양한 연산을 처리하므로 최적화 필요
***실제 게임에서 사용되는 관절만 남겨두고 다른 것은 노출되지 않게 설정, 하이러키 뷰를 간결하게 유지
Monster모델에서 Rig - Optimize Game Object 체크하고 사용하는 관절 두개만 체크한다.
딱 필요한 부분만 하이러키 뷰에서 노출된다
**Optimize Game Object 작업 시점
본 구조를 최적화 하는 Optimaize Game Object 옵션은 반드시 프리팹으로 전환하기 전에 작업해야된다. 예제의 몬스터는 아직 프리팹으로 전환하지 않아서 원본 Monster 모델을 선택하여 본 구조를 최적화할 수 있었다
몬스터 공격 중지
씬 슈에 있는 특정 게임 오브젝트에 접근하기 위한 여러 방법 중 Tag를 사용하여 접근
Monster 오브젝트에 MONSTER라는 이름의 태그를 설정
void PlayerDie()
{
Debug.Log("Player Die !");
// MONSTER 태그를 가진 모든 게임오브젝트를 찾아옴
GameObject[] monsters = GameObject.FindGameObjectsWithTag("MONSTER");
// 모든 몬스터의 OnPlayerDie 함수를 순차적으로 호출
foreach(GameObject monster in monsters)
{
monster.SendMessage("OnPlayerDie", SendMessageOptions.DontRequireReceiver);
}
}
PlayerCtrl 스크립트의 PlayerDie 함수를 위와 같이 수정
첫번째 인자는 전달한 함수명과 동일한 함수가 해당 게임오브젝트의 스크립트에 있다면 실행하라는 명령
두번째 인자를 SendMessageOptions.DontRequireReceiver 로 설정하면호출한 함수가 없더라도 함수가 없다는 메세지를 받지 않겠다는 옵션, 빠른 실행을 위한 옵션 사용
제대로 동작하기 위해서는 MonsterCtrl 스크립트에 아래와 같은 함수 추가
using System.Collections;
using UnityEngine;
using UnityEngine.AI; // 내비게이션 기능을 사용하기 위해 추가해야 하는 네임 스페이스
public class MonsterCtrl : MonoBehaviour
{
...생략
private readonly int hashTrace = Animator.StringToHash("IsTrace");
private readonly int hashAttack = Animator.StringToHash("IsAttack");
private readonly int hashHit = Animator.StringToHash("Hit");
private readonly int hashPlayerDie = Animator.StringToHash("PlayerDie");
// 혈흔 효과 프리팹
private GameObject bloodEffect;
private void Start()
{
...생략
}
// 일정한 간격을 몬스터의 행동 상태를 체크
IEnumerator CheckMonsterState()
{
..생략
}
IEnumerator MonstorAction()
{
...생략
}
private void OnCollisionEnter(Collision coll)
{
...생략
}
void ShowBloodEffect(Vector3 pos, Quaternion rot)
{
...생략
}
void OnPlayerDie()
{
// 몬스터의 상태를 체크하는 코루틴 함수를 모두 정지시킴
StopAllCoroutines();
// 추적을 정지하고 애니메이션을 수행
agent.isStopped = true;
anim.SetTrigger(hashPlayerDie);
}
private void OnDrawGizmos()
{
...생략
}
}
이전에 받은 GangnamStyle을 드래그 해서 몬스터의 애니메이터로 옮긴다.
이제 몬스터를 여러마리 복사하기 위해 지금까지 만들었던 하이러키뷰의 Monster를 프리팹으로 만든다.
애니메이션의 재생 속도 조절
몬스터가 동시에 춤을 시작해서 조금 어색한 느낌이 든다
몬스터의 춤추는 동작을 조금씩 다르게 설정해보기
Speed 라는 이름의 Float 타입의 파라미터를 추가하고
Gangnam Style의 애니메이션에 Multiplier를 활성하 한다.
아래와 같이 애니메이션의 파라미터 Speed를 랜점으로 지정하여 애니메이션의 재생속도를 달리한다.
using System.Collections;
using UnityEngine;
using UnityEngine.AI; // 내비게이션 기능을 사용하기 위해 추가해야 하는 네임 스페이스
public class MonsterCtrl : MonoBehaviour
{
...생략
private readonly int hashTrace = Animator.StringToHash("IsTrace");
private readonly int hashAttack = Animator.StringToHash("IsAttack");
private readonly int hashHit = Animator.StringToHash("Hit");
private readonly int hashPlayerDie = Animator.StringToHash("PlayerDie");
private readonly int hashSpeed = Animator.StringToHash("Speed");
void OnPlayerDie()
{
// 몬스터의 상태를 체크하는 코루틴 함수를 모두 정지시킴
StopAllCoroutines();
// 추적을 정지하고 애니메이션을 수행
agent.isStopped = true;
anim.SetFloat(hashSpeed, Random.Range(0.8f, 1.2f));
anim.SetTrigger(hashPlayerDie);
}
}
'Unity 강의 > Unity Course(2) - 절대강좌! 유니티' 카테고리의 다른 글
[Unity Course 2] 07. 유니티 UI 시스템 1 (0) | 2024.06.22 |
---|---|
[Unity Course 2] 06. 적 캐릭터 제작 6 (0) | 2024.06.22 |
[Unity Course 2] 06. 적 캐릭터 제작 4 (0) | 2024.06.21 |
[Unity Course 2] 06. 적 캐릭터 제작 3 (0) | 2024.06.21 |
[Unity Course 2] 06. 적 캐릭터 제작 2 (0) | 2024.06.21 |