Показать сообщение отдельно
Старый 10.08.2012, 15:17   #577
WISHMASTER35
Бывалый
 
Аватар для WISHMASTER35
 
Регистрация: 21.12.2008
Адрес: UA
Сообщений: 878
Написано 105 полезных сообщений
(для 357 пользователей)
Ответ: Вопросы от новичка

 using UnityEngine;
using System.Collections;

public class CameraOrbit : MonoBehaviour {
	
	public Transform target;
	public Vector3 targetOffset = new Vector3(0, 1.5f, 0);
	private Vector3 oldTargetPosition;
	
	public float minAngleX = -20, maxAngleX = 60;
	private Vector3 angles;
	
	private const float minDistance = 1.0f;
	private float distance;
	public float maxDistance = 7.0f;
	
	public Vector3 cameraOffset = new Vector3(1, 0, 0);
	
	void OnEnable() {
		if( !target ) return;
		angles = transform.eulerAngles;
		distance = maxDistance;
	}
	
	void LateUpdate () {
		if( !target ) return;
		
		angles += GetInputRotation();
		angles.x = ClampAngle(angles.x, minAngleX, maxAngleX);
		
		Vector3 targetPosition = target.TransformPoint(targetOffset);
		// попытка сгладить движение камеры
		//targetPosition = Vector3.Lerp(oldTargetPosition, targetPosition, 15*Time.deltaTime);
		//oldTargetPosition = targetPosition;
		
		// сглаживаем вращение камеры
		Quaternion rotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(angles), 20*Time.deltaTime);
		ComputeTransform(targetPosition, rotation, maxDistance, cameraOffset);
		distance = CollisionTest(targetPosition, distance);
	}
	
	private void ComputeTransform(Vector3 targetPosition, Quaternion rotation, float distance, Vector3 cameraOffset) {
		transform.rotation = rotation;
		transform.position = targetPosition;
		transform.Translate(0, 0, -distance);
		transform.Translate(cameraOffset * distance);
	}
	
	private float CollisionTest(Vector3 targetPosition, float oldDistance) {
		Vector3 dir = transform.position - targetPosition;
		float distance = Raycast(targetPosition, dir, dir.magnitude);
		if(distance < 1) distance = 1;
		distance = Mathf.Lerp(oldDistance, distance, 10*Time.deltaTime);
		transform.position = targetPosition + dir.normalized * distance;
		return distance;
	}
	
	private static float Raycast(Vector3 start, Vector3 dir, float distance) {
		RaycastHit hit = new RaycastHit();
		if( Physics.Raycast(start, dir, out hit, distance) ) {
			return hit.distance;
		}
		return distance;
	}
	
	private static float ClampAngle(float angle, float min, float max) {
		if (angle < -360) angle += 360;
		if (angle > 360) angle -= 360;
		return Mathf.Clamp (angle, min, max);
	}
	
	private Vector3 GetInputRotation() {
		#if (UNITY_ANDROID || UNITY_IOS) && !UNITY_EDITOR
		return MobileInput.GetRotation();
		#else
		if( !Input.GetMouseButton(1) ) return Vector2.zero; 
		float dx = Input.GetAxis( "Mouse X" )*4;
		float dy = Input.GetAxis( "Mouse Y" )*4;
		return new Vector2(-dy, dx);
		#endif
	}
	
	void OnDrawGizmosSelected() {
		if(!enabled) return;
		
		Gizmos.color = Color.red;
		Gizmos.DrawSphere( target.TransformPoint( targetOffset ), 0.05f );
	}
	
}
(Offline)
 
Ответить с цитированием