Unity/과제

2020-05-08 과제 [병맛달리기]

J월드 2020. 5. 9. 23:14

과제내용

-------------------------------------------------------------------------------------------------------------------------

더보기

 

 

달리기 시작 버튼은 비활성화 

생성버튼은 활성화 

생성 버튼을 누르면 케릭이 생성된다.

생성된 유닛과의 간격은 1 유닛이다.

케릭의 이름과 속도가 설정된다.

이름을 생성 최대 갯수에 마추어 준비 된다.

속도는 0.5~ 1.5까지의 난수다

최대 생성 갯수는 제한적이다.

모든 케릭이 생성되었다면 생성버튼은 비활성화 되고 달리기 시작 버튼이 활성화 된다.

달리기 시작 버튼을 누르면 생성된 모든 케릭은 목표 지점까지 달린다.

모든 케릭들이 목표 지점에 도착 했다면 등수와 이름과 걸린시간을 출력한다.

1등은 tumbling 하고 2,3등은 idle하고 을 나머지 케릭들은 die애니메이션을 실행한다.

 

ex) 소수점은 두자까지 단, 0은 제외해도 됨 

1등 : 홍길동 (0.5초)

2등 : 임꺽정 (0.67초)

3등 : 둘리 (0.83초)

4등 : 또치 (1.05초)

5등 : 고길동 (1.67초)

 

 

 

 

결과 보기 버튼 활성화 

단상위에 2등 - 1등 - 3등 케릭터를 동적으로 생성

단상은 고정으로 있어도 됨 

카메라는 단상앞에 위치 

-------------------------------------------------------------------------------------------------------------------------

과제 플레이 영상

 

 

-------------------------------------------------------------------------------------------------------------------------

 

App.Class

더보기
using System;
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
 
public class App : MonoBehaviour
{
    public enum eModel
    {
        ch_01_01,
        ch_02_01,
        ch_03_01,
        ch_04_01,
        ch_05_01
    }
 
 
    const string MODELPATH = "Prefabs/ch_01_01";
    const string HEROPATH = "Prefabs/Hero";
    const string WINNERCUBEPATH = "Prefabs/WinnerCube";
    const string EFFECTPATH = "Prefabs/Effect";
    const string MONSTERPATH = "Prefabs/StoneMonster";
 
    public Button btn_Create;       //생성버튼
    public Button btn_Run;          //달리기버튼
    public Button btn_ResultView;   //결과보기버튼
    public int limitNumber;         //생성 제한 숫자
    public float goalZ;                //목표지점 z좌표
 
    private List<Hero> heroList;    //히어로 관리 리스트
    private List<Hero> winnerList;
 
    private int offsetX;            //초기위치X좌표
    private bool isMoved;           //움직이는지 아닌지 확인
    private bool isEndRace;         //레이스 끝났는지 확인
    private bool isResult;          //결과보기 버튼눌렀는지 확인
 
 
    private void Start()
    {
        this.btn_Run.gameObject.SetActive(false);           //달리기 버튼 비활성화
        this.btn_ResultView.gameObject.SetActive(false);    //결과보기 버튼 비활성화
 
        this.heroList = new List<Hero>();
        this.winnerList = new List<Hero>();
 
        //생성 버튼을 클릭했을때
        this.btn_Create.onClick.AddListener(() =>
        {
            //랜덤으로 0~4까지 숫자를 가져와서 해당하는 enum값으로 명시적 형변환
            eModel randomModel = (eModel)UnityEngine.Random.Range(05);
            var initPos = new Vector3(this.offsetX++00);
            var hero = this.CreateHero(randomModel);
            hero.Init(initPos);
            this.heroList.Add(hero);
 
 
            int nameNumber = 1;
            for (int i = 0; i < this.heroList.Count - 1; i++)         //이름중복 예외처리
            {
                for (int j = i + 1; j < this.heroList.Count; j++)
                {
                    if (this.heroList[i].heroname == this.heroList[j].heroname)
                    {
                        this.heroList[j].heroname = string.Format("{0}({1})"this.heroList[j].heroname, nameNumber);
                    }
                }
            }
 
        });
 
        //달리기 버튼을 클릭했을때
        this.btn_Run.onClick.AddListener(() =>
        {
            this.isMoved = true;
        });
 
        //결과보기 버튼을 클릭했을때
        this.btn_ResultView.onClick.AddListener(() =>
        {
            this.finalResult();
            this.isResult = true;
        });
    }
 
    private void Run()  //달리기
    {
        for (int inx = 0; inx < this.heroList.Count; inx++)
        {
            // 이렇게 하면 transform child out of bounds 에러, transform.GetChild(index)에서 Hero의 Child 하나 뿐인데 하나 이상의값을 불러오려고해서
            //this.heroList[inx].Run(inx);  
            this.heroList[inx].Run(0);
        }
    }
 
    private void Stop() //멈추기 아이들모션
    {
        for (int inx = 0; inx < this.heroList.Count; inx++)
        {
            this.heroList[inx].Idle(0);
        }
        this.isMoved = false;
    }
 
 
    public Hero CreateHero(eModel modelNumber)  //매개변수 모델넘버를 받습니다.
    {
        string fullpath = string.Format("Prefabs/{0}", modelNumber.ToString()); //받은 모델 넘버로 위치저장 
 
        var modelPrefab = Resources.Load<GameObject>(fullpath);         //path 위치에 해당하는 리소스의 프리팹을 가져옴
        var modelGo = Instantiate(modelPrefab) as GameObject;           //Hierarchy에 인스턴스화한다.
        var heroPrefab = Resources.Load<GameObject>(HEROPATH);          //path 위치에 해당하는 리소스의 프리팹을 가져옴
        var heroGo = Instantiate(heroPrefab) as GameObject;             //Hierarchy에 인스턴스화한다.
 
        Hero hero = heroGo.AddComponent<Hero>();                         //hero 클래스 ... 컴포넌트?? 뭐야이게
        var dummyRHand = heroGo.AddComponent<Hero>().dummyRHand;
 
        modelGo.transform.SetParent(hero.transform);
 
        return hero;
    }
 
 
 
 
 
