반응형

포토샵에서 작업한 적 캐릭터 이미지를 유니티에 끌어다 Textrue폴더에 넣습니다 

그리고 아래 그림과 같이 그림 Inspector를 바꿉니다 

그리고 Sprite Editor에 들어감니다 

 

Slice를 누르고 Automatic 으로 그림을 나눕니다

그리고 Pivot을 나중에 캐릭터가 움직임에 원활히 할수있도록 위치를 조종합니다  

 

 

 

 

 

빈오브젝트를 만들고 이름을 Enemy 하고 Enemy그림파일을 각각 관절에 맞게 Hierarchy 창에 끌어다 놓고 그림을 인간형에 맞게 맞춥니다 

 

Enemy의 각각의 관절에 Sorting Layer -> Enemy 를 만들고 그림이 위아래가 바뀌지 않도록 합니다 

 

 

 

 

 

Enemy 오브젝트의 Window -> animation -> animation 을 열고 Create new Clip을 Enemy_Run을 만들고 적 캐릭터가 움직이는 애니메이션을 만듭니다 

 

 

Enemy 스크립트를 생성하고 작성합니다 

 

 

 

 

Enemy 스크립트 작성 

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

public class Enemy : MonoBehaviour
{

    //적캐릭터의 생명카운트
    public int health;

    //Player 위치
    [HideInInspector]
    public Transform player;

    //스피드
    public float speed;

    //공격과 재공격의 시간 
    public float timeBetweenAttacks;
    // 데미지
    public int damage;
    private void Start()
    {
        //Player tag 오브젝트를 찾는다
        player = GameObject.FindGameObjectWithTag("Player").transform;
    }

    //공격을 받을때 생명이 줄어드는 함수
    public void TakeDamage(int damageAmount)
    {
        health -= damageAmount;
        if (health <= 0)
        {
            Destroy(gameObject);
        }
    }
}

 

 

 

 

 

 

Enemy 오브젝트를 선택하고 Enemy 스크립트를 붙히고 Tag에 Enemy를 생성하고  Box Collider2 D를 붙이고 isTrigger를 체크하고 Rigidbody2 D에서 Gravity scale을 0으로 하고 Freeze Rotation -> z를 체크합니다 

 

Prefabs에 있는 bullet 프리팹을 선택하여 BulletCtrl 스크립트를 수정합니다 

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

public class BulletCtrl : MonoBehaviour
{
    public float speed;
    public float lifeTime;
    public GameObject explosion;

    public int damage;
   
   
    void Start() 
    {
        // 총알을 시간에 맞게 지운다
        //Destroy(gameObject, lifeTime);
        Invoke("DestroyBullet", lifeTime);
    } 
      void Update() 
    { 
        // 시간프레임과 speed에 따라 y축방향으로 움직인다
        transform.Translate(Vector2.up * speed * Time.deltaTime); 
    }

    //총알을 삭제하고 이팩트를 생성한다 
    void DestroyBullet()
    {
        Destroy(gameObject); 
        Instantiate(explosion, transform.position, Quaternion.identity);
    }

    private void OnTriggerEnter2D(Collider2D collision)
    {
        //적캐릭터 오브젝트와 닿게 되면 이팩트를 생성하고 적캐릭터 함수에 전달하여 생명을 감소시킨다 
        if (collision.tag == "Enemy")
        {
            collision.GetComponent<Enemy>().TakeDamage(damage);
            Instantiate(explosion, transform.position, Quaternion.identity);
            DestroyBullet();
        }
    }


}

 

 

 

 

bulletCtrl 스크립트를 수정하고 Explosion  -> Particle System  speed 20 , LifeTime 3 , Damage1을 넣습니다  

 

 

 

Player 오브젝트를 선택하고 Tag  -> Player를 선택합니다  그리고 player 스크립트를 수정합니다

