Unity - Scripting API: Animator.SetInteger

Use this as a way to trigger transitions between Animator states. One way of using Integers instead of Floats or Booleans is to use it for something that has multiple states, for example directions (turn left, turn right etc.). Each direction could corresp

docs.unity3d.com

 

애니메이터에 State라는 이름으로 만들어준 Idle과 Run을 각각 0, 1로 지정하였고,

스크립트에서 SetInteger이라는 메소드를 통해 매개변수로 상태와 그 상태번호를 지정

 

기본 State는 0번인 서있는 상태 

키보드 위에 버튼 0번을 누르면 Idle상태

1번을 누르면 Run 상태 호출

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

public class BombGuyController : MonoBehaviour
{
    //BombGuyController가 Animator 컴포넌트를 알아야한다
    //왜? 애니메이션 전환을 해야 해서
    //Animator 컴포넌트는 자식 오브젝트 anim에 붙어 있다
    //어떻게 하면 자식오브젝트에 붙어 있는 Animator 컴포넌트를 가져올 수 있을까
    [SerializeField] private Animator anim;
    
    private void Start()
    {
        this.anim.SetInteger("State", 0);
        // [SerializeField] Animator anim; 를 쓰지 않는다면

        //Transform animTransform = this.transform.Find("anim");
        //GameObject animGo = animTransform.gameObject;
        //this.anim = animGo.GetComponent<Animator>();

        //코루틴 함수 호출시
        //this.StartCoroutine(this.CoMove());
    }

    //IEnumerator CoMove()
    //{
    //    //매 프레임마다 앞으로 이동
    //    while (true)
    //    {
    //        this.transform.Translate(transform.right * 1f * Time.deltaTime);
    //        yield return null; //다음 프레임으로 넘어간다 => while문 안에 들어가야 함
    //    }
    //}

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Alpha0))
            //Alpha+num 은 키보드 위에 숫자버튼
            //Keypad+num 은 키보드 우측 숫자버튼
        {
            Debug.Log("Idle");
            //애니메이션 전환 하기
            //전환 할 때 파라미터에 값을 변경하기
            this.anim.SetInteger("State", 0);

        }
        if (Input.GetKeyDown(KeyCode.Alpha1))
        {
            Debug.Log("Run");
            this.anim.SetInteger("State", 1);

        }

    }
}

 

'산대특 > 게임 알고리즘' 카테고리의 다른 글

Process 와 Thread 그리고 Thread 와 Coroutine  (1) 2024.02.04
Pirate Bomb - Captain(Enemy)  (0) 2024.02.02
ClimbCloud-2  (1) 2024.02.01
ClimbCloud  (2) 2024.02.01
C# 대리자, 람다함수  (1) 2024.01.31

1. ground 요소를 추가하여  Rigidbody 2D -> Body Type - Kinematic 설정하여

땅을 만들어 공중에 떠있게 만들어 주었다.

2. 캔버스 레거시 text로 velocityText를 만들어서 고양이가 제자리부터 이동거리를 수치로 표시

    -  ClimbCloudGameDirector 스크립트를 추가하고 CatController에 연결해줌으로 써 이동거리 표시

3. 고양이 선택후 Tool bar에서 Window - Animation- Animation에 들어가서 Create를 누른후 

     Assets안에 애니메이션 폴더를 만들어주고 걷는 애니메이션을 넣을 것으므로 이름을 Walk로 생성

     Animation탭 안에서 add property를 누르고 sprite 선택 후 적적할게 고양이가 나눠져서 걷는 그림을 넣어주었다.

    마지막으로 애니메이션 탭 안 우측 상단에 있는 add keyframe을 누른 후 적당한 거리 뒤에 넣으면

    마지막 프레임이 복사되고 그 프레임 안까지의 사진들이 연속적으로 실행된다.

    애니메이터는 CatController와 같은 위치에 있으므로 따로 호출하지 않아도 클래스 안에서 사용가능

    애니메이션속도를 캐릭터 움직임 속도에 맞춰 변하도록 설정

    this.anim.speed = (Mathf.Abs(this.rbody.velocity.x) / 2f);

 

4. 물리엔진을 사용해서 충돌판정

1. 둘중 하나는 리지드바디 컴포넌트가 있어야 한다

2. 두 객체모두 콜라이더가 있어야 한다

3. isTrigger 모드를 체크 한다

 

 

트리거모드는 업데이트보다 먼저 일어난다

 

5. 깃발에 도달(충돌)했을 때 화면 전환

6. 그후 화면을 터치하면 다시 복귀

7. 고양이 이동가능 거리 조절

8. 고양이가 공중에서 계속 점프하지 못하게 조건문 추가

using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.Assertions.Comparers;
using UnityEngine.SceneManagement;

public class CatController : MonoBehaviour
{
    [SerializeField] private Rigidbody2D rbody;
    [SerializeField] private float moveForce = 100f;
    [SerializeField] private float jumpForce = 680f;

    [SerializeField]
    private ClimbCloudGameDirector gameDirector;

    private Animator anim;

    private bool hasSpace = false;

