티스토리 뷰
오늘 한 것
- Vector3 기준으로 작동하던 이동 방식을 Degree 각도 기준으로 변경.
- 공격용 오브젝트 작성
- 투사체 오브젝트의 각도 문제 수정
- 파동 오브젝트 추가
- 구체 오브젝트 추가
- 플레이어가 공격의 주체가 될 수 있도록 구성
- 마우스 휠을 이용한 스킬 전환 구현
- 마우스 버튼을 이용한 스킬 및 평타 사용 기능 구현
결과물
코드
이동
더보기
public void Move_Chara(float _velocity)
{
Vector2 Mouse_Pos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
// 탄젠트 값을 이용하여 Radian 각도를 구한 뒤 이를 Degree 각도로 치환하는 공식.
Angle_Mouse = Mathf.Atan2(Mouse_Pos.y - transform.position.y, Mouse_Pos.x - transform.position.x) * Mathf.Rad2Deg;
// 두 점 간의 거리를 구하는 함수.
float distance = Vector3.Distance(transform.position, Mouse_Pos);
if (distance > 3.5)
{
transform.position += Quaternion.Euler(0.0f, 0.0f, Angle_Mouse) * Vector3.right * 5.0f * _velocity;
Stamina.Dec_Gauge(1);
}
else if (distance > 1)
{
transform.position += Quaternion.Euler(0.0f, 0.0f, Angle_Mouse) * Vector3.right * _velocity;
}
else
{
Stamina.Inc_Gauge(1);
}
}
투사체
더보기
투사체 오브젝트
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Projectile : MonoBehaviour
{
public bool is_friendly;
public int[] Damage = new int[5];
public int Pierce_Max;
int Pierce_Cur;
public List<int> Fork;
public float Time_Max = 1.0f;
float Time_Cur;
public float velocity;
public Vector3 Size;
public float rotate;
Vector3 Direction;
public Sprite Shape;
SpriteRenderer Rend;
List<GameObject> Hitted_Units = new List<GameObject>();
private void Start()
{
Pierce_Cur = Pierce_Max;
Rend = GetComponent<SpriteRenderer>();
Rend.sprite = Shape;
transform.localScale = Size;
transform.rotation = Quaternion.Euler(0.0f, 0.0f, rotate);
Time_Cur = 0.0f;
}
private void Update()
{
Direction = transform.rotation * Vector3.right;
transform.position += Direction * velocity;
Time_Cur += Time.deltaTime;
if (Time_Cur >= Time_Max)
Destroy(gameObject);
}
private void OnTriggerEnter2D(Collider2D collision)
{
bool Affective = false;
if (is_friendly)
{
if (collision.gameObject.CompareTag("Enemy"))
Affective = true;
}
else
{
if (collision.gameObject.CompareTag("Player"))
Affective = true;
}
if (Affective && !Hitted_Units.Contains(collision.gameObject))
{
collision.gameObject.GetComponent<Chara_Base>().Get_Damage(Damage);
Hitted_Units.Add(collision.gameObject);
if (Pierce_Cur > 0)
Pierce_Cur--;
else if (Fork.Count > 0)
{
Pierce_Cur = Pierce_Max;
int Fork_Temp = Fork[0];
Fork.RemoveAt(0);
for (int j = 0; j < Fork_Temp; j++)
{
float Fork_rotate = rotate + (((((float)Fork_Temp - 1.0f) / 2.0f) - j) * 30.0f);
GameObject Sub_Projectile = Instantiate(this.gameObject, position: transform.position, rotation: Quaternion.Euler(0.0f, 0.0f, Fork_rotate));
Projectile Sub_Proj_Script = Sub_Projectile.gameObject.GetComponent<Projectile>();
Sub_Proj_Script.rotate = Fork_rotate;
Sub_Proj_Script.Hitted_Units = Hitted_Units;
Sub_Proj_Script.Time_Cur = Time_Cur;
}
Destroy(this.gameObject);
}
else
Destroy(this.gameObject);
}
}
}
투사체 발사 함수
public void Shoot_Proj(Vector3 _Position, float _rotation, float _velocity, float _Size, int[] _Damage)
{
GameObject temp = Instantiate(Projectile_Pref, _Position, Quaternion.identity);
temp.SetActive(false);
Projectile temp_Proj = temp.GetComponent<Projectile>();
temp_Proj.is_friendly = true;
temp_Proj.velocity = _velocity;
temp_Proj.rotate = transform.rotation.z + _rotation;
temp_Proj.Fork.Add(3);
temp_Proj.Damage = _Damage;
temp_Proj.Size = new Vector3(_Size, _Size, 1.0f);
temp.SetActive(true);
}
파동
더보기
파동 오브젝트
public class Pulse : MonoBehaviour
{
public bool is_friendly;
public int[] Damage = new int[5];
public Animator Anim;
public float speed = 1.0f;
float E_Time;
float C_Time;
public Vector3 Size;
private void Start()
{
transform.localScale = Size;
Anim = GetComponent<Animator>();
Anim.SetFloat("E_Speed", speed);
E_Time = 1.25f / speed;
C_Time = 0.0f;
}
private void Update()
{
C_Time += Time.deltaTime;
if (C_Time >= E_Time)
{
Destroy(gameObject);
}
}
private void OnTriggerEnter2D(Collider2D collision)
{
bool Affective = false;
if (is_friendly)
{
if (collision.gameObject.CompareTag("Enemy"))
Affective = true;
}
else
{
if (collision.gameObject.CompareTag("Player"))
Affective = true;
}
if (Affective)
{
collision.gameObject.GetComponent<Chara_Base>().Get_Damage(Damage);
}
}
}
파동 발산 함수
public void Emit_Pulse(Vector3 _Position, float E_Speed, float _Size, int[] _Damage)
{
GameObject temp = Instantiate(Pulse_Pref, _Position, Quaternion.identity);
temp.SetActive(false);
Pulse temp_Pul = temp.GetComponent<Pulse>();
temp_Pul.is_friendly = true;
temp_Pul.speed = E_Speed;
temp_Pul.Damage = _Damage;
temp_Pul.Size = new Vector3(_Size, _Size, 1.0f);
temp.SetActive(true);
}
구체
더보기
구체 오브젝트
public class Orb : MonoBehaviour
{
public bool is_friendly;
public int[] Damage = new int[5];
public float Time_Max = 5.0f;
float Time_Cur;
public float TIme_Term = 0.5f;
bool is_On;
float Timer;
List<GameObject> Hitted_Units = new List<GameObject>();
Animator Anim;
public Vector3 Size;
public float Direction;
public float velocity;
private void Start()
{
transform.localScale = Size;
Time_Cur = 0.0f;
Timer = 0.0f;
is_On = false;
Anim = GetComponent<Animator>();
}
private void Update()
{
Time_Cur += Time.deltaTime;
transform.position += Quaternion.Euler(new Vector3(0.0f, 0.0f, Direction)) * Vector3.right * velocity;
if(is_On)
Timer += Time.deltaTime;
if(Timer >= TIme_Term)
{
Timer -= TIme_Term;
Hitted_Units.Clear();
}
if (Time_Cur >= 0.5f && !is_On)
{
Time_Cur = 0.0f;
is_On = true;
}
if (Time_Cur >= Time_Max)
{
is_On = false;
Anim.SetBool("is_End", true);
Invoke("Destroy_this", 0.5f);
}
}
private void OnTriggerStay2D(Collider2D collision)
{
bool Affective = false;
if (is_friendly)
{
if (collision.gameObject.CompareTag("Enemy"))
Affective = true;
}
else
{
if (collision.gameObject.CompareTag("Player"))
Affective = true;
}
if (Affective && !Hitted_Units.Contains(collision.gameObject) && is_On)
{
Hitted_Units.Add(collision.gameObject);
collision.gameObject.GetComponent<Chara_Base>().Get_Damage(Damage);
}
}
void Destroy_this()
{
Destroy(gameObject);
}
}
구체 생성 함수
public void Create_Orb(Vector3 _Position, float _Time_Max, float _Time_Term, float _Size, float _velocity, float _Direction, int[] _Damage)
{
GameObject temp = Instantiate(Orb_Pref, _Position, Quaternion.identity);
temp.SetActive(false);
Orb temp_Orb = temp.GetComponent<Orb>();
temp_Orb.is_friendly = true;
temp_Orb.Time_Max = _Time_Max;
temp_Orb.TIme_Term = _Time_Term;
temp_Orb.velocity = _velocity;
temp_Orb.Direction = _Direction;
temp_Orb.Damage = _Damage;
temp_Orb.Size = new Vector3(_Size, _Size, 1.0f);
temp.SetActive(true);
}
스킬 사용 관련 코드 (일부)
더보기
스킬 버튼 UI
public class Skill_Button : MonoBehaviour
{
public Chara_Base Chara;
public GameObject Cursor;
public GameObject OFF_Display;
public int Skill_Num;
public int Gauge_Need;
private void Update()
{
if (Chara.Cur_Skill == Skill_Num)
Cursor.SetActive(true);
else
Cursor.SetActive(false);
if (Chara.Point_Cur >= Gauge_Need)
OFF_Display.SetActive(false);
else
OFF_Display.SetActive(true);
}
}
스킬 사용 코드
if (Input.GetMouseButtonDown(0) && Point_Cur >= 2)
{
int[] Damage_Bark = { 15, 0, 0, 0, 0 };
Emit_Pulse(transform.position, 1.0f, 7.5f, Damage_Bark);
}
if (Input.GetMouseButtonDown(1))
{
if (Cur_Skill == 1 && Point_Cur >= 1)
{
Point_Use(8.0f, 1);
int[] Damage_Skill = { 25, 0, 0, 0, 0 };
Shoot_Proj(transform.position, Angle_Mouse, 0.1f, 8.0f, Damage_Skill);
}
else if (Cur_Skill == 2 && Point_Cur >= 3)
{
Point_Use(3.0f, 3);
int[] Damage_Skill = { 10, 0, 0, 0, 0 };
Emit_Pulse(transform.position + (Quaternion.Euler(0.0f, 0.0f, Angle_Mouse) * Vector3.right * 2.0f), 1.0f, 2.5f, Damage_Skill);
Emit_Pulse(transform.position + (Quaternion.Euler(0.0f, 0.0f, Angle_Mouse) * Vector3.right * 3.0f), 1.0f, 2.5f, Damage_Skill);
Emit_Pulse(transform.position + (Quaternion.Euler(0.0f, 0.0f, Angle_Mouse) * Vector3.right * 4.0f), 1.0f, 2.5f, Damage_Skill);
}
else if (Cur_Skill == 3 && Point_Cur >= 2)
{
Point_Use(5.0f, 2);
int[] Damage_Skill = { 4, 0, 0, 0, 0 };
Create_Orb(transform.position + (Quaternion.Euler(0.0f, 0.0f, Angle_Mouse) * Vector3.right * 2.0f), 2.5f, 0.25f, 1.5f, 0.01f, Angle_Mouse, Damage_Skill);
}
}
float Input_Wheel = Input.GetAxis("Mouse ScrollWheel");
if (Input_Wheel > 0)
{
Cur_Skill++;
if (Cur_Skill >= 4)
Cur_Skill = 1;
}
else if (Input_Wheel < 0)
{
Cur_Skill--;
if (Cur_Skill <= 0)
Cur_Skill = 3;
}
정리하며
이틀 전에 언급했듯이, 오늘은 기존에 제작했던 것 들을 다듬고, 공격용 객체와 플레이어 컨트롤 시스템을 작성하였습니다.
이제 여기에 적 캐릭터 관련 요소 및 필드 관련 요소들 만 작성하면 1차적으로 테스트를 해볼 수 있는 버전이 됩니다.
물론, 그 뒤에도 스킬 시스템과 장비 시스템, 타이틀(+ 설정), 세이브 시스템 등등 작성해야 할 것들은 아직 많긴 하지만, 그래도 단판 테스트는 가능하게 됩니다.
그래도 이제 플레이어 조작 관련 최소 요구 기능은 거의 작업 완료된 거 같네요.
여담으로, 기믹 대처용으로 점프를 넣으려고 했는데 2D로 기반을 만들어놔서 3D로 바꾸면 세로로 정렬이 되어 버립니다. 그래서 살짝 골치 아픈데, 아마 실제 좌표가 변하는 게 아닌, 점프 지속 시간 동안 특수한 상태가 적용되는 방식을 사용하거나 좌표랑 각도, 벡터 다 뜯어고쳐서 3D로 엎게 되지 않을까 싶습니다.
일단 어찌되었건 아직 점프를 작성할 단계는 아니라서 좀 더 고민해보지 싶네요.
'스파르타 내일배움캠프 > Today I Learned' 카테고리의 다른 글
(사전 캠프) Day 16 - 멍뭉이! 멍멍뭉! ~ 귀신 잡는 개멍대! (4) | 2024.09.03 |
---|---|
(사전캠프) Day 15 - 멍뭉이! 멍멍뭉! ~ 귀신 잡는 개멍대! (0) | 2024.09.02 |
(사전 캠프) Day 13 - 간단한 역 기획 발표하기 (0) | 2024.08.29 |
(사전 캠프) Day 12 [멍뭉이! 멍멍뭉! - 귀신 잡는 개멍대!] (0) | 2024.08.28 |
(사전 캠프) Day 11 (1) | 2024.08.27 |