그리고 Game 을 실행시키면 Enemy 가 총알에 맞고 Enemy Health가 0 이 되면 Enemy가 삭제되는 것을 확인할 수 있습니다  

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour
{
    public float speed;
    private Rigidbody2D rigid;
    private Vector2 moveAmount;
    private Animator anim;

    public float health;

    private void Start() 
    { 
        rigid = GetComponent<Rigidbody2D>();
        anim = GetComponent<Animator>();
    }
    private void Update()
    { 
        //키보드(WSAD)의 좌우상하를 방향을 정의해 준다
        Vector2 moveInput = new Vector2(Input.GetAxisRaw("Horizontal"), 
            Input.GetAxisRaw("Vertical")); 
        //움직임방향에 속도를 곱한다
        moveAmount = moveInput.normalized * speed;

    //키보드를 누르면 Player 애니메이터 파라미터를 적용하고 캐릭터를 움직인다
      if (moveInput != Vector2.zero) 
        { 
            anim.SetBool("Run", true); 
        } else 
        { 
            anim.SetBool("Run", false); 
        }

    
    }
    
    private void FixedUpdate() 
    { //움직임 방향에 시간에 따라 리지드 바디 포지션값을 더한다
      rigid.MovePosition(rigid.position + moveAmount * Time.fixedDeltaTime); 
    }

    // Player의 체력을 감소 시킨다
    public void TakeDamage(int damageAmount)
    {
        health -= damageAmount;
        if (health <= 0)
        {
            Destroy(gameObject);
        }
    }
}

    

 

 

 

 

Enemy 오브젝트를 선택하고 Enemy 스크립트를 오브젝트에서 삭제 하고 MeleeEnemy 스크립트를 작성합니다 

 

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

public class MeleeEnemy : Enemy
{
    public float stopDistance;

    private float attackTime;

    public  float attackSpeed;
    private void Update()
    {
        if (player != null)
        {
            //Enemy가 Player의  stopDistance 거리 밖이라면 Player 방향으로 speed 속도로 돌진한다 
            if (Vector2.Distance(transform.position,player.position ) > stopDistance) 
            {
                transform.position =
                    Vector2.MoveTowards(transform.position, player.position, speed * Time.deltaTime);
            }
            else
            {
                //Enemy가 Player의  stopDistance 거리 안쪽에 있으면 attackTime의 딜레이를 주고 공격한다 
                if (Time.time >= attackTime)
                {
                    StartCoroutine(Attack());
                    attackTime = Time.time + timeBetweenAttacks;
                }

            }
        }
    }

    // 적캐릭터의 공격
    IEnumerator Attack()
    {
        player.GetComponent<Player>().TakeDamage(damage);

        Vector2 originalPosition = transform.position;
        Vector2 targetPosition = player.position;

        float percent = 0;

        // 한번 공격할때 공격 가속도와 치고 빠지기를 반복한다 
        while (percent <= 1)
        {
            percent += Time.deltaTime * attackSpeed;
            float formula = (-Mathf.Pow(percent, 2) + percent) * 4;
            transform.position = Vector2.Lerp(originalPosition, targetPosition, formula);
            yield return null;
        }
    }
}

 

 

 

 

 

Enemy 오브젝트의 MeleeEnemy 스크립트를 붙힘니다 

그리고 Health 2 , speed 5 , timeBetweenAttacks 2, damage 1, stopDistance 3, attackSpeed 8을 넣습니다  

 

Inspector 창에서 Player,Enemy 레이어를 추가합니다 

 

 

 

 

 

 

Edit -> ProjectSettings -> Phsics2D  에서 아래 그림과 같이

플레이어 레이어가있는 오브젝트와 적 레이어가 있는 오브젝트가 더 이상 서로 충돌하지 않기 때문에 체크 해제 합니다 

 

 

 

 

 

게임을 실행하면 적 캐릭터가 Player를 따라 다니면서 공격하는 것을 볼 수 있습니다 

Enemy_sheet.png
0.12MB

반응형
반응형

주위 배경을 위해서 Background 텍스쳐 파일을 하이 라키 뷰에 올리고 중앙에 맞춥니다 

그리고 텍스쳐 스케일을 카메라뷰보다 넓게 4,4,1로 맞춥니다  

 

 

새로운 오브젝트를 생성하고 이름을 CameraFollow 라 합니다 

 

CameraFollow 오브젝트의 자식으로 Main Camera를 옮겨다 놓습니다 

CameraFollow 스크립트를 작성합니다 

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

public class CameraFollow : MonoBehaviour
{
    //Player 포지션 
    public Transform playerTransform;

    public float speed;

    public float minX;
    public float maxX;
    public float minY;
    public float maxY;


