반응형

https://www.youtube.com/watch?v=LrpaW6VglVU 

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;


//일반형(generic) 을 사용하는 이유 플레이어, 적, 벽 과의 상호작용에서 서로서로 hitComponent 의 종류를 알 수 없기 때문에 당장 OnCantMove 함수에 입력을 받고 각각의 상속한 클래스들의 구현에 따라 동작하게 할 수 있기 때문이다.
public abstract class MovingObject : MonoBehaviour
{
    public float moveTime = 0.1f;
    public LayerMask blockingLayer; //충돌여부 변수


    private BoxCollider2D boxCollider;
    private Rigidbody2D rb2D; //객체의 움직임 레퍼런스를 담을 변수
    private float inverseMoveTime; //움직임을 효율적이게 계산하기 위한 변수


    // Start is called before the first frame update
    protected virtual void Start()//자식 클래스가 덮어써서 재정의 하기 위해 start 를 다시 정의할 수도있어서
    {
        boxCollider = GetComponent<BoxCollider2D>();
        rb2D = GetComponent<Rigidbody2D>();
        inverseMoveTime = 1f / moveTime; //나누기 대신에 효율적인 곱하기를 사용하기 위해 움직임의 역수치를 저장
    }

    protected bool Move (int xDir, int yDir, out RaycastHit2D hit)//bool 리턴값, hit 리턴값 두개의 리턴값을 가짐
    {
        Vector2 start = transform.position; //현재위치를 받기위한 변수
        // position 은 기존 3차원 이지만 Vector 2에 저장함으로 z 값은 날라가게됨 
        Vector2 end = start + new Vector2(xDir, yDir);

        boxCollider.enabled = false;//자기자신과 부딛히지 않기 위해 boxCollider 해제
        hit = Physics2D.Linecast(start, end, blockingLayer); // 시작지점과 끝지점 까지의 라인을 가져오고 blockinglayer 와 충돌검사
        boxCollider.enabled = true; 

        if(hit.transform == null)//부딪힌게 없다면
        {
            StartCoroutine(SmoothMovement(end));//end 방향으로 이동
            return true;
        }
        return false;
    }


    protected IEnumerator SmoothMovement (Vector3 end)//객체를 움직이게 할 함수 end에 어디로 움직일지 저장
    {
        float sqrRemainingDistance = (transform.position - end).sqrMagnitude; // 현재위치 - end 벡터에 sqrMagnitude 로 거리계산 Magnitude : 벡터길이 , sqrMagnitude : 벡터길이 제곱 

        while (sqrRemainingDistance > float.Epsilon)
        {
            Vector3 newPosition = Vector3.MoveTowards(rb2D.position, end, inverseMoveTime * Time.deltaTime); // epsilon (0에 가까운 아주작은 수 ) newposition 을 계산하여 end 값과 가장가까운 위치로 이동시키기 위한 변수
            //(현재위치(rigidpositon), 이동할위치, 시간(이 변수의 단위만틈 목적지로 가까워짐)) 
            rb2D.MovePosition(newPosition); // 새로운 위치로 이동
            sqrRemainingDistance = (transform.position - end).sqrMagnitude; // 움직인 후 남은 거리 계산 
            yield return null; //루프를 갱신하기 전에 다음 프레임을 기다림
        }
    }

    protected virtual void AttemptMove <T> (int xDir, int yDir)
        where T : Component
    {
        RaycastHit2D hit;
        bool canMove = Move(xDir, yDir, out hit);//이동하는데 성공하면 canMove = true else flase    

        if (hit.transform == null)//다른것과 부딪히지 않았다면 코드 종료
            return;

        T hitComponent = hit.transform.GetComponent<T>(); //충동할 레퍼런스를 T 타입 컴포넌트에 할당 

        if (!canMove && hitComponent != null)//움직임이 막힘 -> 충돌
            OnCantMove(hitComponent);
    }

    protected abstract void OnCantMove<T>(T component)
        where T : Component;// 자식 클래스에서 오버라이드 위해 남겨둠 
}

 

일반형(Generic) 타입을 사용하는 이유 

 

플레이어, 적, 벽 과의 상호작용에서 서로서로 hitComponent 의 종류를 알 수 없기 때문에 당장 OnCantMove 함수에 입력을 받고 각각의 상속한 클래스들의 구현에 따라 동작하게 할 수 있기 때문이다.

