요약: 이 섹션에서는 스프링이 무엇인지, 그리고 다양한 방법으로 게임에 스프링을 통합하기 위해 Feel을 사용하는 방법에 대해 설명합니다.
테이블 내용
- 상호작용 - Feel의 스프링
|
소개
아마도 보간(interpolation) 개념에 익숙하실 겁니다. 이는 값을 A에서 B로 이동시키는 아이디어로, float, 벡터, 색상 등을 포함합니다. Feel은 전통적인 선형 보간(lerp)에서 고급 곡선에 이르기까지 다양한 방법을 제공합니다. 또한 값을 “스프링”에 연결하고 그 스프링이 시간이 지남에 따라 값이 어떻게 변할지를 정의하도록 하는 방법도 제공합니다. 이것은 실제 스프링을 가지고 노는 것처럼 매우 만족스러운 동작을 만들어내며, 서로 충돌할 위험 없이 여러 번 사용할 수 있고, 추가적인 이점으로 특정 지점에 이를 때까지 더해집니다. 게다가 Feel의 스프링 시스템은 최적화되어 있으며, 프레임레이트에 독립적이고 사용하기 매우 쉽습니다. 그래서 이 시스템이 게임에 어떤 도움이 될 수 있는지 함께 살펴보겠습니다!
시작하기 전에, 몇 가지 데모를 먼저 사용해 보시는 것이 좋습니다. Feel의 대부분의 데모는 어떤 형태로든 스프링을 특징으로 하지만, FeelSprings 데모 씬은 이 개념에 대한 최고의 소개이며, 이를 위한 작은 순차적 튜토리얼로 설계되었습니다. 그 후, MMFollowTargetDemo 씬과 FeelSquashAndStretch 씬을 살펴보시면 더 많은 예제를 볼 수 있습니다.
핵심 개념
"클래식" 보간에서는 A에서 B로 객체를 이동시키기 위해 A와 B 모두를 지정하고, 이동할 애니메이션 곡선과 지속 시간을 지정할 수 있습니다. 그러나 스프링을 사용하는 방법은 조금 다릅니다. 여기서는 이동에 대한 지속 시간을 지정하지 않고, 단지 스프링에게 새로운 값으로 이동하거나 "충격"을 주도록 지시하면 스프링의 설정이 그것이 어떻게 동작할지를 정의합니다.
설정
스프링의 동작을 정의하는 두 가지 주요 설정이 있습니다:
- 감쇠(Damping): 스프링이 방해를 받은 후 얼마나 빨리 안정 상태로 돌아가는지를 결정합니다. 실제 스프링의 강도 또는 장력으로 생각할 수 있습니다. 감쇠 값은 0에서 1까지로, 0에 가까운 값은 매우 느슨한 스프링을, 1에 가까운 값은 매우 팽팽한 스프링을 나타냅니다.
- 주파수(Frequency): 스프링이 안정 상태로 돌아가기 위해 1초당 몇 번 진동할지를 결정합니다.
이 두 값의 조합은 매우 다른 결과를 만들어낼 수 있으므로 원하는 동작을 얻기 위해 주저하지 말고 실험해 보세요.
상호작용
스프링과 상호작용하는 두 가지 주요 방법이 있습니다:
- MoveTo: 스프링에게 새로운 값으로 이동하도록 요청합니다. 단순히 새로운 값을 지정하면 스프링이 나머지를 처리합니다.
- Bump: 스프링의 값을 지정한 양만큼 "밀어"줍니다. 기본적으로 값을 특정 방향으로 밀어주고, 시간이 지나면서 설정에 따라 이전 상태로 되돌아갑니다. Bump를 사용할 때는 Bump 양이 스프링의 설정에 영향을 받는다는 것을 기억해야 합니다. 매우 느슨한 스프링은 멀리 이동하기 위해 큰 힘이 필요하지 않지만, 매우 팽팽한 스프링은 상당한 힘이 필요합니다.
MoveTo와 Bump의 경우 모두 한 번의 호출, 한 번의 피드백, 한 번의 이벤트 또는 한 줄의 코드로 가능합니다.
Feel의 스프링
그래서 Feel에서 스프링을 어떻게 사용할 수 있을까요? 주요 방법은 다음과 같으며, 모두 아래에 자세히 설명되어 있습니다:
- 스프링 컴포넌트(Spring Components): 70개 이상의 스프링 컴포넌트가 있으며, 이들을 클릭 한 번으로 추가하여 조명의 강도부터 이미지의 색상까지 다양한 요소를 제어할 수 있습니다. 그런 다음 스프링 피드백, 이벤트 또는 직접 호출을 사용하여 이를 조종할 수 있습니다.
- 피드백(Feedbacks): Position Spring 또는 Scale Spring 피드백과 같이 일부 피드백은 내장된 스프링 동작을 제공합니다.
- 스프링 API(Spring API): Feel은 고급이면서도 사용하기 쉬운 스프링 API를 제공하며, 이를 통해 자체 코드에 스프링 효과를 추가할 수 있습니다.
- 기타 컴포넌트(Other components): Feel의 다양한 컴포넌트와 헬퍼에서 스프링이 사용되는 것을 볼 수 있습니다. 예를 들어 MMFollowTarget 헬퍼는 스프링 또는 다른 수단을 사용하여 몇 번의 클릭만으로 팔로우 동작을 설정할 수 있게 해줍니다.
스프링 컴포넌트
스프링을 사용하기 가장 쉬운 방법은 Feel에 포함된 70개 이상의 스프링 컴포넌트 중 하나를 사용하는 것입니다(아래 전체 목록 참조). 객체에 영향을 미치고 싶은 속성을 결정하고, 적절한 스프링을 선택한 다음 AddComponent 메뉴를 통해 게임 객체에 추가하면 됩니다.

