一、场景
二、激光发射逻辑
EmissionLaser
using UnityEngine;
using System.Collections;
public class EmissionLaser : MonoBehaviour {
//开关控制是否发射激光
public bool Enable;
//激光发射点
public GameObject pointer;
public float thickness = 0.002f;
Transform previousContact = null;
void Start()
{
//创建激光发射点
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);
//删除激光发射器的碰撞
BoxCollider collider = pointer.GetComponent<BoxCollider>();
GameObject.Destroy(collider);
if (Enable)
{
pointer.SetActive(true);
}
else
{
pointer.SetActive(false);
}
}
//开始发射激光
public void StartEmission()
{
pointer.SetActive(true);
Enable = true;
}
//停止发射激光
public void EndEmission()
{
pointer.SetActive(false);
Enable = false;
//当前是有下一个传递物体,如果有将停止发射激光事件传递给它
if (previousContact != null)
{
ReceiveLaser r = previousContact.GetComponent<ReceiveLaser>();
if (r != null)
{
r.PointerOut();
}
previousContact = null;
}
}
void Update()
{
//根据Enable来判断是否发射激光
if(!Enable)
{
return;
}
Ray raycast = new Ray(transform.position, transform.forward);
RaycastHit hit;
bool bHit = Physics.Raycast(raycast, out hit);
float dist = 100f;
//击中物体并且不等于当前击中物体,如果原物体不为空触发PointerOut,新物体触发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();
}
}
//如果没有击中物体,并且原有击中物体,则触发原有物体的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 {
//引用计数
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();
}
}
//进入低能量状态
public virtual void LowEnergy()
{
}
//进入高能量状态
public virtual void HighEnergy()
{
}
}
2、接收并发射激光
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);
}
}
四、制作接收和发射激光的预制体
五、操作狮子旋转
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并监听属性
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;
}
}