    // Start is called before the first frame update
    void Start()
    {
        //Player 포지션을 가지고 온다 
        transform.position = playerTransform.position;
    }

    // Update is called once per frame
    void Update()
    {
        if (playerTransform != null)
        {
            //화면의 X축의 최대점과 최소점을 넘지않게 설정
            float clampedX = Mathf.Clamp(playerTransform.position.x, minX, maxX);
            //화면의 Y축의 최대점과 최소점을 넘지않게 설정
            float clampedY = Mathf.Clamp(playerTransform.position.y, minY, maxY);

            //카메라를 clampedX,clampedY 방향으로 speed 속도를 부드럽게 이동
            transform.position = Vector2.Lerp(transform.position,new Vector2(clampedX,clampedY), speed);
        }
        
    }
}

 

 

Player 오브젝트를 드래그하여 Player Transform 빈 공간에 드래그하여 붙이고 speed를 0.12  정도 합니다 

 

CameraFollow오브젝트를 X 쪽으로 -11 만큼 움직입니다 카메라가 배경 보이는 끝선에 맞춤니다 

그리고 Min X 에 -11을 넣습니다 

 

 

CameraFollow를 x축으로 그림영역 최댓값에 맞추고  MaxX를 11을 넣습니다 

 

CameraFollow를 y축으로 그림영역 최솟값에 맞추고  MinY를 -7을 넣습니다 

CameraFollow를 y축으로 그림영역 최댓값에 맞추고  MaxY를 5를 넣습니다 

 

 

하이라키뷰에 Stoper오브젝트 4개를 생성합니다 

 

Stoper 오브젝트에 BoxCollider2D를 붙이고 각각 위치를 배경 끝에 놓습니다 

 

 

Player 오브젝트에 BoxCollider2D 를 붙입니다 

게임을 실행하여 Player의 움직임에 Camera가 따라가고 배경의 보이는 부분까지만 Player가 제한되는 움직임을 보입니다 

 

 

반응형
반응형

포토샵에서 여러 가지 모양을 하얀색으로 그립니다 

바탕을 투명으로 하고 png 파일로 저장합니다 

ㅗㅗ

 

유니티에 Texture 폴더에 저장합니다 

 

 

 

particle 텍스쳐를 선택하고 아래와 같이 속성을 바꾸어줍니다 

그리고 Sprite Editor 를 클릭합니다 

Slice를 누르고 Type을  Automatic으로 하고 Slice 합니다  

 

 

Hierarchy 뷰에서 마우스 오른쪽 버튼을 누르고 Effects -> Paticle System을 생성합니다 

 

 

 

 

생성된 파티클 오브젝트를 선택하고 Rotation 을 0 ,0, 0으로 잡고  Paticle System 속성을 아래 그림과 같이 만듭니다 

 

 

 

Texture 폴더에 저장하였던 그림파일을  Texture Sheet Animation 에 Sprites에 하나씩 대입합니다 

 

Sorting Layer ID 를 새로 만들고 이름을 Effect로 하고 아래 그림과 같이 맨 마지막 위치에 레이어를 놓습니다 

 

 

 

Play  하면 아래 동영상과 같이  이팩트가 터지는 모습을 볼수있습니다 

Particle.unitypackage
0.13MB

반응형
반응형

 

Gun 오브젝트를 선택하고 총알이 나올 수 있는 포인트를 만들어 주어야 합니다 

그래서 새로운 오브젝트를 Create Empty 를 생성하고 자식으로 이름을 sPoint라고 합니다 

GunCtrl 스크립트 수정

아래와 같이 GunCtrl 스크립트를 수정합니다 

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

public class GunCtrl : MonoBehaviour
{
    public GameObject bullet;
    public Transform sPoint;
    public float timeBetweenShots;


    private float shotTime;

    void Update()
    {
        //카메라 스크린의 마우스 거리와 총과의 방향 
        Vector2 direction = Camera.main.ScreenToWorldPoint(Input.mousePosition) - transform.position;
        //마우스 거리로 부터 각도 계산
        float angle = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg;
        //축으로부터 방향과 각도의 회전값
        Quaternion rotation = Quaternion.AngleAxis(angle , Vector3.forward);
        transform.rotation = rotation;

        //마우스 왼쪽버튼을 눌렀을때
        if (Input.GetMouseButton(0))
        {
            if (Time.time >= shotTime)
            {
                //총알을 생성한다
                Instantiate(bullet, sPoint.position, Quaternion.AngleAxis(angle - 90,Vector3.forward));
                //재장전 총알 딜레이 
                shotTime = Time.time + timeBetweenShots;
            }
        }
    }
}

 

 

 

 

