Unity/게임 엔진 응용 프로그래밍

[Unity 3D] MiniRPG : 캐릭터 생성과 이동 연결하기

치명적흑형 2021. 10. 19. 15:50

버튼을 누르면 히어로가 생성되는 스크립트

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;   //버튼 UI사용하기 위한 네임스페이스

public class TestCreateHero : MonoBehaviour
{
    private GameObject modelPrefab;

    //버튼 어싸인
    public Button btnCreateHero;


    void Start()
    {
        this.modelPrefab = Resources.Load<GameObject>("Prefabs/ch_01_01");

        this.btnCreateHero.onClick.AddListener(() => {
            var go = new GameObject();
            go.name = "Hero";
            var modelgo = Instantiate<GameObject>(this.modelPrefab, go.transform);
            modelgo.name = "model";
            //히어로 오브젝트에 히어로 스크립트 추가
            var hero = go.AddComponent<Hero>();
            //히어로 오브젝트의 초기화
            hero.Init();
        });
    }
}

 

히어로 스크립트

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Hero : MonoBehaviour
{
    public float moveSpeed;
    private Coroutine moveRoutine;
    public GameObject model;
    private Animation anim;

    public float hp;
    public float maxHp;
    public float damage;

    public void Start()
    {
        Debug.Log("start");
        //자식으로 찾기
        this.model = this.transform.GetChild(0).gameObject;

        //확인용
        Debug.LogFormat("->{0}", this.model);
        this.anim = this.model.GetComponent<Animation>();
    }

    //초기화 메서드 
    public void Init()
    {
        Debug.Log("init");
        this.moveSpeed = 1;
        this.hp = 100;
        this.maxHp = 100;
        this.damage = 10;

        GameObject.Find("InputTestMain").GetComponent<InputTestMain>().hero = GetComponent<Hero>();
    }

    public void Move(Vector3 tpos)
    {
        this.transform.LookAt(tpos);

        if (this.moveRoutine != null)
        {
            StopCoroutine(this.moveRoutine);
        }
        this.moveRoutine = StartCoroutine(this.MoveImpl(tpos));

    }
    private IEnumerator MoveImpl(Vector3 tpos)
    {
        this.anim.Play("run@loop");
        while (true)
        {
            this.transform.Translate(Vector3.forward * this.moveSpeed * Time.deltaTime);
            float distance = Vector3.Distance(tpos, this.transform.position);
            if (distance <= 0.1f)
            {
                break;
            }

            yield return null;
        }
        this.anim.Stop("run@loop");
        this.anim.Play("idle@loop");
    }
}
InputTestMain의 hero에  Hero스크립트를 할당

GameObject.Find("InputTestMain").GetComponent<InputTestMain>().hero = GetComponent<Hero>();

 

메인스크립트

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class InputTestMain : MonoBehaviour
{
    public Transform point;
    public Hero hero;

    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;
            if (Physics.Raycast(ray, out hit, 1000))
            {
                //Debug.Log(hit.point);
                var tpos = new Vector3(hit.point.x, 0, hit.point.z);
                this.point.position = hit.point;
                this.hero.Move(tpos);
            }
            Debug.DrawRay(ray.origin, ray.direction * 1000f, Color.red, 1f);
        }
    }
}

 


Hero생성시에 InputTestMain에 Hero스크립트를 할당하는데

InputTestMain의 Update에서 this.hero.Move()를 계속 호출하기 때문에 문제 발생


해결

명확한 해결은 아닐지 모르지만

if (hero != null) 구문을 추가해줌.

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class InputTestMain : MonoBehaviour
{
    public Transform point;
    public Hero hero;

    void Update()
    {
        if (hero != null)
        {
            if (Input.GetMouseButtonDown(0))
            {
                Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
                RaycastHit hit;
                if (Physics.Raycast(ray, out hit, 1000))
                {
                    //Debug.Log(hit.point);
                    var tpos = new Vector3(hit.point.x, 0, hit.point.z);
                    this.point.position = hit.point;
                    this.hero.Move(tpos);
                }
                Debug.DrawRay(ray.origin, ray.direction * 1000f, Color.red, 1f);
            }
        }
    }
}