캐릭터 이동 코드
// CharCharacter.cs
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
public class CharController : MonoBehaviour
{
private const float jumpTestValue = 0.3f;
private static readonly int Speed1 = Animator.StringToHash("Speed");
private static readonly int Ground = Animator.StringToHash("Ground");
[SerializeField] private float Speed = 5.0f;
[SerializeField] private float JumpSpeed = 15.0f;
[SerializeField] private Camera _mainCamera;
[SerializeField] private float CameraSpeed = 4.0f;
[SerializeField] private float MaxDistence = 4.0f;
private Vector3 cameraOffset;
InputAction Move_Input;
private Animator _animator;
private Rigidbody2D _rigidbody;
private SpriteRenderer _spriteRenderer;
private InputAction Jump_Input;
public bool Grounded = true;
void Start()
{
_animator = GetComponent<Animator>();
_rigidbody = GetComponent<Rigidbody2D>();
_spriteRenderer = GetComponent<SpriteRenderer>();
UnityEngine.InputSystem.PlayerInput Input = GetComponent<UnityEngine.InputSystem.PlayerInput>();
Move_Input = Input.actions["Move"];
Jump_Input = Input.actions["Jump"];
cameraOffset = _mainCamera.transform.position - transform.position;
}
void Update()
{
Vector2 moveValue = Move_Input.ReadValue<Vector2>();
if (moveValue.x != 0)
_spriteRenderer.flipX = moveValue.x < 0;
_animator.SetFloat(Speed1, Mathf.Abs(moveValue.x));
_rigidbody.velocity = new Vector2(moveValue.x * Speed, _rigidbody.velocity.y);
if (Jump_Input.triggered && Grounded)
{
_rigidbody.AddForce(Vector2.up * JumpSpeed, ForceMode2D.Impulse);
_animator.Play("Alchemist_Jump");
}
}
private void LateUpdate()
{
var CharPosition = transform.position + cameraOffset;
float speed = CameraSpeed;
Vector3 newPosition = Vector3.zero;
if (Vector3.Distance(CharPosition, _mainCamera.transform.position) >= MaxDistence)
{
Vector3 Gap = ((_mainCamera.transform.position) - CharPosition).normalized * MaxDistence;
newPosition = CharPosition + Gap;
}
else
{
newPosition = Vector3.MoveTowards(_mainCamera.transform.position,
CharPosition,
speed * Time.deltaTime);
}
_mainCamera.transform.position = newPosition;
}
}
강사님이 주로 쓰시는 방식인 빈게임 오브젝트 만들어서 Circle Collider 사용하는 방식
// GroundCheck.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GroundChecker : MonoBehaviour
{
CharController charController;
void Start()
{
charController = GetComponentInParent<CharController>();
}
void OnTriggerEnter2D(Collider2D other)
{
Debug.Log("OnTriggerEnter2D");
charController.Grounded = true;
charController.GetComponent<Animator>().Play("Idles");
}
void OnTriggerExit2D(Collider2D other)
{
Debug.Log("OnTriggerExit2D");
charController.Grounded = false;
}
}
ProjectSetting에서 일괄 물리 설정 가능
2D는 2D 설정이 따로 있음
최종적으로 이펙트까지 추가함
using System;
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.UI;
public class ItemGetter : MonoBehaviour
{
// 아이템이 이동할 목표 위치를 나타내는 UI 요소(RectTransform)
public RectTransform itemRectTransform;
// 아이템이 표시되는 캔버스
public Canvas canvas;
// 충돌 시 생성될 UI 아이템의 프리팹
public GameObject itemPrefab;
// 아이템이 목표 위치로 도착할 때 나타날 이펙트의 프리팹
public GameObject getEffectPrefab;
// 화면 좌표 변환에 사용할 카메라
public Camera camera;
// EaseInOut 함수: 부드럽게 가속과 감속을 적용하는 보간(Interpolation) 함수입니다.
// t 값(0~1 사이)을 받아 움직임을 부드럽게 만드는 데 사용됩니다.
private float EaseInOut(float t)
{
// t가 0.5보다 작으면 빠르게 가속, 크면 천천히 감속합니다.
return t < 0.5f ? 2f * t * t : -1f + (4f - 2f * t) * t;
}
// GoingToBox 코루틴: 아이템을 박스(UI)로 이동시키고 도착 후 이펙트를 생성합니다.
IEnumerator GoingToBox(RectTransform itemTransform, RectTransform boxTransform)
{
// 이동에 걸리는 총 시간(초)
float duration = 2.0f;
// 경과 시간 초기화
float t = 0.0f;
// 아이템의 초기 위치 저장
Vector3 itemBeginPOS = itemTransform.position;
// 경과 시간 비율이 1.0 이하일 때까지 반복
while (1.0f >= t / duration)
{
// EaseInOut을 사용해 새 위치 계산
Vector3 newPosition = Vector3.Lerp(itemBeginPOS, boxTransform.position, EaseInOut(t / duration));
// 아이템의 위치를 새로 계산된 위치로 설정
itemTransform.position = newPosition;
// 경과 시간 증가
t += Time.deltaTime;
// 다음 프레임까지 대기
yield return null;
}
// 이동 종료 후 정확히 목표 박스 위치로 아이템 설정
itemTransform.position = boxTransform.position;
// 아이템 UI 오브젝트 제거
Destroy(itemTransform.gameObject);
// 목표 위치에 이펙트 생성
var particle = Instantiate(getEffectPrefab, boxTransform.position, getEffectPrefab.transform.rotation);
// 디버그 로그로 이펙트 객체 정보를 출력
Debug.Log(particle);
// 생성된 이펙트의 크기를 변경
particle.transform.localScale = new Vector3(4.0f, 4.0f, 4.0f);
// Z축 위치를 0으로 설정 (2D 화면에서 정확히 보이도록 설정)
var vector3 = particle.transform.position;
vector3.z = 0.0f;
particle.transform.position = vector3;
// 3초 후 이펙트를 삭제
Destroy(particle, 3.0f);
}
// OnTriggerEnter2D: 2D 물리 충돌이 발생했을 때 호출되는 Unity 이벤트 메서드
private void OnTriggerEnter2D(Collider2D other)
{
// 충돌한 오브젝트 정보를 디버그 로그로 출력
Debug.Log(other);
// 충돌 위치에서 새로운 UI 아이템 생성
var newObject = Instantiate(itemPrefab, other.transform.position, Quaternion.identity, canvas.transform);
// 생성된 아이템의 이미지를 충돌한 오브젝트의 스프라이트로 설정
newObject.GetComponent<Image>().sprite = other.GetComponent<SpriteRenderer>().sprite;
// 새로 생성된 아이템의 위치를 충돌한 오브젝트와 동일하게 설정
newObject.transform.position = other.transform.position;
// 월드 좌표를 화면 좌표로 변환
var newScreenPosition = Camera.main.WorldToScreenPoint(newObject.transform.position);
// 화면 좌표를 캔버스의 로컬 좌표로 변환
Vector2 localPoint;
RectTransformUtility.ScreenPointToLocalPointInRectangle(
canvas.GetComponent<RectTransform>(), newScreenPosition, camera, out localPoint);
// 생성된 아이템의 로컬 위치를 캔버스 내 좌표로 설정
newObject.transform.localPosition = localPoint;
// 아이템을 목표 박스 위치로 이동시키는 코루틴 실행
StartCoroutine(GoingToBox(newObject.GetComponent<RectTransform>(), itemRectTransform));
// 충돌한 오브젝트를 제거
Destroy(other.gameObject);
}
}
'공부 > [TIL] Game Bootcamp' 카테고리의 다른 글
[멋쟁이사자처럼 부트캠프 TIL] 유니티 게임 개발 3기 : 스킬 + 액션툴 (0) | 2024.12.18 |
---|---|
[멋쟁이사자처럼 부트캠프 TIL] 유니티 게임 개발 3기 : Curve, 몬스터 생성, 몬스터와 충돌 이벤트 (1) | 2024.12.17 |
[멋쟁이사자처럼 부트캠프 TIL] 유니티 게임 개발 3기 : Input System, TileMap 등 (4) | 2024.12.13 |
[멋쟁이사자처럼 부트캠프 TIL] 유니티 게임 개발 3기 : Unity C# (0) | 2024.12.12 |
[멋쟁이사자처럼 부트캠프 TIL] 유니티 게임 개발 3기 : 정렬 (0) | 2024.12.11 |