수정된 GunCtrl 스크립트에 프리팹으로 만들었던 bullet과 Gun 오브젝트의 자식으로 있는 sPoint를 GunCtrl스크립트에 연결합니다 

 

아래 동영상과 같이 총알이 나오는 것을 볼 수 있습니다 

 

bullet 프리팹을 선택하여 BulletCtrl 스크립트를 생성하고 작성합니다 

 

 

 

 

BulletCtrl 스크립트를 작성합니다 

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

public class BulletCtrl : MonoBehaviour
{
    public float speed;
    public float lifeTime;

    // Start is called before the first frame update
    void Start()
    {
        // 총알을 시간에 맞게 지운다 
        Destroy(gameObject, lifeTime);
    }

    // Update is called once per frame
    void Update()
    {
        // 시간프레임과 speed에 따라 y축방향으로 움직인다 
        transform.Translate(Vector2.up * speed * Time.deltaTime);
    }
}

 

 

아래 동영상과 같이 마우스에 따라 총이 움직이고 총알이 마우스에 따라 방향대로 발사되는 것을 확인합니다 

 

반응형
반응형

그림파일을 Texture 폴더에 끌어 옮겨 저장합니다 

 

Gun 텍스쳐타입을 아래 그림과 같이 바꿉니다 

 

 

 

 

Gun 그림파일의 속성에서 Sprite Editor를 들어가서 Pivot 점을 방아쇠 근처로 옮깁니다 

 

Gun 텍스쳐를 Hierachy 에 옮기고  Gun 오브젝트를 선택하여 Sorting Layer를 하나 만들고 order in Layer 1로 합니다 

 

bullet 텍스쳐를 Hierachy로 옮기고 SortingLayer를 Bullet을 만들고 Order in Layer 1로 합니다 

 

 

 

 

Prefabs 폴더를 만들고 드래그하여 프리팹을 만듭니다 

 

Gun 오브젝트를 Player 자식으로 옮기고 Gun 오브젝트에 GunCtrl 스크립트를 생성하여 작성합니다 

 

 

 

 

GunCtrl 스크립트를 작성합니다 

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

public class GunCtrl : MonoBehaviour
{

    void Update()
    {
        //카메라 스크린의 마우스 거리와 총과의 방향 
        Vector2 direction = Camera.main.ScreenToWorldPoint(Input.mousePosition) - transform.position;
        //마우스 거리로 부터 각도 계산
        float angle = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg;
        //축으로부터 방향과 각도의 회전값
        Quaternion rotation = Quaternion.AngleAxis(angle, Vector3.forward);
        transform.rotation = rotation;
    }
}

 

 

 

 

 

게임을 실행 시키고 아래 동영상과 같이 마우스 움직임에 따라 총이 움직이는 것을 확인합니다 

Texture2.zip
0.04MB

반응형
반응형

포토샵에서 Player로 사용할 캐릭터를 각 관절을 나눈 후에 파일을 저장합니다 

왜냐하면 그림파일을 유니티에 옮긴 후에 캐릭터를 움직이는 애니메이션을 주기 위함입니다 

그림파일을 PNG 파일로 저장합니다 

 

 

유니티 새프로젝트를 만들고 Assets에 폴더 이름을 Texture 라 하고 그림파일을 임포트 합니다

그림파일을 드래그 하셔서 옮기셔도 파일이 Texture파일에 들어가게 됩니다 

 

 

 

 

 

 

 

그림파일을 안드로이드 환경에서 작업하기 위해서는 그림 파일 설정을 해 주어야 합니다 

아래 그림과 같이 설정값을 바꾸고 Sprite Editor에 들어갑니다 

 

Sprite Editor 에 들어가지 않으면 Window -> Package Manager 세 들어갑니다 

 

 

package Manager에서 2 DSprite를 인스톨합니다 

 

 

 

 

 

 

 

 

