유니티 챌린지/서브프로젝트

0429 _ 서브프로젝트 R&D 캐릭터 조이스틱으로 움직이기

minquu 2021. 4. 29. 16:21
반응형

0. 조이스틱을 움직이면 들어오는 값을 찾고,

그 값을 이용한다.

 

 

먼저 캐릭터가 움직이게 한다 ..

 

 

 

 

 

1. 보는 쪽으로 각도를 바꾸게한다.

키워드 위주로 검색해서 찾았다 .

 

 

 

 

참고 영상

(2) THIRD PERSON MOVEMENT in Unity - YouTube

 

 

 

 

2. 돌리고 나서, 캐릭터의 방향(forward)으로 움직이게 한다.

 

 

 

 

돌리고나서, 앞 방향으로 움직이게함

 

 

 

3. 움직임 애니메이션 넣기

 

 

 

 

 

4. 버튼 클릭시 공격하기 

 

 

 

isAttack  부울값으로 하나 만들어준다. 그래서 공격 중 일때는 true로 만들어서

걷기나 기본 애니메이션이 나오지 않게 해준다.

그리고 애니메이션이 끝나는 시간을 코루틴에서 WaitForSeconds 써서 지연시켜주고, 

부울 값을 false 로 다시 바꿔준다.

 

 

 

 

 

 

--------

 

캐릭터 주변으로 원을 만들어서, 그 안에 몬스터가 있고, 공격을 누르면 몬스터에게 데미지가 들어가는 걸 만들어보자

 

1. 먼저 OverlapSphere 를 써서 캐릭터에게 범위를 지정해주자.

 

 

 Collider[] hit = Physics.OverlapSphere(transform.position, size, whatIsLayer);

(원을 그릴 센터 포지션, 크기 사이즈 , 레이어마스크(비교할것)) 이 오버라이딩 된다.

 

hit가 배열로 (여러가지있을 때) 반환이 된다. 

 

 

 private void OnDrawGizmos()
    {
        Gizmos.color = Color.red;
        Gizmos.DrawWireSphere(transform.position, size);
    }

 

캐릭터 주변에 스피어를 그려줘서 범위를 확인해 준다.

 

 

 

 

 

2. 원 안에 hit된 오브젝트가  "monster" tag를 가지고 있다면, 로그가 나오게 테스트합니다.

 

 

 

 

 

원 안에서 공격을 하고, 만약 원 안에 대상이 monster면 공격 로그가 뜨게합니다.

 

 

3. 공격하는 순간 공격한 대상을 바라보게 한다.

 

 

 

this.transform.LookAt(hit[i].transform);

LookAt 코드를 사용하여서, 현재 오브젝트의 트랜스폼. 룩엣 (타겟) 으로 지정해준다.

 

 

 

 

4. 공격할때 몬스터의 체력이 닳게하고, 체력이 0일때 데스 애니메이션을 하게하고 사라지게 한다.

히어로가 공격할 때 몬스터의 체력를 깍게 해준다.

 

 

Die를 코루틴으로 만들어주고,

 

호출시, 죽는 모션

isDie 를 true로

2f 이후, 게임오브젝트를 사라지게한다.

 

 

 

전투, 컨트롤 시스템 정리

 

------

 

여기까지 한 코드

 

JoystickTest

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

public class JoystickTest : MonoBehaviour
{
    public Transform heroTrans;
    public VariableJoystick joystick;
    public bool isSnap;
    public float speed = 2f;
    public Animation anim;
    public Button btnAttack;
    public bool isAttack;
    public Hero hero;
    void Start()
    {        
    }
    void Update()
    {
        this.isAttack = hero.isAttack;

        if (joystick.Direction.magnitude >= 0.1f)
        {
            var targetAngle = Mathf.Atan2(joystick.Direction.x, joystick.Direction.y) * Mathf.Rad2Deg;
            this.heroTrans.rotation = Quaternion.Euler(0f, targetAngle, 0f);

            var movement = Vector3.forward * speed * Time.deltaTime;
            this.heroTrans.Translate(movement);
            if (this.isAttack == false) {
                this.anim.Play("run@loop");
            }
        }
        else
        {
            if (this.isAttack == false)
            {
                this.anim.Play("idle@loop");
            }

        }
    }
}

 

 

Hero

 

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

public class Hero : MonoBehaviour
{
    public float size = 1.0f;
    public LayerMask whatIsLayer;
    private Animation anim;
    public bool isAttack = false;
    public Monster monster;
    public int damage = 25;
    void Start()
    {
        this.anim = GetComponent<Animation>();
    }
    private void OnDrawGizmos()
    {
        Gizmos.color = Color.red;
        Gizmos.DrawWireSphere(transform.position, size);
    }
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            Debug.Log("공격 클릭되었습니다.");
            StartCoroutine(Attack());
            Collider[] hit = Physics.OverlapSphere(transform.position, size, whatIsLayer);
            for (int i = 0; i < hit.Length; i++)
            {
                if (hit[i].tag == "monster") {
                    Debug.Log("몬스터를 공격합니다.");
                    this.transform.LookAt(hit[i].transform);
                    this.monster.monsterHp -= damage;
                }
            }
        };
    }
    IEnumerator Attack()
    {
        if (this.isAttack == false)
        {
            this.isAttack = true;
            this.anim.Play("attack_sword_01");
            yield return new WaitForSeconds(0.8f);
            this.isAttack = false;
        }
    }
    public void OnTriggerEnter(Collider other)
    {
        if (other.tag == "monster") {
            Debug.Log("몬스터와 닿았습니다");
        }
    }
}

 

Monster

 

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

public class Monster : MonoBehaviour
{
    public int monsterHp = 50;
    private Animation anim;
    public bool isDie = false;
    // Start is called before the first frame update
    void Start()
    {
        this.anim = GetComponent<Animation>();
    }

    // Update is called once per frame
    void Update()
    {
        if (this.monsterHp <= 0&& isDie == false) {
            StartCoroutine(Die());
        }
    }

    IEnumerator Die()
    {
        this.anim.Play("Anim_Death");
        this.isDie = true;
        yield return new WaitForSeconds(2f);
        Destroy(gameObject);
    }
}
반응형