EasyCastleUNITY

간단 RPG Test3 (완전한 장착) 2023/08/10 11:19pm 작성 본문

유니티 기초

간단 RPG Test3 (완전한 장착) 2023/08/10 11:19pm 작성

EasyCastleT 2023. 8. 10. 23:28

앞에 포스팅인 불완전한 장착에서 HeroController의 GetItem부분을 고쳐 완전하게 장비를 장착하도록 했다. 

using System.Collections;
using System.Collections.Generic;
using Test;
using UnityEngine;
using static Test3.GameEnums;

namespace Test3
{
    public class HeroController : MonoBehaviour
    {
        private Vector3 targetPosition; //타겟이 되는 위치
        private Coroutine moveRoutine;  //전에 실행하던 코루틴을 저장하는 변수
        private Animator anim; //Hero의 Animator
        [SerializeField]
        ItemGenerator itemGenerator;
        [SerializeField]
        public float radius = 1.0f; //Hero 사거리 
        private MonsterController target; //target이 된 몬스터의 MonsterController 컴포넌트
        private int index = 0;
        private List<ItemController> getItems;
        // Start is called before the first frame update
        void Start()
        {
            this.getItems = new List<ItemController>();
            this.anim = this.GetComponent<Animator>();
            GameObject main = GameObject.Find("ItemGenerator");
            this.itemGenerator = main.GetComponent<ItemGenerator>();
        }

        public void Move(MonsterController target)
        {
            this.target = target;
            this.targetPosition = this.target.gameObject.transform.position;
            this.anim.SetInteger("State", 1);
            if (this.moveRoutine != null)
            {
                //이미 코루틴이 실행중이다 -> 중지 
                this.StopCoroutine(this.moveRoutine);
            }
            this.moveRoutine = this.StartCoroutine(this.CoMove());
        }

        public void Move(Vector3 targetPosition)
        {
            //타겟을 지움
            this.target = null;
            //이동할 목표 지점을 저장
            this.targetPosition = targetPosition;
            Debug.Log("Move");

            //이동 애니메이션 실행
            this.anim.SetInteger("State", 1);

            if (this.moveRoutine != null)
            {
                //이미 코루틴이 실행중이다 -> 중지
                this.StopCoroutine(this.moveRoutine);
            }
            this.moveRoutine = StartCoroutine(this.CoMove());

        }

        private IEnumerator CoMove()
        {
            while (true)
            //무한 반복이 되어 유니티가 멈출 수도 있음
            //그러므로 yield return 필수
            {
                Vector3 pos = new Vector3(targetPosition.x, 0, targetPosition.z);
                //방향을 바라봄
                this.transform.LookAt(pos);
                //이미 바라봤으니깐 정면으로 이동 (relateTo: Self/지역좌표)
                //방향 * 속도 * 시간 
                this.transform.Translate(Vector3.forward * 2f * Time.deltaTime);
                //목표지점과 나 사이의 거리를 계산, 즉 1프레임 마다 거리를 계산 
                float distance = Vector3.Distance(this.transform.position, this.targetPosition);
                //타겟이 있을 경우
                if (this.target != null)
                {
                    if (distance <= (1f + 1f))
                    {
                        break;
                    }
                }
                else
                {
                    if (distance <= 0.1f)
                    {
                        //도착
                        break;
                    }
                }
                yield return null; //다음 프레임 시작
            }
            Debug.Log("<color=yellow>도착!</color>");
            this.anim.SetInteger("State", 0);
        }

        private void OnDrawGizmos()
        {
            GizmosExtensions.DrawWireArc(this.transform.position, this.transform.forward, 360, 1, 40);
        }

        private void OnTriggerEnter(Collider other)
        {
            if(other.gameObject.tag == "Item")
            {
                this.GetItem(other);
            }
        }

        private void GetItem(Collider other)
        {
            GameEnums.eItemType itemType = other.gameObject.GetComponent<ItemController>().ItemType;
            this.getItems.Add(other.GetComponent<ItemController>());
            Debug.LogFormat("<color=lime>{0}을 획득</color>" ,other.gameObject.name);

            if (itemType == GameEnums.eItemType.Sword)
            {
                //Transform rootChild = this.gameObject.transform.Find("root");
                //Transform pelvisChild = rootChild.Find("pelvis");
                Transform weaponChild = GameObject.Find("Weapon").transform;
                Vector3 weaponPos = weaponChild.GetChild(0).gameObject.transform.position;
                Destroy(weaponChild.GetChild(0).gameObject); //전에 장착하고 있던 검 삭제
                other.gameObject.transform.position = Vector3.zero; //위치 초기화
                other.gameObject.transform.SetParent(weaponChild, false);
                Destroy(other.gameObject.GetComponent<BoxCollider>());
            }
            else if (itemType == GameEnums.eItemType.Shield)
            {
                //Transform rootChild = this.gameObject.transform.Find("root");
                //Transform pelvisChild = rootChild.Find("pelvis");
                Transform shieldChild = GameObject.Find("Shield").transform;
                Vector3 shieldPos = shieldChild.GetChild(0).gameObject.transform.position;
                Destroy(shieldChild.GetChild(0).gameObject); //전에 장착하고 있던 방패 삭제
                other.gameObject.transform.position = Vector3.zero; //위치 초기화
                other.gameObject.transform.SetParent(shieldChild, false);
                Destroy(other.gameObject.GetComponent<BoxCollider>());
            }
            //other.gameObject.transform.SetParent(this.transform);
            Debug.LogFormat("getItemList: {0}", getItems[index].name);
            index++;
        }
        // Update is called once per frame

    }
}

아이템 습득을 위해 영웅의 Rigidbody를 부여하였는데, 이것이 문제가 된 것인지 

가끔 부자연스러운 움직임을 취할 때가 있다. (tag의 문제일수도?)

내가 만든 장착 시스템은 생성된 드롭아이템을 그대로 영웅의 자식으로 만들어 사용하는 방법이다.

이 점이 문제가 되어, 생성되었을 때 당시에 좌표값을 그대로 가지고 있는 상태로 영웅의 자식으로 들어가게 되었다.

 

그 결과가 이전의 포스팅인 영웅의 주변에 둥둥 떠다니는 아이템이 되게 된것이다. 

그래서 이번에는 자식으로 들어가기 전에 (0,0,0)으로 초기화를 한 상태로 들어가게 하여, 

이 문제를 해결하였다. 

'유니티 기초' 카테고리의 다른 글

간단 RPG 보스 씬 Test  (0) 2023.08.14
간단 RPG  (0) 2023.08.11
간단 RPG Test3 (불완전한 장착)  (0) 2023.08.10
간단 RPG Test 3-1  (0) 2023.08.10
간단 RPG Game Main (몬스터가 전부 죽으면, 포탈 생성)  (1) 2023.08.09