인프런 강의 - 케이디 생존게임
케이디 강의15 - (나무 파괴, 효과음, 이펙트, 오브젝트 변형)
WMG1
2022. 11. 16. 22:15
반응형
public class TreeComponent : MonoBehaviour
{
//깎일 나무조각들
[SerializeField]
private GameObject[] go_treePieces;
//나무의 경우 HP가 아닌 나무 조각으로 파괴 여부를 판단할것임
[SerializeField]
private GameObject go_TreeCenter; // 나무 중심부
//통나무(나무 본체파괴 결과물)
[SerializeField]
private GameObject go_Log_Prefabs;
//쓰러질 때 랜덤으로 가해질 힘의 양
[SerializeField]
private float force;
//자식 트리
[SerializeField]
private GameObject go_ChildTree;
//부모객체 콜라이더(파괴 시 비활성화)
[SerializeField]
private CapsuleCollider parent_col;
//##쓰러질 때 필요한 자식요소##
//자식객체 콜라이더(파괴 시 활성화)
[SerializeField]
private CapsuleCollider child_col;
//자식트리 리지드바디(파괴 시 중력 활성화)
[SerializeField]
private Rigidbody childRigid;
//파편 이펙트
[SerializeField]
private GameObject go_hit_effect_prefab;
//파편 삭제 시간
[SerializeField]
private float debrisDestroyTime;
//나무 삭제 시간
[SerializeField]
private float destroyTime;
//##사운드##
//나무 타격사운드
[SerializeField]
private string chop_sound;
//나무 쓰러지는 사운드
[SerializeField]
private string falldown_sound;
//쓰러진 나무 통나무로 바뀌는 사운드
[SerializeField]
private string logChange_sound;
//serializeField로 요소들을 전부 얻어오므로
//Start 함수에서 초기화시킬 필요가 없어짐
public void Chop(Vector3 _pos, float angleY) //도끼랑 충돌한 지점의 위치를 알기위해 (힘을받은 지점,플레이어 위치)
{
Hit(_pos);
AngleCalc(angleY);
if (CheckTreePieces()) //피스들이 남았는지 조건분기 만들어주기
return; //트루면 바로 끝내기
FallDownTree();
}
//적중 이펙트
private void Hit(Vector3 _pos)
{
SoundManager.instance.PlaySE(chop_sound); //나무 피격사운드 재생
GameObject clone = Instantiate(go_hit_effect_prefab, _pos, Quaternion.Euler(Vector3.zero));
Destroy(clone, debrisDestroyTime);
//생성 할 오브젝트,위치,회전값 ((나무 타격 이펙트)
//Quaternion.Euler(Vector3.zero) 는 Quaternion.identity와 거의 동일함 (0,0,0) 기본값과 000의 차이
}
//맞은 각도에 따라 함수 호출함
private void AngleCalc(float _angleY)
{
Debug.Log(_angleY);
//각도에 따른 피스 파괴 함수호출
if (0 <= _angleY && _angleY <= 70)
DestroyPiece(2);
else if (70 <= _angleY && _angleY <= 140)
DestroyPiece(3);
else if (140 <= _angleY && _angleY <= 210)
DestroyPiece(4);
else if (210 <= _angleY && _angleY <= 280)
DestroyPiece(0);
else if (280 <= _angleY && _angleY <= 360)
DestroyPiece(1);
}
//파편 직접 파괴함수
private void DestroyPiece(int _num) //넘어오는 인수 num(피스번호)
{
if(go_treePieces[_num].gameObject !=null) //피스가 있을때만 파괴함수 실행하게 조건달기
{
GameObject clone = Instantiate(go_hit_effect_prefab, transform.position, Quaternion.Euler(Vector3.zero));
Destroy(clone, debrisDestroyTime);
//기존 위치에도 파편 프리팹을 생성함(해당 위치 타격시 타격이펙트 두배로 생성)
Destroy(go_treePieces[_num].gameObject); //피스번호에 따라 파괴
}
}
private bool CheckTreePieces()
{
for (int i = 0; i < go_treePieces.Length; i++) //피스조각 배열만큼 반복
{
if(go_treePieces[i].gameObject != null) // 피스가 남아있는지 체크
{
return true; //있으면 다른 함수들 계속 실행하기
}
}
return false; //조각 없으면 함수 실행못하게 하기
}
private void FallDownTree()
{
SoundManager.instance.PlaySE(falldown_sound); //쓰러지는 사운드
Destroy(go_TreeCenter); //나무 중심부 파괴
parent_col.enabled = false; //부모 콜라이더 비활성화
child_col.enabled = true; //자식 콜라이더 활성화
childRigid.useGravity = true; //자식 리지드 중력 활성화
childRigid.AddForce(Random.Range(-force, force), 0f, Random.Range(-force, force));
//리지드바디에 힘 가하기 ==> 변수 force 만큼 x,z에 랜덤값 부여
StartCoroutine(LogCoroutine());
}
IEnumerator LogCoroutine()
{
yield return new WaitForSeconds(destroyTime); //나무 본체 삭제 시간만큼 대기
SoundManager.instance.PlaySE(logChange_sound); // 통나무로 바뀌는 효과음
//회전값 바라보는 위치(자식 나무오브젝트의 y값==축값)
Instantiate(go_Log_Prefabs, transform.position + (go_ChildTree.transform.up * 3f), Quaternion.LookRotation(go_ChildTree.transform.up));
Instantiate(go_Log_Prefabs, transform.position + (go_ChildTree.transform.up * 6f) , Quaternion.LookRotation(go_ChildTree.transform.up));
Instantiate(go_Log_Prefabs, transform.position + (go_ChildTree.transform.up * 9f) , Quaternion.LookRotation(go_ChildTree.transform.up));
Destroy(go_ChildTree.gameObject);
}
}
이전 오브젝트 파괴들과 비슷한 맥락으로 진행되었다.
새로운 내용 없음
반응형