티스토리 뷰
메인을 만들어본다. 사실 메인도 초보가 하기에 딱 좋다. 오히려 처음에 만들면서 만났던 이상한 에러들을 보여주고 싶은데, 재현을 할 수 있을지는 한 번 해보면서 나오면 따로 써보겠다.
Gamelog 20. 총알피하기 게임 만들기(4)
총알
- 캐릭터를 향해서 일자로 전진함
- 일정시간마다 계속 생성되며 점점 속도가 빨라짐
- 캐릭터와 닿으면 멈춤
Gamelog 20_1. 총알 캐릭터를 향하게 하기
기본세팅
행성이 날라오는 것을 피하는 것처럼 표현하고자 한다.
따라서 별사탕 같은 이미지를 사용하였으며,Scale
은 캐릭터는 0.3, 0.3 이었으나 별사탕은 0.25, 0.25로 약간 더 작게 설정하였다.
그리고 Sorting Layer
는 Characters
로 설정한다.
캐릭터에 향하게 하기
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Direct_TargetObjtect : MonoBehaviour {
public string targetObjectName; // 목표 오브젝트 이름 : Inspector에 지정
private float speed = 1;
GameObject targetObject;
Rigidbody2D rbody;
Vector3 dir;
void Start() {
targetObject = GameObject.Find(targetObjectName); // 목표 오브젝트를 찾아낸다
// 중력을 0으로 해서 충돌 시에 회전시키지 않는다
rbody = GetComponent<Rigidbody2D>();
rbody.gravityScale = 0;
rbody.constraints = RigidbodyConstraints2D.FreezeRotation;
// 방향만 지닌 Vector로 변경한다.
dir = (targetObject.transform.position - this.transform.position).normalized;
}
// 생성시 캐릭터가 있던 방향으로 움직인다.
void FixedUpdate() {
rbody.velocity = new Vector2(dir.x * speed, dir.y * speed);
}
}
Direct\_TargetObject
스크립트를 생성한다.targetObject
는 Inspector에서 설정할 수 있도록 한다.
방향을 찾기 위해서는,
타겟 오브젝트의 위치에서 별사탕의 position을 제거하면 방향만 남게 되게 되는데
이때 normalized
를 통해 같은 방향을 유지한 길이가 1.0인 벡터를 반환하게 되는 방식을 활용한다.
이전에 한 방식을 참고하였다. (게시글 바로가기)
이 스크립트를 별사탕에 컴포넌트로 추가하고, Target Obejct Name
을 설정한다.
Rigidbody 2D 컴포넌트도 함께 추가한다.
캐릭터의 방향으로 움직이는 별사탕이 생성되었다.
Gamelog 20_2. 일정시간마다 생성되게 하기
먼저 사방에서 날라올 수 있도록 하기 위해 그 범위를 생성한다.
이 block 이미지를 활용하여 세팅을 해준다.
이 방법 외에도 다른 방법이 있을지 모르지만 이전 게시글에서 배운 방법을 응용해서 구현해보았다.
Block 오브젝트의 Draw Mode
를 Tiled
로 설정하고, Sorting Layer를 BackGround
로 설정했다.
그리고 메인카메라 밖에서 사방으로 둘러 별사탕을 생성할 것이다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// 범위 내에 랜덤으로 프리팹을 만든다
public class Sometime_RandomCreatePrefab : MonoBehaviour {
public GameObject newPrefab; // 만드는 프리팹 :Inspector에 지정한다
public float intervalSec = 1; // 작성 간격(초):Inspector로에 지정한다
void Start() {
// 지정 초 수마다 CreatePrefab를 반복 실행하는 예약
InvokeRepeating("CreatePrefab", intervalSec, intervalSec);
}
void CreatePrefab() {
// 이 오브젝트의 범위 내에 랜덤으로
Vector3 area = GetComponent<SpriteRenderer>().bounds.size;
Vector3 newPos = this.transform.position;
newPos.x += Random.Range(-area.x / 2, area.x / 2);
newPos.y += Random.Range(-area.y / 2, area.y / 2);
// 프리팹을 만든다
GameObject newGameObject = Instantiate(newPrefab) as GameObject;
newGameObject.transform.position = newPos;
}
}
스크립트를 추가한 뒤 생성할 프리팹을 설정해준다.
프리팹은 Hierachy에서 Bomb를 프로젝트 뷰로 드래그하여 생성할 수 있다.
그러면 한쪽에서 이렇게 별사탕이 슬라임을 향해 날라오는 것을 구현할 수 있다.
블록도 동일하게 프리팹으로 생성한 후, 전체 메인 화면 주변으로 둘러준다.
Gamelog 20_3. 바깥으로 나가면 사라지게 하기
현재는 별사탕이 무한으로 생성되고 사라지지 않아 Hierachy에 오브젝트가 엄청나게 쌓이는 것을 볼 수 있다.
이렇게 되면, 게임에 부하가 가기 때문에 별사탕이 바깥으로 나가게 되면 사라지게 하는 것이 필요하다.
using System;
using UnityEngine;
// 바깥으로 나가면 자기 자신을 삭제한디
public class OnEscape_DestroyMe : MonoBehaviour {
public float size = 9;
void Update() {
Vector3 pos = this.transform.position;
if (Math.Abs(pos.x)>size || Math.Abs(pos.y)>size) {
Destroy(this.gameObject);
}
}
}
현재 화면 바깥쪽 크기가 x축이 -9 ~ 9 사이이며, y축이 -6 ~ 6 사이이다.
따라서 별사탕이 큰 값인 x축을 기준으로 9보다 큰 위치로 나가게 되면 Destory
를 통해 삭제를 시켜준다.
해당 위치는 transform 오브젝트의 position 값을 기준으로 하였으므로, 해당 값을 Vector로 가지고 온다.
또한, size = 9
로 설정하기 위해 절대값을 사용하여 Math.Abs()
를 사용한다.
다 되었다면, 별사탕 오브젝트에 해당 스크립트를 추가한다.
그러면 이렇게 스크롤바가 늘었다 줄었다 하는 것을 통해 별똥별이 사라지고 있음을 알 수 있다.
Gamelog 20_4. 캐릭터와 닿으면 멈추게 하기
이제 게임답게, 별사탕을 피하게 만들어보자.
별사탕과 슬라임이 닿으면 게임이 중단되도록 구성한다.
먼저, 별사탕은 동그랗기 때문에 동그란 오브젝트에 사용하는 콜라이더인 Circle Collider 2D
를 프리팹에 추가한다.
그리고 바깥영역이 아닌 안쪽 영역으로 Edit Collider
를 통해 조정해준다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// 충돌하면 게임을 정지한다
public class OnCollision_StopGame : MonoBehaviour {
public string targetObjectName; // 목표 오브젝트 이름 : Inspector에 지정
void OnCollisionEnter2D(Collision2D collision) {
// 만약 충돌한 것의 이름이 목표 오브젝트였다면
if (collision.gameObject.name == targetObjectName) {
// 시간을 멈춘다
Time.timeScale = 0;
}
if (collision.gameObject.tag == "Bomb") {
Physics2D.IgnoreCollision(collision.collider, GetComponent<Collider2D>(), true);
}
}
}
그리고 스크립트를 추가하여, 충돌하면 게임이 정지하도록 한다.
만약 targetObject와 부딪히면, Time.timeScale=0
을 통해 게임을 멈춘다.
그러나 이 설정만 있으면, 별사탕끼리 서로를 인식하여 엉겨붙어 모이는 현상이 발생한다.
(처음에 이거보고 얼마나 당황스러웠던지..)
따라서 Physics2D.IgnoreCollision()
을 통해 충돌을 무시를 하는 방법을 적용하는 것이 필요하다.
Tags & Layers
에서 Tags
에 Bomb를 추가한다.
그리고 Tag를 Bomb
로 설정한다.
if (collision.gameObject.tag == "Bomb") {
Physics2D.IgnoreCollision(collision.collider, GetComponent<Collider2D>(), true);
}
그러면 이 코드를 통해서 gameObject
의 tag
를 인식하고 충돌을 무시할 수 있게 된다.
이렇게 별사탕들이 서로 충돌했을 때, 무시하고 잘 지나가게 되었다.
이제 캐릭터와 닿으면 멈추도록 슬라임에 콜라이더를 적용해주자.
슬라임도 동그랗기 때문에 Circle Collider 2D
를 적용해주었으며, 사람이 닿았다고 인식하는 범위로 좁혀주었다.
그러면 이렇게 닿았을 때, 게임이 멈추도록 하는 것까지 완료되었다.
다음 게시글에서는 기록 측정을 할 수 있도록 타이머를 구현하고 마무리해보자.
'프로그래밍 > Unity' 카테고리의 다른 글
Gamelog 22. 미로찾기 게임 만들기(1) (1) | 2023.04.12 |
---|---|
Gamelog 21. 총알피하기 게임 만들기(5) (0) | 2023.04.04 |
Gamelog 19. 총알피하기 게임 만들기(3) (2) | 2023.03.26 |
Gamelog 18. 총알피하기 게임 만들기(2) (2) | 2023.03.22 |
Gamelog 17. 총알피하기 게임 만들기(1) (0) | 2023.03.21 |