Notice
Recent Posts
Recent Comments
Link
스토리지
쿠키런 중간결과 본문
- 아이템 추가 및 장애물 설치
- 캐릭터가 더블점프 시 이펙트 출력하기
- 일시정지 기능 구현
- 일시정지(우측상단) 버튼을 누를때마다 애니메이션과 맵드래그가 멈춘다.
- 죽는것도 맵 드래그가 멈추기 때문에 동시에 구현했다.
if (!this.gameManager.player.isDie && !this.pause)
{
jellys.Translate(new Vector3(-this.scrollSpeed, 0));
background.Translate(new Vector3(-this.scrollSpeed / 10, 0));
if (background.position.x <= 1.51f)
{
background.position = new Vector3(27.2f, background.position.y);
}
floor.Translate(new Vector3(-this.scrollSpeed, 0));
if (floor.position.x <= 0.62f)
{
floor.position = new Vector3(14.08f, floor.position.y);
}
this.obstacles.Translate(new Vector3(-this.scrollSpeed, 0));
앞으로 더 구현해야 할것
- 아이템 먹을 때마다 이펙트 출력
- 어떤 아이템을 먹는지? 또한 효과가 있는 아이템을 먹을 때, 그 효과 구현
- 자석 효과 : 캐릭터의 자식으로 Sphere Collider를 가진 빈 게임오브젝트를 설치 후 is Trigger로 체크한 뒤에 Collider에 걸린 아이템 하나하나 Translate하여 유저에게 충돌시키면 될 듯. 유저에게 충돌한 아이템은 이미 짜놓은 코드에 의해서 자동으로 사라지고 효과가 적용됨.
알아봐야 될 것
- 젤리 오브젝트라던가 장애물은 직접 손으로 구현하는 것인가? 아니면 다른 방법이 있는것인가? 배열로도 생각해보았는데 구현이 머릿속에 떠오르지 않는다.
============================================================================
소스코드
PlayerController.cs
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
public float hp;
public float maxHp;
public float jumpForce;
public bool isDie;
public bool isHit;
public Animator animator;
public Action OnJump;
public Action<bool> OnSlide;
public GameObject jumpAnim;
private int jumpCount;
private bool hpCoroutine;
private bool hitTect;
private float afterHitTimer;
private Vector3 mainBoxPos;
private Vector3 mainBoxSize;
private Vector3 sliderBoxPos;
private Vector3 sliderBoxSize;
private Rigidbody2D playerRigidbody;
private BackgroundScroller background;
private GameManager gameManager;
// Start is called before the first frame update
void Start()
{
this.jumpForce = 600;
this.jumpCount = 0;
this.hp = 100;
this.maxHp = this.hp;
this.playerRigidbody = GetComponent<Rigidbody2D>();
this.animator = GetComponent<Animator>();
this.mainBoxPos = GetComponent<BoxCollider2D>().offset;
this.mainBoxSize = GetComponent<BoxCollider2D>().size;
this.background = FindObjectOfType<BackgroundScroller>();
this.gameManager = FindObjectOfType<GameManager>();
this.sliderBoxPos = new Vector3(-0.06096035f, -1.463048f);
this.sliderBoxSize = new Vector3(1.750231f, 0.7139049f);
this.OnJump = Jump;
this.OnSlide = Slide;
this.jumpAnim.SetActive(false);
}
// Update is called once per frame
void Update()
{
Debug.Log(this.GetComponent<SpriteRenderer>().color.a);
if (this.isDie) return;
//장애물에 맞은 후 0.5초동안 스크롤 느려짐 3초동안은 무적
if (isHit)
{
this.afterHitTimer += Time.deltaTime;
if (this.afterHitTimer > 0.5f && !this.hitTect)
{
this.animator.SetBool("Hit", false);
this.background.SetScrollSpeed(10f);
hitTect = true;
this.GetComponent<SpriteRenderer>().color = Color.white;
}
if (this.afterHitTimer > 3)
{
isHit = false;
var tmp = this.GetComponent<SpriteRenderer>().color;
tmp.a = 1f;
this.GetComponent<SpriteRenderer>().color = tmp;
this.afterHitTimer = 0;
}
}
if (!this.hpCoroutine)
{
this.hpCoroutine = true;
StartCoroutine("DecreaseHp");
}
if (this.hp <= 0)
{
this.isDie = true;
this.gameManager.OnDie();
}
}
private void Jump()
{
if (this.GetComponent<SpriteRenderer>().color != Color.red)
{
if (this.jumpCount < 2)
{
this.jumpCount++;
playerRigidbody.velocity = Vector3.zero;
this.playerRigidbody.AddForce(new Vector3(0, this.jumpForce));
}
if (this.jumpCount == 2)
{
this.animator.SetBool("DoubleJump", true);
StartCoroutine("DoubleJump");
}
else
{
this.animator.SetBool("Jump", true);
}
}
}
IEnumerator DoubleJump()
{
this.jumpAnim.transform.position = new Vector3(this.transform.position.x, this.transform.position.y - 2);
this.jumpAnim.SetActive(true);
yield return new WaitForSeconds(0.4f);
this.jumpAnim.SetActive(false);
}
private void Slide(bool slideState)
{
if (this.GetComponent<SpriteRenderer>().color != Color.red && !this.isDie)
{
if (slideState)
{
this.animator.SetBool("Slide", true);
this.GetComponent<BoxCollider2D>().offset = this.sliderBoxPos;
this.GetComponent<BoxCollider2D>().size = this.sliderBoxSize;
}
else
{
this.animator.SetBool("Slide", false);
this.GetComponent<BoxCollider2D>().offset = this.mainBoxPos;
this.GetComponent<BoxCollider2D>().size = this.mainBoxSize;
}
}
else
{
this.animator.SetBool("Slide", false);
this.GetComponent<BoxCollider2D>().offset = this.mainBoxPos;
this.GetComponent<BoxCollider2D>().size = this.mainBoxSize;
}
}
IEnumerator DecreaseHp()
{
if (this.hpCoroutine)
{
yield return new WaitForSeconds(2f);
if (!this.isDie)
{
this.hp -= this.gameManager.imageFillAmount * this.maxHp;
this.hpCoroutine = false;
}
}
}
void OnCollisionEnter2D(Collision2D collision)
{
if (this.GetComponent<SpriteRenderer>().color != Color.red && collision.transform.CompareTag("Floor"))
{
if (this.jumpCount == 2)
{
this.animator.SetBool("DoubleJump", false);
this.animator.SetBool("Jump", false);
}
else if (this.jumpCount == 1)
{
this.animator.SetBool("Jump", false);
}
this.jumpCount = 0;
}
}
void OnTriggerEnter2D(Collider2D collision)
{
if (!isHit && collision.CompareTag("Obstacle"))
{
if (this.jumpCount == 2)
{
this.animator.SetBool("DoubleJump", false);
this.animator.SetBool("Jump", false);
}
else
{
this.animator.SetBool("Jump", false);
}
this.jumpCount = 0;
this.isHit = true;
this.hitTect = false;
this.hp -= collision.gameObject.GetComponent<Obstacle>().damage;
this.animator.SetBool("Hit", true);
this.background.SetScrollSpeed(0.1f);
this.GetComponent<SpriteRenderer>().color = Color.red;
this.gameManager.OnHit(collision.gameObject.GetComponent<Obstacle>());
var tmp = this.GetComponent<SpriteRenderer>().color;
tmp.a = 0.2f;
this.GetComponent<SpriteRenderer>().color = tmp;
}
else if (collision.CompareTag("Jelly"))
{
Destroy(collision.gameObject);
this.gameManager.OnScore();
}
}
}
BackgroundScroller.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BackgroundScroller : MonoBehaviour
{
public bool pause;
public Transform background;
public Transform floor;
public Transform jellys;
public Transform obstacles;
private float scrollSpeed;
private GameManager gameManager;
// Start is called before the first frame update
void Start()
{
this.scrollSpeed = 0.1f;
this.gameManager = FindObjectOfType<GameManager>();
}
// Update is called once per frame
void Update()
{
if(this.scrollSpeed < 0.01f)
{
this.scrollSpeed = 0.01f;
}
if(!this.gameManager.player.isDie && !this.pause)
{
jellys.Translate(new Vector3(-this.scrollSpeed, 0));
background.Translate(new Vector3(-this.scrollSpeed / 10, 0));
if (background.position.x <= 1.51f)
{
background.position = new Vector3(27.2f, background.position.y);
}
floor.Translate(new Vector3(-this.scrollSpeed, 0));
if (floor.position.x <= 0.62f)
{
floor.position = new Vector3(14.08f, floor.position.y);
}
this.obstacles.Translate(new Vector3(-this.scrollSpeed, 0));
}
}
public void SetScrollSpeed(float speed)
{
this.scrollSpeed *= speed;
}
}
GameManager.cs
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameManager : MonoBehaviour
{
public Action OnDie;
public Action<Obstacle> OnHit;
public Action OnScore;
public float imageFillAmount;
public PlayerController player;
private bool isHpCoroutineStart;
private bool isWarningCoroutineStart;
private bool checkSlide;
private int score = 0;
public float hpWarningSignSize = 0;
private UIManager ui;
private BackgroundScroller background;
// Start is called before the first frame update
void Start()
{
this.ui = FindObjectOfType<UIManager>();
this.player = FindObjectOfType<PlayerController>();
this.background = FindObjectOfType<BackgroundScroller>();
this.ui.hpAlarm.gameObject.SetActive(false);
this.ui.jump.onClick.AddListener(() =>
{
this.player.OnJump();
});
this.ui.pause.onClick.AddListener(() =>
{
this.background.pause = !this.background.pause;
if (this.background.pause)
{
this.player.animator.speed = 0;
this.imageFillAmount = 0;
}
else
{
this.player.animator.speed = 1f;
this.imageFillAmount = 0.07f;
}
});
this.imageFillAmount = 0.07f;
this.OnHit = this.Hit;
this.OnDie = this.Die;
this.OnScore = this.UpdateScore;
}
// Update is called once per frame
void Update()
{
if (!this.isHpCoroutineStart)
{
this.isHpCoroutineStart = true;
StartCoroutine("DecreaseHp");
}
if (this.player.hp <= this.player.maxHp * 0.25)
{
if (!this.isWarningCoroutineStart)
{
this.isWarningCoroutineStart = true;
this.ui.hpAlarm.gameObject.SetActive(true);
this.ui.hpAlarm.GetComponent<Animator>().SetBool("Danger", true);
}
}
if (!this.player.isDie)
{
this.player.OnSlide(this.checkSlide);
}
}
public void PointDown()
{
this.checkSlide = true;
}
public void PointUp()
{
this.checkSlide = false;
}
public void Hit(Obstacle obstacle)
{
this.ui.hpBar.fillAmount -= obstacle.damage / this.player.maxHp;
float x = this.ui.hpBar.rectTransform.rect.width * obstacle.damage / this.player.maxHp;
this.ui.hpBarLight.rectTransform.anchoredPosition = new Vector3(this.ui.hpBarLight.rectTransform.anchoredPosition.x - x, this.ui.hpBarLight.rectTransform.anchoredPosition.y);
}
public void Die()
{
this.player.animator.SetBool("Die", true);
this.player.GetComponent<SpriteRenderer>().color = Color.white;
this.ui.hpAlarm.GetComponent<Animator>().SetBool("Danger", false);
this.ui.hpAlarm.gameObject.SetActive(false);
this.ui.jump.gameObject.SetActive(false);
this.ui.slide.gameObject.SetActive(false);
//몇초뒤에 게임결과 씬으로 이동
}
IEnumerator DecreaseHp()
{
yield return new WaitForSeconds(2f);
if (!this.player.isDie)
{
float x = this.ui.hpBar.rectTransform.rect.width * this.imageFillAmount;
this.ui.hpBarLight.rectTransform.anchoredPosition = new Vector3(this.ui.hpBarLight.rectTransform.anchoredPosition.x - x, this.ui.hpBarLight.rectTransform.anchoredPosition.y);
this.ui.hpBar.fillAmount -= this.imageFillAmount;
this.isHpCoroutineStart = false;
}
}
public void UpdateScore()
{
if (!this.player.isDie)
{
score += 10;
this.ui.score.text = string.Format("{0:#,0}", this.score);
}
}
}
'개발일지' 카테고리의 다른 글
[4.18] 클론게임 개발 - 슈퍼마리오 브라더스(NES) 2 (0) | 2021.04.18 |
---|---|
[4.18] 클론게임 개발 - 슈퍼마리오 브라더스(NES) 1 (0) | 2021.04.18 |
유니티 클론게임 개발 - 쿠키런 1 (0) | 2021.04.13 |
자동저장 구현 (0) | 2021.04.02 |
머드게임 개발 1. 창 띄우기 (0) | 2021.03.27 |
Comments