为了实现角色被遮挡时,让遮挡物变透明的效果,就是下图的效果,我把墙体的材质设置成了透明模式,见下图:

材质渲染模式见下图:经过测试发现,只有将材质设置为这种,或者将shader改为任意一种Transparent路径下的一种,才能用代码去修改物体材质的alpha值,才能让物体变透明。。其他模式均不能透明。但是,这是了这种模式之后,就存在了下面的问题:

请看,当摄像机一定角度时(不一定什么角度总之很奇葩),设置了透明模式的物体渲染就会有问题,比如下面的:看上去貌似错位了一样。。

但是当你转一下摄像机角度,看上去就好像又变正常了。。。。

大神,麻烦赐教这是肿么回事,怎么避免这种情况??或者有什么其他的方法让物体变透明??
using System;
using System.Linq;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraViewControll : MonoBehaviour {
	[SerializeField]
	private Transform m_target;         // 目标
	[SerializeField]
	private float m_roteSpeed = 5.0f;   // 视角旋转速度
	[SerializeField]
	private float m_zoomSpeed = 5.0f;   // 视角缩放速度
	private Vector3 m_offset;           // 摄像机到角色的偏移
    private RaycastHit[] m_lastHits;        // 上次渲染时遮挡角色的物体(用于恢复透明度)
    void Start () {
		if (m_target == null) {
			m_target = GameObject.Find ("Player").transform;
			if (m_target == null) {
				Debug.LogError ("Target Player Not Set");
			}
		}
		transform.LookAt (m_target);
		m_offset = transform.position - m_target.position;
	}
	
	// Update is called once per frame
	void Update () {
                // 重新计算位置
		transform.position = m_offset + m_target.position;
                // 右键按下时,处理视角旋转
		if (Input.GetMouseButton (1)) {
			Vector3 pos = transform.position;
			Quaternion rot = transform.rotation;
			float h = Input.GetAxis ("Mouse X");
			float v = - Input.GetAxis ("Mouse Y");
			transform.RotateAround (m_target.position, m_target.up, h * m_roteSpeed );
			transform.RotateAround (m_target.position, transform.right, v * m_roteSpeed );
			float a = transform.rotation.eulerAngles.x;
			if (a <= 10 || a >= 80) {
				transform.position = pos;
				transform.rotation = rot;
			} else {
				m_offset = transform.position - m_target.position;
			}
		}
                // 处理视角缩放
		float d = - Input.GetAxis ("Mouse ScrollWheel");
		if (d > 0.01f || d < -0.01f) {
			float distance = m_offset.magnitude;
			distance = Mathf.Clamp ( distance + d * m_zoomSpeed, 3, 20 );
			transform.position = ( m_offset.normalized * distance ) + m_target.position;
			m_offset = transform.position - m_target.position;
		}
        // 判断遮挡
        CheckMask();
	}
    void CheckMask()
    {
        // 用射线检测所有挡在摄像机和角色之间的物体。
        RaycastHit[] hits = Physics.RaycastAll(m_target.position, m_offset.normalized, m_offset.magnitude );
        // 如果上次保存了遮挡物,求出上次跟这次的差集,就是说上次遮挡了但这次没遮挡的物体,然后恢复他们的透明度。
        if( m_lastHits != null && m_lastHits.Length > 0 )
        {
            if (hits.Length > 0)
            {
                var needShow = m_lastHits.Except(hits);
                foreach (var i in needShow)
                {
                    SetTransparent( i.transform.GetComponent<Renderer>(), 1);
                }
            }
            else
            {
                foreach( var i in m_lastHits )
                {
                    SetTransparent(i.transform.GetComponent<Renderer>(), 1);
                }
            }
        }
        
        // 如果本次检测到有遮挡物体,求出本次与上次遮挡物的差集,就是说新增的遮挡物,设置他们的透明度为0.3
        if (hits.Length > 0)
        {
            if( m_lastHits == null || m_lastHits.Length <= 0 )
            {
                foreach( var i in hits )
                {
                    SetTransparent(i.transform.GetComponent<Renderer>(), 0.3f);
                }
            }
            else
            {
                var needHide = hits.Except(m_lastHits);
                foreach( var i in needHide )
                {
                    SetTransparent(i.transform.GetComponent<Renderer>(), 0.3f);
                }
            }
        }
        // 保存本次的遮挡物列表
        m_lastHits = hits;
    }
    // 设置物体材质的透明度
    void SetTransparent( Renderer render, float alpha )
    {
        for( int i = render.sharedMaterials.Length - 1; i >= 0; -- i )
        {
            Color col = render.materials[i].color;
            col.a = alpha;
            render.materials[i].SetColor("_Color", col);
        }
    }
}
另外,附上我摄像机控制的代码,还有变透明代码: