Камера от третьего лица, обход препятствий

На этот раз попробуем решить проблему, когда камера, которая должна следовать за персонажем, «проваливается» в графику. То есть, камера должна находиться на некотором расстоянии от объекта, вид от третьего лица, но если позади нее, например стена, то позиция камеры изменяется и она приближается к персонажу, конкретней говоря, сокращается дистанция между объектами. Данный вариант, заточен под игру, в которой нет управления камеры мышкой. Мы уже выкладывали скрипт вращения вокруг чего-либо, поэтому при желании, не трудно объединить части кода, сделать контроль камеры мышкой и чтобы она не проходила сквозь стены.


Так, логика. Две точки, дочерние целевому объекту, одна спереди и одна сзади. Настраивается расстояние между точками и объектом, в дальнейшем их позиция будет наследоваться. Еще одна точка, расстояние которой регулируется в зависимости от наличия препятствий, опорой служат две предыдущие точки и исходный объект. И наконец камера, которая преследует третью точку, с использованием сглаживания в движении.

Делаем два пустых объекта с именами Normal и Front, перетаскиваем в персонаж.


Обратите внимание на направление осей. Суть в том, что одна точка смотрит в спину, то бишь, нормальное положение, а другая смотрит в лицо.


Настройте расстояние и высоту. В процессе игры, меняться они не будут.

Далее, вешаем на камеру скрипт ThirdPersonCamera:

using UnityEngine;
using System.Collections;

public class ThirdPersonCamera : MonoBehaviour {

	public Transform cameraCorrection;
	public float smooth = 3f;
	public Transform normalPosition;
	public Transform frontPosition;
	private bool isFront;
	private Vector3 curPos;
	public static Transform positionCorrection;
	public static float targetHeight;
	
	void Start()
	{
		isFront = false;
		transform.position = normalPosition.position;
		transform.forward = normalPosition.forward;	
	}

	void FixedUpdate()
	{
		if(Input.GetMouseButton(0)) FrontView(); else NormalView(); //переключить вид - удерживать ЛКМ
	}

	void Result()
	{
		transform.position = Vector3.Lerp(transform.position, cameraCorrection.position, Time.fixedDeltaTime * smooth);
		transform.forward = Vector3.Lerp(transform.forward, cameraCorrection.forward, Time.fixedDeltaTime * smooth);
	}
	
	void NormalView()
	{
		positionCorrection = normalPosition;
		targetHeight = normalPosition.position.y;
		if(!isFront)
		{
			Result();
		}
		else
		{
			transform.position = normalPosition.position;	
			transform.forward = normalPosition.forward;
			isFront = false;
		}
	}
	
	
	void FrontView()
	{
		positionCorrection = frontPosition;
		targetHeight = frontPosition.position.y;
		if(!isFront)
		{
			isFront = true;
			transform.position = frontPosition.position;	
			transform.forward = frontPosition.forward;
		}
		else
		{
			Result();
		}
	}
}

Здесь переключение вида для камеры и ее движение.

Создаем пустой объект с именем CameraCorrection и вешаем на него скрипт ThirdPersonCameraCorrection:

using UnityEngine;
using System.Collections;

public class ThirdPersonCameraCorrection : MonoBehaviour {

	public Transform target;
	public float distanceOffset = 0.25f;

	void Update() 
	{
		transform.position = ThirdPersonCamera.positionCorrection.position;
		transform.forward = ThirdPersonCamera.positionCorrection.forward;
		RaycastHit hit;
		Vector3 trueTargetPosition = target.transform.position;
		if (Physics.Linecast (trueTargetPosition, transform.position, out hit)) 
		{
			float tempDistance = Vector3.Distance (trueTargetPosition, hit.point);
			Vector3 position = target.position - (transform.rotation * Vector3.forward * (tempDistance - distanceOffset));
			transform.position = new Vector3(position.x, ThirdPersonCamera.targetHeight, position.z);
		}
	}
}

Тут создается луч от цели и до данной точки. Если луч обрывается каким либо объектом, то назначается новая позиция в место, куда попал луч. Проще говоря, точка перемещается ближе к цели. Если никаких препятствий нет, то возврат к Normal или Front.

P.S.
target - здесь надо указать персонажа.
Всё остальное назначается в соответствии с названиями.

Комментариев 2

Офлайн
+ всё норм работает, и спасибо большое
Офлайн
KamandorDark 24 сентября 2016
Огромное спасибо!
Информация
Посетители, находящиеся в группе Гости, не могут оставлять комментарии к данной публикации.
  • Яндекс.Метрика