물리적충돌이 없는것들은 OnTrigger 사용
물리적충돌이 있는것들은 OnCollision 사용
transform은 값을 담고 있는 객체
collision.gameObject.name.Contains(비교문);
대상 문자열에 비교문이 있으면 true 반환
bool isBronze = collision.gameObject.name.Contains("Bronze"); bool isSilver = collision.gameObject.name.Contains("Silver"); bool isGold = collision.gameObject.name.Contains("Gold"); ``
collision.attachedRigidbody.velocity = Vector2.zero;
-> 충돌체에 붙어있는 리지드바디의 속력을 0으로 만든다.
스테이지 부피에 따라 스테이지가 작으면 오브젝트로 컨트롤하고 스테이지가 크다면 Scene으로 구분해서 컨트롤 한다.
Time.timeScale = 0 (시간 멈추게하기)
Time.timeScale = 1 (시간 흐르게하기)
Button은 GameObject변수로 Button안의 Text를 가져올때는 GetComponentInChildren으로 가져온다.
사운드가 겹칠 때는 PlayOneShot(clip)을 사용한다.
데미지를 입었을 때 UI가 투명해지는 모습
코인을 먹었을 때 점수 확인
다음 스테이지에서의 UI 확인
사망했을 때 재시작 버튼 활성화!
게임 클리어 버튼
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour
{
public int JumpPower;
public int mxSpeed;
public AudioClip Jump;
public AudioClip Item;
public AudioClip Die;
public AudioClip Finish;
public AudioClip Damaged;
public AudioClip Attack;
public GameManager gameManager;
CapsuleCollider2D capCollider;
Rigidbody2D rigid;
SpriteRenderer spriteRenderer;
Animator anim;
AudioSource audioSource;
// Start is called before the first frame update
private void Awake()
{
rigid = GetComponent<Rigidbody2D>();
spriteRenderer = GetComponent<SpriteRenderer>();
anim = GetComponent<Animator>();
capCollider = GetComponent<CapsuleCollider2D>();
audioSource = GetComponent<AudioSource>();
}
void Start()
{
}
// Update is called once per frame
void Update()
{
if (Input.GetButtonDown("Jump") && !anim.GetBool("isJumping"))
{
Playsound("JUMP");
rigid.AddForce(Vector2.up * JumpPower, ForceMode2D.Impulse);
anim.SetBool("isJumping", true);
}
if (Input.GetButtonUp("Horizontal"))
rigid.velocity = new Vector2(rigid.velocity.normalized.x * 0.5f, rigid.velocity.y);
if (rigid.velocity.x < 0)
spriteRenderer.flipX = true;
else
spriteRenderer.flipX = false;
// Mathf 수학관련 함수를 제공하는 클래스
if (Mathf.Abs(rigid.velocity.x) > 0.5f)
anim.SetBool("isWalking", true);
else
anim.SetBool("isWalking", false);
}
private void FixedUpdate()
{
float x = Input.GetAxisRaw("Horizontal");
rigid.AddForce(Vector2.right * x, ForceMode2D.Impulse);
if (rigid.velocity.x > mxSpeed)
rigid.velocity = new Vector2(mxSpeed, rigid.velocity.y);
else if (rigid.velocity.x < -mxSpeed)
rigid.velocity = new Vector2(-mxSpeed, rigid.velocity.y);
if (rigid.velocity.y < 0)
{
Debug.DrawRay(rigid.position, Vector3.down, new Color(0, 1, 0));
RaycastHit2D rayHit = Physics2D.Raycast(rigid.position, Vector3.down, 1, LayerMask.GetMask("Platform"));
if (rayHit.collider != null)
{
if (rayHit.distance < 0.5f)
anim.SetBool("isJumping", false);
}
}
}
private void OnCollisionEnter2D(Collision2D collision)
{
if(collision.gameObject.tag == "Enemy" || collision.gameObject.tag == "Trap")
{
if (collision.gameObject.tag == "Enemy" && rigid.velocity.y < 0 && rigid.transform.position.y > collision.transform.position.y)
{
OnAttack(collision.transform);
Playsound("ATTACK");
}
else
{
OnDamaged(collision.transform.position);
}
}
}
private void OnTriggerEnter2D(Collider2D collision)
{
if(collision.gameObject.tag == "Item")
{
Playsound("ITEM");
// Point Up
bool isBronze = collision.gameObject.name.Contains("Bronze");
bool isSilver = collision.gameObject.name.Contains("Silver");
bool isGold = collision.gameObject.name.Contains("Gold");
if (isBronze)
gameManager.stagePoint += 50;
else if (isSilver)
gameManager.stagePoint += 100;
else if (isGold)
gameManager.stagePoint += 300;
// DeActive
collision.gameObject.SetActive(false);
}
else if(collision.gameObject.tag == "Finish")
{
Playsound("FINISH");
// NextStage
gameManager.NextStage();
}
}
void Playsound(string s)
{
switch(s)
{
case "JUMP":
audioSource.clip = Jump;
audioSource.Play();
break;
case "ATTACK":
audioSource.clip = Attack;
audioSource.Play();
break;
case "ITEM":
audioSource.clip = Item;
audioSource.Play();
break;
case "DAMAGED":
audioSource.PlayOneShot(Damaged);
break;
case "FINISH":
audioSource.clip = Finish;
audioSource.Play();
break;
case "DIE":
audioSource.PlayOneShot(Die); // 죽을 때 데미지입는 소리와 중첩되도록 OneShot사용
break;
}
}
void OnAttack(Transform _enemy)
{
gameManager.stagePoint += 150;
rigid.AddForce(Vector2.up * 10, ForceMode2D.Impulse);
Enemy enemy = _enemy.GetComponent<Enemy>();
enemy.OnDamaged();
}
void OnDamaged(Vector2 target)
{
gameManager.HealthDown();
Playsound("DAMAGED");
gameObject.layer = 11;
anim.SetTrigger("Damaged");
spriteRenderer.color = new Color(1, 1, 1, 0.5f);
int dir = transform.position.x - target.x > 0 ? 1 : -1;
rigid.AddForce(new Vector2(dir, 1) * 7, ForceMode2D.Impulse);
Invoke("OffDamaged", 1);
}
void OffDamaged()
{
gameObject.layer = 10;
spriteRenderer.color = new Color(1, 1, 1, 1);
}
public void OnDie()
{
Playsound("DIE");
spriteRenderer.color = new Color(1, 1, 1, 0.5f);
spriteRenderer.flipY = true;
rigid.AddForce(Vector2.up * 5, ForceMode2D.Impulse);
capCollider.enabled = false; // 콜라이더 비활성화
}
public void VelocityZero()
{
rigid.velocity = Vector2.zero;
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Enemy : MonoBehaviour
{
public int nextMove;
SpriteRenderer spriteRenderer;
Rigidbody2D rigid;
CapsuleCollider2D capCollider;
Animator anim;
private void Awake()
{
rigid = GetComponent<Rigidbody2D>();
anim = GetComponent<Animator>();
spriteRenderer = GetComponent<SpriteRenderer>();
capCollider = GetComponent<CapsuleCollider2D>();
Invoke("Think", 5);
}
// Update is called once per frame
void FixedUpdate()
{
rigid.velocity = new Vector2(nextMove, rigid.velocity.y);
Vector2 vec = new Vector2(rigid.position.x + nextMove*0.3f, rigid.position.y);
Debug.DrawRay(vec, Vector3.down, new Color(0, 1, 0));
RaycastHit2D rayHit = Physics2D.Raycast(vec, Vector3.down, 1, LayerMask.GetMask("Platform"));
if (rayHit.collider == null)
{
nextMove *= -1;
spriteRenderer.flipX = (nextMove == 1);
CancelInvoke();
Invoke("Think", 2);
}
}
void Think()
{
nextMove = Random.Range(-1, 2);
float nextTime = Random.Range(2f, 6f);
anim.SetInteger("Walk", nextMove);
Invoke("Think", nextTime);
if (nextMove != 0)
spriteRenderer.flipX = (nextMove == 1);
}
public void OnDamaged()
{
spriteRenderer.color = new Color(1, 1, 1, 0.5f);
spriteRenderer.flipY = true;
rigid.AddForce(Vector2.up * 5, ForceMode2D.Impulse);
capCollider.enabled = false; // 콜라이더 비활성화
Invoke("EnableMonster", 5);
}
void EnableMonster()
{
gameObject.SetActive(false);
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class GameManager : MonoBehaviour
{
public int totalPoint;
public int stageIdx;
public int stagePoint;
public int health;
public GameObject[] stages;
public Player player;
public Image[] images;
public Text Stagetext;
public Text Pointtext;
public GameObject RetryBtn; // Button은 GameObject
private void Start()
{
Stagetext.text = "STAGE" + (stageIdx + 1).ToString();
}
private void Update()
{
Pointtext.text = (totalPoint + stagePoint).ToString();
}
private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.gameObject.tag == "Player")
{
HealthDown();
if (health > 0)
{
Reposition();
}
else
{
player.OnDie();
Time.timeScale = 0;
RetryBtn.SetActive(true);
}
}
}
public void NextStage()
{
if (stageIdx < stages.Length-1)
{
stages[stageIdx].SetActive(false);
stageIdx++;
stages[stageIdx].SetActive(true);
Reposition();
Stagetext.text = "STAGE " + (stageIdx + 1).ToString();
}
else
{
Time.timeScale = 0;
RetryBtn.SetActive(true);
Text btnText = RetryBtn.GetComponentInChildren<Text>();
btnText.text = "게임 클리어!";
stageIdx = 0;
}
totalPoint += stagePoint;
stagePoint = 0;
}
public void HealthDown()
{
if (health > 1)
{
health--;
images[health].color = new Color(1, 1, 1, 0.5f);
}
else
{
images[0].color = new Color(1, 1, 1, 0.5f);
player.OnDie();
RetryBtn.SetActive(true);
Time.timeScale = 0;
}
}
public void Restart()
{
Time.timeScale = 1;
SceneManager.LoadScene(0);
}
void Reposition()
{
player.VelocityZero();
player.transform.position = new Vector3(-4, 1, 0);
}
}