오늘 할 일
오전
1. 코인먹기 , 벽돌 깨기
오후
2. 벽돌 깨면 코인 또는 버섯 생성
집가서
3. 어제 못한 마리오 애니메이션
1. 코인 먹기
collider의 trigger 모드로 충돌 검사하면 될 것 같음 , tag가 coin 이면 setActive false 하거나 destroy , 둘중에 뭐로 할지 고민인데 찾아보고 사람들이 더 많이 하는거로 할 예정이다.
private void OnTriggerEnter2D(Collider2D other)
{
if (other.gameObject.tag == "coin")
{
Destroy(other.gameObject);
}
}

코인에 collider 컴포넌트 추가 후 is Trigger 체크

2. 코인 돌아가기 애니메이션
3. 벽돌 깨기
생각해보기 : collider의 충돌검사로 충돌하면 벽돌 애니메이션을 실행한다, 하지만 아래에서 위로만 깰수 있으니까
고민을 하다가, 아래에만 적용할 collider 종류를 찾아보던도중 edge collider 를 발견하고 추가하고 edge collider에만 is Trigger를 체크하였다. 즉 question brick은 collider를 2개 갖고있음 , 또한 Qbrick이라는 태그를 달아주었다.

private void OnTriggerEnter2D(Collider2D other)
{
if (other.gameObject.tag == "coin")
{
Destroy(other.gameObject);
}
if(other.gameObject.tag == "Qbrick")
{
Debug.Log("벽돌 깨기 애니메이션 실행");
}
}
테스트로 블록 하나에만 적용하고 충돌 검사하면 log 에 찍히도록 하였다.

<애니메이션 적용>
1. 블록애니메이션 만들기

만들어야하는거 : 거의 바로 그냥 블록으로 바뀌고 위로 살짝 튕기면서 윗 부분에 코인이 돌아가면서 올라가면서 생성됐다가 내려오면서 소멸
Qbrick과 바뀌는 블록의 사이즈가 달라서 애니메이션 만들 때 어떻게 해야하는지 고민이었다 .
=>
대충 바뀌는 블록이 씬에서 Qbrick과 크기가 비슷한 scale이 0.27이었으므로 빈 오브젝트를 만들어서 크기를 0.27로 바꾼 후 자식으로 Qbrick을 넣어주었더니 해결되었다.
using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using UnityEditor.Experimental.GraphView;
using UnityEngine;
public class MarioController : MonoBehaviour
{
private Rigidbody2D rBody2D;
private float jumpForce = 500f;
private float moveForce = 60f;
private Animator anim;
private bool isJump=false;
private bool isLongJump = false;
[SerializeField]
private GameObject qBirckgo;
private Animator anim2;
// Start is called before the first frame update
void Start()
{
this.rBody2D = this.GetComponent<Rigidbody2D>();
this.anim = this.GetComponent<Animator>();
this.anim2=this.qBirckgo.GetComponent<Animator>();
}
// Update is called once per frame
void Update()
{
//jump
if (Input.GetKeyDown(KeyCode.Space))
{
if (this.rBody2D.velocity.y == 0)
{
this.rBody2D.AddForce(Vector2.up * this.jumpForce);
if (this.isJump == false)
this.isJump = true;
}
}
//if (Input.GetButtonUp("Horizontal"))
//{
// this.rBody2D.velocity = new Vector2(this.rBody2D.velocity.normalized.x * 0.8f, this.rBody2D.velocity.y);
//}
//if (this.isJump)// space를 눌렀는데
//{
// if (this.rBody2D.velocity.y > 0)// 점프상태
// {
// this.anim.SetInteger("State", 2);
// }
// else if(this.rBody2D.velocity.y < 0)//떨어지는 중
// {
// this.anim.SetInteger("State", 2);
// }
//}
int dirX = 0;
if (Input.GetKey(KeyCode.LeftArrow))
{
dirX = -1;
}
if (Input.GetKey(KeyCode.RightArrow))
{
dirX = 1;
}
float speedX = Mathf.Abs(this.rBody2D.velocity.x);//절대값(속도는 음수 나오면 안됨), 가속도
if (speedX < 5f)//가속도 제한
{
this.rBody2D.AddForce(new Vector2(dirX, 0) * this.moveForce);
}
//움직이는 방향으로 쳐다보기
if (dirX != 0)//달리고 있다면?
{
//if (!this.isJump)//좌우를 쳐다보는데 점프 상태가 아니라면 => 걷는중
//{
// this.anim.SetInteger("State", 1);
//}
this.transform.localScale = new Vector3(dirX * 0.5f, 0.5f, 1);
}
//else//좌우를 쳐다보지도 않고 점프 상태도 아니라면 =>idle
//{
// if (!this.isJump)
// this.anim.SetInteger("State", 0);
//}
this.anim.speed = speedX / 2.0f;
//길게 누르면 높은 점프 짧게 누르면 낮은 점프
if (Input.GetKey(KeyCode.Space))
{
isLongJump = true;
}
else if (Input.GetKeyUp(KeyCode.Space))
{
isLongJump = false;
}
}
private void FixedUpdate()
{
if (isLongJump && this.rBody2D.velocity.y > 0)
{
this.rBody2D.gravityScale = 1.3f;
}
else
{
this.rBody2D.gravityScale = 2.5f;
}
}
private void OnTriggerEnter2D(Collider2D other)
{
if (other.gameObject.tag == "coin")
{
Destroy(other.gameObject);
}
if(other.gameObject.tag == "Qbrick")
{
this.anim2.SetBool("isCrash", true);
Debug.Log("벽돌 깨기 애니메이션 실행");
}
}
}

