티스토리 뷰
어제 에니메이터랑 뭐여러가지에서 놓치는 부분이 많았는데 이제 아주 익숙해졌다 하하 그래서 오늘은 사진이 없다 티스토리에 올리기 편해서 좋다..
그리고 과제도 나름 빠르게 하는 것 같다 뿌듯…
💻 Unity
Update vs FixedUpdate
구분 | Update() | FixedUpdate() |
실행 빈도 | 프레임마다 실행 (FPS에 따라 변동) | 물리 업데이트마다 일정한 시간 간격으로 실행 |
사용 목적 | 입력 처리, 애니메이션, UI 업데이트 등 | 물리 엔진을 사용하는 오브젝트(Rigidbody) 업데이트 |
시간 간격 | Time.deltaTime 사용 | Time.fixedDeltaTime 사용 (기본값 0.02초) |
예제 사용처 | transform.position += Vector3.forward * speed * Time.deltaTime; | rigidbody.velocity = new Vector3(1, 0, 0); |
Rigidbody와 Collider
Rigidbody | 물리 연산(중력, 힘, 충돌 등)을 적용하기 위한 물리 엔진 컴포넌트 |
Collider | 물리적인 충돌 영역을 정의하는 컴포넌트 (실제 렌더링되지 않음) |
- Rigidbody 없이 Collider만 있으면: 충돌 감지는 가능하지만 물리적인 반응 없음
- Collider 없이 Rigidbody만 있으면: 물리 연산 적용되지만, 충돌 감지 불가능
- 둘 다 있으면 : 정상적인 물리 연산(중력, 충돌, 반응) 수행 가능
🕹️ 게임 만들기
1945
Player
public float moveSpeed = 5f;
public Animator MyAnimator;
// 총알
public GameObject MyBullet;
public Transform pos = null;
// 아이템
// 레이저
private Vector2 minBounds;
private Vector2 maxBounds;
void Start()
{
MyAnimator = GetComponent<Animator>();
SetCameraBound();
}
private void SetCameraBound()
{
// 화면 경계 설정
Camera cam = Camera.main;
Vector3 bottomLeft = cam.ViewportToWorldPoint(new Vector3(0, 0, 0));
Vector3 topRight = cam.ViewportToWorldPoint(new Vector3(1, 1, 0));
minBounds = new Vector2(bottomLeft.x, bottomLeft.y);
maxBounds = new Vector2(topRight.x, topRight.y);
}
void Update()
{
MovePlayer();
SetAnimation();
FireBullet();
}
private void MovePlayer()
{
float moveX = Input.GetAxis("Horizontal") * moveSpeed * Time.deltaTime;
float moveY = Input.GetAxis("Vertical") * moveSpeed * Time.deltaTime;
Vector3 newPosition = transform.position + new Vector3(moveX, moveY, 0);
// 경계를 벗어나지 않도록 위치 제한
newPosition.x = Mathf.Clamp(newPosition.x, minBounds.x, maxBounds.x);
newPosition.y = Mathf.Clamp(newPosition.y, minBounds.y, maxBounds.y);
transform.position = newPosition;
}
private void FireBullet()
{
if (Input.GetKeyDown(KeyCode.Space))
{
Instantiate(MyBullet, pos.position, Quaternion.identity);
}
}
private void SetAnimation()
{
if (Input.GetAxis("Horizontal") <= -0.25f)
{
MyAnimator.SetBool("left", true);
}
else
{
MyAnimator.SetBool("left", false);
}
if (Input.GetAxis("Horizontal") >= 0.25f)
{
MyAnimator.SetBool("right", true);
}
else
{
MyAnimator.SetBool("right", false);
}
if (Input.GetAxis("Vertical") >= 0.25f)
{
MyAnimator.SetBool("up", true);
}
else
{
MyAnimator.SetBool("up", false);
}
}
HomingBullet
public GameObject Target; // 플레이어
public float moveSpeed = 3f;
Vector2 homingVector;
Vector2 normalizedHomingVector;
void Start()
{
SetHomingVector();
}
void Update()
{
transform.Translate(normalizedHomingVector * moveSpeed * Time.deltaTime);
}
private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.CompareTag("Player"))
{
Destroy(gameObject);
// 플레이어 지우기
}
}
private void SetHomingVector()
{
Target = GameObject.FindGameObjectWithTag("Player");
homingVector = Target.transform.position - transform.position; // A - B : A를 바라보는 벡터 (Player - HBullet)
normalizedHomingVector = homingVector.normalized; // Normalize
//transform.position = Vector3.MoveTowards(transform.position, Target.transform.position, moveSpeed * Time.deltaTime);
}
private void OnBecameInvisible()
{
Destroy(gameObject);
}
SpawnManager
public float spawnStartX = -2;
public float spawnEndX = 2;
public float spawnStartTime = 1;
public float spawnStopTime = 10;
public GameObject MyMonster;
public GameObject MyMonster2;
private bool isMonster1 = true;
private bool isMonster2 = true;
void Start()
{
StartCoroutine("RandomSpawn");
Invoke("Stop", spawnStopTime);
}
IEnumerator RandomSpawn()
{
while (isMonster1)
{
yield return new WaitForSeconds(spawnStartTime);
float x = Random.Range(spawnStartX, spawnEndX);
Vector2 pos = new Vector2(x, transform.position.y);
Instantiate(MyMonster, pos, Quaternion.identity);
}
}
IEnumerator RandomSpawn2()
{
while (isMonster2)
{
yield return new WaitForSeconds(spawnStartTime + 2);
float x = Random.Range(spawnStartX, spawnEndX);
Vector2 pos = new Vector2(x, transform.position.y);
Instantiate(MyMonster2, pos, Quaternion.identity);
}
}
private void Stop()
{
isMonster1 = false;
StopCoroutine("RandomSpawn");
isMonster2 = true;
StartCoroutine("RandomSpawn2");
Invoke("Stop2", spawnStopTime + 20);
}
private void Stop2()
{
isMonster2 = false;
StopCoroutine("RandomSpawn2");
// 보스
}
📝 과제
적 사망시 아이템 드롭, 데미지 강화 구현
public static GameManager Instance;
private int _gainedItemCnt;
public int GainedItemCnt
{
get { return _gainedItemCnt; }
set
{
if (_gainedItemCnt != value)
{
_gainedItemCnt = value;
}
}
}
public int DropedItemCnt = 0;
public float AttackPower = 10;
private void Awake()
{
if (Instance == null)
{
Instance = this;
}
GainedItemCnt = 0;
}
public float moveSpeed = 5f;
public Animator MyAnimator;
// 총알
public GameObject MyBullet;
public GameObject MyBullet2;
public GameObject MyBullet3;
public GameObject MyBullet4;
public Transform pos = null;
// 아이템
// 레이저
private Vector2 minBounds;
private Vector2 maxBounds;
void Start()
{
MyAnimator = GetComponent<Animator>();
SetCameraBound();
}
private void SetCameraBound()
{
// 화면 경계 설정
Camera cam = Camera.main;
Vector3 bottomLeft = cam.ViewportToWorldPoint(new Vector3(0, 0, 0));
Vector3 topRight = cam.ViewportToWorldPoint(new Vector3(1, 1, 0));
minBounds = new Vector2(bottomLeft.x, bottomLeft.y);
maxBounds = new Vector2(topRight.x, topRight.y);
}
void Update()
{
MovePlayer();
SetAnimation();
FireBullet();
}
private void MovePlayer()
{
float moveX = Input.GetAxis("Horizontal") * moveSpeed * Time.deltaTime;
float moveY = Input.GetAxis("Vertical") * moveSpeed * Time.deltaTime;
Vector3 newPosition = transform.position + new Vector3(moveX, moveY, 0);
// 경계를 벗어나지 않도록 위치 제한
newPosition.x = Mathf.Clamp(newPosition.x, minBounds.x, maxBounds.x);
newPosition.y = Mathf.Clamp(newPosition.y, minBounds.y, maxBounds.y);
transform.position = newPosition;
}
private void FireBullet()
{
if (Input.GetKeyDown(KeyCode.Space))
{
switch (GameManager.Instance.GainedItemCnt)
{
case 0:
Instantiate(MyBullet, pos.position, Quaternion.identity);
break;
case 1:
Instantiate(MyBullet2, pos.position, Quaternion.identity);
break;
case 2:
Instantiate(MyBullet3, pos.position, Quaternion.identity);
break;
case 3:
Instantiate(MyBullet4, pos.position, Quaternion.identity);
break;
default:
break;
}
}
}
private void SetAnimation()
{
if (Input.GetAxis("Horizontal") <= -0.25f)
{
MyAnimator.SetBool("left", true);
}
else
{
MyAnimator.SetBool("left", false);
}
if (Input.GetAxis("Horizontal") >= 0.25f)
{
MyAnimator.SetBool("right", true);
}
else
{
MyAnimator.SetBool("right", false);
}
if (Input.GetAxis("Vertical") >= 0.25f)
{
MyAnimator.SetBool("up", true);
}
else
{
MyAnimator.SetBool("up", false);
}
}
'Unity > 멋쟁이사자처럼' 카테고리의 다른 글
멋쟁이 사자처럼 부트캠프 유니티 게임 개발 4기 17일차 회고 (0) | 2025.04.03 |
---|---|
멋쟁이 사자처럼 부트캠프 유니티 게임 개발 4기 16일차 회고 (0) | 2025.04.03 |
멋쟁이 사자처럼 부트캠프 유니티 게임 개발 4기 14일차 회고 (0) | 2025.03.12 |
멋쟁이 사자처럼 부트캠프 유니티 게임 개발 4기 13일차 회고 (0) | 2025.03.11 |
멋쟁이 사자처럼 부트캠프 유니티 게임 개발 4기 12일차 회고 (0) | 2025.03.11 |