    private void Start()
    {
        //this.gameObject.GetComponent<Animation>();

        anim = GetComponent<Animator>();

        //this.gameDirector = GameObject.Find("GameDirector").GetComponent<ClimbCloudGameDirector>();
        //this.gameDirector = GameObject.FindAnyObjectByType<ClimbCloudGameDirector>();

    }

    void Update()
    {
        //스페이스바를 누르면 
        if (Mathf.Abs(rbody.velocity.y) < 0.01f)

        {
            if (Input.GetKeyDown(KeyCode.Space))
            {
                if (!hasSpace)
                {
                    //힘을 가한다 
                    this.rbody.AddForce(this.transform.up * this.jumpForce);
                    //this.rbody.AddForce(Vector3.up * this.force);

                        hasSpace = false; // 다시 점프할 수 있도록 허용

                }
            }


        }
        // -1, 0, 1 : 방향 
        int dirX = 0;
        //왼쪽화살표키를 누르고 있는 동안에 
        if (Input.GetKey(KeyCode.LeftArrow))
        {
            dirX = -1;
        }

        if (Input.GetKey(KeyCode.RightArrow))
        {
            dirX = 1;
        }

        // Debug.Log(dirX); //방향 -1, 0, 1

        //스케일 X를 변경 하는데 키가 눌렸을 때만 
        //키가 눌렸을때만 = (dirX != 0)
        if (dirX != 0)
        {
            this.transform.localScale = new Vector3(dirX, 1, 1);
        }


        //벡터의 곱 
        //Debug.Log(this.transform.right * dirX);  //벡터3

        //도전 ! : 속도를 제한하자 
        //velocity.x 가 3정도가 넘어가니깐 빨라지는거 같드라구...
        if (Mathf.Abs(this.rbody.velocity.x) < 3)
        {
            this.rbody.AddForce(this.transform.right * dirX * moveForce);
        }

        this.anim.speed = (Mathf.Abs(this.rbody.velocity.x) / 2f);
        this.gameDirector.UpdateVelocityText(this.rbody.velocity);


        // Debug.Log(this.transform.position);

        float clampX = Mathf.Clamp(this.transform.position.x, -2.39f, 2.35f);
        Vector3 pos = this.transform.position;
        pos.x = clampX;
        this.transform.position = pos;


    }

    // Trigger 모드 일경우 충돌 판정을 해주는 이벤트 함수
    private bool hasEntered = false;
    private void OnTriggerEnter2D(Collider2D collision)
    {
        if (!hasEntered)
        {
            Debug.LogFormat("OnTriggerEnter2D: {0}", collision);
            SceneManager.LoadScene("ClimbCloudClear");
            hasEntered = true; // 한 번 이벤트가 발생하면 이 변수를 true로 설정하여 두 번 이상 호출되지 않도록 함

        }

    }



}

 

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

public class ChangeScene : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetMouseButton(0))
        {
            
            SceneManager.LoadScene("ClimbCloud");
            Debug.Log("화면이 전환됨");
        }
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class ClimbCloudGameDirector : MonoBehaviour
{
    [SerializeField] private Text velocityText;

    public void UpdateVelocityText(Vector2 velocity)
    {
        float velocityX = Mathf.Abs(velocity.x);
        this.velocityText.text = velocityX.ToString();
    }
}


+ 개선할 점

 

카메라가 고양이 따라가기

'산대특 > 게임 알고리즘' 카테고리의 다른 글

Pirate Bomb - Captain(Enemy)  (0) 2024.02.02
Pirate Bomb - BombGuy  (0) 2024.02.02
ClimbCloud  (2) 2024.02.01
C# 대리자, 람다함수  (1) 2024.01.31
Git, SourceTree  (1) 2024.01.31
R&D
1. 고양이(Player)가 구름 위에서 점프할 수 있도록 구현
2. 고양이가 좌우로 이동할 수 있도록 구현

 

텍스쳐와 하이어라이키를 추가하였고

 

이번에 중요한 점은 Rigidbody 2D 와 Collider 2D이다.

 

콜라이더란 물리 충돌 처리를 위한 오브젝트

고양이와 구름 둘 다 리지드바디와 콜라이더 오브젝트를 추가

그리고 각각의 radius(반지름), offset을 이용하여 크기를 조정

리지드바디

Rigidbody  GameObject 가 물리 제어로 동작하게 합니다.

리지드바디는 힘과 토크를 받아 오브젝트가 사실적으로 움직이도록 해줍니다.

리지드바디가 포함된 모든 게임 오브젝트는 중력의 영향을 받아야 하며 스크립팅을 통해 가해진 힘으로 움직이거나 NVIDIA PhysX 물리 엔진을 통해 다른 오브젝트와 상호 작용해야 합니다.

https://docs.unity3d.com/kr/2021.3/Manual/class-Rigidbody.html

 

리지드바디 - Unity 매뉴얼

Rigidbody 는 GameObject 가 물리 제어로 동작하게 합니다. 리지드바디는 힘과 토크를 받아 오브젝트가 사실적으로 움직이도록 해줍니다. 리지드바디가 포함된 모든 게임 오브젝트는 중력의 영향을

docs.unity3d.com

 

콜라이더

