728x90
728x90
상속 -> 제네릭(Generic), 추상메소드, 추상클래스
상속을 받는 다는건 다 쓴다는 것
but 플레이어와 에너미가 다름 -> 제네릭을 만들어서 플레이어의 경우 -wall 로 에너미의 경우 - player로
protected 부모-자식
abstract(추상메소드) - 이름만 존재 -> 내용은 상속을 받은 쪽에서 채운다
virtual - override
MovingObj 코드
using UnityEngine;
using System.Collections;
using System;
//한번에 한칸만 움직이도록
public abstract class MovingObject : MonoBehaviour
{
[SerializeField] float moveSpeed;
[SerializeField] LayerMask BlockingLayer;
protected Animator myAnim;
Rigidbody2D myrigid;
BoxCollider2D myCollider;
protected void Start()
{
myrigid = GetComponent<Rigidbody2D>();
myCollider = GetComponent<BoxCollider2D>();
myAnim = GetComponent<Animator>();
}
//private void Update()
//{
// int h = (int)Input.GetAxis("Horizontal"); //GetAxis VS GetAxisRaw
// int v = (int)Input.GetAxis("Vertical"); //GetAxis VS GetAxisRaw
// if (h != 0 || v != 0) AttempMove<Wall>(h, v);
//}
//player --> wall공격
//enemy --> player 공격
//이동? 공격?
protected virtual void AttempMove<T>(int xDir, int yDir) //<>->제네릭 : 일부의 요소의 차이만 존재 -> 호출 시 결정
{
RaycastHit2D hit;
bool canMove = Move(xDir, yDir, out hit);
if (canMove) return; //공격여부확인 -> ray에 감지된 대상이 존재 -> wall 인지 다른 존재인지
T target = hit.transform.GetComponent<T>();
if (target != null) Attack(target);
}
protected abstract void Attack<T>(T target);
protected bool Move(int xDir, int yDir, out RaycastHit2D hit) //이동할 곳에 장애물 존재여부 확인
{
Vector2 start = transform.position;
Vector2 end = start + new Vector2(xDir, yDir);
myCollider.enabled = false;
hit = Physics2D.Linecast(start, end, BlockingLayer);
myCollider.enabled = true;
if (hit.transform == null) //rat에 감지된 물체가 없다 ---> 이동하시오
{
StartCoroutine(SmoothMove(end));
return true;
}
return false; // 공격여부판단
}
//코루틴 -> 쉬는 시간
protected IEnumerator SmoothMove(Vector3 end)
{
//magnitude(루트 계산 후의 결과), sqrMagnitude(루트 계산 전)
float distance = (end - transform.position).sqrMagnitude;
while (distance != 0)
{
//조금씩 이동
Vector3 newPos = Vector3.MoveTowards(transform.position, end, moveSpeed * Time.deltaTime);
myrigid.MovePosition(newPos);
distance = distance = (end - transform.position).sqrMagnitude;
yield return null; // while 과 실과 바늘
}
}
}
Player 코드
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
using System;
public class Player : MovingObject
{
[SerializeField] Text foodText;
int food;
int damage = 1;
int delayTime = 2;
int pointPerFood = 10;
int pointPerSoda = 20;
private void OnEnable() //활성화
{
food = GameManager.instance.PlayerFood;
foodText.text = "Food : " + food;
}
//비활성
private void OnDisable() => GameManager.instance.PlayerFood = food;
private void Update()
{
if (GameManager.instance.playerTurn == false) return;
int h = (int)Input.GetAxis("Horizontal"); //GetAxis VS GetAxisRaw
int v = (int)Input.GetAxis("Vertical"); //GetAxis VS GetAxisRaw
if (h != 0 || v != 0) AttempMove<Wall>(h, v);
}
protected override void AttempMove<T>(int xDir, int yDir)
{
base.AttempMove<T>(xDir, yDir); //base -> 부모 this -> 나
GameManager.instance.playerTurn = false;
food--;// 1개 삭제
foodText.text = "Food : " + food;
CheckIfGameOver();
}
void CheckIfGameOver()
{
if (food <= 0)
{
print("GameOver");
}
}
public void LossFood(int loss)
{
food -= loss;
CheckIfGameOver();
}
protected override void Attack<T>(T target)
{
Wall wall = target as Wall;
wall.DamageWall(damage);
}
//food, soda, exit 처리 -> OnTrigger
private void OnTriggerEnter2D(Collider2D collision)
{
switch (collision.tag) //if 를 3개 이상 써야하는 경우
{
case "Food":
food += pointPerFood;
foodText.text = "+" + pointPerFood + ",Food:" + food;
collision.gameObject.SetActive(false);
break;
case "Soda":
food += pointPerSoda;
foodText.text = "+" + pointPerSoda + ",Food:" + food;
collision.gameObject.SetActive(false);
break;
case "Exit":
Invoke("Restart", delayTime);
gameObject.SetActive(false);
break;
}
}
void Restart()
{
SceneManager.LoadScene(SceneManager.GetActiveScene().name); //SceneManager.GetActiveScene 지금 열려있는 씬
}
}
Enemy 스크립트
using UnityEngine;
using System.Collections;
public class Enemy : MovingObject
{
[SerializeField] int damage;
protected override void Attack<T>(T target)
{
Player player = target as Player;
player.LossFood(damage);
}
}
728x90
'유니티 > C#' 카테고리의 다른 글
18. DungeonShooter 게임 만들기-1 (0) | 2023.04.13 |
---|---|
17. 인벤토리 만들기-2 (0) | 2023.04.12 |
13. 간단 로그라이크 만들기 - 4 (0) | 2023.04.05 |
12. 간단 로그라이크 만들기 - 3 (0) | 2023.04.04 |
11. 간단 로그라이크 만들기 - 2 (0) | 2023.04.03 |