애니메이터에 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);
}
}
}
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();
}
}
콜라이더(Collider)컴포넌트는 물리 충돌 처리를 위한 오브젝트의 형태를 정의합니다. 콜라이더는 보이지 않는 요소이므로 오브젝트의 메시와 정확히 동일한 모양일 필요는 없으며, 실제로는 게임플레이 시에는 대략적인 근사치로도 크게 구분되지 않으며 더 효율적입니다.
가장 간단한(그리고 프로세서에 부하를 주지 않는) 콜라이더는기본콜라이더 타입입니다. 3D에서는박스 콜라이더,스피어 콜라이더,캡슐 콜라이더가 바로 이 타입입니다. 2D에서는박스 콜라이더 2D와써클 콜라이더 2D를 사용할 수 있습니다.복합 콜라이더를 만들기 위해 하나의 오브젝트에 위와 같은 콜라이더를 몇 개든 추가할 수 있습니다.
대리자는 - 메서드에 대한 참조를 나타내는 형식 -> class 모든 메서드가 있는 인스턴스를 호환되는 시그니처 및 반환 형식에 연결 가능 대리자는 메서드를 다른 메서드에 인수(매개변수에 메서드를 인스턴스로 할당) 전달하는데 사용된다 시그니처 -> private 접근제한자 메서드이름 값 메서드 전달하는 것 X
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;
git add. / git commit -m "" 같은 문구를 보기 편한 UI 버튼으로 만들어주기에
보기에 편하여 사용하는 Tool 이다.
추 후
깃에 올릴때는 본인이 만든 Assets, Packages, ProjectSettings만 복사 한다 나머지 ignore + .vsconfig 깃 레포지 링크를 복사해서 sourcetree에 넣고
새폴더를 만들어 저장위치를 지정하고 클론 생성된 로컬 레포지에 들어가서 새폴더 생성 sourcetree에서 스테이지에 올리면 -> git add. 상태 그리고 메세지를 입력하여 커밋하면 로컬 레퍼지토리로 넘어간다. -> git commit -m " " 그 다음 단계는 푸시 => git push
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가 사라지게 할 것이다.
그러고 나서 생성된 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 이미지를 넣으면 완성된다.