콜라이더(Collider) 컴포넌트는 물리 충돌 처리를 위한 오브젝트의 형태를 정의합니다. 콜라이더는 보이지 않는 요소이므로 오브젝트의 메시와 정확히 동일한 모양일 필요는 없으며, 실제로는 게임플레이 시에는 대략적인 근사치로도 크게 구분되지 않으며 더 효율적입니다.

가장 간단한(그리고 프로세서에 부하를 주지 않는) 콜라이더는 기본 콜라이더 타입입니다. 3D에서는 박스 콜라이더, 스피어 콜라이더, 캡슐 콜라이더가 바로 이 타입입니다. 2D에서는 박스 콜라이더 2D 써클 콜라이더 2D를 사용할 수 있습니다. 복합 콜라이더 를 만들기 위해 하나의 오브젝트에 위와 같은 콜라이더를 몇 개든 추가할 수 있습니다.

https://docs.unity3d.com/kr/2018.4/Manual/CollidersOverview.html

 

콜라이더 - Unity 매뉴얼

콜라이더(Collider) 컴포넌트는 물리 충돌 처리를 위한 오브젝트의 형태를 정의합니다. 콜라이더는 보이지 않는 요소이므로 오브젝트의 메시와 정확히 동일한 모양일 필요는 없으며, 실제로는 게

docs.unity3d.com

 

구름도 중력의 영향을 받아 떨어지는 것을 방지하기 위해 kinematic사용

Rigidbody 2D -> Body type -> Kinematic

 

회전축인 z축을 고정하지 않으면 다음과 같이 구름에 닿으면 넘어진다.

 

 

Constraints - Freeze Rotation - z축(초록색 회전축)의  Rotation 값을 고정

회전축인 z축을 고정하면 다음과 같이 구름에 닿으면 고정된다.

 

스페이스를 누르면 고양이가 점프를 하고

마지막으로 방향키로 고양이를 이동할 수 있도록 구현하였다.

Rigidbody.AddForce(transform.up * force)

AddForce 안에는 방향 * 힘이 들어오면 된다.

 

이동을하려면

this.rbody.AddForce(transform.right * dir * moveForce);

여기에서 방향 * 힘

 

using System.Collections;
using System.Collections.Generic;
using System.Runtime.ExceptionServices;
using UnityEngine;

public class CatController : MonoBehaviour
{
    [SerializeField]
    private Rigidbody2D rbody;
    [SerializeField]
    private float jumpForce = 200f;
    [SerializeField]
    private float moveForce = 100f;
    
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            Debug.Log("스페이스누름");
            rbody.AddForce(transform.up * jumpForce);
        }
        //방향 : -1, 0, 1
        int dir = 0;
        if (Input.GetKeyDown(KeyCode.LeftArrow))
        {
            dir = -1;
        }
        if (Input.GetKeyDown(KeyCode.RightArrow))
        {
            dir = 1;
        }
        //Debug.LogFormat(dir);
        //Debug.Log(this.transform.right * dir);

        this.rbody.AddForce(transform.right * dir * moveForce);

    }
}

'산대특 > 게임 알고리즘' 카테고리의 다른 글

Pirate Bomb - BombGuy  (0) 2024.02.02
ClimbCloud-2  (1) 2024.02.01
C# 대리자, 람다함수  (1) 2024.01.31
Git, SourceTree  (1) 2024.01.31
CatEscape 게임  (2) 2024.01.30

대리자는 - 메서드에 대한 참조를 나타내는 형식 -> class
모든 메서드가 있는 인스턴스를 호환되는 시그니처 및 반환 형식에 연결 가능
대리자는 메서드를 다른 메서드에 인수(매개변수에 메서드를 인스턴스로 할당)
전달하는데 사용된다
시그니처 -> private 접근제한자 메서드이름 값
메서드 전달하는 것 X

인스턴스를  전달 O
대리자 선언 => 형식 정의

delegate는 클래스이므로 인스턴스를 만들 수 있다.


https://learn.microsoft.com/ko-kr/dotnet/csharp/programming-guide/delegates/using-delegates


public delegate int PerformCalculation(int x, int y);
                                         클래스
반환타입 대리자명 매개변수로 구성된다.
int PerformCalculation(int x, int y); 까지 타입이자시그니처이다.

메서드와 비슷하게 생겼다.

 


대리자(메서드 참조를 나타내는 형식)

https://learn.microsoft.com/ko-kr/dotnet/csharp/programming-guide/delegates/

대리자는 C 및 C++의 함수 포인터처럼 메서드를 안전하게 캡슐화하는 형식

1.  메서드 정의
private int Sum(int a, int b){
return a+b;
}
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
2. 메서드를 연결할대리자 형식정의
public delegate int PerformCalculation(int x, int y);
시그니처
반환 타입 int 형
매개변수 2개 (int형, int형)
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
3. 대리자 인스턴스 생성
+
4. 대리자에 메서드 연결 

// Instantiate the delegate.
Callback handler = DelegateMethod;

// Call the delegate.
handler("Hello World");

 

람다함수

 

람다식을 사용하면 함수를 직접 만들지 않고

코드 블록을 넘겨줄 수 있으며,

코드의 길이를 줄이고 가독성을 높일 수 있다
ex)  매개변수의 형태 => 리턴형식;

 

 

대리자 - C# 프로그래밍 가이드

