게임 개발/유니티

20240208 Unity - MiniGame

싹난 감자 2024. 2. 13. 10:05

WallHolder.cs

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

public class WallHoler : MonoBehaviour
{
    [SerializeField] private float respawnPosZ = 10f;
    [SerializeField] private float endPosZ = -4f;
    [SerializeField] private float moveSpeed = 4f;
    [SerializeField] private float waveSpeed = 0f;

    private void Start()
    {
        Respawn();
    }
    private void Update()
    {
        //MovingProcess();
        MovingWaveProcess();
        if (CheckEndPosition()) {
            Respawn();
        }
    }

    public void Respawn() {
        Vector3 newPos = transform.position;
        newPos.x = UnityEngine.Random.Range(-3f, 3f);
        newPos.z = respawnPosZ;
        transform.position = newPos;

        waveSpeed = Random.Range(1f, 3f);
    }

    public bool CheckEndPosition() {
        return transform.position.z < endPosZ;
    }

    public void MovingProcess() {
        transform.Translate(Vector3.back * moveSpeed * Time.deltaTime);
    }

    private void MovingWaveProcess() {
        Vector3 newPos = new Vector3();
        newPos.x = Mathf.Sin(Time.time * waveSpeed) * 3f;
        newPos.z = transform.position.z + (-1f * moveSpeed * Time.deltaTime);

        transform.position = newPos;
    }
}

 

PlayerController.cs

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

public class PlayerController : MonoBehaviour
{
    /*[SerializeField] private GameObject playerGo = null;
    // GameObject에는 모든 것들이 들어가서 카메라 같은것도 들어감
    // Player라는 컴포넌트를 가지고 있지 않으면 GetComponent했을 때 NULL이 나옴*/

    [SerializeField] private Player player = null;
    // Player player처럼 컴포넌트의 이름으로 변수를 만들면 해당 컴포넌트를 가진 오브젝트만 넣을 수 있음

    private void Update()
    {
        float axisH = Input.GetAxis("Horizontal");
        /*Player playerComp = playerGo.GetComponent<Player>(); // <Player>: 템플릿
        // GetComponent 느림. Update에서 쓰면 안됨
        // Player 컴포넌트로 변수를 만들면 GetComponent도 할 필요가 없음
        playerComp.MoveHorizontal(axisH);*/
        player.MoveHorizontal(axisH);
    }
}

 

Player.cs

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

public class Player : MonoBehaviour
{
    // delegate 함수 포인터. 반환형 void, 매개변수 없어야함
    public delegate void CollisionDelegate();
    private CollisionDelegate collisionCallback = null;
    public CollisionDelegate CollisionCallback { set { collisionCallback = value; } }

    public delegate void TriggerDelegate();
    private TriggerDelegate triggerCallback = null;
    public TriggerDelegate TriggerCallback { set { triggerCallback = value; } }

    [SerializeField] private float limitLeft = -3.5f;
    [SerializeField] private float limitRight = 3.5f;
    [SerializeField] private float moveSpeed = 7f;

    /*private void Updata() {
        float axisH = Input.GetAxis("Horizontal");
        transform.Translate(Vector3.right * moveSpeed * Time.deltaTime);
    }*/

    public void MoveHorizontal(float _axisH) {
        //if (transform.position.x >= -3.5f && transform.position.x <= 3.5f)
                transform.Translate(Vector3.right * _axisH * moveSpeed * Time.deltaTime);
        #region Failed Limit Check
        /*//if (transform.position.x < limitLeft)
        if(CheckLimitLeft())
        {
            //transform.position.x = -3.5f; //transform은 Vector라서 바로 실수로 값을 변경할 수 없음
            Vector3 newPos = transform.position;
            newPos.x = limitLeft;
            transform.position = newPos;
        }
        else if (CheckLimitRight()) {
            Vector3 newPos = transform.position;
            newPos.x = limitRight;
            transform.position = newPos;
        }*/
        #endregion
        if (CheckLimitLeft())
            FixedLimitHorizontal(limitLeft);
        else if (CheckLimitRight())
            FixedLimitHorizontal(limitRight);
    }

    private bool CheckLimitLeft() {
        return transform.position.x < limitLeft;
    }
    private bool CheckLimitRight()
    {
        return transform.position.x > limitRight;
    }
    private void FixedLimitHorizontal(float _limitH) {
        Vector3 newPos = transform.position;
        newPos.x = _limitH;
        transform.position = newPos;
    }

    private void OnCollisionEnter(Collision _collision)
    {
        /*Debug.Log("On Collision: "+ _collision.gameObject.name);   */
        if (_collision.gameObject.CompareTag("Wall")) { // ==보다 빠름
            if (collisionCallback != null) {
                collisionCallback(); // 이제 이런식으로 안씀 triggerCallback?.Invoke(); 이렇게 씀
            }
        }
    }

    private void OnTriggerEnter(Collider _collider)
    {
        Debug.Log("On Trigger: "+ _collider.name);
        if (_collider.tag == "Gate") { // gameObject.CompareTag보다 느림
            triggerCallback?.Invoke(); // 요즘 권장하는 방식. triggerCallback이 null이 아니면 Invoke를 실행
                                       // ? : null로 초기화하는 애들 null인지 검사하는 기능 
        }
    }
}

 

GameManager.cs

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

public class GameManager : MonoBehaviour
{
    [SerializeField] private Player player = null;
    [SerializeField] private Button reButton = null;
    [SerializeField] private WallHoler wall = null;

    private int score = 0;

/*    public delegate int GetScoreDelegate();
    private GetScoreDelegate getScoreCallback = null;
    public GetScoreDelegate GetScoreCallback { get { return getScoreCallback; } set { getScoreCallback = value; } }*/
    
    public int Score { get { return score; } set { score = value; } }

    private void Start()
    {
        player.CollisionCallback = OnCollisionAtWall; // Delegate는 함수 포인터 같은거라서 함수를 호출하는게 아니라 함수의 주소를 넣어줌
        player.TriggerCallback = OnTriggerAtGate;
    }

    private void OnCollisionAtWall() {
        //Debug.Break();
        player.gameObject.SetActive(false);
        reButton.gameObject.SetActive(true);
        Debug.Log("YOU DIE");
        wall.gameObject.SetActive(false);
    }

    private void OnTriggerAtGate() {
        ++score;
        Debug.Log("Score : " + score);
    }
}

 

개인추가

BtnEvent.cs

using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using UnityEngine;
using UnityEngine.SocialPlatforms.Impl;
using UnityEngine.UI;

public class BtnEvent : MonoBehaviour
{
    [SerializeField] private Player player = null;
    [SerializeField] private Button reButton = null;
    [SerializeField] private WallHoler wall = null;
    [SerializeField] private GameManager manager = null;

    private void Start()
    {
        initBtn();
        reButton.onClick.AddListener(reStart);
    }

    private void initBtn() {
        reButton.gameObject.SetActive(false);
    }

    public void reStart()
    {
        manager.Score = 0;
        wall.Respawn();
        reButton.gameObject.SetActive(false);
        player.gameObject.SetActive(true);
        wall.gameObject.SetActive(true);
        Debug.Log(manager.Score);
    }
}

 

 

'게임 개발 > 유니티' 카테고리의 다른 글

20240215 Unity - Rotate  (1) 2024.02.15
20240214 Unity - Transformation  (3) 2024.02.14
20240207 Unity - Input, Collision 충돌판정  (0) 2024.02.07
20240206 Unity - HelloWorld  (3) 2024.02.06
Unity - VS 연결이 되지 않을 때  (0) 2024.02.06