Notice
Recent Posts
Recent Comments
Link
거의 알고리즘 일기장
10. 유니티 _ 간단 2D 플랫포머 게임 본문
게임 설명
Scripts
GameManager Script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
public class Manager : MonoBehaviour
{
public int totalPoint;
public int stagePoint;
public int stageIndex;
public int health;
public Player player;
public GameObject[] stages;
public Image[] UIhealth;
public Text UIPoint;
public Text UIStage;
public Button UIRestartBtn;
private void Update()
{
UIPoint.text = (totalPoint + stagePoint).ToString();
}
public void NextStage()
{
//changeStage
if (stageIndex < stages.Length-1)
{
stages[stageIndex].SetActive(false);
stageIndex++;
stages[stageIndex].SetActive(true);
//player reposition
player.RePosition();
UIStage.text = (stageIndex + 1).ToString();
}
//game clear
else
{
Debug.Log("게임 클리어!");
//Player control lock
Time.timeScale = 0;
//result UI
Text btnText = UIRestartBtn.GetComponentInChildren<Text>();
btnText.text = "Clear!";
UIRestartBtn.gameObject.SetActive(true);
}
//calculate Point
totalPoint += stagePoint;
stagePoint = 0;
}
public void HealthDown()
{
if (health > 1)
{
health--;
UIhealth[health].color = new Color(1, 0, 1, 0.4f);
}
else
{
UIhealth[0].color = new Color(1, 0, 1, 0.4f);
//player die
player.OnDie();
//result ui
Debug.Log("죽었습니다.");
//retry ui
UIRestartBtn.gameObject.SetActive(true);
}
}
public void Restart()
{
SceneManager.LoadScene(0);
Time.timeScale = 1;
}
private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.gameObject.tag == "Player")
{
if (health > 1)
{
//player reposition
player.RePosition();
}
//health down
HealthDown();
}
}
}
Enemy Script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Enermy : MonoBehaviour
{
Rigidbody2D rigid;
//-1 0 1
Animator anim;
public int nextMove;
SpriteRenderer spRender;
CapsuleCollider2D capsuleCollider;
private void Awake()
{
capsuleCollider = GetComponent<CapsuleCollider2D>();
spRender = GetComponent<SpriteRenderer>();
anim = GetComponent<Animator>();
rigid = GetComponent<Rigidbody2D>();
Think();
}
private void FixedUpdate()
{
//move
rigid.velocity = new Vector2(nextMove, rigid.velocity.y);
//platform check
Vector2 frontVec = new Vector2(rigid.position.x + nextMove*0.3f, rigid.position.y);
Debug.DrawRay(frontVec, Vector3.down, new Color(0, 1, 0));
RaycastHit2D rayHit = Physics2D.Raycast(frontVec, Vector3.down, 1,
LayerMask.GetMask("Platform"));
if (rayHit.collider == null)
{
nextMove *= (-1);
Motion();
}
}
void Turn()
{
//방향전환
if (nextMove == 1)
spRender.flipX = true;
else if (nextMove == -1)
spRender.flipX = false;
}
void Motion()
{
//emermy motion
if (nextMove == 0)
anim.SetBool("isWalking", false);
else
anim.SetBool("isWalking", true);
Turn();
}
void Think()
{
//랜덤 방법
nextMove = Random.Range(-1, 2);
float nextMoveTime = Random.Range(2.0f, 4.0f);
Motion();
Invoke("Think", nextMoveTime);
}
void DeActive()
{
gameObject.SetActive(false);
}
public void OnDamaged()
{
//sprite alpha
spRender.color = new Color(1, 1, 1, 0.4f);
//sprite Flip Y
spRender.flipY = true;
//collider false
capsuleCollider.enabled = false;
//die effect jump
rigid.AddForce(Vector2.up * 3.0f, ForceMode2D.Impulse);
//destroy
Invoke("DeActive", 3);
}
}
Player Script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour
{
public Manager gameManager;
public AudioClip audioJump;
public AudioClip audioAttack;
public AudioClip audioDamaged;
public AudioClip audioItem;
public AudioClip audioDie;
public AudioClip audioFinish;
public float maxSpeed;
public float jumpPower;
bool isJump;
Rigidbody2D rigid;
SpriteRenderer spriteRenderer;
Animator anim;
CapsuleCollider2D capsuleCollider;
AudioSource audioSource;
private void Awake()
{
isJump = false;
audioSource = GetComponent<AudioSource>();
capsuleCollider = GetComponent<CapsuleCollider2D>();
anim = GetComponent<Animator>();
rigid = GetComponent<Rigidbody2D>();
spriteRenderer = GetComponent<SpriteRenderer>();
}
void PlaySound(string action)
{
switch (action)
{
case "JUMP":
audioSource.clip = audioJump;
break;
case "ATTACK":
audioSource.clip = audioAttack;
break;
case "DAMAGED":
audioSource.clip = audioDamaged;
break;
case "ITEM":
audioSource.clip = audioItem;
break;
case "DIE":
audioSource.clip = audioDie;
break;
case "FINISH":
audioSource.clip = audioFinish;
break;
}
audioSource.Play();
}
//단발적인 입력은 update에
void Update()
{
//stop speed
if(Input.GetButtonUp("Horizontal"))
{
//normalized -> 벡터 크기를 1로 만든 상태
rigid.velocity = new Vector2(rigid.velocity.normalized.x *0.5f, rigid.velocity.y);
}
//jump
if (Input.GetButtonDown("Jump") && isJump == false)
{
isJump = true;
rigid.AddForce(new Vector2(rigid.velocity.x, jumpPower), ForceMode2D.Impulse);
PlaySound("JUMP");
}
//방향전환
if (Input.GetButton("Horizontal"))
{
bool v = (Input.GetAxisRaw("Horizontal") == -1.0f);
spriteRenderer.flipX = v;
}
//walking motion
if (Mathf.Abs(rigid.velocity.x) <= 0.3f)
anim.SetBool("isWalking", false);
else
anim.SetBool("isWalking", true);
//jump motion
if(isJump == true)
anim.SetBool("isJumping", true);
else
anim.SetBool("isJumping", false);
}
private void FixedUpdate()
{
//move by key control
float h = Input.GetAxisRaw("Horizontal");
rigid.AddForce(Vector2.right * h, ForceMode2D.Impulse);
if (rigid.velocity.x > maxSpeed)
rigid.velocity = new Vector2(maxSpeed, rigid.velocity.y);
else if (rigid.velocity.x < maxSpeed*(-1))
rigid.velocity = new Vector2(maxSpeed*(-1), rigid.velocity.y);
if (rigid.velocity.y < 0)
{
//landing platform, 레이저로 쏴서 맞춘 첫번째 물체를 식별
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.5)
isJump = false;
}
}
void OnDamaged(Vector2 targetPos)
{
//Health down
gameManager.HealthDown();
//player damaged
gameObject.layer = 11;
spriteRenderer.color = new Color(1, 1, 1, 0.4f);
//reaction forc
int dirc = transform.position.x - targetPos.x > 0 ? 1 : -1;
rigid.AddForce(new Vector2(dirc, 1)*10.0f, ForceMode2D.Impulse);
//animation
anim.SetTrigger("doDamaged");
//sound
PlaySound("DAMAGED");
Invoke("OffDamaged", 2);
}
void OffDamaged()
{
gameObject.layer = 10;
spriteRenderer.color = new Color(1, 1, 1, 1);
}
void OnAttack(Transform enemy)
{
//Point
gameManager.stagePoint += 100;
//reation force
rigid.AddForce(Vector2.up * 5, ForceMode2D.Impulse);
//Enermy Die
Enermy enemyMove = enemy.GetComponent<Enermy>();
enemyMove.OnDamaged();
//SOUND
PlaySound("ATTACK");
}
public void OnDie()
{
//sprite alpha
spriteRenderer.color = new Color(1, 1, 1, 0.4f);
//sprite Flip Y
spriteRenderer.flipY = true;
//collider false
capsuleCollider.enabled = false;
//die effect jump
rigid.AddForce(Vector2.up * 3.0f, ForceMode2D.Impulse);
//SOUND
PlaySound("DIE");
}
public void RePosition()
{
rigid.velocity = Vector2.zero;
gameObject.transform.position = new Vector3(-5, 1, 0);
}
private void OnCollisionEnter2D(Collision2D collision)
{
//적에게 닿았을때
if (collision.gameObject.tag == "Enermy")
{
//attack
if (rigid.velocity.y < 0 && transform.position.y > collision.transform.position.y)
{
OnAttack(collision.transform);
}
//Damaged
else
OnDamaged(collision.transform.position);
}
}
private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.gameObject.tag == "Item")
{
bool isBronze = collision.gameObject.name.Contains("Bronze");
bool isSliver = collision.gameObject.name.Contains("Sliver");
bool isGold = collision.gameObject.name.Contains("Gold");
//Point
if(isBronze)
gameManager.stagePoint += 50;
else if(isSliver)
gameManager.stagePoint += 100;
else if(isGold)
gameManager.stagePoint += 150;
//SOUND
PlaySound("ITEM");
//deactive item
collision.gameObject.SetActive(false);
}
else if(collision.gameObject.tag == "Finish")
{
//next stage
gameManager.NextStage();
//sound
PlaySound("FINISH");
}
}
}
게임동작
참고
https://www.youtube.com/channel/UCw_N-Q_eYJo-IJFbNkhiYDA
후기
그 전 강의까지는 내맘대로 바꾸고 함수도 다르게 바꾸고 이렇게 만들었었는데, 이건 끝마무리라 그런지 구현량이 많아서 따라 치기도 벅찼다.ㅎㅎㅎ
반응형
'유니티' 카테고리의 다른 글
12. 유니티 _ 타워디펜스 _ 진행중 (2) | 2020.05.19 |
---|---|
11. 유니티 _ 3D 닷지 (0) | 2020.05.12 |
9.유니티 _ 피격 이벤트 구현 (0) | 2020.05.06 |
8. 유니티 _ 몬스터 움직임 구현 (0) | 2020.05.05 |
7. 유니티 _ 타일맵 (0) | 2020.05.05 |
Comments