C#의 대리자는 매개 변수 목록 및 반환 형식이 있는 메서드를 나타내는 형식입니다. 대리자는 메서드를 다른 메서드에 인수로 전달하는 데 사용됩니다.

learn.microsoft.com

 

대리자 사용 - C# 프로그래밍 가이드 - C#

대리자를 사용하는 방법을 알아봅니다. 대리자는 메서드를 안전하게 캡슐화하는 개체 지향적이고 형식이 안전하며 보안이 유지되는 형식입니다.

learn.microsoft.com

 

대리자 사용 - C# 프로그래밍 가이드 - C#

대리자를 사용하는 방법을 알아봅니다. 대리자는 메서드를 안전하게 캡슐화하는 개체 지향적이고 형식이 안전하며 보안이 유지되는 형식입니다.

learn.microsoft.com

 

'산대특 > 게임 알고리즘' 카테고리의 다른 글

ClimbCloud-2  (1) 2024.02.01
ClimbCloud  (2) 2024.02.01
Git, SourceTree  (1) 2024.01.31
CatEscape 게임  (2) 2024.01.30
멤버 변수와 지역 변수  (0) 2024.01.29

깃이란?

깃다운로드 검색

윈도우면 윈도우 클릭

https://git-scm.com/downloads

 

Git - Downloads

Downloads macOS Windows Linux/Unix Older releases are available and the Git source repository is on GitHub. GUI Clients Git comes with built-in GUI tools (git-gui, gitk), but there are several third-party tools for users looking for a platform-specific exp

git-scm.com

 

버전에 맞춰 설치하면 되지만 일반적으로 이럴 것이다.

 

그 후 다른 옵션은 건들지 않고 Next만 누르면 설치가 된다

 

깃이 설치가 완료되면 깃허브를 들어가서 회원가입 or 로그인

 

https://github.com/

 

GitHub: Let’s build from here

GitHub is where over 100 million developers shape the future of software, together. Contribute to the open source community, manage your Git repositories, review code like a pro, track bugs and fea...

github.com

 

그후 레포지토리를 관리해주는 SourceTree를 설치할 것이다.

 

소스 트리 다운 로드

https://www.sourcetreeapp.com/

 

Sourcetree | Free Git GUI for Mac and Windows

A Git GUI that offers a visual representation of your repositories. Sourcetree is a free Git client for Windows and Mac.

www.sourcetreeapp.com

 

여기는 건너뛰

가끔 이렇게 깃이 설치된 경로를 못찾거나 하는 경우에 생기는 것 같은데

저기에 체크박스가 있으면 체크박스 선택 후 

고급옵션 => 기본적으로 줄 끝을 자동으로 처리하도록설정을 체크

 

 

이렇게 하면 기본적으로 Git, SourceTree 설치가 완료된다.

 

SourceTree를 사용하면 cmd창에서

git add. / git commit -m ""  같은 문구를 보기 편한 UI 버튼으로 만들어주기에

보기에 편하여 사용하는 Tool 이다. 

 

추 후

깃에 올릴때는
본인이 만든 Assets, Packages, ProjectSettings만 복사 한다 나머지 ignore + .vsconfig
깃 레포지 링크를 복사해서 sourcetree에 넣고

새폴더를 만들어 저장위치를 지정하고 클론
생성된 로컬 레포지에 들어가서 새폴더 생성
sourcetree에서 스테이지에 올리면 -> git add. 상태
그리고 메세지를 입력하여 커밋하면 로컬 레퍼지토리로 넘어간다. -> git commit -m " "
그 다음 단계는 푸시 => git push

'산대특 > 게임 알고리즘' 카테고리의 다른 글

ClimbCloud  (2) 2024.02.01
C# 대리자, 람다함수  (1) 2024.01.31
CatEscape 게임  (2) 2024.01.30
멤버 변수와 지역 변수  (0) 2024.01.29
유니티 실행 시 인터페이스  (0) 2024.01.25

우선 textures에 새로운 사진들을 첨부한후

Texture Type을 Sprite(2D and UI)로 변경후 Apply 

 

배경을 덮은 후 

캐릭터를 가져오는데 뒤에 가려져서 보이지 않으면

다음과 같이 Order in Layer을 1로 변경하면 앞에 배치된다.

 

캐릭터에 적용 할 c# script의 제목으로 PlayerController로 저장후

이동과 이동시 콘솔에 찍히도록 코드를 작성

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

public class PlayerController : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.LeftArrow))
        {
            Debug.Log("왼쪽으로 2유닛만큼 이동");
            this.transform.Translate(-2, 0, 0);
        }
        if (Input.GetKeyDown(KeyCode.RightArrow))
        {
            Debug.Log("오른쪽으로 2유닛만큼 이동");
            this.transform.Translate(2, 0, 0);
        }
    }
}

 

그 후 화살표가 땅에 닿으면 사라지게 작성

아래 콘솔을 보면 arrow의 좌표가 찍히다가 사라지는 것을 알 수 있다.

using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEngine.Windows.Speech;

public class ArrowController : MonoBehaviour
{
    [SerializeField] private float speed = 1f;
    void Start()
    {

    }

