摄像机穿墙拉近

using UnityEngine;
using System.Collections;

public class MyCamera : MonoBehaviour {

    // 相机与主角头顶默认距离
    public const float DISTANCE_DEFAULT = 8.0f;

    // 主角物体
    public GameObject target;
    // 主角锚点到头顶高度
    public float target_offsetY = 1.8f;

    // 相机与主角头顶实际距离
    private float distance = 0.0f;
    // 头顶位置
    private Vector3 payerTarget;

    void Awake()
    {
        distance = DISTANCE_DEFAULT;
        // 头顶位置 
        payerTarget = new Vector3 (target.transform.position.x, target.transform.position.y + target_offsetY, target.transform.position.z);
        // X轴转动30°
        Quaternion cr = Quaternion.Euler (30.0f, transform.eulerAngles.y, 0);
        transform.position = payerTarget + cr * Vector3.back * distance;
        transform.LookAt (payerTarget);
    }

    void LateUpdate()
    {
        payerTarget = new Vector3 (target.transform.position.x, target.transform.position.y + target_offsetY, target.transform.position.z);
        Quaternion cr = Quaternion.Euler (30.0f, transform.eulerAngles.y, 0);
        Vector3 position = payerTarget + cr * Vector3.back * distance;
        // 射线与物体交叉所有碰撞点
        RaycastHit[] hits = Physics.RaycastAll( new Ray( payerTarget, ( position - payerTarget ).normalized ));
        distance = DISTANCE_DEFAULT;
        if( 0 < hits.Length )
        {
            RaycastHit stand = hits[0];
            foreach( RaycastHit hit in hits )
            {
                if( "Plane" == hit.collider.gameObject.tag )
                {
                    if( hit.distance < stand.distance )
                    {
                        stand = hit;
                    }
                }
            }
            Debug.Log( stand.point + " " + stand.collider.gameObject.tag );
            string tag = stand.collider.gameObject.tag;
            distance = Vector3.Distance( stand.point, payerTarget );
            if( distance > DISTANCE_DEFAULT )
            {
                distance = DISTANCE_DEFAULT;
            }
            position = payerTarget + cr * Vector3.back * distance;
            transform.position = Vector3.Lerp( transform.position, position, 0.3f );
            transform.LookAt( payerTarget );

            Debug.DrawRay( payerTarget, position - payerTarget, Color.red );
        }
    }
}