유니티3D 프로그래밍

Unity 간단한 게임 구현 (21.04.29~30) 본문

Unity/수업내용

Unity 간단한 게임 구현 (21.04.29~30)

tjdgus9955 2021. 4. 30. 12:12

29일 구현 내용

 

Enemy 생성 및 애니메이터 적용, 플레이어 조이스틱 및 공격 구현, 공격 시 일정 범위 안에 있는 적만 타격하는 방식

 

Enemy : 적 오브젝트 반응 구현

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

public class Enemy : MonoBehaviour
{
    public int maxHp = 2;
    public int hp;
    private Animator enemyAnimator;
    private bool isDead = false;
    public bool isAttack = false;
    // Start is called before the first frame update
    void Start()
    {
        this.hp = this.maxHp;
        enemyAnimator = this.GetComponent<Animator>();
    }

    // Update is called once per frame
    void Update()
    {
        
    }

    IEnumerator HitAnimation()
    {
        yield return new WaitForSeconds(0.4f);
        enemyAnimator.Play("Anim_Idle");
    }

    public void Hit()
    {
        if(!isDead)
        {
            if (hp > 0)
            {
                enemyAnimator.SetTrigger("isHit");
                StartCoroutine(HitAnimation());
                hp -= 1;
            }
        if (hp <= 0)
            {
                enemyAnimator.SetBool("isDead", true);
                isDead = true;
                Destroy(this.gameObject, 2f);
            }
        }
        
    }
}

 

InGame : 오브젝트의 반응을 다른 오브젝트에 적용하기 위한 단계

 

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

public class InGame : MonoBehaviour
{
    public PlayerController player;
    private Enemy enemy;
    // Start is called before the first frame update
    void Start()
    {
        this.player.IsAttack = (enemy) =>
        {
            this.enemy = enemy;
            this.enemy.Hit();
        };
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

 

JoyStickTest : 조이스틱을 통해 플레이어의 움직임 구현

 

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

public class JoyStickTest : MonoBehaviour
{
    public VariableJoystick joystick;
    public bool isSnap;
    public Transform hero;
    public float speed = 1f;
    public float rotationSpeed = 0.1f;
    private Animator animator;
    private Rigidbody rigidbody;

    void Start()
    {
        joystick.SnapX = isSnap;
        animator = this.GetComponent<Animator>();
        rigidbody = this.GetComponent<Rigidbody>();
    }

    // Update is called once per frame
    void Update()
    {
        //Debug.LogFormat("{0}", joystick.Direction);
        if (joystick.Direction != Vector2.zero)
        {
            Vector3 moveDir = new Vector3(joystick.Horizontal, 0, joystick.Vertical);
            Quaternion newRotation = Quaternion.LookRotation(moveDir);
            rigidbody.rotation = Quaternion.Slerp(rigidbody.rotation, newRotation, rotationSpeed * Time.deltaTime);
            this.transform.position += this.transform.forward * this.speed * Time.deltaTime;
        }
        animator.SetFloat("Move", joystick.Vertical*joystick.Horizontal);
    }
}

 

PlayerController : 플레이어의 반응(공격, 적탐지)을 구현

 

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

public class PlayerController : MonoBehaviour
{
    public System.Action<Enemy> IsAttack;

    public Button btn;
    private bool inAttack = true;
    private Animator animator;
    public Collider[] detectEnemy;
    public Collider detector;
    public Vector3 size;
    public LayerMask layerMask;
    void Start()
    {
        animator = this.GetComponent<Animator>();
        
        
    }

    IEnumerator Attack()
    {
        animator.SetBool("isAttack", true);
        yield return new WaitForSeconds(0.33f);
        DetectEnemy(); ;
        animator.SetBool("isAttack", false);
    }

    public void DetectEnemy()
    {
        size = ((BoxCollider)detector).size;
        detectEnemy = Physics.OverlapBox(detector.transform.position, size, Quaternion.identity, layerMask);
        if (detectEnemy.Length == 0)
        {
            return;
        }
        var tempEnemy = detectEnemy[0];
        IsAttack(tempEnemy.gameObject.GetComponent<Enemy>());
    }

    void Update()
    {
        if(Input.GetButtonDown("Attack"))
        {
            StartCoroutine(Attack());
        }
    }
}

 

Test : 체력바를 플레이어의 상단에 고정해서 움직여도 따라가게끔 구현

 

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

public class Test : MonoBehaviour
{
    public Transform target;
    public RectTransform canvas;
    public RectTransform gauge;
    // Update is called once per frame
    void Update()
    {
        Vector3 offsetPos = target.transform.position;
        Vector2 screenPoint = Camera.main.WorldToScreenPoint(offsetPos);

        Vector2 canvasPos;
        RectTransformUtility.ScreenPointToLocalPointInRectangle(canvas, screenPoint, null, out canvasPos);

        gauge.localPosition = canvasPos;
        Debug.Log(canvasPos);
    }
}

 

 

30일 구현 내용

 

 

위 사진은 버튼을 누르면 캐릭터가 조금씩 회전하고 아래 사진은 스크롤을 이용하여 캐릭터를 이동 시키는 방식이다.

 

사용한 오브젝트

 

사용한 2개의 스크리븥

 

UIDragArea : IDragHandler 이벤트를 이용해서 드래그 회전을 구현한다.

 

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

public class UIDragArea : MonoBehaviour, IDragHandler
{
    public System.Action<float> onDrag;
    public void OnDrag(PointerEventData eventData)
    {
        this.onDrag(eventData.delta.x);
    }
}

 

LobbyScene : 버튼을 클릭하면 회전시키고 이벤트가 적용된 Area를 드래그하면 캐릭터가 회전한다.

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

public class LobbyScene : MonoBehaviour
{
    public Button btnL;
    public Button btnR;
    public GameObject uiHero;
    private float rotateY;
    public UIDragArea uiDragArea;
    // Start is called before the first frame update
    void Start()
    {
        this.rotateY = this.uiHero.transform.rotation.y;

        this.btnL.onClick.AddListener(() => {
            this.rotateY += 5;
            this.uiHero.transform.Rotate(new Vector3(0, rotateY, 0));
            this.rotateY = this.uiHero.transform.rotation.y;
        });
        this.btnR.onClick.AddListener(() => {
            this.rotateY -= 5;
            this.uiHero.transform.Rotate(new Vector3(0, rotateY, 0));
            this.rotateY = this.uiHero.transform.rotation.y;
        });

        this.uiDragArea.onDrag = (deltaX) => {
            if (deltaX > 0)
            {
                this.rotateY -= 5;
                this.uiHero.transform.Rotate(new Vector3(0, rotateY, 0));
                this.rotateY = this.uiHero.transform.rotation.y;
            }
            else
            {
                this.rotateY += 5;
                this.uiHero.transform.Rotate(new Vector3(0, rotateY, 0));
                this.rotateY = this.uiHero.transform.rotation.y;
            }
        };
    }

    // Update is called once per frame
    void Update()
    {

    }
}