인스펙터는 4개의 주요 섹션으로 나뉘어져 있습니다:
- Target: 여기에서 스프링의 타겟을 지정할 수 있습니다. 비워두면 스프링은 자동으로 해당 객체의 관련 컴포넌트를 가져오려고 시도합니다. 이 섹션에서는 특정 스프링에 대한 필드도 찾을 수 있습니다.
- Channel and TimeScale: 여기에서는 채널 옵션(채널에 대한 자세한 정보는 여기를 참조)을 정의하고, 스프링이 스케일된 시간 또는 비스케일된 시간에서 실행될지 선택할 수 있습니다(비스케일된 시간은 타임스케일 변경에 영향을 받지 않습니다).
- Spring Settings: 여기에서는 스프링의 감쇠와 주파수를 정의할 수 있습니다. 벡터 값을 대상으로 하는 스프링의 경우 축을 분리할 수도 있습니다. 그렇게 하면 각 축에 대해 별도의 감쇠 및 주파수 설정과 각 축에 대한 클램핑 옵션을 얻을 수 있습니다.
- Randomness: 이 섹션에서는 MoveToRandom() 또는 BumpRandom() 메서드를 호출할 때 선택될 무작위 값의 범위를 정의할 수 있습니다.
- Test: 이 섹션에서는 스프링에서 사용할 수 있는 다양한 명령과 상호작용할 수 있습니다. 주요 동작(MoveTo 및 Bump)은 파란색으로 강조 표시되며, 바로 위에 있는 테스트 값 필드와 연결됩니다.
간단한 스프링 컴포넌트 설정 방법
|
스프링 메서드
스프링을 컴포넌트, 피드백, 이벤트 또는 메서드의 직접 호출을 통해 상호작용할 때, 사용할 수 있는 주요 명령을 알고 싶을 것입니다:
- MoveTo(newValue): 감쇠와 주파수 설정을 사용하여 지정된 값으로 스프링을 이동시킵니다.
- MoveToAdditive(newValue): 현재 값에 전달된 newValue를 더한 값으로 스프링을 이동시킵니다.
- MoveToSubtractive(newValue): 현재 값에서 전달된 newValue를 뺀 값으로 스프링을 이동시킵니다.
- MoveToRandom: 최소값과 최대값 사이에서 선택된 새로운 값으로 스프링을 이동시킵니다.
- MoveToInstant(newValue): 지정된 값으로 스프링을 즉시 이동시킵니다.
- Bump(bumpAmount): 지정된 양만큼 스프링을 "밀어"줍니다.
- BumpRandom: 최소값과 최대값 사이에서 선택된 양으로 스프링을 밀어줍니다.
- Stop: 스프링의 움직임을 즉시 멈춥니다.
- Finish: 스프링을 최종 목적지 위치로 즉시 이동시킵니다.
- RestoreInitialValue: 스프링의 목표 값을 초기값으로 복원합니다 (스프링이 활성화되었을 때 또는 마지막으로 ResetInitialValue()가 호출되었을 때의 값).
- ResetInitialValue: 스프링의 목표의 현재 값을 초기 위치로 설정하여 나중에 RestoreInitialValue() 호출을 통해 복원할 수 있도록 합니다.
피드백과 함께 스프링 컴포넌트 사용하기
피드백으로 모든 스프링 컴포넌트를 쉽게 조종할 수 있습니다. 이를 위해 먼저 해당 스프링이 어떤 타입인지 확인해야 합니다(예: float, Vector2, Vector3, Vector4, Color). 이는 스프링이 조종하는 값의 타입에 따라 다릅니다. 예를 들어, 라이트 강도 스프링은 Float 스프링이고, 위치 스프링은 Vector3 스프링입니다. 의심스러울 때는 스프링의 인스펙터에서 Spring Settings 섹션 상단에 작성된 내용을 확인할 수 있습니다.
그런 다음 동일한 타입의 스프링 피드백을 MMF Player에 추가하고, 직접 참조를 통해 타겟 스프링을 드래그하여 설정하거나 채널을 사용하여 이벤트를 통해 타겟팅할 수 있습니다.
피드백을 사용하여 스프링 컴포넌트를 조종하는 방법
|
코드를 통해 스프링 컴포넌트 사용하기
스프링 컴포넌트와 상호작용하는 것은 매우 쉽습니다. 예를 들어, mySpring이 MMSpringLightIntensity에 대한 참조일 때, 그냥 메서드를 직접 호출하면 됩니다:
// 스프링의 값을 3으로 이동시킵니다
mySpring.MoveTo(3f);
// 스프링을 25의 힘으로 밀어줍니다
mySpring.Bump(25f);
// 스프링의 무작위 설정에 따라 무작위 힘으로 스프링을 밀어줍니다
mySpring.BumpRandom();
// 0에서 5 사이에서 선택된 무작위 힘으로 스프링을 밀어줍니다
mySpring.BumpRandom(0f, 5f);
물론, 스프링 명령 중 어느 것이든 호출할 수 있습니다.
모든 스프링 컴포넌트는 이벤트를 수신하므로, 다음과 같이 자신의 코드에서 트리거할 수 있습니다:
// 채널 3을 듣고 있는 모든 float 스프링이 값 2로 이동하도록 하는 이벤트를 트리거합니다
MMChannelData channelData = new MMChannelData(MMChannelModes.Int, 3, null);
MMSpringFloatEvent.Trigger(SpringCommands.MoveTo, null, channelData, 2f);
물론 모든 클래식 스프링 명령을 이벤트를 통해서도 사용할 수 있습니다.
포함된 스프링 컴포넌트 목록
Feel은 게임 내 모든 것을 제어할 수 있는 수많은 스프링을 기본적으로 제공합니다. 여기 그 목록이 있습니다:
- AudioSource: 피치, 볼륨
- Camera: 시야각(Field of View), 직교 크기(Orthographic Size)
- HDRP: 블룸 강도, 색수차 강도, 색상 조정 대비, 색상 조정 색상 이동, 색상 조정 채도, 피사계 심도 초점 거리, 렌즈 왜곡 강도, 모션 블러 강도, 파니니 투사 거리, 비네트 중심, 비네트 색상, 비네트 강도, 화이트 밸런스 온도, 화이트 밸런스 색조
- Light: 색상, 강도, 범위
- Rendering: 셰이더 컨트롤러, 스프라이트 색상, 텍스처 오프셋, 텍스처 스케일
- Others: MMTimeScale, 애니메이터 속도
- Post Processing: 블룸 강도, 색수차 강도, 색상 보정 대비, 색상 보정 색상 이동, 색상 보정 채도, 색상 보정 온도, 색상 보정 색조, 피사계 심도 초점 거리, 렌즈 왜곡 강도, 모션 블러 셔터 각도, 비네트 중심, 비네트 색상, 비네트 강도
- Transform: 위치, 회전, 회전 중심, 스케일, 스쿼시 & 스트레치
- UI: 이미지 알파, 이미지 색상, 이미지 채우기 양, RectTransform 위치, RectTransform 사이즈 델타
- TextMeshPro: 알파, 문자 간격, 확장, 글꼴 크기, 줄 간격, 부드러움, 텍스트 색상, 단어 간격
- URP: 블룸 강도, 색수차 강도, 색상 조정 대비, 색상 조정 색상 이동, 색상 조정 채도, 피사계 심도 초점 거리, 렌즈 왜곡 강도, 모션 블러 강도, 파니니 투사 거리, 비네트 중심, 비네트 색상, 비네트 강도, 화이트 밸런스 온도, 화이트 밸런스 색조
그리고 이게 부족하다면, 새로운 스크립트를 만드는 데는 단 몇 초밖에 걸리지 않습니다!
새로운 스프링 컴포넌트 만들기
새로운 스프링 컴포넌트를 만드는 것은 매우 쉽고, 1분 이내에 완료할 수 있습니다. 이를 위해 새로운 스크립트를 생성하고, 원하는 유형의 스프링 컴포넌트로부터 상속받도록 하면 됩니다.
이 작업이 어떻게 이루어지는지 보기 위해, Rigidbody2D의 Mass를 대상으로 하는 맞춤형 스프링의 예제를 살펴보겠습니다:
using MoreMountains.Feedbacks;
using UnityEngine;
public class Rigidbody2DMassSpring : MMSpringFloatComponent<Rigidbody2D>
{
public override float TargetFloat
{
get => Target.mass;
set => Target.mass = value;
}
}
우리는 이 스프링이 float 값인 질량(mass) 값을 조종하기를 원하기 때문에 MMSpringFloatComponent를 확장합니다. 만약 Vector2 스프링이 필요하다면, MMSpringVector2Component로부터 상속받으면 됩니다. Vector3, Vector4 또는 Color도 마찬가지입니다. 그런 다음 Rigidbody2D 스프링 float 컴포넌트를 원한다고 지정합니다. 이렇게 하면 스프링이 자동으로 Target을 설정할 수 있습니다. 마지막으로, TargetFloat을 오버라이드하고 그 getter와 setter를 정의합니다. MMSpringVector2Component를 다룰 때는 TargetVector2를 오버라이드하게 됩니다.
물론, 포함된 70개 이상의 스프링 컴포넌트를 살펴보면 그들이 어떻게 하는지에 대한 예제를 볼 수 있습니다.
클램핑

