[Unity2D] 몬스터,캐릭터와 충돌 및 공격 변경C#/Unity2020. 7. 9. 17:28
Table of Contents
GreenMonster.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// 이동간 절대기준 사용위한 Tweening 라이브러리 사용
using DG.Tweening;
using System;
public class GreenMonster : MonoBehaviour
{
////////////////////////////////////////////////////////////////////////////////
// 멤버변수 선언
bool _IsMoveAction = false;
// 이동 겹치기 방지
bool _DontMoveDown = false;
bool _DontMoveUp = false;
bool _DontMoveLeft = false;
bool _DontMoveRight = false;
// HitCount
int _HitCount = 0;
// hero 위치
int _AttackDirection = 0;
////////////////////////////////////////////////////////////////////////////////
// 델리게이트 선언(return형과 함수형이같아야함)
// 함수를 추가 삭제하기 편함
delegate void DelegateInit();
DelegateInit CurrentAction;
// Start is called before the first frame update
void Start()
{
// 델리게이트 Start
CurrentAction += new DelegateInit(MoveAction);
}
// Update is called once per frame
void Update()
{
// 델리게이트 사용
CurrentAction();
}
// 움직이는 액션
void MoveAction()
{
if (!_IsMoveAction)
{
int R = UnityEngine.Random.Range(0, 4); // 랜덤이동을 위한 부분
switch (R)
{
case 0:
LeftMove();
break;
case 1:
RightMove();
break;
case 2:
UpMove();
break;
case 3:
DownMove();
break;
}
}
}
// 위쪽 이동
void UpMove()
{
if (_DontMoveUp == false)
{
float EndPositionY = transform.position.y;
float delay = UnityEngine.Random.Range(0, 3); // delay속도 랜덤 생성
_IsMoveAction = true; // 토큰 값 변경
GetComponent<Animator>().SetInteger("State", 0);
EndPositionY += 1.5f;
// delay먼저 작동하고 complete
transform.DOMoveY(EndPositionY, 1.5f).OnComplete(MoveActionComplete).SetEase(Ease.Flash).SetDelay(delay);
}
}
// 아래쪽 이동
void DownMove()
{
if (_DontMoveDown == false)
{
float EndPositionY = transform.position.y;
float delay = UnityEngine.Random.Range(0, 3); // delay속도 랜덤 생성
_IsMoveAction = true; // 토큰 값 변경
GetComponent<Animator>().SetInteger("State", 1);
EndPositionY -= 1.5f;
transform.DOMoveY(EndPositionY, 1.5f).OnComplete(MoveActionComplete).SetEase(Ease.Flash).SetDelay(delay);
}
}
// 왼쪽 이동
void LeftMove()
{
if (_DontMoveLeft == false)
{
float EndPositionX = transform.position.x;
float delay = UnityEngine.Random.Range(0, 3);
// 내부 컴포넌트는 GetComponent로 불러올 수 있다.
_IsMoveAction = true; // 토큰 값 변경
GetComponent<Animator>().SetInteger("State", 2); // Animator에서 State값 가져와 변경하는 코드
EndPositionX -= 1.5f;
transform.DOMoveX(EndPositionX, 1.5f).OnComplete(MoveActionComplete).SetEase(Ease.Flash).SetDelay(delay);
}
}
// 오른쪽이동
void RightMove()
{
if (_DontMoveRight == false)
{
float EndPositionX = transform.position.x;
float delay = UnityEngine.Random.Range(0, 3);
GetComponent<Animator>().SetInteger("State", 3);
_IsMoveAction = true; // 토큰 값 변경
EndPositionX += 1.5f;
transform.DOMoveX(EndPositionX, 1.5f).OnComplete(MoveActionComplete).SetEase(Ease.Flash).SetDelay(delay);
}
}
// 이동이 끝났을 때
void MoveActionComplete()
{
// 토큰값 false
_IsMoveAction = false;
GetComponent<Animator>().SetInteger("State", GetComponent<Animator>().GetInteger("State") + 4);
}
////////////////////////////////////////////////////////////////////////////////
// 공격 모션
void AttackAction()
{
// 움직이는 도중에 공격하지 않게 함
if (!_IsMoveAction)
{
GetComponent<Animator>().SetInteger("State", _AttackDirection % 4 + (4 * 4));
}
}
// 총알 맞았을 때
void HitAction()
{
}
////////////////////////////////////////////////////////////////////////////////
// 이동모션에서 공격모션으로 변경
// 방향값 인자로 받아옴
public void ChangeToAttack(CollisionDetaction.Direction d)
{
if (CurrentAction.Method.Name == "MoveAction")
{
// Direction -> int로 캐스팅
_AttackDirection = (int)d;
CurrentAction -= new DelegateInit(MoveAction);
CurrentAction += new DelegateInit(AttackAction);
}
}
// 공격모션에서 이동모션으로 변경
public void ChangeToMoveAction()
{
if (CurrentAction.Method.Name == "AttackAction")
{
CurrentAction -= new DelegateInit(AttackAction);
CurrentAction += new DelegateInit(MoveAction);
}
}
////////////////////////////////////////////////////////////////////////////////
// 트리거 진입
private void OnTriggerEnter2D(Collider2D collision)
{
String name = collision.gameObject.name;
// collosion은 상대방의 정보 가져옴
if (name == "bot_wall")
{
_DontMoveDown = true;
}
else if (name == "top_wall")
{
_DontMoveUp = true;
}
else if (name == "left_wall")
{
_DontMoveLeft = true;
}
else if (name == "right_wall")
{
_DontMoveRight = true;
}
// 총알에 맞았을 때
else if(name == "Player_Bullet(Clone)")
{
// Hit
_HitCount++;
GetComponent<Animator>().SetInteger("State", GetComponent<Animator>().GetInteger("State")%4 + (4*2));
// Death
if (_HitCount >= 3)
{
// 곱해서 더한값을 나머지 연산으로 다시 처음으로 돌아감(방향 파악하기위해)
GetComponent<Animator>().SetInteger("State", GetComponent<Animator>().GetInteger("State")%4 + (4 * 3));
}
}
}
// 트리거 나옴
private void OnTriggerExit2D(Collider2D collision)
{
String name = collision.gameObject.name;
// collosion은 상대방의 정보 가져옴
if (name == "bot_wall")
{
_DontMoveDown = false;
}
else if (name == "top_wall")
{
_DontMoveUp = false;
}
else if (name == "left_wall")
{
_DontMoveLeft = false;
}
else if (name == "right_wall")
{
_DontMoveRight = false;
}
}
// 몬스터 죽음(애니메이션에 이벤트 등록함)
private void MonsterDestroy()
{
Destroy(gameObject);
}
}
CollisionDetaction.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CollisionDetaction : MonoBehaviour
{
// 방향 정의함
// 열거형(자동으로 ++ 되서 넘버링된다)
public enum Direction
{
Up = 0,
Down,
Left,
Right,
}
// public 하면 유니티 에디터에 Script 부분에 추가된다. 근데 멤버변수는 public하면 좋지 않기 떄문에
// 그 앞에 [SerializeField]를 추가해 Script에 추가한다.
[SerializeField]Direction _MyDirection;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
private void OnTriggerEnter2D(Collider2D collision)
{
if(collision.name == "hero")
{
// 부모의 정보를 받아올 수 있다.
//transform.parent.gameObject.GetComponent<GreenMonster>().ChangeToAttack(_MyDirection);
// SendMassage() 자주안씀 퍼포먼스가 좀 부족함. public으로 다 알면 위에 정보처리로 하는게 좋음
// 외부 라이브러리가 private로 되어있거나 찾아오기 어려우면 쓰기도 한다.
// SendMessageOptions 는 혹시 실패났을때 예외처리 할 수 있게 값 받아오는 것. RequireReceiver하면 퍼포먼스면에서 부족함
transform.parent.gameObject.SendMessage("ChangeToAttack",_MyDirection, SendMessageOptions.DontRequireReceiver);
}
}
private void OnTriggerExit2D(Collider2D collision)
{
//transform.parent.gameObject.GetComponent<GreenMonster>().ChangeToMoveAction();
transform.parent.gameObject.SendMessage("ChangeToMoveAction", SendMessageOptions.DontRequireReceiver);
}
}
반응형
'C# > Unity' 카테고리의 다른 글
[기타내용] 공부할때 썼던 내용들 (0) | 2020.08.03 |
---|---|
[Unity2D] 몬스터만들기, 애니메이션, 애니메이터(이동, 대기, 공격, 죽음) (0) | 2020.07.08 |
[Unity2D] Collision, Trigger 충돌 조건 확인 & 총알 발사하기 (0) | 2020.07.07 |
[Unity2D] Tweening을 사용한 캐릭터 움직이기 (0) | 2020.07.06 |
@반나무 :: 반나무_뿌리
3년차 WPF 개발자입니다.
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!