一、場景

二、激光發(fā)射邏輯

EmissionLaser
using UnityEngine;
using System.Collections;
public class EmissionLaser : MonoBehaviour {
//開關控制是否發(fā)射激光
public bool Enable;
//激光發(fā)射點
public GameObject pointer;
public float thickness = 0.002f;
Transform previousContact = null;
void Start()
{
//創(chuàng)建激光發(fā)射點
pointer = GameObject.CreatePrimitive(PrimitiveType.Cube);
pointer.transform.parent = this.transform;
pointer.transform.localScale = new Vector3(thickness, thickness, 100f);
pointer.transform.localPosition = new Vector3(0f, 0f, 50f);
pointer.transform.rotation = new Quaternion(0, 0, 0, 0);
//刪除激光發(fā)射器的碰撞
BoxCollider collider = pointer.GetComponent<BoxCollider>();
GameObject.Destroy(collider);
if (Enable)
{
pointer.SetActive(true);
}
else
{
pointer.SetActive(false);
}
}
//開始發(fā)射激光
public void StartEmission()
{
pointer.SetActive(true);
Enable = true;
}
//停止發(fā)射激光
public void EndEmission()
{
pointer.SetActive(false);
Enable = false;
//當前是有下一個傳遞物體,如果有將停止發(fā)射激光事件傳遞給它
if (previousContact != null)
{
ReceiveLaser r = previousContact.GetComponent<ReceiveLaser>();
if (r != null)
{
r.PointerOut();
}
previousContact = null;
}
}
void Update()
{
//根據(jù)Enable來判斷是否發(fā)射激光
if(!Enable)
{
return;
}
Ray raycast = new Ray(transform.position, transform.forward);
RaycastHit hit;
bool bHit = Physics.Raycast(raycast, out hit);
float dist = 100f;
//擊中物體并且不等于當前擊中物體,如果原物體不為空觸發(fā)PointerOut,新物體觸發(fā)PointIn事件。
if (bHit && previousContact != hit.transform)
{
ReceiveLaser r;
if (previousContact!= null)
{
r = previousContact.GetComponent<ReceiveLaser>();
if (r != null)
{
r.PointerOut();
}
}
previousContact = hit.transform;
r = previousContact.GetComponent<ReceiveLaser>();
if (r != null)
{
r.PointerIn();
}
}
//如果沒有擊中物體,并且原有擊中物體,則觸發(fā)原有物體的PointerOut事件,并將previousContact至空
if (!bHit)
{
if(previousContact != null)
{
ReceiveLaser r = previousContact.GetComponent<ReceiveLaser>();
if (r != null)
{
r.PointerOut();
}
previousContact = null;
}
}
if (bHit && hit.distance < 100f)
{
dist = hit.distance;
}
pointer.transform.localScale = new Vector3(thickness, thickness, dist);
pointer.transform.localPosition = new Vector3(0f, 0f, dist / 2f);
}
}
三、接收激光
1、父類接收激光腳本
ReceiveLaser
using UnityEngine;
using System.Collections;
public class ReceiveLaser : MonoBehaviour {
//引用計數(shù)
int ReferenceCount = 0;
// Use this for initialization
void Start () {
}
//有激光擊中
public void PointerIn()
{
ReferenceCount++;
if(ReferenceCount > 0)
{
HighEnergy();
}
}
//激光離開
public void PointerOut()
{
ReferenceCount--;
if (ReferenceCount <=0 )
{
LowEnergy();
}
}
//進入低能量狀態(tài)
public virtual void LowEnergy()
{
}
//進入高能量狀態(tài)
public virtual void HighEnergy()
{
}
}
2、接收并發(fā)射激光

ReceiveAndEmissionLaser
using UnityEngine;
using System.Collections;
public class ReceiveAndEmissionLaser : ReceiveLaser
{
public EmissionLaser[] EmissionLasers;
public override void HighEnergy()
{
foreach (EmissionLaser EmissionLaser in EmissionLasers)
{
EmissionLaser.StartEmission();
}
}
public override void LowEnergy()
{
foreach (EmissionLaser EmissionLaser in EmissionLasers)
{
EmissionLaser.EndEmission();
}
}
}
3、接收激光后開門

ReceiveAndOpenDoor
using UnityEngine;
using System.Collections;
public class ReceiveAndOpenDoor : ReceiveLaser
{
public Transform[] Doors;
bool HasEnergy = false;
void FixedUpdate()
{
if(HasEnergy)
{
foreach(Transform tr in Doors)
{
tr.position = Vector3.Lerp(tr.position , new Vector3(tr.position.x,-10, tr.position.z),Time.fixedDeltaTime);
}
}
}
public override void HighEnergy()
{
HasEnergy = true;
}
}
4、接收后通過關卡勝利

ReceiveAndWin
using UnityEngine;
using System.Collections;
public class ReceiveAndWin : ReceiveLaser
{
public GameObject Win;
public override void HighEnergy()
{
Win.SetActive (true);
}
}
四、制作接收和發(fā)射激光的預制體

五、操作獅子旋轉


using UnityEngine;
using System.Collections;
public class RotateLion : MonoBehaviour
{
SteamVR_LaserPointer SteamVR_LaserPointer;
SteamVR_TrackedController SteamVR_TrackedController;
Transform pointTransform;
GameObject currentCatch;
bool isTrigger;
// Use this for initialization
void Start()
{
//獲取SteamVR_LaserPointer和SteamVR_TrackedController并監(jiān)聽屬性
SteamVR_LaserPointer = GetComponent<SteamVR_LaserPointer>();
SteamVR_LaserPointer.PointerIn += PointerIn;
SteamVR_LaserPointer.PointerOut += PointerOut;
SteamVR_TrackedController = GetComponent<SteamVR_TrackedController>();
SteamVR_TrackedController.TriggerClicked += TriggerClicked;
SteamVR_TrackedController.TriggerUnclicked += TriggerUnclicked;
}
void FixedUpdate()
{
if (pointTransform != null && isTrigger)
{
pointTransform.rotation = Quaternion.AngleAxis(pointTransform.rotation.eulerAngles.y + 0.5f,Vector3.up);
}
}
void PointerIn(object sender, PointerEventArgs e)
{
//判斷是不是tag為Lion,如果不是就不設置標志。
if (e.target.gameObject.tag == "Lion")
{
pointTransform = e.target;
}
}
void PointerOut(object sender, PointerEventArgs e)
{
pointTransform = null;
}
void TriggerClicked(object sender, ClickedEventArgs e)
{
isTrigger = true;
}
void TriggerUnclicked(object sender, ClickedEventArgs e)
{
isTrigger = false;
}
}
六、完善場景布置