반응형

'Unity > 로그라이크 따라해보기' 카테고리의 다른 글

로그라이크 따라하기 7,8,9  (0) 2021.07.09
반응형
struct bucket* hashTable = NULL;
struct bucket* hashTable1 = NULL;
struct bucket* hashTable2 = NULL;
int SIZE = 11;
int SIZE1 = 101;
int SIZE2 = 1001;


struct Node {
	int key;
	int value;
	struct Node* next;
};

struct bucket {

	struct Node* head;
	int count;
};

struct Node* createNode(int key, int value) {

	struct Node* newNode;

	newNode = new Node;

	newNode->key = key;
	newNode->value = value;

	newNode->next = NULL;

	return newNode;
}

int hashFunction(int key, int SIZE) {

	return key % SIZE;
}

int hashBuild = 0;
int hashBuild1 = 0;
int hashBuild2 = 0;
void insert(struct bucket* hashTable, int key, int value, int SIZE) {

	int hashIndex = hashFunction(key, SIZE);

	struct Node* newNode = createNode(key, value);

	if (hashTable[hashIndex].count == 0) {
		hashTable[hashIndex].head = newNode;
		hashTable[hashIndex].count = 1;
		hashBuild++;

	}

	else {
		newNode->next = hashTable[hashIndex].head;
		hashTable[hashIndex].head = newNode;
		hashTable[hashIndex].count++;
		hashBuild++;

	}

	return;
}
int nodeCompare = 0;
void search(struct bucket* hashTable, int key, int SIZE) {

	int hashIndex = hashFunction(key, SIZE);
	struct Node* node = hashTable[hashIndex].head;

	if (node == NULL) {

		nodeCompare++;
		return;
	}

	while (node != NULL) {
		if (node->key == key) {
			nodeCompare++;
			//std::cout << "key found key = " << node->key << " value = " << node->value;
			break;
		}
		nodeCompare++;
		node = node->next;
	}
	//std::cout << "\nno key found";
	return;
}

void display() {
	struct Node* horse;
	int i = 0;

	for (i = 0; i < SIZE; i++) {

		horse = hashTable[i].head;

		std::cout << "Bucket[" << i << "] : ";

		while (horse != NULL) {
			printf("(key:%d, val:%d) -> ", horse->key, horse->value);
			horse = horse->next;

		}
		printf("\n");
	}
	printf("\n-------end of display--------");
	return;
}
반응형
반응형
int isPointInside(struct point A, vector<point>& v, int N) {
	int Count, i, LastPoint;
	bool PointOnTestLine = false;
	struct line TestLine, PolyLine;
	Count = LastPoint = 0;
	TestLine.p1 = A; TestLine.p2 = A;
	TestLine.p2.x = 9999;
	for (i = 0;i <= N;i++) {
		PolyLine.p1 = PolyLine.p2 = v[i];
		if (intersection(TestLine, PolyLine)) {
			PointOnTestLine = true;
			LastPoint = i;
		} //테스트 라인에 점이 있다
		else {// 테스트 라인과 변끼리 교차 확인
			PolyLine.p2 = v[LastPoint];
			LastPoint = i;
			if (!PointOnTestLine) {// false 라면
				if (intersection(PolyLine, TestLine)) Count++;
			}
			else {// true 라면
				if (direction(TestLine.p1, PolyLine.p2, PolyLine.p1) * direction(TestLine.p1, PolyLine.p2, v[LastPoint - 2]) < 0) {
					Count++; PointOnTestLine = false;
				}
			}
		}
	}
	if ((Count % 2) == 1) {
		cout << "true"; return 0;
	}
	else {
		cout << "false";
		return 0;
	}
}
반응형
반응형
void quickSort(vector<int>& v, int start, int end) {
	int pivot, left, right;
	pivot = start;
	left = start + 1;
	right = end;
	if (start >= end) return;
	while (left <= right) {
		while (left <= end && v[left] <= v[pivot]) {
			left++;
		}
		while (right > start && v[right] >= v[pivot] ) {
			right--;
		}
		if (left > right) swap(v[pivot], v[right]);
		else swap(v[left], v[right]);
	}

	quickSort(v, start, right - 1);
	quickSort(v, right + 1, end);
}

 

 

반응형

+ Recent posts