본문 바로가기

Unity 공부/Unity_2D

[Day 16] 로직 보완

[ 로직 보완하기 ] --> 코드 깔끔하게 정리

  • 기존의 Reposition 스크립트에 코드 추가
    ㅡ아래는 완성된 코드ㅡ
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Reposition : MonoBehaviour
{
    Collider2D coll;

    private void Awake(){
        coll = GetComponent<Collider2D>();
    }

    void OnTriggerExit2D(Collider2D collision){
        if (!collision.CompareTag("Area")) {
            return;
        }

        Vector3 playerPos = GameManager.instance.player.transform.position;
        Vector3 myPos = transform.position;

        switch (transform.tag){
            case "Ground":
                float diffX = playerPos.x - myPos.x; // 입력 키에 상관없이 거리로만 계산
                float diffY = playerPos.y - myPos.y; // 입력 키에 상관없이 거리로만 계산
                float dirX = diffX < 0 ? -1 : 1;
                float dirY = diffY < 0 ? -1 : 1;
                diffX = Mathf.Abs(diffX); // 입력 키에 상관없이 거리로만 계산
                diffY = Mathf.Abs(diffY); // 입력 키에 상관없이 거리로만 계산

                if (diffX > diffY) {
                    transform.Translate(Vector3.right * dirX * 40);
                }
                else if (diffX < diffY) {
                    transform.Translate(Vector3.up * dirY * 40);
                }
                break;
            case "Enemy": // 적 재배치 위치
                if (coll.enabled){
                    Vector3 dist = playerPos - myPos;
                    Vector3 ran = new Vector3(Random.Range(-3, 3), Random.Range(-3, 3), 0);
                    transform.Translate(ran + dist * 2);
                }
                break;
        }
    }

}
  • 기존의 Weapon 스크립트에 코드 추가
    ㅡ아래는 완성된 코드ㅡ
using System.Collections;
using System.Collections.Generic;
using System.Runtime.ConstrainedExecution;
using UnityEngine;

public class Weapon : MonoBehaviour
{
    public int id;
    public int prefabId;
    public float damage;
    public int count;
    public float speed;

    float timer;
    Player player;

    void Awake(){
        player = GameManager.instance.player;
    }

    void Update(){
        if (!GameManager.instance.isLive)
            return;

        switch (id){
            case 0:
                transform.Rotate(Vector3.back * speed * Time.deltaTime);
                break;

            default:
                timer += Time.deltaTime;

                if(timer > speed){
                    timer = 0f;
                    Fire();
                }
                break;

        }

        // .. Test Code ..
        if (Input.GetButtonDown("Jump")){
            LevelUp(10, 1);
        }
    }

    public void LevelUp(float damage, int count)
    {
        this.damage += damage * Character.Damage;
        this.count += count;

        if(id == 0){
            Batch();
        }

        player.BroadcastMessage("ApplyGear",SendMessageOptions.DontRequireReceiver);
    }

    public void Init(ItemData data)
    {
        // Basic Set
        name = "Weapon " + data.itemId;
        transform.parent = player.transform;
        transform.localPosition = Vector3.zero;

        // Property Set
        id = data.itemId;
        damage = data.baseDamage * Character.Damage;
        count = data.baseCount + Character.Count;

        for(int index=0; index<GameManager.instance.pool.prefabs.Length; index++){
            if (data.projectile == GameManager.instance.pool.prefabs[index]){
                prefabId = index;
                break;
            }    
        }

        switch(id){
            case 0:
                speed = 150 * Character.WeaponSpeed; // (+) --> 반시계방향
                Batch();
                break;

            default:
                speed = 0.5f * Character.WeaponRate;
                break;
        }

        // Hand Set
        Hand hand = player.hands[(int)data.itemType];
        hand.spriter.sprite = data.hand;
        hand.gameObject.SetActive(true);

        player.BroadcastMessage("ApplyGear", SendMessageOptions.DontRequireReceiver);
    }

    void Batch(){
        for(int index=0; index < count; index++) {
            Transform bullet;
           
            if(index < transform.childCount){
                bullet = transform.GetChild(index);
            }
            else{
                bullet = GameManager.instance.pool.Get(prefabId).transform;
                bullet.parent = transform;

            }

            bullet.localPosition = Vector3.zero;
            bullet.localRotation = Quaternion.identity;

            Vector3 rotVec = Vector3.forward * 350 * index / count;
            bullet.Rotate(rotVec);
            bullet.Translate(bullet.up * 1.5f, Space.World);
            bullet.GetComponent<Bullet>().Init(damage, -100, Vector3.zero); // -100으로 바꿔주기

        }
    }

    void Fire()
    {
        if (!player.scanner.nearestTarget){
            return;
        }

        Vector3 targetPos = player.scanner.nearestTarget.position;
        Vector3 dir = targetPos - transform.position;
        dir = dir.normalized;

        Transform bullet = GameManager.instance.pool.Get(prefabId).transform;
        bullet.position = transform.position;
        bullet.rotation = Quaternion.FromToRotation(Vector3.up, dir);
        bullet.GetComponent<Bullet>().Init(damage, count, dir);

        AudioManager.instance.Playsfx(AudioManager.Sfx.Range);

    }
}
  • 기존의 Bullet 스크립트에 코드 추가
    ㅡ아래는 완성된 코드ㅡ
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Bullet : MonoBehaviour
{
    public float damage;
    public int per;

    Rigidbody2D rigid;

    void Awake(){
        rigid = GetComponent<Rigidbody2D>();
    }

    public void Init(float damage, int per, Vector3 dir)
    {
        this.damage = damage;
        this.per = per;

        if(per >= 0){ // 변경
            rigid.velocity = dir * 15f;
        }
    }

    void OnTriggerEnter2D(Collider2D collision)
    {
        if(!collision.CompareTag("Enemy") || per == -100){ // -100으로 변경
            return;
        }

        per--;

        if (per < 0){ // 느슨하게 변경
            rigid.velocity = Vector2.zero;
            gameObject.SetActive(false);
        }
    }

    private void OnTriggerExit2D(Collider2D collision) // Area를 벗어나면 오브젝트 비활성화
    {
        if(!collision.CompareTag("Area") || per == -100)
        {
            return;
        }

        gameObject.SetActive(false);
    }
}
  • 기존의 Spawner 스크립트에 코드 추가
    ㅡ아래는 완성된 코드ㅡ
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Spawner : MonoBehaviour{
    public Transform[] spawnPoint;
    public SpawnData[] spawnData;
    public float levelTime; // 구간 시간
    int level;
    float timer;

    void Awake(){
        spawnPoint = GetComponentsInChildren<Transform>();
        levelTime = GameManager.instance.maxGameTime / spawnData.Length; // 구간 시간 계산
    }
    void Update(){
        if (!GameManager.instance.isLive)
            return;

        timer += Time.deltaTime;
        level = Mathf.Min(Mathf.FloorToInt(GameManager.instance.gameTime / levelTime), spawnData.Length-1); // levelTime 넣어주기

        if (timer > spawnData[level].spawnTime){
            timer = 0;
            Spawn();
        }
    }

    void Spawn(){
        GameObject enemy = GameManager.instance.pool.Get(0);
        enemy.transform.position = spawnPoint[Random.Range(1, spawnPoint.Length)].position;
        enemy.GetComponent<Enemy>().Init(spawnData[level]);
    }
}

[System.Serializable]
public class SpawnData{
    public float spawnTime;
    public int spriteType;
    public float hp;
    public float speed;
}
  • GameManager 오브젝트에서 Next Exp 조절

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

 

★Slow and Steady★