Unity2D

Unity) [유니티 2D] 조이스틱을 통한 슈터 캐릭터 구현

HSH12345 2023. 3. 4. 01:24
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;

public class Joystick : MonoBehaviour, IDragHandler, IPointerUpHandler, IPointerDownHandler
{
    public RectTransform frame;
    public RectTransform handle;

    private float handleRange = 130;
    private Vector3 input;
    private bool isDraged;

    public float Horizontal { get { return input.x; } }
    public float Vertical { get { return input.y; } }
    public Vector3 Input { get { return input; } }
    public bool IsDraged { get { return isDraged; } }

    public virtual void OnDrag(PointerEventData eventData)
    {
        if (RectTransformUtility.ScreenPointToLocalPointInRectangle(
            this.gameObject.GetComponent<RectTransform>(), eventData.position,
            eventData.pressEventCamera, out Vector2 localVector))
        {
            if (localVector.magnitude < this.handleRange)
            {
                this.handle.transform.localPosition = localVector;
            }
            else 
            {
                this.handle.transform.localPosition = localVector.normalized * this.handleRange;
            }

            this.input = localVector;
        }
        
        this.SetJoystickColor(true);
    }

    public virtual void OnPointerUp(PointerEventData eventData)
    {
        this.input = Vector2.zero;
        this.handle.anchoredPosition = Vector2.zero;

        this.SetJoystickColor(false);
        this.isDraged = false;
    }

    public virtual void OnPointerDown(PointerEventData eventData)
    {
        this.OnDrag(eventData);
        this.isDraged = true;
    }

    private void SetJoystickColor(bool isOnDraged)
    {
        Color pointedFrameColor;
        Color pointedHandleColor;

        if (isOnDraged)
        {
            pointedFrameColor = new Color(255, 0, 0, 0.5f);
            pointedHandleColor = new Color(255, 0, 0, 0.6f);
        }
        else
        {
            pointedFrameColor = new Color(255, 255, 255, 0.5f);
            pointedHandleColor = new Color(255, 255, 255, 0.6f);
        }

        this.frame.gameObject.GetComponent<Image>().color = pointedFrameColor;
        this.handle.gameObject.GetComponent<Image>().color = pointedHandleColor;
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;

public class JoystickGunDir : Joystick
{
    public bool IsShoot { get { return IsDraged; } }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerShell : MonoBehaviour
{
    private enum eLookState
    {
        Down, Left, Up, Right
    }

    public float playerMoveSpeed = 5f;
    public CharacterController cc;
    private JoystickMove joystickMove;
    public GunShell gunShell;
    public Animator anim;

    private eLookState lookState;
    private float maxAttackTime = 0.1f;
    private float attackTime;

    void Start()
    {
        this.joystickMove = GameObject.FindObjectOfType<JoystickMove>();
        this.anim.SetInteger("LookState", 3);
        this.lookState = eLookState.Right;        
    }

    private void Update()
    {
        Vector2 dir = new Vector2(this.joystickMove.Horizontal, this.joystickMove.Vertical);
        cc.Move(dir.normalized * this.playerMoveSpeed * Time.deltaTime);

        // -50 ~ -130, -130 ~ 130, 130 ~ 60, 60 ~ -50
        var angle = this.gunShell.Angle;

        if (angle < -50f && angle > -130f) this.lookState = eLookState.Down;
        else if (angle < -130f || angle > 130f) this.lookState = eLookState.Left;
        else if (angle < 130 && angle > 60) this.lookState = eLookState.Up;
        else if (angle < 60f && angle > -50) this.lookState = eLookState.Right;

        if ((int)this.lookState != this.anim.GetInteger("LookState"))
        {
            if (this.lookState == eLookState.Down) this.anim.SetInteger("LookState", 0);
            else if (this.lookState == eLookState.Left) this.anim.SetInteger("LookState", 1);
            else if (this.lookState == eLookState.Up) this.anim.SetInteger("LookState", 2);
            else if (this.lookState == eLookState.Right) this.anim.SetInteger("LookState", 3);  
        }

        if (dir != new Vector2(0, 0)) this.anim.SetBool("MoveState", true);
        else this.anim.SetBool("MoveState", false);

        this.anim.SetBool("ShootState", this.gunShell.IsShoot);
        this.gunShell.anim.SetBool("State", this.gunShell.IsShoot);

        if (this.gunShell.IsShoot)
        {
            this.attackTime += Time.deltaTime;
            if(this.attackTime >= this.maxAttackTime)
            {
                this.attackTime = 0;
                this.gunShell.Shoot();
            }
        }
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GunShell : MonoBehaviour
{
    public enum eGunState
    {
        Idle, Shoot
    }
    private eGunState gunState;

    private JoystickGunDir joystickGunDir;
    private float angle;
    public GameObject gun;
    public Animator anim;
    private Quaternion lookRotation;

    public float Angle { get { return angle; } }
    public bool IsShoot { get { return this.joystickGunDir.IsShoot; } }

    public GameObject bulletGo;
    public GameObject bulletPoint; 

    private void Start()
    {
        this.joystickGunDir = GameObject.FindObjectOfType<JoystickGunDir>();
    }

    private void Update()
    {
        if (this.joystickGunDir.Input == Vector3.zero) return;
        this.angle = Mathf.Atan2(this.joystickGunDir.Vertical, this.joystickGunDir.Horizontal) * Mathf.Rad2Deg;
        this.lookRotation = Quaternion.Euler(angle * Vector3.forward);
        this.transform.rotation = this.lookRotation;

        //Debug.Log(this.angle);

        var gunSprite = this.gun.GetComponent<SpriteRenderer>();
        if (this.angle < -90f || this.angle > 90f) gunSprite.flipY = true;
        else gunSprite.flipY = false;

        if (this.angle < 130f && this.angle > 60f) gunSprite.sortingOrder = 9;
        else gunSprite.sortingOrder = 11;

        if ((int)this.gunState != this.anim.GetInteger("State")) 
        { 
            if(this.gunState == eGunState.Idle) this.anim.SetInteger("State", 0);
            else if(this.gunState == eGunState.Shoot) this.anim.SetInteger("State", 1);
        }
    }

    public void Shoot()
    {
        var go = Instantiate(this.bulletGo);
        go.transform.position = this.bulletPoint.transform.position;
        go.transform.rotation = this.lookRotation;
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Bullet : MonoBehaviour
{
    public float bulletSpeed = 20f;
    private float maxExistTime = 0.5f;
    private float existTime;

    void Update()
    {
        this.transform.Translate(new Vector2(1, 0) * this.bulletSpeed * Time.deltaTime);

        this.existTime += Time.deltaTime;
        if (this.existTime >= this.maxExistTime)
        {
            this.existTime = 0;
            Destroy(this.gameObject);
        }        
    }
}