Unity3D_Camera摄像机跟随之物体遮挡处理方案

Unity3D_Camera摄像机跟随之物体遮挡处理方案

引言:想必大家都玩过RPG类型的游戏,那么有没有注意到当角色摄像机被物体遮挡后会怎样?游戏开发者当然不会就这样让角色一直被遮挡,否则那样你得有多难受啊(看不到角色、辨别不了方向),那你有没有想过是怎样处理的呢?细心的你肯定发现一般都是将遮挡物体置为透明,或者是将摄像机拉近(绝地求生?),接下来就讨论一下吧!

摄像机拉近

不多说了,注释很详细了

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class LookAtObject : MonoBehaviour {

	private Transform transformOfTargetObject;//目标物体
	private Vector3 offset;//摄像机对于角色的差量
	private Vector3 targetPosition;//计算后得到的摄像机位置
	private float speed=5;//摄像机拉近速度
	private bool isCloser=false;//控制是否拉近
	private float dis;//用于记录当前距离,以判断是否达到不碰的临界
	void Start () {
		//初始化
		transformOfTargetObject=GameObject.Find("Cube").GetComponent<Transform>();
		offset=gameObject.transform.position-transformOfTargetObject.position;
		dis=Vector3.Distance(gameObject.transform.position,transformOfTargetObject.position);
	}
	
	void Update () {
		//获得由物体射向摄像机的射线以及碰到的所有物体hits
		Vector3 dir = -(transformOfTargetObject.position - transform.position).normalized;
		RaycastHit[] hits;
		hits = Physics.RaycastAll(transformOfTargetObject.position, dir, Vector3.Distance(transformOfTargetObject.position,transform.position));
		//有碰到且物体没有移走,就拉近
		if(hits.Length>0&&dis>Vector3.Distance(gameObject.transform.position,transformOfTargetObject.position))
		{
			isCloser=true;
		}
		else
		{
			isCloser=false;
		}
		if(isCloser)
		{
			//拉近
			gameObject.transform.position=Vector3.Lerp(gameObject.transform.position,hits[0].point,Time.deltaTime*speed);;
			gameObject.transform.LookAt(transformOfTargetObject);
			isCloser=false;
		}
		else
		{
			//正常跟随
			targetPosition=transformOfTargetObject.position+transformOfTargetObject.TransformDirection(offset);
			gameObject.transform.position=Vector3.Lerp(gameObject.transform.position,targetPosition,Time.deltaTime*speed);
			gameObject.transform.LookAt(transformOfTargetObject);
		}
		
	}
}

结果:在这里插入图片描述
在这里插入图片描述

二、置为透明

在第三人称摄像机跟随下进行测试(我的博客里有说过)摄像机跟随
不多说了,注释很详细了

在这里插入代码片using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CollisionHandling : MonoBehaviour {

	public Transform player_Transform;//玩家角色
	    
	private List<GameObject> collideredObjects;//本次射线hit到的GameObject
	private List<GameObject> bufferOfCollideredObjects;//上次射线hit到的GameObject
	
	void Start () {
		collideredObjects=new List<GameObject>();
		bufferOfCollideredObjects=new List<GameObject>();
	}
	
	// Update is called once per frame
	void Update () {
		bufferOfCollideredObjects.Clear();
		for(int temp=0;temp<collideredObjects.Count; temp++)
		{
			bufferOfCollideredObjects.Add(collideredObjects[temp]);//得到上次的
		}
		collideredObjects.Clear();

		//发射射线
		Vector3 dir = -(player_Transform.position - transform.position).normalized;
		RaycastHit[] hits;
		hits = Physics.RaycastAll(player_Transform.position, dir, Vector3.Distance(player_Transform.position,transform.position));
		Debug.DrawLine(player_Transform.position, transform.position, Color.red);//让其显示以便观测

		for(int i=0;i<hits.Length;i++)
		{
			if(hits[i].collider.gameObject.name!="Plane"&&hits[i].collider.gameObject.name!="Cube")
			{
				collideredObjects.Add(hits[i].collider.gameObject);//得到现在的
			}
		}
		//把上次的还原,这次的透明
		for(int i=0;i<bufferOfCollideredObjects.Count;i++)
		{
			SetMaterialsColor(bufferOfCollideredObjects[i].GetComponent<Renderer>(),false);
		}
		for(int i=0;i<collideredObjects.Count;i++)
		{
			SetMaterialsColor(collideredObjects[i].GetComponent<Renderer>(),true);
		}
	}
	
	//是否搞透明
	void SetMaterialsColor(Renderer r,bool isClear)
	{
		if(isClear)
		{
			int materialsNumber = r.sharedMaterials.Length;
			for (int i = 0; i < materialsNumber; i++)
			{
				r.materials[i].shader = Shader.Find("Transparent/Diffuse");
            	Color tempColor = r.materials[i].color;
            	tempColor.a = 0.4f;
            	r.materials[i].color = tempColor;
			
			}
		}
		else
		{
			int materialsNumber = r.sharedMaterials.Length;
			for (int i = 0; i < materialsNumber; i++)
			{
				r.materials[i].shader = Shader.Find("Transparent/Diffuse");
            	Color tempColor = r.materials[i].color;
            	tempColor.a = 1f;
            	r.materials[i].color = tempColor;
			
			}
		}
	}
}

结果:
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值