본문 바로가기
KDT/유니티 심화

23/08/23 HeroShooter 포탈 닿으면 FadeOut

by 잰쟁 2023. 8. 23.
728x90

Main

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

public class GameMain1 : MonoBehaviour
{
    [SerializeField]
    private Player player;
    [SerializeField]
    private Joystick joystick;
    [SerializeField]
    private Portal portal;
    [SerializeField]
    private Door door;
    [SerializeField]
    private GameObject portal2;
    [SerializeField]
    private Image dim;

    // Start is called before the first frame update
    void Start()
    {

        //포탈에 닿으면
        this.portal.onReachPortal = () =>
        {
            Debug.Log("open door");
            //door에게 문 열라고 명령
            this.door.Open();
        };

        //문에 닿았으면
        this.door.onReachDoor = () =>
        {
            //fadeout 실행
            this.FadeOut();
        };
    }
    private void FadeOut()
    {
        this.dim.gameObject.SetActive(true);
        //코루틴 호출
        this.StartCoroutine(this.CoFadeOut());
    }

    IEnumerator CoFadeOut()
    {
        var color = this.dim.color;

        while (true)
        {
            color.a += 0.01f;
            this.dim.color = color;
            if(this.dim.color.a >= 1)
            {
                break;
            }
            yield return null;
        }
        Debug.Log("<color=yellow>다음씬으로 이동!</color>");
    }
  
    void Update()
    {
        //조이스틱 방향 가져오기
        float h = this.joystick.Horizontal;
        float v = this.joystick.Vertical;
        var dir = new Vector3(h, 0, v);

        //화면 밖 나가지 않게
        //float ClampX = Mathf.Clamp(this.transform.position.x, -2.7f, 2.7f);
        //float ClampY = Mathf.Clamp(this.transform.position.y, -4.6f, 4.8f);
        //this.playerTrans.position = new Vector3(ClampX,0,ClampY);

        //Player 이동시키기
        if (dir != Vector3.zero)
        {
            this.player.Move(dir);
        }
        else
        {
            this.player.Idle();
        }
    }
}

Door

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

public class Door : MonoBehaviour
{
    [SerializeField]
    private Transform leftDoor;
    [SerializeField]
    private Transform rightDoor;
    [SerializeField]
    private float openAngle_r = 100f;
    [SerializeField]
    private float openAngle_l = 80f;
    [SerializeField]
    private float openDamping = 2f;
    [SerializeField]
    private GameObject portal2;
    private Collider col;

    //open 대리자
    public System.Action onOpen;
    //reach 대리자
    public System.Action onReachDoor;

    void Start()
    {
        this.portal2.SetActive(false);
        this.col = this.GetComponent<Collider>();
    }

    public void Open()
    {
        //바로 열기
        //transform.localRotation = Quaternion.Euler(x,y,z);
        //this.leftDoor.localRotation = Quaternion.Euler(new Vector3(0, this.openAngle, 0));
        //this.rightDoor.localRotation = Quaternion.Euler(new Vector3(0, this.openAngle, 0));

        //대리자 호출
        //this.onOpen();
        //코루틴 호출
        this.StartCoroutine(this.CoOpen());
    }

    private IEnumerator CoOpen()
    {
        //문 열릴 각도(위치) 설정
        var left = Quaternion.Euler(new Vector3(0, -1*this.openAngle_l, 0));
        var right = Quaternion.Euler(new Vector3(0, -1 * this.openAngle_r, 0));

        while (true)
        {
            //문 회전하여 열기
            this.leftDoor.localRotation = Quaternion.Slerp(this.leftDoor.localRotation, left, Time.deltaTime * this.openDamping);
            this.rightDoor.localRotation = Quaternion.Slerp(this.rightDoor.localRotation,right,Time.deltaTime * this.openDamping);
            
            //왼쪽 문이 설정한 위치까지 회전하여 열리면 멈추기
            if(this.leftDoor.localRotation == left)
            {
                break;
            }           
            yield return null;
        }
        this.portal2.SetActive(true);
        Debug.Log("door open complete!");
        //문 열린 후 포탈 활성화
    }

    public void OnTriggerEnter(Collider other)
    {
        if (other.CompareTag("Player"))
        {
            //reach 대리자 호출
            this.onReachDoor();
            Debug.Log("reach door");
        }
    }
}

Player

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

public class Player : MonoBehaviour
{
    private Transform playerTrans;
    public float moveSpeed = 5f;
    private Animator anim;
    public float turnSpeed = 80f;

    void Start()
    {
        this.playerTrans = this.GetComponent<Transform>();
        this.anim = this.GetComponent<Animator>();
    }

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

    }

    //이동 메서드
    public void Move(Vector3 dir)
    {
        //애니메이션
        this.anim.SetInteger("State", 1);
        //회전하기
        float angle = Mathf.Atan2(dir.x, dir.z) * Mathf.Rad2Deg;
        this.playerTrans.localRotation = Quaternion.AngleAxis(angle, Vector3.up);
        //이동하기
        this.playerTrans.Translate(Vector3.forward * this.moveSpeed * Time.deltaTime);
    }

    //정지 메서드
    public void Idle()
    {
        this.anim.SetInteger("State", 0);
    }

    private void OnDrawGizmos()
    {
        Gizmos.color = Color.white;
        GizmosExtensions.DrawWireArc(this.transform.position, this.transform.forward, 360, 1);
    }
}

Portal

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

public class Portal : MonoBehaviour
{
    private Collider col;
    public System.Action onReachPortal;

    // Start is called before the first frame update
    void Start()
    {
        this.col = this.GetComponent<Collider>();
    }

    //콜라이더로 충돌체크
    private void OnTriggerEnter(Collider other)
    {
        if (other.CompareTag("Player"))
        {
            //중복 충돌 방지하기 위해 1번 닿으면 없애기
            this.col.enabled = false;
            //포탈 대리자 호출
            this.onReachPortal();
        }
    }
}