그러면 Sprite Ediltor에 들어가서  자동으로 그림파일을 나누는 작업을 합니다 

아래 그림과 같이 Slilce 해주고 Apply 합니다 

 

 

그림파일을 hierarchy 창에 옮긴 후 각각의 그림파일이 보일 수 있게 Sorting Layer를 지정하고 Order in Layer 각각의 값을 줍니다 

 

하이 라키에 빈 오프젝트를 만들고 이름을 Player 하고 그림파일을 자식으로 옮깁니다 

 

 

 

 

 

 

 

 

Player를 선택하고 Window -> Animation->Animation을 선택합니다 

 

Animation 탭에서 Create New Clip.. 을 선택하여  Player_idle 을 만들고 애니메이션을  만듭니다 

 

 

 

 

Player_Run 애니메이션을 만듭니다 

 

 

 

 

Scripts 폴더를 만들고 새로운 Player 스크립트를 만듭니다  

Player 오브젝트에 Player 스크립트를 연결하고 Rigidbody2D 컴포넌트를 생성해줍니다 

그리고 Player 스크립트를 작성합니다 

 

 

 

Player 스크립트 작성

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

public class Player : MonoBehaviour
{
    public float speed;

    private Rigidbody2D rigid;

    private Vector2 moveAmount;

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

    private void Update()
    {
        //키보드(WSAD)의 좌우상하를 방향을 정의해 준다   
        Vector2 moveInput = new Vector2(Input.GetAxisRaw("Horizontal"),
            Input.GetAxisRaw("Vertical"));

        //움직임방향에 속도를 곱한다
        moveAmount = moveInput.normalized * speed;
    }

    private void FixedUpdate()
    {
        //움직임 방향에 시간에 따라 리지드 바디 포지션값을 더한다 
        rigid.MovePosition(rigid.position + moveAmount * Time.fixedDeltaTime);
    }

}

 

 

키보드에서  상하좌우 키와 WSAD 키보드를 움직이면 캐릭터가 상하 좌우 방향 대로 움직이는 것을 확인합니다 

Player.psd
1.07MB

 

 

 

 

 

Player 오브젝트를 선택하고 Animation -> Animator 를 선택합니다 

 

 

Animator 창이 뜨면 Base Layer 에서 Player_idle과 Player_Run을 서로 Make Transition 하여 연결합니다 

그리고 Parameters 에서 + 버튼을 누르고 Bool을 선택하고 이름을 Run으로 합니다 

 

 

 

Player_idle에서 Player_Run으로 가는 선을 선택하고 Conditions에서 + 추가하고 Run을 선택하고 true 하며 아래 사진과 같이 속성 값을 바꿉니다 

 

Player_Run에서 Player_idle 가는 선을 선택하고  Conditions 에서 + 추가하고 Run 하고 fale 하며 아래와 같이 속성 값을 바꿉니다 

 

 

 

Player 스크립트를 수정 합니다 

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

public class Player : MonoBehaviour
{
    public float speed;

    private Rigidbody2D rigid;

    private Vector2 moveAmount;

    private Animator anim;
    private void Start()
    {
        rigid = GetComponent<Rigidbody2D>();
        anim = GetComponent<Animator>();


    }

    private void Update()
    {
        //키보드(WSAD)의 좌우상하를 방향을 정의해 준다   
        Vector2 moveInput = new Vector2(Input.GetAxisRaw("Horizontal"),
            Input.GetAxisRaw("Vertical"));

        //움직임방향에 속도를 곱한다
        moveAmount = moveInput.normalized * speed;

        //키보드를 누르면 Player 애니메이터 파라미터를 적용하고 캐릭터를 움직인다 
        if (moveInput != Vector2.zero)
        {
            anim.SetBool("Run", true);
        }
        else
        {
            anim.SetBool("Run", false);
        }
    }

    private void FixedUpdate()
    {
        //움직임 방향에 시간에 따라 리지드 바디 포지션값을 더한다 
        rigid.MovePosition(rigid.position + moveAmount * Time.fixedDeltaTime);
    }

}

 

 

 

아래 화면과 같이 캐릭터가 평상시 Player_idle 에서 키보드 누르면 Player_Run으로 애니메이션 되는 것을 볼 수 있습니다 

 

반응형

+ Recent posts