float 스프링 또는 개별 축 벡터 스프링에서는 클램프 설정을 할 수 있습니다. 이 설정은 스프링이 제어하는 값이 정의한 경계를 초과하지 않도록 하는 매우 간단한 설정입니다. 값을 최소값, 최대값 또는 둘 다로 클램프할 수 있습니다. 이는 예를 들어 캐릭터의 y 값을 제어하는 스프링이 있을 때, 공중으로 밀어 올리면서 내려올 때 바닥을 뚫고 지나가지 않도록 하는 데 유용합니다.
최소 및 최대 클램프에 대해 초과하지 않도록 최소값 또는 최대값을 정의하거나 ClampInitial을 true로 설정할 수 있습니다. 이 경우 스프링의 초기 값이 클램프 값으로 사용됩니다. 마지막으로, Bounce 옵션은 클램프가 스프링을 반대 방향으로 튕겨야 하는지 여부를 결정합니다.
스프링 API
이미 만들어진 컴포넌트나 피드백을 사용하여 스프링을 처리하는 방법을 보았지만, Springs API를 직접 코드에서 사용할 수도 있습니다. 이를 위해 기본 스프링 타입(MMSpringFloat, MMSpringVector2, MMSpringVector3, MMSpringVector4 또는 MMSpringColor) 중 하나를 선언하면 됩니다. 다음과 같이:
[Header("Spring")] // 선택 사항
public MMSpringFloat MySpring;
이렇게 하면 인스펙터에 사용자 정의 속성 드로어가 추가되어 스프링의 감쇠, 주파수 및 클램프 설정을 조정할 수 있습니다. 이제 어디서든 해당 스프링에 메서드를 호출할 수 있으며, 이전에 언급한 것과 동일한 메서드를 사용할 수 있습니다. 예를 들어:
MySpring.MoveTo(2f); // Bump, MoveToAdditive 등도 호출할 수 있습니다.
마지막으로 해야 할 일은 업데이트 시 스프링을 처리하는 것입니다. 다음과 같이 합니다:
MySpring.UpdateSpringValue(Time.deltaTime); // 다른 deltaTime 값을 전달할 수도 있습니다.
그 후에는 스프링의 값을 원하는 방식으로 사용할 수 있습니다. 다음과 같이:
float something = MySpring.CurrentValue;
다음은 이미지가 탄력 있는 스프링으로 마우스를 따라가도록 설정하는 전체 예제입니다:
using UnityEngine;
using MoreMountains.Feedbacks;
public class Test : MonoBehaviour
{
public MMSpringVector2 _vector2Spring;
private RectTransform _rectTransform;
private Vector2 _mouseLocalPoint;
void Start()
{
_rectTransform = GetComponent<RectTransform>();
}
void Update()
{
// 마우스 위치를 기준으로 이미지가 이동할 위치를 계산합니다.
RectTransformUtility.ScreenPointToLocalPointInRectangle(_rectTransform.parent as RectTransform,
Input.mousePosition, null, out _mouseLocalPoint);
// 스프링에게 그 값으로 이동하도록 지시합니다.
_vector2Spring.MoveTo(_mouseLocalPoint);
// 스프링을 업데이트합니다.
_vector2Spring.UpdateSpringValue(Time.deltaTime);
// 스프링의 현재 값을 이미지의 위치에 적용합니다.
_rectTransform.anchoredPosition = _vector2Spring.CurrentValue;
}
}
'유니티 에셋 > Feel' 카테고리의 다른 글
Nice Vibrations (0) | 2024.07.13 |
---|---|
Recipes (0) | 2024.07.11 |
Screen Shakes (0) | 2024.07.10 |
Creating a new feedback (0) | 2024.07.09 |
Complete list of Feedbacks (0) | 2024.07.09 |