    public void finalResult()
    {
        //버튼 비활성화
        this.btn_Create.gameObject.SetActive(false);
        this.btn_Run.gameObject.SetActive(false);
        this.btn_ResultView.gameObject.SetActive(false);
 
        //히어로 오브젝트 비활성화
        for (int inx = 0; inx < this.heroList.Count; inx++)
        {
            this.heroList[inx].gameObject.SetActive(false);
        }
 
        var winnerCubePrefab = Resources.Load<GameObject>(WINNERCUBEPATH);
        var winnerCubeGo = Instantiate(winnerCubePrefab) as GameObject;
 
        var effectPrefab = Resources.Load<GameObject>(EFFECTPATH);
        var effectGo = Instantiate(effectPrefab) as GameObject;
 
        winnerCubeGo.transform.position = new Vector3(3f, 1.5f, 3f);
        effectGo.transform.position = new Vector3(2f, 0f, 4f);
 
        for (int inx = 0; inx < 3; inx++)
        {
            this.winnerList[inx].gameObject.SetActive(true);
        }
 
        this.winnerList[0].transform.position = new Vector3(3f, 2.7f, 3.75f);
        this.winnerList[0].transform.rotation = Quaternion.Euler(0900);
 
        this.winnerList[1].transform.position = new Vector3(3f, 1.5f, 4.7f);
        this.winnerList[1].transform.rotation = Quaternion.Euler(0900);
 
        this.winnerList[2].transform.position = new Vector3(3f, 0.8f, 2.7f);
        this.winnerList[2].transform.rotation = Quaternion.Euler(0900);
 
    }
 
    private void Update()
    {
 
        if (this.heroList.Count == limitNumber)     //생성 히어로가 제한 숫자를 넘었을때.
        {
            this.btn_Create.gameObject.SetActive(false);
            this.btn_Run.gameObject.SetActive(true);
 
 
            if (this.isMoved)
            {
                this.btn_Run.gameObject.SetActive(false);
 
                this.Run();
 
                var moveDir = new Vector3(001);
 
                for (int inx = 0; inx < this.heroList.Count; inx++)
                {
                    var displacement = moveDir * this.heroList[inx].speed * Time.deltaTime;     //히어로 각각의 스피드를 적용시킴.
                    this.heroList[inx].transform.Translate(displacement);                       //적용시킨 스피드로 1유닛씩 이동
 
                    if (this.heroList[inx].transform.position.z >= this.goalZ)   //Z좌표값이 골과 같거나 크면.
                    {
                        this.isEndRace = true;     //레이스 끝남
 
                        if (this.isEndRace)
                        {
                            this.Stop();        //아이들 루프 실행
 
 
                            List<float> arrDistance = new List<float>();
 
                            foreach (var hero in this.heroList)
                            {
                                arrDistance.Add(this.goalZ - hero.transform.position.z);
                            }
 
                            arrDistance.Sort(); // 오름차순으로 정렬
 
                            for (int i = 0; i < this.heroList.Count; i++)
                            {
                                for (int j = 0; j < arrDistance.Count; j++)
                                {
                                    if (arrDistance[i] == this.goalZ - this.heroList[j].transform.position.z)
                                    {
                                        this.winnerList.Add(this.heroList[j]);
                                    }
                                }
                            }
                            int dd = 1;
 
                            foreach (var hero in this.winnerList)
                            {
                                Debug.LogFormat("{0}위 : {1}", dd++, hero.heroname);
                            }
 
                            for (int i = 0; i < this.winnerList.Count; i++)
                            {
                                this.winnerList[i].Tumbling(0);
 
                                if (i >= 3)
                                {
                                    this.winnerList[i].Die(0);
                                }
                            }
                            this.btn_ResultView.gameObject.SetActive(true);         //레이스 끝나면 결과보기 보여주기.
                            this.isMoved = false;   //달리기 조건식을 빠져나오기 위해.
                        }
                    }
                }
            }
        }
    }
 
}
 
 
 

 

 

Hero.Class

 

더보기
using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using UnityEngine;
 
public class Hero : MonoBehaviour
{
    public enum eName { 
        Dog,Monkey,Bird,Rabbit,Cat,   
    }
    private Animation anim;
    public float speed;
    public string heroname;
 
    public Transform dummyRHand;
 
    public void Init(Vector3 initPos)
    {
        this.transform.position = initPos;
        this.speed = UnityEngine.Random.Range(1f, 3f);
        var rnd = UnityEngine.Random.Range(05);
        this.heroname = ((eName)rnd).ToString();
    }
 
    public void Run(int index)
    {
        anim = this.transform.GetChild(index).GetComponent<Animation>();
        anim.Play("run@loop");
    }
 
    public void Idle(int index)
    {
        anim = this.transform.GetChild(index).GetComponent<Animation>();
        anim.Play("idle@loop");
    }
 
    public void Die(int index)
    {
        anim = this.transform.GetChild(index).GetComponent<Animation>();
        anim.Play("die");
    }
 
    public void Tumbling(int index)
    {
        anim = this.transform.GetChild(index).GetComponent<Animation>();
        anim.Play("tumbling");
    }
 
 
    private void Start()
    {
 
    }
 
    private void Update()
    {
 
    }
 
}
 
 
 

 

 

참고

더보기