    void Update()
    {
        // 화살표가 내려오면서 Console에 찍히도록 
        Vector3 movement = Vector3.down * speed * Time.deltaTime; // 방향 * 속도 * 시간
        this.transform.Translate(movement);
        Debug.LogFormat("y: {0}", this.transform.position.y);
        
        if(this.transform.position.y <= -3.56)
        {
            Destroy(this.gameObject);
        }
    }
}

 

그리고 이제 충돌하면 사라지게 만들 것인데

그러기 위해 두 텍스쳐간의 radius (캐릭터를 중심으로한 테두리 원이라 생각하면 편하다.)을 보이는 선을 지정해주고

두 텍스쳐간의 거리가 두텍스쳐간의 radius의 합보다 가까워 지면 arrow가 사라지게 할 것이다.

https://docs.unity3d.com/ScriptReference/Gizmos.DrawWireSphere.html

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

public class PlayerController : MonoBehaviour
{
    public float radius = 1f; // radius를 개발자가 인스펙터에서 바꿀수 있도록 선언
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.LeftArrow))
        {
            Debug.Log("왼쪽으로 2유닛만큼 이동");
            this.transform.Translate(-2, 0, 0);
        }
        if (Input.GetKeyDown(KeyCode.RightArrow))
        {
            Debug.Log("오른쪽으로 2유닛만큼 이동");
            this.transform.Translate(2, 0, 0);
        }
    }
    private void OnDrawGizmos()
    {
        Gizmos.color = Color.red;
        Gizmos.DrawWireSphere(this.transform.position, this.radius);
    }

}

 

using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEngine.Windows.Speech;

public class ArrowController : MonoBehaviour
{
    [SerializeField] private float speed = 1f;
    [SerializeField] private float radius = 1f;

    private GameObject playerGo;
    void Start()
    {
        this.playerGo = GameObject.Find("player");
    }

    void Update()
    {
        // 화살표가 내려오면서 Console에 찍히도록 
        Vector3 movement = Vector3.down * speed * Time.deltaTime; // 방향 * 속도 * 시간
        this.transform.Translate(movement);
        Debug.LogFormat("y: {0}", this.transform.position.y);
        
        if(this.transform.position.y <= -3.56)
        {
            Destroy(this.gameObject);
        }
        // 두 텍스쳐(arrow, player) 간의 거리
        Vector2 p1 = this.transform.position;
        Vector2 p2 = this.playerGo.transform.position;
        Vector2 dir = p1 - p2; // 방향
        float distance = dir.magnitude; // 거리 
        // float distance = Vector2.Distane(p1,p2); // => 거리만 알고 싶을 때

        // 두 radius 간의 거리
        float r1 = this.radius;
        PlayerController controller = this.playerGo.GetComponent<PlayerController>();
        float r2 = controller.radius;// 여기서 보호 수준 때문에 PlayController.cs 의 radius를 퍼블릭으로 변경
        float sumRadius = r1 + r2;

        // 두 텍스쳐간의 거리가 두텍스쳐간의 radius의 합보다 가까워 지면 arrow가 충돌이라 인지하고 arrow를 사라지게 할 것이다.
        if(distance < sumRadius)
        {
            Debug.LogFormat("충돌함: {0}, {1}", distance, sumRadius);
            Destroy(this.gameObject) ;
        }
    }
    private void OnDrawGizmos()
    {
        Gizmos.color = Color.red;
        Gizmos.DrawWireSphere(this.transform.position, this.radius);
    }

}

 


 

프리팹

프리팹 : 게임 오브젝트를 파일화 시킨것 (에셋)

https://docs.unity3d.com/kr/2018.4/Manual/Prefabs.html

 

프리팹 - Unity 매뉴얼

Unity의 프리팹 시스템을 이용하면 게임 오브젝트를 생성, 설정 및 저장할 수 있으며, 해당 게임 오브젝트의 모든 컴포넌트, 프로퍼티 값, 자식 게임 오브젝트를 재사용 가능한 에셋으로 만들 수

docs.unity3d.com

 

아래와 같이 하이어라이키에 있는 arrow를 새폴더(Prefabs)를 만들어 넣어주었고,

그러면 하이어라이키에 있는 arrow는 삭제해도 된다.

 

그 후 c# script를 만들어서 아래와 같은 선언

 

그러고 나서 생성된 gameObject의 arrowPrefab에 Prefabs에 있는 arrow를 할당

 

클론한 arrow가 떨어지게 한다.

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

public class ArrowGenerator : MonoBehaviour
{
    //프리팹 에셋을 가지고 프리팹 인스턴스를 만든다 
    [SerializeField] private GameObject arrowPrefab;

    void Start()
    {
        GameObject go = Instantiate(this.arrowPrefab);  //프리팹 인스턴스 
        //위치는 프리팹 에셋에 설정된 위치 
        //위치를 재설정 
        Debug.LogFormat("go: {0}", go);
    }

    void Update()
    {

    }
}

 

델타를 선언한후 3이될때마다 새로운 arrow 출력

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

public class ArrowGenerator : MonoBehaviour
{
    //프리팹 에셋을 가지고 프리팹 인스턴스를 만든다 
    [SerializeField] private GameObject arrowPrefab;
    private float delta;
    void Start()
    {
       
    }

