앵그리버드 게임을 보면 어디로 날라갈지 미리 궤적을 보여줍니다.
이런건 어떻게 만드는지 궁금해서 영상 참고해서 만들어봤습니다!
참고한 유튜브링크는 글 아래에 적어뒀습니다.
원리를 간단하게 설명하자면
등가속운동 공식을 사용하여 시간에 따른 위치값을 미리 계산하는 것입니다!
스크립트는 3개로 만들어봤습니다
GameManager : force 계산해서 넣어주는애
BallController : force 받아서 날아가는 애
TrajectoryDrawer : force 받아서 궤적 그려주는 애
using UnityEngine;
public class GameManager : MonoBehaviour
{
public BallController Ball;
public TrajectoryDrawer Drawer;
public float MaxDistance;
public float ForcePower;
private Vector2 _startPos;
private Vector2 _endPos;
private Vector2 _force;
void Update()
{
if (Input.GetMouseButtonDown(0))
{
Drawer.SetActiveTrajectory(true);
_startPos = Ball.transform.position;
}
if (Input.GetMouseButton(0))
{
_endPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
var sub = _startPos - _endPos;
if (sub.magnitude > MaxDistance)
{
sub = sub.normalized * MaxDistance;
_endPos = _startPos - sub;
}
_force = sub * ForcePower;
Ball.SetPosition(_endPos);
Drawer.DrawDots(_endPos, _force);
}
if (Input.GetMouseButtonUp(0))
{
Ball.AddForce(_force);
Drawer.SetActiveTrajectory(false);
}
if (Input.GetKeyDown(KeyCode.Space))
{
Ball.ResetPos();
}
}
}
using UnityEngine;
public class BallController : MonoBehaviour
{
private Rigidbody2D _rigid;
void Awake()
{
_rigid = GetComponent<Rigidbody2D>();
_rigid.isKinematic = true;
}
public void SetPosition(Vector2 pos)
{
transform.position = pos;
}
public void AddForce(Vector2 force)
{
_rigid.isKinematic = false;
_rigid.AddForce(force, ForceMode2D.Impulse);
}
public void ResetPos()
{
_rigid.isKinematic = true;
_rigid.velocity = Vector2.zero;
transform.position = Vector2.zero;
}
}
using System.Collections.Generic;
using UnityEngine;
public class TrajectoryDrawer : MonoBehaviour
{
public GameObject DotPrefab;
public float TimeScale;
public int DotCount;
private List<GameObject> _dots;
private void Awake()
{
_dots = new List<GameObject>(DotCount);
for(int i = 0; i < DotCount; i++)
{
_dots.Add(Instantiate(DotPrefab, transform));
_dots[i].SetActive(false);
}
}
public void DrawDots(Vector2 startPos, Vector2 force)
{
for(int i = 0; i < _dots.Count; i++)
{
_dots[i].transform.position = GetDotPosition(i);
}
Vector2 GetDotPosition(int index)
{
float time = index * TimeScale;
return startPos + force * time + 0.5f * Physics2D.gravity * time * time;
}
}
public void SetActiveTrajectory(bool isActive)
{
foreach(var dot in _dots)
{
dot.SetActive(isActive);
}
}
}
참고자료
'유니티' 카테고리의 다른 글
[Unity] Custom Editor 인스펙터 드랍다운 (enum 없이) (0) | 2023.06.20 |
---|---|
[Unity] Material Property Block 사용하여 배칭시키기 (0) | 2023.02.20 |
[Unity] 서로 이어지는 이펙트 만들기 (2D) (0) | 2023.01.29 |
[Unity] Json Utility : 유니티에서 Json 읽기 쓰기 (0) | 2022.03.15 |
[Unity] Awake Start Coroutine 상속 (0) | 2022.03.12 |