在3D遊戲開發的過程中,第三人稱的攝像機是不可逃避的問題。
1.我先獻上攝像機縮放,跟隨,右鍵調節角度的代碼:
主要是利用差值計算來改變位置,很簡單,沒什麼可說的。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class LookAtPlayer : MonoBehaviour {
private GameObject target;
private Vector3 offset;
void Start () {
target = GameObject.FindGameObjectWithTag("Player");
offset = target.transform.position - this.transform.position;
}
void LateUpdate()
{
this.transform.position = target.transform.position - offset;
Rotate();
Scale();
}
//縮放
private void Scale()
{
float dis = offset.magnitude;
dis += Input.GetAxis("Mouse ScrollWheel") * 5;
if (dis < 1.5f || dis > 5)
{
return;
}
offset = offset.normalized * dis;
}
//左右上下移動
private void Rotate()
{
if (Input.GetMouseButton(0))
{
Vector3 pos = transform.position;
Vector3 rot = transform.eulerAngles;
//圍繞原點旋轉,也可以將Vector3.zero改爲 target.position,就是圍繞觀察對象旋轉
transform.RotateAround(target.transform.position, Vector3.up, Input.GetAxis("Mouse X") * 10);
// transform.RotateAround(target.transform.position, Vector3.left, Input.GetAxis("Mouse Y") * 10);
float x = transform.eulerAngles.x;
// float y = transform.eulerAngles.y;
Debug.Log("x=" + x);
//Debug.Log("y=" + y);
//控制移動範圍
if (x < 20 || x > 45)
{
transform.position = pos;
transform.eulerAngles = rot;
}
// 更新相對差值
offset = target.transform.position - this.transform.position;
}
}
}
2.獻上視線受阻透明化處理的代碼
基本原理就是從攝像機發出射線到主角或相反方向,射線碰撞到的gameObject組,改變其材質顏色的透明度。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraHandle : MonoBehaviour {
private Transform player_Transform;//玩家角色
private GameObject Player;
private List<GameObject> collideredObjects;//本次射線hit到的GameObject
private List<GameObject> bufferOfCollideredObjects;//上次射線hit到的GameObject
void Start () {
collideredObjects=new List<GameObject>();
bufferOfCollideredObjects=new List<GameObject>();
Player = GameObject.FindGameObjectWithTag("Player");
}
// Update is called once per frame
void Update () {
bufferOfCollideredObjects.Clear();
for(int temp=0;temp<collideredObjects.Count; temp++)
{
bufferOfCollideredObjects.Add(collideredObjects[temp]);//得到上次的
}
collideredObjects.Clear();
//發射射線
player_Transform = Player.transform;
Vector3 dir = (transform.position - player_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.tag!="Player")
{
collideredObjects.Add(hits[i].collider.gameObject);//得到現在的
SetMaterialsColor(collideredObjects[i].GetComponent<Renderer>(),true);
}
}
//上次與本次對比,本次還存在的物體則賦值爲null
for (int i = 0; i < bufferOfCollideredObjects.Count; i++)
{
for (int j = 0; j < collideredObjects.Count; j++)
{
if (collideredObjects[j] != null)
{
if (bufferOfCollideredObjects[i].name == collideredObjects[j].name)
{
bufferOfCollideredObjects[i] = null;
break;
}
}
}
}
//把上次的還原,這次的透明
for (int i = 0; i < bufferOfCollideredObjects.Count; i++)
{
if (bufferOfCollideredObjects != null)
{
print(bufferOfCollideredObjects[i].name);
SetMaterialsColor(bufferOfCollideredObjects[i].GetComponent<Renderer>(),false);
}
}
}
//是否搞透明
void SetMaterialsColor(Renderer r,bool isClear)
{
if(isClear)
{
int materialsNumber = r.sharedMaterials.Length;
for (int i = 0; i < materialsNumber; i++)
{
Color _color = r.materials[i].color;
_color.a = 0.6f;
r.materials[i].SetColor("_Color", _color);
}
}
else
{
int materialsNumber = r.sharedMaterials.Length;
for (int i = 0; i < materialsNumber; i++)
{
Color _color = r.materials[i].color;
_color.a = 1.0f;
r.materials[i].SetColor("_Color", _color);
}
}
}
}
注意的是:如果本次遮擋物中存在上次遮擋物,則置爲空,否則會存在閃爍問題。