    void Update()
    {
        delta += Time.deltaTime;
        Debug.Log(delta);
        if (delta >= 3)
        {
            GameObject go = Instantiate(this.arrowPrefab);  //프리팹 인스턴스 
                                                            //위치는 프리팹 에셋에 설정된 위치 
                                                            //위치를 재설정 
            delta = 0;
        }
    }
}

 

 

이제 기즈모의 테두리를 볼 필요 없으니 기즈모 부분만 주석처리하고

화살표 떨어지는것의 방향 Vector3는 구조체 이므로 x좌표만 랜덤으로 지정하였다.

(y, z는 기존에 ArrowController에서 0으로 지정하였기에 좌표만 찍어주면 된다.)

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

public class ArrowGenerator : MonoBehaviour
{
    //프리팹 에셋을 가지고 프리팹 인스턴스를 만든다 
    [SerializeField] private GameObject arrowPrefab;
    private float delta;
    void Start()
    {
       
    }

    void Update()
    {
        delta += Time.deltaTime;  //이전 프레임과 현재 프레임 사이 시간 
        //Debug.Log(delta);
        if (delta > 3)  //3초보다 크다면 
        {
            GameObject go = Object.Instantiate(this.arrowPrefab); // 생성
            float randX = Random.Range(-9.7f, 9.7f); // 화살표가 화면 상에 떨어질 범위
            go.transform.position = new Vector3(randX, go.transform.position.y, go.transform.position.z); // x축 위치만 랜덤하게
            delta = 0;  //경과 시간을 초기화 
        }
    }
}


이제 체력바를 만들어줄건데

하이어라이키에 우클릭후 ui-canvas 로 만들어주고

저렇게 두군데를 canvas scaler에 있는 scale with screen size, expand를 해줘야

각각의 다른 매체에서 열 때 화면 사이즈 최적화가 된다.

 

 

이렇게 캔버스 안에 이미지를 넣어주고 적절하게 크기 조절 후 배치

※캔버스가 너무 커서 이미지가 scene에 잘 안보일수 있으므로

하이라이키에 있는 이미지를 더블클릭해서 위치 찾기

 

그후 보기와 같이 이미지 타입과

fill origin은 기호에 맞게 설정한후

fill amount 수치를 바꾸면 원안에 파란색 게이지가 변함을 확인할 수 있다.

새로운 하이어라이키와 script 생성 후 오브젝트로 넣는다.

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI; // UI를 사용할 것이므로 추가

public class CatEscapeGameDirector : MonoBehaviour
{
    [SerializeField] private Image hpGauge;

    public void DecreaseHp() //체력을 감소시키는 메서드 생성
    {
        this.hpGauge.fillAmount -= 0.1f; //충돌할때마다 체력을 감소하기 위한 선언
    }
}

 

맴버변수에 선언

이름으로 게임오브젝트를 찾는 것에 FindObjectOfType<CatEscapeGameDirector>(); 추가

마지막에 충돌했을 때 체력이 감소하는 메서드 선언

using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEngine.Windows.Speech;

public class ArrowController : MonoBehaviour
{
    [SerializeField] private float speed = 1f;
    [SerializeField] private float radius = 1f;

    private GameObject playerGo;

    //동적으로 생성되는 메서드는 씬에 있는것 을 Assign 할수 없다 
    private CatEscapeGameDirector gameDirector;
    void Start()
    {
        //이름으로 게임오브젝트를 찾는다 
        this.playerGo = GameObject.Find("player");
        this.gameDirector = GameObject.FindObjectOfType<CatEscapeGameDirector>();
    }

    void Update()
    {
        // 화살표가 내려오면서 Console에 찍히도록 
        Vector3 movement = Vector3.down * speed * Time.deltaTime; // 방향 * 속도 * 시간
        this.transform.Translate(movement);
        //Debug.LogFormat("y: {0}", this.transform.position.y);
        
        if(this.transform.position.y <= -3.56)
        {
            Destroy(this.gameObject);
        }
        // 두 텍스쳐(arrow, player) 간의 거리
        Vector2 p1 = this.transform.position;
        Vector2 p2 = this.playerGo.transform.position;
        Vector2 dir = p1 - p2; // 방향
        float distance = dir.magnitude; // 거리 
        // float distance = Vector2.Distane(p1,p2); // => 거리만 알고 싶을 때

        // 두 radius 간의 거리
        float r1 = this.radius;
        PlayerController controller = this.playerGo.GetComponent<PlayerController>();
        float r2 = controller.radius;// 여기서 보호 수준 때문에 PlayController.cs 의 radius를 퍼블릭으로 변경
        float sumRadius = r1 + r2;

        // 두 텍스쳐간의 거리가 두텍스쳐간의 radius의 합보다 가까워 지면 arrow가 충돌이라 인지하고 arrow를 사라지게 할 것이다.
        if(distance < sumRadius)
        {
            Debug.LogFormat("충돌함: {0}, {1}", distance, sumRadius);
            Destroy(this.gameObject) ;
            this.gameDirector.DecreaseHp();
        }
    }
    private void OnDrawGizmos()
    {
        //Gizmos.color = Color.red;
        //Gizmos.DrawWireSphere(this.transform.position, this.radius);
    }

}

 

