오늘은 스파르타 코딩 클럽 unity 게임 개발 과정 58일차(최종프로젝트 9일차 오브젝트에게 다양한 상호작용을 만들어 적용하자)

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);
            }
        }
    }
}

작동 원리 및 원칙

  1. 중력력 설정: public float gravityForce = -10f;
    • gravityForce 변수는 중력의 강도를 결정함. 이 값은 음수로 설정되어 있어, 중력 소스를 향해 힘을 발생시키는 역할을 함.(즉 장력 발생중 +값이면 인력)
  2. 물리 업데이트에서의 중력 적용: void FixedUpdate()
    • FixedUpdate 메소드는 각 물리 업데이트마다 호출되며, 이 안에서 중력 힘을 적용함.
  3. 주변 객체 탐지: Collider[] colliders = Physics.OverlapSphere(transform.position, 10f);
    • Physics.OverlapSphere 함수를 사용하여 중력 소스 주변 10미터 반경 내의 모든 콜라이더를 탐지함.
  4. Rigidbody에 중력 힘 적용: foreach (Collider hit in colliders) { ... }
    • 탐지된 각 콜라이더에 대해 Rigidbody 컴포넌트가 있는지 확인함.
    • 있을 경우, 중력 소스에서 객체의 위치를 뺀 방향(direction)을 계산함.
    • 이 방향을 정규화하고 gravityForceTime.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);
        }
    }
}

작동 원리 및 원칙

  1. 가속 강도 설정: public float accelerationStrength = 10f;
    • accelerationStrength 변수는 가속의 강도를 결정함. 이 값은 객체에 적용될 힘의 크기를 정의함.
  2. 트리거 구역에서의 가속 적용: private void OnTriggerStay(Collider other)
    • OnTriggerStay 메소드는 객체가 트리거 구역 안에 있을 때 매 프레임마다 호출된다. 이 메소드는 구역 내의 Rigidbody를 가진 객체에 가속 힘을 적용함.
  3. 이동 방향에 따른 힘 적용: Vector3 movementDirection = body.velocity.normalized;
    • body.velocity.normalized를 통해 객체의 현재 이동 방향을 얻음. 이 방향은 객체의 속도 벡터를 정규화하여 방향만을 추출한 것입니다.
  4. 가속력 적용: 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);
    }
}

작동 원리 및 원칙

  1. 중력 강도 설정: private float gravityStrength = 9.81f;
    • gravityStrength 변수는 중력의 강도를 결정함. 기본값은 지구의 중력 상수(9.81 m/s²)이다.
  2. 중력 적용 해제: rb.useGravity = false;
    • Start 메소드에서 기본 중력 적용을 해제함. 이는 사용자 정의 중력을 적용하기 위함이다.
  3. 시점 방향에 따른 중력 적용: void FixedUpdate()
    • FixedUpdate 메소드는 물리 업데이트마다 호출된다.
    • 화살표 키 입력에 따라 카메라의 방향을 기준으로 중력 방향을 결정함.
  4. 중력 방향 및 적용: rb.AddForce(gravityDirection, ForceMode.Acceleration);
    • 계산된 gravityDirectiongravityStrength를 곱하여 최종 중력 벡터를 생성함.
    • 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;
        }
    }
}

작동 원리 및 원칙

  1. 점프 강도 설정: public float jumpStrength = 10f;
    • jumpStrength 변수는 점프의 강도를 결정함.
  2. 충돌 감지 및 반사각 계산: private void OnCollisionEnter(Collision collision)
    • OnCollisionEnter 메소드는 객체가 다른 객체와 충돌할 때 호출된다.
    • 충돌 정보에서 첫 번째 접촉 지점의 정보를 가져와 입사 벡터와 법선을 계산함.
  3. 반사 벡터 계산: Vector3 reflectVector = Vector3.Reflect(incomingVector, normal).normalized;
    • Vector3.Reflect 함수를 사용하여 입사 벡터와 법선을 바탕으로 반사 벡터를 계산함.
    • 계산된 반사 벡터는 정규화되어 방향만을 나타냅니다.
  4. 반사 방향으로 점프 힘 적용: 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;
    }
}

작동 원리 및 원칙

  1. 가속도 및 속도 설정: [SerializeField, Min(0f)] float acceleration = 10f, speed = 10f;
    • acceleration 변수는 가속도를, speed 변수는 목표 속도를 결정함.
  2. 트리거 구역에서의 연속 가속 적용: private void OnTriggerStay(Collider other)
    • OnTriggerStay 메소드는 객체가 트리거 구역 내에 머무는 동안 가속 효과를 적용함.
  3. 가속 함수: void Accelerate(Rigidbody body)
    • Accelerate 함수는 객체의 현재 속도를 점진적으로 증가시켜 목표 속도에 도달하도록 함.
    • Mathf.MoveTowards 함수를 사용하여 현재 속도를 부드럽게 목표 속도에 가까워지도록 조절함.
    • acceleration이 0이면, 속도를 즉시 목표 속도로 변경함.

ContinuousAccelerationZone 스크립트는 객체가 특정 구역 내에 있을 때 점진적으로 속도를 증가시키는 효과를 구현함.
예를 들어, 플레이어가 특정 구역을 지나갈 때 추가적인 추진력을 제공하는 데 사용할 수 있음.

 

 

예시 영상

 

 

반응형