2024. 1. 23. 08:20ㆍ카테고리 없음
개요
재밌는 퍼즐게임을 만들기 위해서는 우리의 컨셉인 시간을 되돌리거나 가속시키는 것 뿐만아니라 기본적으로 퍼즐게임에서 주로 볼 수 있는 다양한 객체의 상호작용이 필요하다.
그래서 오늘은 객체의 다양한 상호작용을 구현하는데 힘을 썼다.
참고한 자료는 아래에 표시해두었다.
Unity Movement 튜토리얼 (catlikecoding.com)
Unity Movement Tutorials
A series about controlling the movement of a character.
catlikecoding.com
오브젝트에게 다양한 상호작용을 위한 클래스
클래스 이름 | 기능 설명 |
GravityAttractor | 특정 범위 내의 모든 객체에 중력과 같은 힘을 적용하여 주변의 Rigidbody를 끌어당긴다. |
AccelerationZone | 객체가 트리거 구역에 머무르는 동안 해당 객체를 가속. 객체의 현재 이동 방향으로 지속적으로 힘을 가하여 가속한다. 카트라이더에서 나오는 가속패드 같은 것과 같다. |
ContinuousAccelerationZone | 구역 내에서 객체에 연속적으로 가속. 설정된 속도에 도달할 때까지 객체의 속도를 부드럽게 증가시켜 마치 바람에 날리는 효과를 볼 수있다. |
PlayerViewGravity | 플레이어의 카메라 방향에 따라 중력을 다르게 적용. 플레이어가 화살표 키를 사용하여 중력의 방향을 조절할 수 있지만 추후 조정이 필요하다. |
ReflectiveJump | 객체가 다른 객체와 충돌했을 때, 입사각을 기반으로 한 반사각 방향으로 점프하는 기능. 충돌 시의 입사각과 법선을 이용해 반사 벡터를 계산하고, 이를 바탕으로 점프 힘을 적용한다. |
GravityAttractor 스크립트 설명
GravityAttractor
스크립트는 특정 위치에서 중력과 같은 힘을 발생시켜 주변의 Rigidbody를 끌어당기는 역할을 함.
코드 구조
using UnityEngine;
using System.Collections.Generic;
public class GravityAttractor : MonoBehaviour
{
public float gravityForce = -10f;
void FixedUpdate()
{
Collider[] colliders = Physics.OverlapSphere(transform.position, 10f);
foreach (Collider hit in colliders)
{
Rigidbody rb = hit.GetComponent<Rigidbody>();
if (rb != null)
{
Vector3 direction = transform.position - rb.position;
rb.AddForce(direction.normalized * gravityForce * Time.fixedDeltaTime);
}
}
}
}
작동 원리 및 원칙
- 중력력 설정:
public float gravityForce = -10f;
gravityForce
변수는 중력의 강도를 결정함. 이 값은 음수로 설정되어 있어, 중력 소스를 향해 힘을 발생시키는 역할을 함.(즉 장력 발생중 +값이면 인력)
- 물리 업데이트에서의 중력 적용:
void FixedUpdate()
FixedUpdate
메소드는 각 물리 업데이트마다 호출되며, 이 안에서 중력 힘을 적용함.
- 주변 객체 탐지:
Collider[] colliders = Physics.OverlapSphere(transform.position, 10f);
Physics.OverlapSphere
함수를 사용하여 중력 소스 주변 10미터 반경 내의 모든 콜라이더를 탐지함.
- Rigidbody에 중력 힘 적용:
foreach (Collider hit in colliders) { ... }
- 탐지된 각 콜라이더에 대해
Rigidbody
컴포넌트가 있는지 확인함. - 있을 경우, 중력 소스에서 객체의 위치를 뺀 방향(
direction
)을 계산함. - 이 방향을 정규화하고
gravityForce
및Time.fixedDeltaTime
과 곱하여 실제 중력 힘을 계산함. rb.AddForce
를 통해 계산된 힘을 각Rigidbody
에 적용함.
- 탐지된 각 콜라이더에 대해
GravityAttractor
스크립트는 중력과 유사한 힘을 구현함. 이 스크립트를 사용하면 특정 범위 내의 객체들을 중력 소스 쪽으로 당기거나 밀수 있으며, 다양한 상호작용을 만드는 데 유용함.
AccelerationZone 스크립트 설명
AccelerationZone
스크립트는 특정 트리거 구역 내에서 객체에 지속적인 가속을 제공함.
코드 구조
using UnityEngine;
public class AccelerationZone : MonoBehaviour
{
public float accelerationStrength = 10f; // 가속 강도
private void OnTriggerStay(Collider other)
{
Rigidbody body = other.attachedRigidbody;
if (body != null)
{
// 객체의 현재 속도 벡터에서 이동 방향을 얻음
Vector3 movementDirection = body.velocity.normalized;
Vector3 force = movementDirection * accelerationStrength;
body.AddForce(force, ForceMode.Acceleration);
}
}
}
작동 원리 및 원칙
- 가속 강도 설정:
public float accelerationStrength = 10f;
accelerationStrength
변수는 가속의 강도를 결정함. 이 값은 객체에 적용될 힘의 크기를 정의함.
- 트리거 구역에서의 가속 적용:
private void OnTriggerStay(Collider other)
OnTriggerStay
메소드는 객체가 트리거 구역 안에 있을 때 매 프레임마다 호출된다. 이 메소드는 구역 내의Rigidbody
를 가진 객체에 가속 힘을 적용함.
- 이동 방향에 따른 힘 적용:
Vector3 movementDirection = body.velocity.normalized;
body.velocity.normalized
를 통해 객체의 현재 이동 방향을 얻음. 이 방향은 객체의 속도 벡터를 정규화하여 방향만을 추출한 것입니다.
- 가속력 적용:
body.AddForce(force, ForceMode.Acceleration);
- 계산된 이동 방향에
accelerationStrength
를 곱하여 실제 가속력을 계산함. - 이 가속력은
body.AddForce
를 사용하여 해당 객체의Rigidbody
에 적용된다.
- 계산된 이동 방향에
AccelerationZone
스크립트를 사용하면, 특정 구역 내에서 객체가 자연스럽게 가속되는 효과를 만들 수 있다.
예를 들어 빠르게 움직이는 지역이나 바람이 부는 구역 등을 구현하는 데 유용함.
PlayerViewGravity 스크립트 설명
PlayerViewGravity
스크립트는 플레이어의 시점 방향에 따라 중력을 다르게 적용함. 플레이어가 화살표 키를 사용하여 중력의 방향을 조절할 수 있음.
코드 구조
using UnityEngine;
public class PlayerViewGravity : MonoBehaviour
{
private Rigidbody rb;
public Transform playerCamera;
private float gravityStrength = 9.81f;
void Start()
{
rb = GetComponent<Rigidbody>();
rb.useGravity = false;
}
void FixedUpdate()
{
Vector3 gravityDirection = Vector3.zero;
if (Input.GetKey(KeyCode.UpArrow))
{
gravityDirection = playerCamera.up;
}
else if (Input.GetKey(KeyCode.DownArrow))
{
gravityDirection = -playerCamera.up;
}
else if (Input.GetKey(KeyCode.RightArrow))
{
gravityDirection = playerCamera.right;
}
else if (Input.GetKey(KeyCode.LeftArrow))
{
gravityDirection = -playerCamera.right;
}
gravityDirection *= gravityStrength;
rb.AddForce(gravityDirection, ForceMode.Acceleration);
}
}
작동 원리 및 원칙
- 중력 강도 설정:
private float gravityStrength = 9.81f;
gravityStrength
변수는 중력의 강도를 결정함. 기본값은 지구의 중력 상수(9.81 m/s²)이다.
- 중력 적용 해제:
rb.useGravity = false;
Start
메소드에서 기본 중력 적용을 해제함. 이는 사용자 정의 중력을 적용하기 위함이다.
- 시점 방향에 따른 중력 적용:
void FixedUpdate()
FixedUpdate
메소드는 물리 업데이트마다 호출된다.- 화살표 키 입력에 따라 카메라의 방향을 기준으로 중력 방향을 결정함.
- 중력 방향 및 적용:
rb.AddForce(gravityDirection, ForceMode.Acceleration);
- 계산된
gravityDirection
에gravityStrength
를 곱하여 최종 중력 벡터를 생성함. AddForce
메소드를 사용하여 해당 중력을Rigidbody
에 적용함.
- 계산된
ReflectiveJump 스크립트 설명
ReflectiveJump
스크립트는 객체가 다른 객체와 충돌했을 때 반사각을 계산하고, 이 방향으로 점프 힘을 적용함.
코드 구조
using UnityEngine;
public class ReflectiveJump : MonoBehaviour
{
public float jumpStrength = 10f; // 점프 강도
private void OnCollisionEnter(Collision collision)
{
Rigidbody body = collision.rigidbody;
if (body != null)
{
// 첫 번째 접촉 지점에서 입사각과 법선을 얻음
ContactPoint contact = collision.contacts[0];
Vector3 incomingVector = body.velocity; // 정규화된 벡터가 아니라 실제 속도 사용
Vector3 normal = contact.normal;
// 입사각에 기반한 반사각 계산
Vector3 reflectVector = Vector3.Reflect(incomingVector, normal).normalized;
// 반사 방향으로 점프 힘 적용
body.velocity = reflectVector * jumpStrength;
}
}
}
작동 원리 및 원칙
- 점프 강도 설정:
public float jumpStrength = 10f;
jumpStrength
변수는 점프의 강도를 결정함.
- 충돌 감지 및 반사각 계산:
private void OnCollisionEnter(Collision collision)
OnCollisionEnter
메소드는 객체가 다른 객체와 충돌할 때 호출된다.- 충돌 정보에서 첫 번째 접촉 지점의 정보를 가져와 입사 벡터와 법선을 계산함.
- 반사 벡터 계산:
Vector3 reflectVector = Vector3.Reflect(incomingVector, normal).normalized;
Vector3.Reflect
함수를 사용하여 입사 벡터와 법선을 바탕으로 반사 벡터를 계산함.- 계산된 반사 벡터는 정규화되어 방향만을 나타냅니다.
- 반사 방향으로 점프 힘 적용:
body.velocity = reflectVector * jumpStrength;
- 계산된 반사 벡터에 점프 강도를 곱하여 새로운 속도를 생성함.
- 이 속도는 충돌한 객체의
Rigidbody
에 적용되어 반사각 방향으로 점프함.
ContinuousAccelerationZone 스크립트 설명
ContinuousAccelerationZone
스크립트는 구역 내에서 객체에 연속적으로 가속을 적용함.
코드 구조
using UnityEngine;
public class ContinuousAccelerationZone : MonoBehaviour
{
[SerializeField, Min(0f)]
float acceleration = 10f, speed = 10f;
private void OnTriggerStay(Collider other)
{
Rigidbody body = other.attachedRigidbody;
if (body)
{
Accelerate(body);
}
}
void Accelerate(Rigidbody body)
{
Vector3 velocity = body.velocity;
if (acceleration > 0f)
{
velocity.y = Mathf.MoveTowards(
velocity.y, speed, acceleration * Time.deltaTime
);
}
else
{
velocity.y = speed;
}
body.velocity = velocity;
}
}
작동 원리 및 원칙
- 가속도 및 속도 설정:
[SerializeField, Min(0f)] float acceleration = 10f, speed = 10f;
acceleration
변수는 가속도를,speed
변수는 목표 속도를 결정함.
- 트리거 구역에서의 연속 가속 적용:
private void OnTriggerStay(Collider other)
OnTriggerStay
메소드는 객체가 트리거 구역 내에 머무는 동안 가속 효과를 적용함.
- 가속 함수:
void Accelerate(Rigidbody body)
Accelerate
함수는 객체의 현재 속도를 점진적으로 증가시켜 목표 속도에 도달하도록 함.Mathf.MoveTowards
함수를 사용하여 현재 속도를 부드럽게 목표 속도에 가까워지도록 조절함.acceleration
이 0이면, 속도를 즉시 목표 속도로 변경함.
ContinuousAccelerationZone
스크립트는 객체가 특정 구역 내에 있을 때 점진적으로 속도를 증가시키는 효과를 구현함.
예를 들어, 플레이어가 특정 구역을 지나갈 때 추가적인 추진력을 제공하는 데 사용할 수 있음.
예시 영상