그리고 마지막으로 만들어 hpGauge 오브젝트에 하이러라이키에 있는 hp 이미지를 넣으면 완성된다.

 

 

'산대특 > 게임 알고리즘' 카테고리의 다른 글

C# 대리자, 람다함수  (1) 2024.01.31
Git, SourceTree  (1) 2024.01.31
멤버 변수와 지역 변수  (0) 2024.01.29
유니티 실행 시 인터페이스  (0) 2024.01.25
게임 아이템 정보 출력  (0) 2024.01.24

Class의 멤버로는 멤버변수와 멤버메서드가 있다.

 

<멤버변수>

 

멤버변수란 Class 내에 선언되는 변수

멤버변수도 클래스변수, 인스턴스변수 2가지로 나눈다.

클래스변수는 static으로 선언하여 인스턴스를 생성하지 않아도 접근하여 사용할 수 있으며,

new를 통한 인스턴스 생성시 static은 제외하고 생성된다.

인스턴스 변수는 new를 통하여 인스턴스를 생성 시 메모리가 할당되어 인스턴스 생성 후 부터 사용

private수준의 변수에 접근할 때에는 Class내에서 "this."를 이용하여 접근하고,

public수준의 변수에 접근할 때에는 Class밖에서도 ClassName.변수명 을 통하여 접근이 가능

 


 

<지역변수>

지역변수는 각 Method내에서 선언되고 존재하는 변수

Method가 호출되면서 Stack에 변수포함 데이터들이 쌓이고,

Method가 소멸하면서 Stack이 비워지기 때문에 지역변수는 Method가 소멸할 때 같이 소멸

즉 지역변수는 Method내부가 아닌 다른 곳에서 사용하려고 하면 사용할 수 없다.

'산대특 > 게임 알고리즘' 카테고리의 다른 글

C# 대리자, 람다함수  (1) 2024.01.31
Git, SourceTree  (1) 2024.01.31
CatEscape 게임  (2) 2024.01.30
유니티 실행 시 인터페이스  (0) 2024.01.25
게임 아이템 정보 출력  (0) 2024.01.24

유니티를 실행했을 때 인터페이스

참고: https://docs.unity3d.com/kr/2018.4/Manual/Le

 

Toolbar :

 

 

Scene View :

 

 

Hierarchy Window :

 

 

Inspector Window :

 

Toolbar :

'산대특 > 게임 알고리즘' 카테고리의 다른 글

C# 대리자, 람다함수  (1) 2024.01.31
Git, SourceTree  (1) 2024.01.31
CatEscape 게임  (2) 2024.01.30
멤버 변수와 지역 변수  (0) 2024.01.29
게임 아이템 정보 출력  (0) 2024.01.24

<예시 이미지>

이미지 예시

 

1. 코드

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _20240124
{
    internal class Program
    {
        static void Main(string[] args)
        {
            string weaponName = "Hand Axe";
            string weaponType = "Axe";
            float DamagePerSecond = 3.2f;
            int minDamage = 2;
            int maxDamage = 3;
            float AttacksPerSecond = 1.30f;

            Console.WriteLine(weaponName);
            Console.WriteLine(weaponType);
            Console.WriteLine(DamagePerSecond);
            Console.WriteLine("Damage Per Second");
            Console.WriteLine("{0}-{1} Damage", minDamage, maxDamage);
            Console.WriteLine($"{AttacksPerSecond:F2} Attacks Per Second");
        }
    }
}

 

 

 

1. 출력

 

2. 코드

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _20240124
{
    internal class Program
    {
        static void Main(string[] args)
        {
            string weaponName = "Aidan's Revenge";
            string weaponType = "Axe";
            float DamagePerSecond = 10.4f;
            int minDamage = 6;
            int maxDamage = 10;
            float AttacksPerSecond = 1.30f;

            Console.WriteLine(weaponName);
            Console.WriteLine(weaponType);
            Console.WriteLine(DamagePerSecond);
            Console.WriteLine("Damage Per Second");
            Console.WriteLine("{0}-{1} Damage", minDamage, maxDamage);
            Console.WriteLine($"{AttacksPerSecond:F2} Attacks Per Second");
        }
    }
}

 

2. 출력

 

3. 코드

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _20240124
{
    internal class Program
    {
        static void Main(string[] args)
        {
            string weaponName = "Weathered Hand Axe";
            string weaponType = "Axe";
            float DamagePerSecond = 3.0f;
            int minDamage = 2;
            int maxDamage = 3;
            float AttacksPerSecond = 1.20f;

            Console.WriteLine(weaponName);
            Console.WriteLine(weaponType);
            Console.WriteLine(DamagePerSecond);
            Console.WriteLine("Damage Per Second");
            Console.WriteLine("{0}-{1} Damage", minDamage, maxDamage);
            Console.WriteLine($"{AttacksPerSecond:F2} Attacks Per Second");
        }
    }
}

 

3. 출력

 

