오전에 Vector 외적...했음
궤적 그리기
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Cannon : MonoBehaviour
{
// 캐논의 발사력과 질량을 설정
public float Power = 500.0f; // 발사력
public float Mass = 10.0f; // 캐논볼의 질량
public int maxStep = 20; // 예측할 궤적의 최대 단계 수
public float timeStep = 0.1f; // 시간 간격 (매 단계마다의 시간 차)
// 발사체와 궤적을 표시할 오브젝트
public GameObject CannonBall; // 발사체 프리팹
public GameObject Trajectory; // 궤적 표시용 오브젝트
// 궤적을 표시할 오브젝트 목록
public List<GameObject> Objects = new List<GameObject>();
// 예상 궤적을 계산하는 함수
List<Vector3> PredictTrajectory(Vector3 force, float mass)
{
List<Vector3> trajectory = new List<Vector3>();
// 현재 캐논의 위치와 초기 속도
Vector3 position = transform.position;
Vector3 velocity = force / mass; // 힘 / 질량 = 속도
trajectory.Add(position); // 첫 번째 위치 (캐논의 현재 위치)
// 궤적을 계산 (최대 단계 수만큼 반복)
for (int i = 1; i <= maxStep; i++)
{
float timeElapsed = timeStep * i; // 시간 간격
// 등가속도 운동 공식 적용: 거리 = 초기 위치 + 속도 * 시간 + 0.5 * 중력 * 시간^2
trajectory.Add(position +
velocity * timeElapsed +
Physics.gravity * (0.5f * timeElapsed * timeElapsed));
// 충돌 체크
if (CheckCollision(trajectory[i - 1], trajectory[i], out Vector3 hitPoint))
{
trajectory[i] = hitPoint; // 충돌 지점으로 궤적 수정
break; // 충돌 시 궤적 계산 중단
}
}
return trajectory; // 계산된 궤적 반환
}
// 충돌 여부를 체크하는 함수
private bool CheckCollision(Vector3 start, Vector3 end, out Vector3 hitPoint)
{
hitPoint = end; // 기본적으로 끝 지점으로 설정
Vector3 direction = end - start; // 시작 지점과 끝 지점 사이의 방향
float distance = direction.magnitude; // 두 지점 간 거리
// Raycast로 충돌 검사 (Default 레이어에 대해 Raycast 진행)
if (Physics.Raycast(start, direction.normalized, out RaycastHit hit, distance, 1 << LayerMask.NameToLayer("Default")))
{
hitPoint = hit.point; // 충돌 지점 저장
return true; // 충돌 있음
}
return false; // 충돌 없음
}
// 매 프레임마다 호출되는 Update 함수
void Update()
{
// 'W' 키를 눌렀을 때 캐논을 위로 회전
if (Input.GetKey(KeyCode.W))
{
transform.rotation *= Quaternion.Euler(-90 * Time.deltaTime, 0, 0);
}
// 'S' 키를 눌렀을 때 캐논을 아래로 회전
if (Input.GetKey(KeyCode.S))
{
transform.rotation *= Quaternion.Euler(90 * Time.deltaTime, 0, 0);
}
// 'Z' 키를 눌렀을 때 캐논볼 발사
if (Input.GetKeyDown(KeyCode.Z))
{
// 캐논볼 생성 후 발사
GameObject go = Instantiate(CannonBall, transform.position, transform.rotation);
go.GetComponent<Rigidbody>().mass = Mass; // 캐논볼의 질량 설정
go.GetComponent<Rigidbody>().AddForce(transform.forward * Power, ForceMode.Impulse); // 힘을 가하여 발사
Destroy(go, 3.0f); // 3초 후 캐논볼 삭제
}
// 'Space' 키를 눌렀을 때 궤적 표시
if (Input.GetKeyDown(KeyCode.Space))
{
// 예측된 궤적 계산
List<Vector3> trajectorys = PredictTrajectory(transform.forward * Power, Mass);
// 기존의 궤적 오브젝트들 삭제
foreach (var o in Objects)
{
Destroy(o);
}
Objects.Clear(); // 리스트 초기화
// 새로 계산된 궤적에 대해 궤적 표시용 오브젝트 생성
foreach (var trajectory in trajectorys)
{
var go = Instantiate(Trajectory, trajectory, Quaternion.identity);
Objects.Add(go);
}
}
// 기존에 생성된 궤적 오브젝트를 비활성화
foreach (var o in Objects)
{
o.SetActive(false);
}
// 새로운 궤적 계산
List<Vector3> trajectorys2 = PredictTrajectory(transform.forward * Power, Mass);
// 궤적 개수가 같으면 오브젝트 활성화하고 위치 업데이트
if (Objects.Count == trajectorys2.Count)
{
for (var index = 0; index < trajectorys2.Count; index++)
{
var trajectory = trajectorys2[index];
Objects[index].SetActive(true); // 궤적 오브젝트 활성화
Objects[index].transform.position = trajectory; // 위치 갱신
}
}
}
}
HpBar 달기
일단 Image로 Background 하나 Gauge 하나 만든다
그리고 HpBar에 스크립트 추가해주고
private Camera camera; // 메인 카메라
private Transform owner; // HP바가 따라다닐 대상 (플레이어)
private Camera ui_camera; // UI 카메라
public void UpdateOwner(Transform owner, Camera ui_camera)
{
this.owner = owner; // HP바의 소유자 설정
this.ui_camera = ui_camera; // UI 카메라 설정
}
void LateUpdate()
{
if (owner != null && camera != null) // 소유자와 메인 카메라가 존재할 때만 업데이트 실행
{
// 월드 좌표의 소유자 위치를 화면 좌표로 변환
Vector3 screenPoint = camera.WorldToScreenPoint(owner.position);
// 화면 좌표를 UI 캔버스의 로컬 좌표로 변환
Vector2 localPoint;
RectTransformUtility.ScreenPointToLocalPointInRectangle(
transform.parent.GetComponent<RectTransform>(), screenPoint, ui_camera, out localPoint);
// HP바의 로컬 위치를 업데이트하여 소유자의 위치를 따라감
transform.localPosition = localPoint;
}
}
CharCharacter에도 코드 추가해준다(단 아래 코드는 권장되지 않음)
public Canvas _canvas; // HP바를 표시할 UI 캔버스
public HpBar _hpBar; // HP바 프리팹
public Camera ui_camera; // UI 카메라
public Transform hpPosition; // HP바가 따라다닐 대상의 위치 (플레이어 캐릭터)
void Start()
{
// ... 생략 ...
// HP바를 생성하고 소유자 정보를 업데이트
GameObject go = Instantiate(_hpBar.gameObject, _canvas.transform); // 캔버스의 자식으로 HP바 생성
go.GetComponent<HpBar>().UpdateOwner(hpPosition, ui_camera); // HP바가 따라다닐 오브젝트와 UI 카메라 설정
}
캔버스는 안의 무언가가 바뀌면 통째로 리로드한다고 함
'공부 > Game Bootcamp' 카테고리의 다른 글
[TIL] #1. 모바일 게임 플레이어 이동 구현 : 멋쟁이사자처럼부트캠프 Unity 게임 개발 3기 (0) | 2025.04.16 |
---|---|
[멋쟁이사자처럼 부트캠프 TIL] 유니티 게임 개발 3기 : 리더보드 구현 (0) | 2025.03.06 |
[멋쟁이사자처럼 부트캠프 TIL] 유니티 게임 개발 3기 : 스킬 + 액션툴 (0) | 2024.12.18 |
[멋쟁이사자처럼 부트캠프 TIL] 유니티 게임 개발 3기 : Curve, 몬스터 생성, 몬스터와 충돌 이벤트 (1) | 2024.12.17 |
[멋쟁이사자처럼 부트캠프 TIL] 유니티 게임 개발 3기 : 애니메이션을 더한 캐릭터 점프, 아이템 먹기 (1) | 2024.12.16 |