프로그래밍 공부
작성일
2023. 12. 11. 15:28
작성자
WDmil
728x90

Trail방식을 활용하면서, UV좌표를 수정하여 애니메이션이 2D형태로 출력되게 해보자.

 

쉐이더를 먼저 설정한다.

 

#include "../VertexHeader.hlsli"
#include "../PixelHeader.hlsli"

struct PixelInput
{
	float4 pos : SV_POSITION;
	float2 uv : UV;
};

PixelInput VS(VertexUV input)
{
	PixelInput output;
	output.pos = mul(input.pos, world);
	output.pos = mul(output.pos, view);
	output.pos = mul(output.pos, projection);
	
	output.uv = input.uv;
	
	return output;
}

cbuffer FrameBuffer : register(b10)
{
	float2 maxFrame;
	float2 curFrame;
}

float4 PS(PixelInput input) : SV_TARGET
{	
	float2 uv = (input.uv / maxFrame) + (curFrame / maxFrame);
	
	return diffuseMap.Sample(samp, uv) * mDiffuse;
}

 

기본적인 UV데이터를 끌어오는것은 맞으나, 데이터값을 받아올 때 Buffer에 최대 Frame과 curFrame을 받아와서,

 

현재 uv값을 계산한다.

 

uv의 현제 uv값은 들어온 uv값에 maxFrmae에서 나눈것, 현재 Frame에서 max를 나눈것을 더한 값이다.

 

현재 uv값은 0~ 1사이가 나와야 함으로, 최대 Frame을 나누어서, 현재 애니메이션의 uv값을 산출한다.

 


#pragma once

class WeaponLightning : public Weapon
{
public:
    WeaponLightning(SkillData data, Transform* player);
    ~WeaponLightning();    

    void Update() override;
    void Render() override;

private:
    void Fire();
    void Move();

private:
    float time = 0.0f;
    int chainCount = 0;

    Trail* trail;
    Sphere* ball;
    Transform* rightPos;
    Transform* leftPos;

    unordered_set<Transform*> targets;
    Transform* curTarget = nullptr;
};

 

Lightning를 생성한다. target의 set을 사용해서 적중한 객체에 다시 공격이 들어가지 않도록 해준다.

 

#include "Framework.h"

// WeaponLightning 클래스 생성자
WeaponLightning::WeaponLightning(SkillData data, Transform* player)
    : Weapon(data, player)
{
    // Transform, Sphere, Trail 등의 멤버 변수 초기화 및 설정
    rightPos = new Transform();
    leftPos = new Transform();
    ball = new Sphere();
    ball->SetActive(false);

    // 무기의 위치 설정 및 부착
    rightPos->SetParent(ball);
    leftPos->SetParent(ball);
    rightPos->SetLocalPosition(Vector3::Right());
    leftPos->SetLocalPosition(Vector3::Left());

    // 체인 효과를 나타내는 Trail 설정
    trail = new Trail(L"Textures/FX/Lightning_8x1.png",
        rightPos, leftPos, 20, 1, 8);
    trail->SetSpeed(10.0f);
    trail->SetActive(false);
}

// WeaponLightning 클래스 소멸자
WeaponLightning::~WeaponLightning()
{
    // 동적 할당된 메모리의 해제
    delete trail;
    delete rightPos;
    delete leftPos;
    delete ball;
}

// Update 함수 오버라이드
void WeaponLightning::Update()
{
    // 무기의 업데이트 로직 수행
    time += DELTA;

    if (time >= data.interval)
    {
        time -= data.interval;
        Fire(); // 발사 동작 호출
    }

    Move(); // 이동 동작 호출

    // 무기의 위치 및 체인 이펙트 업데이트
    rightPos->UpdateWorld();
    leftPos->UpdateWorld();
    trail->Update();
}

// Render 함수 오버라이드
void WeaponLightning::Render()
{
    // 체인 이펙트 렌더링
    trail->Render();
    // 주석 처리된 코드: 공 모델 렌더링 (필요에 따라 주석 해제하여 사용)
    //ball->Render();
}

// 무기 발사 동작
void WeaponLightning::Fire()
{
    // 무기와 체인 이펙트 활성화
    ball->SetActive(true);
    trail->SetActive(true);

    // 무기 위치 초기화 및 체인 효과 초기화
    ball->SetLocalPosition(player->GetLocalPosition());
    ball->UpdateWorld();
    rightPos->UpdateWorld();
    leftPos->UpdateWorld();
    trail->Init();

    // 대상 초기화 및 가장 가까운 몬스터 설정
    targets.clear();
    curTarget = MonsterManager::Get()->GetClosestMonster(player->GetLocalPosition());
    targets.insert(curTarget);
    chainCount = 0; // 체인 횟수 초기화
}

// 무기 이동 동작
void WeaponLightning::Move()
{
    // 대상이 없으면 이동하지 않음
    if (curTarget == nullptr) return;

    // 목표 방향 계산 및 회전 설정
    Vector3 direction = curTarget->GetLocalPosition() - ball->GetLocalPosition();
    float angle = atan2(direction.x, direction.z);
    ball->SetLocalRotation({ 0, angle, 0 });

    // 무기 이동
    ball->Translate(ball->GetForward() * data.speed * DELTA);
    ball->UpdateWorld();

    // 대상에 도달하면 데미지를 입히고 체인 동작 수행
    if (direction.Length() < 0.1f)
    {
        Monster* monster = (Monster*)curTarget;
        monster->Damage(data.power);

        // 마지막 체인 동작이면 대상 초기화 및 비활성화
        if (chainCount == data.count - 1)
        {
            curTarget = nullptr;
            ball->SetActive(false);
            return;
        }

        // 다음 대상 설정 및 체인 횟수 증가
        curTarget = MonsterManager::Get()->GetClosestMonster(
            ball->GetLocalPosition(), targets);
        targets.insert(curTarget);
        chainCount++;
    }
}

 

구체가 적을 따라서 이동하고, Effect가 공을 따라서 이동하는 형태로 구현되어있다.

 

rightPos, leftPos는 공의 좌측 우측에 붙어서 이동한다.

 

Update시 DELTA타임마다 시간을 중첩시켜서 타임이 일정값 이상이 되면 공격한다.

 

Move는 현재 객체의 Trail에 따라 목표방향의 direction을 구하고, 해당 위치로 속도에 DELTA만큼 곱한값으로 이동시킨다.

 

 

 

728x90