문제점 . 애니메이션은 잘 실행되지만 바뀐 sprite에는 collider가 없어서 통과되는 문제발생
=> 빈 오브젝트 안에 두개의 오브젝트(Question brick과 바뀐블록) 두가지를 넣어놓고 Question brick 이 비활성화 되는것으로 바꿔야할거같음

잘 수정됨
나머지 블록은 그냥 복사하면 된다고 생각했는데 안됨 , 생각해보니 모두 MarioController 에서 알아야하고 , 같은 자리에 생성되어버리는문제 ..
=> 부모자식 관계 프리팹으로 등록 각각 원하는 위치에 빈 오브젝트를 만들고 자식(main)을 만들어서 자식에다가 animator를 적용한다. 부모에다가 XX!!!

배열을 사용해서 gameobject에 접근하려고 했는데 또 제대로 된 위치에 애니메이션이 실행되지 않고 다른곳에서 실행됨 .. 결국 코드를 하나하나 따로 쓰니 해결은 됐는데 .... 코드가 심각하게 더럽다 정말 돌아가기만 하는 코드
using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using UnityEditor.Experimental.GraphView;
using UnityEngine;
public class MarioController : MonoBehaviour
{
private Rigidbody2D rBody2D;
private float jumpForce = 500f;
private float moveForce = 60f;
private Animator anim;
private bool isJump=false;
private bool isLongJump = false;
[SerializeField]
private GameObject qBirckgo1;
[SerializeField]
private GameObject qBirckgo2;
[SerializeField]
private GameObject qBirckgo3;
[SerializeField]
private GameObject qBirckgo4;
private Animator anim1;
private Animator anim2;
private Animator anim3;
private Animator anim4;
// Start is called before the first frame update
void Start()
{
this.rBody2D = this.GetComponent<Rigidbody2D>();
this.anim = this.GetComponent<Animator>();
this.anim1 = this.qBirckgo1.GetComponent<Animator>();
this.anim2 = this.qBirckgo2.GetComponent<Animator>();
this.anim3 = this.qBirckgo3.GetComponent<Animator>();
this.anim4 = this.qBirckgo4.GetComponent<Animator>();
}
// Update is called once per frame
void Update()
{
//jump
if (Input.GetKeyDown(KeyCode.Space))
{
if (this.rBody2D.velocity.y == 0)
{
this.rBody2D.AddForce(Vector2.up * this.jumpForce);
if (this.isJump == false)
this.isJump = true;
}
}
//if (Input.GetButtonUp("Horizontal"))
//{
// this.rBody2D.velocity = new Vector2(this.rBody2D.velocity.normalized.x * 0.8f, this.rBody2D.velocity.y);
//}
//if (this.isJump)// space를 눌렀는데
//{
// if (this.rBody2D.velocity.y > 0)// 점프상태
// {
// this.anim.SetInteger("State", 2);
// }
// else if(this.rBody2D.velocity.y < 0)//떨어지는 중
// {
// this.anim.SetInteger("State", 2);
// }
//}
int dirX = 0;
if (Input.GetKey(KeyCode.LeftArrow))
{
dirX = -1;
}
if (Input.GetKey(KeyCode.RightArrow))
{
dirX = 1;
}
float speedX = Mathf.Abs(this.rBody2D.velocity.x);//절대값(속도는 음수 나오면 안됨), 가속도
if (speedX < 5f)//가속도 제한
{
this.rBody2D.AddForce(new Vector2(dirX, 0) * this.moveForce);
}
//움직이는 방향으로 쳐다보기
if (dirX != 0)//달리고 있다면?
{
//if (!this.isJump)//좌우를 쳐다보는데 점프 상태가 아니라면 => 걷는중
//{
// this.anim.SetInteger("State", 1);
//}
this.transform.localScale = new Vector3(dirX * 0.5f, 0.5f, 1);
}
//else//좌우를 쳐다보지도 않고 점프 상태도 아니라면 =>idle
//{
// if (!this.isJump)
// this.anim.SetInteger("State", 0);
//}
this.anim.speed = speedX / 2.0f;
//길게 누르면 높은 점프 짧게 누르면 낮은 점프
if (Input.GetKey(KeyCode.Space))
{
isLongJump = true;
}
else if (Input.GetKeyUp(KeyCode.Space))
{
isLongJump = false;
}
}
private void FixedUpdate()
{
if (isLongJump && this.rBody2D.velocity.y > 0)
{
this.rBody2D.gravityScale = 1.3f;
}
else
{
this.rBody2D.gravityScale = 2.5f;
}
}
private void OnTriggerEnter2D(Collider2D other)
{
if (other.gameObject.tag == "coin")
{
Destroy(other.gameObject);
}
if(other.gameObject.tag == "Qbrick1")
{
this.anim1.SetBool("isCrash", true);
}
if (other.gameObject.tag == "Qbrick2")
{
this.anim2.SetBool("isCrash", true);
}
if (other.gameObject.tag == "Qbrick3")
{
this.anim3.SetBool("isCrash", true);
}
if (other.gameObject.tag == "Qbrick4")
{
this.anim4.SetBool("isCrash", true);
}
}
}
mario Controller가 너무 길어서 갑자기 든 생각인데 그냥 brickController를 만들면 될라나 생각이 들었다.
아 근데 그러면 mario 에 isTrigger를 체크해야하는데 그러면 아래로 떨어져버림 => onCollisionEnter을 사용하면 된다!!
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BrickController : MonoBehaviour
{
private Rigidbody2D rBody2D;
private Animator anim;
// Start is called before the first frame update
void Start()
{
this.rBody2D = this.GetComponent<Rigidbody2D>();
this.anim = this.GetComponent<Animator>();
}
// Update is called once per frame
void Update()
{
}
private void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.tag == "mario")
{
this.anim.SetBool("isCrash", true);
Debug.Log("충돌");
}
}
}
using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using UnityEditor.Experimental.GraphView;
using UnityEngine;
public class MarioController : MonoBehaviour
{
private Rigidbody2D rBody2D;
private float jumpForce = 500f;
private float moveForce = 60f;
private Animator anim;
private bool isJump=false;
private bool isLongJump = false;
// Start is called before the first frame update
void Start()
{
this.rBody2D = this.GetComponent<Rigidbody2D>();
this.anim = this.GetComponent<Animator>();
}
// Update is called once per frame
void Update()
{
//jump
if (Input.GetKeyDown(KeyCode.Space))
{
if (this.rBody2D.velocity.y == 0)
{
this.rBody2D.AddForce(Vector2.up * this.jumpForce);
if (this.isJump == false)
this.isJump = true;
}
}
int dirX = 0;
if (Input.GetKey(KeyCode.LeftArrow))
{
dirX = -1;
}
if (Input.GetKey(KeyCode.RightArrow))
{
dirX = 1;
}
float speedX = Mathf.Abs(this.rBody2D.velocity.x);//절대값(속도는 음수 나오면 안됨), 가속도
if (speedX < 5f)//가속도 제한
{
this.rBody2D.AddForce(new Vector2(dirX, 0) * this.moveForce);
}
//움직이는 방향으로 쳐다보기
if (dirX != 0)//달리고 있다면?
{
this.transform.localScale = new Vector3(dirX * 0.5f, 0.5f, 1);
}
//길게 누르면 높은 점프 짧게 누르면 낮은 점프
if (Input.GetKey(KeyCode.Space))
{
isLongJump = true;
}
else if (Input.GetKeyUp(KeyCode.Space))
{
isLongJump = false;
}
}
private void FixedUpdate()
{
if (isLongJump && this.rBody2D.velocity.y > 0)
{
this.rBody2D.gravityScale = 1.3f;
}
else
{
this.rBody2D.gravityScale = 2.5f;
}
}
private void OnTriggerEnter2D(Collider2D other)
{
if (other.gameObject.tag == "coin")
{
Destroy(other.gameObject);
}
}
}
훨씬 깔끔해진 코드 !!

