using UnityEngine;
using System.Collections;
public class FollowPlayer : MonoBehaviour
{
public Vector3 offset; // The offset at which the Health Bar follows the player.
private Transform player; // Reference to the player.
void Awake ()
{
// Setting up the reference.
player = GameObject.FindGameObjectWithTag("Player").transform;
}
void Update ()
{
// Set the position to the player's position with the offset.
transform.position = player.position + offset;
}
}
위의 소스가 제대로 작동이 안되서.. Transform player를 public으로 선언하고, 외부에서 직접 Hero를 연결했음
이렇게 하면 Awake 부분은 필요 없게 됨.
using UnityEngine;
using System.Collections;
public class CameraFollow : MonoBehaviour
{
public float xMargin = 1f; // Distance in the x axis the player can move before the camera follows.
public float yMargin = 1f; // Distance in the y axis the player can move before the camera follows.
public float xSmooth = 8f; // How smoothly the camera catches up with it's target movement in the x axis.
public float ySmooth = 8f; // How smoothly the camera catches up with it's target movement in the y axis.
public Vector2 maxXAndY; // The maximum x and y coordinates the camera can have.
public Vector2 minXAndY; // The minimum x and y coordinates the camera can have.
private Transform player; // Reference to the player's transform.
void Awake ()
{
// Setting up the reference.
player = GameObject.FindGameObjectWithTag("Player").transform;
}
bool CheckXMargin()
{
// Returns true if the distance between the camera and the player in the x axis is greater than the x margin.
return Mathf.Abs(transform.position.x - player.position.x) > xMargin;
}
bool CheckYMargin()
{
// Returns true if the distance between the camera and the player in the y axis is greater than the y margin.
return Mathf.Abs(transform.position.y - player.position.y) > yMargin;
}
void FixedUpdate ()
{
TrackPlayer();
}
void TrackPlayer ()
{
// By default the target x and y coordinates of the camera are it's current x and y coordinates.
float targetX = transform.position.x;
float targetY = transform.position.y;
// If the player has moved beyond the x margin...
if(CheckXMargin())
// ... the target x coordinate should be a Lerp between the camera's current x position and the player's current x position.
targetX = Mathf.Lerp(transform.position.x, player.position.x, xSmooth * Time.deltaTime);
// If the player has moved beyond the y margin...
if(CheckYMargin())
// ... the target y coordinate should be a Lerp between the camera's current y position and the player's current y position.
targetY = Mathf.Lerp(transform.position.y, player.position.y, ySmooth * Time.deltaTime);
// The target x and y coordinates should not be larger than the maximum or smaller than the minimum.
targetX = Mathf.Clamp(targetX, minXAndY.x, maxXAndY.x);
targetY = Mathf.Clamp(targetY, minXAndY.y, maxXAndY.y);
// Set the camera's position to the target position with the same z component.
transform.position = new Vector3(targetX, targetY, transform.position.z);
}
}
Awake()에서 Player(GameObject)의 정보를 얻어옴
FixedUpdate()에서 TrackPlayer()를 호출함으로써, 매 프레임마다 카메라의 조정을 하게됨
TrackPlayer()는 카메라의 이동이 요구되는 상황이면, 카메라를 부드럽게 이동할 수 있도록 함
Mathf.Lerp(인자1,인자2,인자3) : 보간 값을 돌려 주는 함수로 부드러운 처리를 위해서 사용함
[인자1]과[인자2] 사이의 값을 [인자3](0~1사이)에 따라 값을 보간해서 알려줌
세번째 인자 값이 Xsmooth * Time.deltatime인 이유 : 상수 값을 넣어도 상관 없으나 그렇게 되면 느린 컴퓨터에서는 빠른 경우에는 끊기는 현상이 벌어질 수 있음, 따라서 이 함수가 매 프레임마다 호출될 때, 컴퓨터의 성능에 관계없이 부드럽게 움직일 수 있게 하기 위해서 Time.deltatime을 넣고 Xsmooth는 외부에서 이 값들을 세팅할 수 있도록 하기 위해 사용된 변수라고 보면 됨
Mathf.Clamp(인자1, 인자2, 인자3) : [인자1]이 [인자2:min]와 [인자3:max] 사이의 값이면 리턴 값으로 그냥 그 값(인자1)을 돌려 주고 [인자2]보다 작으면 [인자2]의 값을 돌려주며, [인자3]보다 크면 [인자3]의 값을 돌려준다. 따라서, minXAndY와 maxXAndY를 이루는 사각형 내 Hero가 존재하면 Camera의 이동이 발생하게 된다.
이 부분을 주석 처리하면 카메라는 항상 주인공 캐릭터를 따라 다니게 됨
targetX = Mathf.Clamp(targetX, minXAndY.x, maxXAndY.x);
targetY = Mathf.Clamp(targetY, minXAndY.y, maxXAndY.y);
CheckX/YMargin()는 카메라의 이동을 요구하는 허용범위(x/yMargin)를 체크
x/yMargin : 주인공 캐릭터 위치와 카메라의 위치의 오차 범위
Mathf.Abs() : 매개변수의 절대 값을 돌려 줌