본문 바로가기
개발/Unity) 코드분석

코드분석) Spy Game

by 테샤르 2021. 5. 2.

Spy Game 코드 분석

 

스파이 게임의 코드를 분석하는 포스팅이다.

 

프로젝트 링크 주소 : [링크]

 

Spy Game

A 2D top down puzzle shooter built in Unity.

unitylist.com

 

<플레이 영상>

 

-----------------------------------------------------------------------

반응형

키보드의 방향키로 캐릭터를 움직이고 Shift 버튼으로 순간이동이 가능하고 마우스 클릭(일반 미사일)/ 마우스 오른쪽(레이저)이 생성되어서 적을 공격할 수 있다.

탑 뷰의 스타일로 체력이 존재하고 센서 근처에 가게 되면 적이 리젠되서 공격을 하게 된다.

 

 

<PlayerMovement>

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

public class PlayerMovement : MonoBehaviour
{

    public Vector2 lookDir;
    public Transform firePoint;
    public HealthBar healthBar;
    public float moveSpeed = 5f;
    public Camera cam;
    public GameObject tryAgain;
    public GameObject exit;
    public GameObject winning;
    public Rigidbody2D rb;
    Vector2 movement;
    Vector2 mousePos;
    bool showGameOverScreen = false;
    float health = 100f;
    public bool wincondition = false;

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

    }

    // Update is called once per frame
    void Update()
    {
        movement.x = Input.GetAxisRaw("Horizontal");
        movement.y = Input.GetAxisRaw("Vertical");
        movement = movement.normalized;

        mousePos = cam.ScreenToWorldPoint(Input.mousePosition);
        if (wincondition)
        {
            if (killedAllEnemies())
            {
                Win();
            }
        }
    }
    void FixedUpdate()
    {
        rb.MovePosition(rb.position + movement * moveSpeed * Time.fixedDeltaTime);
        lookDir = mousePos - (Vector2)firePoint.position;
        if (lookDir.magnitude > .9)
        {
            float angle = Mathf.Atan2(lookDir.y, lookDir.x) * Mathf.Rad2Deg - 90;
            rb.rotation = angle;
        }

    }

    public void TakeDamage(int damage)
    {
        float percentageDamage = (damage / health) * -1f;
        healthBar.ChangeHealth(percentageDamage);
        //health -= damage;
        if (health <= 0)
        {
            Die();
        }
    }
    void Die()
    {
        print("Wipe yourself off man, you dead");
        Destroy(gameObject);
        tryAgain.SetActive(true);
        exit.SetActive(true);
    }
    public void Win()
    {
        GameObject enemy = GameObject.FindGameObjectWithTag("enemy");
        if (enemy == null)
        {
            print("you won");
            Destroy(gameObject);
            winning.SetActive(true);
        }


    }
    public bool killedAllEnemies()
    {
        GameObject enemy = GameObject.FindGameObjectWithTag("enemy");
        if (enemy == null)
        {
            return true;
        }
        return false;

    }

}

<Shooting>

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

public class Shooting : MonoBehaviour
{
    public Transform firePoint;
    public GameObject bulletPrefab;
    public GameObject impactEffect;
    public LineRenderer lineRenderer;
    public int lazerDamage = 15;

    public float bulletForce = 5f;
    // Update is called once per frame
    void Update()
    {
        if (Input.GetButtonDown("Fire1"))
        {
            Shoot();
        }
        if (Input.GetButtonDown("Fire2"))
        {
            StartCoroutine(ShootRay());
        }
    }
    void Shoot()
    {
        GameObject bullet = Instantiate(bulletPrefab, firePoint.position, firePoint.rotation);
        Rigidbody2D rb = bullet.GetComponent<Rigidbody2D>();
        rb.AddForce(firePoint.up * bulletForce, ForceMode2D.Impulse);
    }
    IEnumerator ShootRay()
    {
        int layer_mask = LayerMask.GetMask("normal", "player","projectiles","enemy");
        RaycastHit2D hitinfo = Physics2D.Raycast(firePoint.position, firePoint.up,100f,layer_mask);
        if (hitinfo)
        {

            if(hitinfo.transform.gameObject.tag == "enemy")
            {
                Enemy enemy = hitinfo.transform.GetComponent<Enemy>();
                enemy.TakeDamage(lazerDamage,"lazer");
            }
            if(hitinfo.transform.gameObject.tag == "bullet")
            {
                Bullet b = hitinfo.transform.GetComponent<Bullet>();
                b.ExplosionDamage(hitinfo.collider);
                b.Explode();
            }
            lineRenderer.SetPosition(0,firePoint.position);
            lineRenderer.SetPosition(1,hitinfo.point);
            GameObject effect = Instantiate(impactEffect,hitinfo.point,Quaternion.identity);
            Destroy(effect,1f);

        }
        else
        {
            lineRenderer.SetPosition(0,firePoint.position);
            lineRenderer.SetPosition(0,firePoint.up *1000);
        }
        lineRenderer.enabled = true;
        yield return new WaitForSeconds(.05f);
        lineRenderer.enabled = false;

    }

}

맵은 2D Tile맵으로 Walls / Walkable으로 두 가지로 구분되어서 처리되어있다.

Enemy는 플레이어의 캐릭터를 찾아서 Update마다 움직임이 되어있고 공격을 하게 되어 있다.

오픈소소 스여서 정리가 안된 코드들도 있지만 대략적인 구조를 알게 되어서 좋았다.

----------------------------------------------------------------------

 

 

반응형

댓글