튕기는거?
4. 벽돌 깨면 코인 또는 버섯 나오기
1. 코인은 뱅글뱅글 돌아야하고
2. 버섯은 작았다가 커져서 생성되고 오른쪽으로 이동해야함 바닥으로도 떨어짐 아마 구멍 있을때까지 계속 이동하는듯
1단계
그냥 블록 위 위치에 동적으로 아이템 생성하기
main, ItemController,ItemGenerator 스크립트를 만듬
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Main : MonoBehaviour
{
public GameObject mushroomPrefab;
public GameObject coinPrefab;
// Start is called before the first frame update
void Start()
{
GameObject fxGo = Instantiate(this.coinPrefab);
fxGo.transform.position = new Vector2(-0.95f, 0.7f);
}
// Update is called once per frame
void Update()
{
}
}

2 단계
블록이 마리오와 부딪혀서 바뀌면 생성
대리자 이용

잘 생성 됨

위치정보가 포함된 맨 상위 오브젝트를 넣지 못하고 brick Controller컴포넌트를 가진 main을 넣는게 마음에 좀 걸리지만 일단은 잘 돌아감
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Main : MonoBehaviour
{
[SerializeField]
private BrickController brickController;
public GameObject mushroomPrefab;
public GameObject coinPrefab;
// Start is called before the first frame update
void Start()
{
GameObject fxGo = Instantiate(this.coinPrefab);
this.brickController.onChanged = () =>
{
fxGo.transform.position = new Vector2(-0.95f, 0.7f);
};
}
// Update is called once per frame
void Update()
{
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BrickController : MonoBehaviour
{
private Rigidbody2D rBody2D;
private Animator anim;
public System.Action onChanged;
// Start is called before the first frame update
void Start()
{
this.rBody2D = this.GetComponent<Rigidbody2D>();
this.anim = this.GetComponent<Animator>();
}
// Update is called once per frame
public void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.tag == "mario")
{
this.anim.SetBool("isCrash", true);
this.onChanged();
}
}
}
3단계 블럭마다 지정된 item 생성하기
'2D 콘텐츠 제작 개발일지 (mario)' 카테고리의 다른 글
| 마리오개발 5일차 (0) | 2023.09.17 |
|---|---|
| 마리오개발 4일차 (0) | 2023.09.16 |
| 마리오 개발 3일차(포탈이동/UI) (0) | 2023.09.15 |
| 마리오 개발 1일차(이동 및 점프 및 애니메이션 구현) (0) | 2023.09.14 |
| Sprite 리소스 모으기(0일차) (1) | 2023.09.12 |