[Unity]cinemachine을 이용한 효과들(by targetGroup)

jh Seo·2023년 6월 25일
0

유니티

목록 보기
30/42

개요

시네머신을 사용해야해서 시네머신을 공부하던 중 이분의 블로그에서
재밌는 효과를 발견해서 작성한다.

영상 링크

유니티블로그에서도 소개되는 기능이다.
오브젝트의 proximity보다 가까이 가게되면 해당 오브젝트쪽으로 카메라가 움직이는 방식이다.

방법

CinemachineTargetGroup를 사용하는 방식으로, targetGroup에 원하는 오브젝트들을 넣어준다.

cameraMagnetProperty

자석효과를 나타나길 원하는 오브젝트들에 CameraMagnetProperty코드를 붙여준다.
변수로는 proximity와 magnetStrength가 있으며, 범위를 씬에서 보기위한 동그라미 ProximityVisualization오브젝트를 하나 만들어서 넣어준다.

[ExecuteInEditMode]를 통해 플레이를 하지않고도 update문을 통해
범위가 표시가 된다.

cameraMagnetController

자석 오브젝트들의 부모 오브젝트를 하나 생성 후,
CameraMagnetController코드를 붙여준다.

이 함수를 살펴보면 awake함수에서
자식오브젝트들의 cameraMagnetProperty컴퍼넌트를 다 CameraMagnetProperty[] 배열에 넣어주고,
플레이어의 인덱스를 0으로 정한다.

따라서 타겟그룹의 리스트에 0번째 인덱스에 플레이어를 넣어야 제대로 작동한다.

//player index=0 so start from 1
	for(int i = 1; i < targetGroup.m_Targets.Length; ++i)
    {
    	float distance = (targetGroup.m_Targets[playerIndex].target.position - targetGroup.m_Targets[i].target.position).magnitude;
    	//i-1번째 오브젝트보다 i번째 오브젝트가 더 가까우면 
   		if (distance < cameraMagnetProperties[i-1].Proximity)
        {
        	targetGroup.m_Targets[i].weight = cameraMagnetProperties[i - 1].magnetStrength * 
            	(1 - (distance / cameraMagnetProperties[i - 1].Proximity));
        }
        //i-1 오브젝트가 더 가까우면
        else
        {
        targetGroup.m_Targets[i].weight = 0;   
        }
	}

Update함수에서 1번째 인덱스의 오브젝트부터 순회하며
i번째 오브젝트와와 i-1번째 오브젝트의 플레이어로부터의 거리를 비교한다.

i-1번째 오브젝트가 플레이어와 더 가까우면 i번째 오브젝트의 weight을 0으로 둬서 i-1번째 오브젝트를 타겟그룹카메라가 비추도록한다.
i번째 오브젝트가 더 가까우면 i번째 오브젝트의 weight을 새로 설정한다.
설정값은 i-1번째 오브젝트의 magneticStrength 변수값 *
(1- (플레이어와 i번째 오브젝트와의 거리 / i-1번째 오브젝트의 proximity값)) 이다.

따라서 i번째 오브젝트와의 거리가 적을수록,
i-1번째 오브젝트의 proximity가 클수록,
i-1번째 오브젝트의 magneticStrength값이 클수록
i번째 오브젝트의 weight값이 커져서 i번째 오브젝트를 더 비추게된다.

CameraMagnetProperty 코드

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[ExecuteInEditMode]
public class CameraMagnetProperty : MonoBehaviour
{
    [Header("근처에 왔을 때 자석이 끌어당기는 힘")]
    [Range(0.1f, 50.0f)]
    public float magnetStrength = 5.0f;

    [Header("접근 반경")]
    [Range(0.1f, 50.0f)]
    public float Proximity = 5.0f;

    public Transform ProximityVisualization;

    [HideInInspector] public Transform myTransform;

    private void Start()
    {
        myTransform = transform;
    }

    // Update is called once per frame
    void Update()
    {
        if (ProximityVisualization != null)
        {
            ProximityVisualization.localScale = new Vector3(Proximity * 2.0f, Proximity * 2.0f, 1);
        }

    }
}

CameraMagnetController

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Cinemachine;

public class CameraMagnetController : MonoBehaviour
{
    public  CinemachineTargetGroup targetGroup;
    private int playerIndex;
    private CameraMagnetProperty[] cameraMagnetProperties;

    // Start is called before the first frame update
    void Start()
    {
        cameraMagnetProperties = GetComponentsInChildren<CameraMagnetProperty>();
        playerIndex = 0;
    }

    // Update is called once per frame
    void Update()
    {
        //player index=0 so start from 1
        for(int i = 1; i < targetGroup.m_Targets.Length; ++i)
        {
            float distance = (targetGroup.m_Targets[playerIndex].target.position - targetGroup.m_Targets[i].target.position).magnitude;
            //i-1번째 오브젝트보다 i번째 오브젝트가 더 가까우면 
            if (distance < cameraMagnetProperties[i-1].Proximity)
            {
                targetGroup.m_Targets[i].weight = cameraMagnetProperties[i - 1].magnetStrength * 
                    (1 - (distance / cameraMagnetProperties[i - 1].Proximity));
            }
            //i-1 오브젝트가 더 가까우면
            else
            {
                targetGroup.m_Targets[i].weight = 0;   
            }
        }
    }
}

레퍼런스

https://fkdl0048.github.io/unity/unity_in_cinemachine/
https://blog.unity.com/engine-platform/cinemachine-2-6-magic-in-unity-2020-lts-precision-workflows-and-more

profile
코딩 창고!

0개의 댓글