4. 코드

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _20240124
{
    internal class Program
    {
        static void Main(string[] args)
        {
            string weaponName = "Broad Axe";
            string weaponType = "Axe";
            float DamagePerSecond = 7.1f;
            int minDamage = 4;
            int maxDamage = 7;
            float AttacksPerSecond = 1.30f;

            Console.WriteLine(weaponName);
            Console.WriteLine(weaponType);
            Console.WriteLine(DamagePerSecond);
            Console.WriteLine("Damage Per Second");
            Console.WriteLine("{0}-{1} Damage", minDamage, maxDamage);
            Console.WriteLine($"{AttacksPerSecond:F2} Attacks Per Second");
        }
    }
}

 

4.  출력

 

5. 코드

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _20240124
{
    internal class Program
    {
        static void Main(string[] args)
        {
            string weaponName = "Heavy Axe";
            string weaponType = "Axe";
            float DamagePerSecond = 17.5f;
            int minDamage = 10;
            int maxDamage = 17;
            float AttacksPerSecond = 1.30f;

            Console.WriteLine(weaponName);
            Console.WriteLine(weaponType);
            Console.WriteLine(DamagePerSecond);
            Console.WriteLine("Damage Per Second");
            Console.WriteLine("{0}-{1} Damage", minDamage, maxDamage);
            Console.WriteLine($"{AttacksPerSecond:F2} Attacks Per Second");
        }
    }
}

 

5. 출력

 

6. 코드

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _20240124
{
    internal class Program
    {
        static void Main(string[] args)
        {
            string weaponName = "Marauder Axe";
            string weaponType = "Axe";
            float DamagePerSecond = 26.6f;
            int minDamage = 15;
            int maxDamage = 26;
            float AttacksPerSecond = 1.30f;

            Console.WriteLine(weaponName);
            Console.WriteLine(weaponType);
            Console.WriteLine(DamagePerSecond);
            Console.WriteLine("Damage Per Second");
            Console.WriteLine("{0}-{1} Damage", minDamage, maxDamage);
            Console.WriteLine($"{AttacksPerSecond:F2} Attacks Per Second");
        }
    }
}

 

6. 출력

 

7. 코드

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _20240124
{
    internal class Program
    {
        static void Main(string[] args)
        {
            string weaponName = "Toporok";
            string weaponType = "Axe";
            float DamagePerSecond = 101.4f;
            int minDamage = 55;
            int maxDamage = 101;
            float AttacksPerSecond = 1.30f;

            Console.WriteLine(weaponName);
            Console.WriteLine(weaponType);
            Console.WriteLine(DamagePerSecond);
            Console.WriteLine("Damage Per Second");
            Console.WriteLine("{0}-{1} Damage", minDamage, maxDamage);
            Console.WriteLine($"{AttacksPerSecond:F2} Attacks Per Second");
        }
    }
}

 

7. 출력

 

8. 코드

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _20240124
{
    internal class Program
    {
        static void Main(string[] args)
        {
            string weaponName = "Masakari";
            string weaponType = "Axe";
            float DamagePerSecond = 118.3f;
            int minDamage = 64;
            int maxDamage = 118;
            float AttacksPerSecond = 1.30f;

            Console.WriteLine(weaponName);
            Console.WriteLine(weaponType);
            Console.WriteLine(DamagePerSecond);
            Console.WriteLine("Damage Per Second");
            Console.WriteLine("{0}-{1} Damage", minDamage, maxDamage);
            Console.WriteLine($"{AttacksPerSecond:F2} Attacks Per Second");
        }
    }
}

 

8. 출력

 

9. 코드

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _20240124
{
    internal class Program
    {
        static void Main(string[] args)
        {
            string weaponName = "Tomahawk";
            string weaponType = "Axe";
            float DamagePerSecond = 129.3f;
            int minDamage = 70;
            int maxDamage = 129 ;
            float AttacksPerSecond = 1.30f;

            Console.WriteLine(weaponName);
            Console.WriteLine(weaponType);
            Console.WriteLine(DamagePerSecond);
            Console.WriteLine("Damage Per Second");
            Console.WriteLine("{0}-{1} Damage", minDamage, maxDamage);
            Console.WriteLine($"{AttacksPerSecond:F2} Attacks Per Second");
        }
    }
}

 

9. 출력

 

10. 코드

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _20240124
{
    internal class Program
    {
        static void Main(string[] args)
        {
            string weaponName = "Two-Handed Club";
            string weaponType = "Two-Handed Mace";
            float DamagePerSecond = 15.8f;
            int minDamage = 17;
            int maxDamage = 18 ;
            float AttacksPerSecond = 0.90f;

            Console.WriteLine(weaponName);
            Console.WriteLine(weaponType);
            Console.WriteLine(DamagePerSecond);
            Console.WriteLine("Damage Per Second");
            Console.WriteLine("{0}-{1} Damage", minDamage, maxDamage);
            Console.WriteLine($"{AttacksPerSecond:F2} Attacks Per Second");
        }
    }
}

 

10. 출력

'산대특 > 게임 알고리즘' 카테고리의 다른 글

C# 대리자, 람다함수  (1) 2024.01.31
Git, SourceTree  (1) 2024.01.31
CatEscape 게임  (2) 2024.01.30
멤버 변수와 지역 변수  (0) 2024.01.29
유니티 실행 시 인터페이스  (0) 2024.01.25

+ Recent posts