1、瞬移
因为HTC Vive活动范围有限制(3m * 5m),所以我们在实际的使用中,为了更好的浏览场景,查看场景,会使用这种移动的方式,达到游戏中的视野移动。
一般来说就是手柄选取一个位置,通过扳机键确认移动。
移动的方式有两种:一种是水平移动即X,Z轴移动;另一种就是垂直移动,即Y轴移动。
2、如何实现位置选取?
只要能得到目标位置点,我们就可以移动。那这种功能如何做?
使用射线检测!
HTC Vive中有类似的脚本实现,所以我们只需要修改相关的脚本就可以办到,但是还是需要一定的编程功底。
脚本实现:
将下面脚本复制就可,
修改类名,添加脚本
using UnityEngine;
using System.Collections;
public class CatchPointer : MonoBehaviour
{
public bool active = true;
public Color color;
public float thickness = 0.002f;
public GameObject holder;
public GameObject pointer;
bool isActive = false;
public bool addRigidBody = false;
public Transform reference;
public event PointerEventHandler PointerIn;
public event PointerEventHandler PointerOut;
public Vector3 HitPoint;
Transform previousContact = null;
// Use this for initialization
void Start ()
{
holder = new GameObject();
holder.transform.parent = this.transform;
holder.transform.localPosition = Vector3.zero;
pointer = GameObject.CreatePrimitive(PrimitiveType.Cube);
pointer.transform.parent = holder.transform;
pointer.transform.localScale = new Vector3(thickness, thickness, 100f);
pointer.transform.localPosition = new Vector3(0f, 0f, 50f);
BoxCollider collider = pointer.GetComponent<BoxCollider>();
if (addRigidBody)
{
if (collider)
{
collider.isTrigger = true;
}
Rigidbody rigidBody = pointer.AddComponent<Rigidbody>();
rigidBody.isKinematic = true;
}
else
{
if(collider)
{
Object.Destroy(collider);
}
}
Material newMaterial = new Material(Shader.Find("Unlit/Color"));
newMaterial.SetColor("_Color", color);
pointer.GetComponent<MeshRenderer>().material = newMaterial;
}
public virtual void OnPointerIn(PointerEventArgs e)
{
if (PointerIn != null)
PointerIn(this, e);
}
public virtual void OnPointerOut(PointerEventArgs e)
{
if (PointerOut != null)
PointerOut(this, e);
}
// Update is called once per frame
void Update ()
{
if (!isActive)
{
isActive = true;
this.transform.GetChild(0).gameObject.SetActive(true);
}
float dist = 100f;
SteamVR_TrackedController controller = GetComponent<SteamVR_TrackedController>();
Ray raycast = new Ray(transform.position, transform.forward);
RaycastHit hit;
bool bHit = Physics.Raycast(raycast, out hit);
if(previousContact && previousContact != hit.transform)
{
PointerEventArgs args = new PointerEventArgs();
if (controller != null)
{
args.controllerIndex = controller.controllerIndex;
}
args.distance = 0f;
args.flags = 0;
args.target = previousContact;
OnPointerOut(args);
previousContact = null;
}
if(bHit && previousContact != hit.transform)
{
PointerEventArgs argsIn = new PointerEventArgs();
if (controller != null)
{
argsIn.controllerIndex = controller.controllerIndex;
}
argsIn.distance = hit.distance;
argsIn.flags = 0;
argsIn.target = hit.transform;
OnPointerIn(argsIn);
previousContact = hit.transform;
}
if(!bHit)
{
previousContact = null;
}
if (bHit && hit.distance < 100f)
{
dist = hit.distance;
}
if (bHit)
{
HitPoint = hit.point;
}
if (controller != null && controller.triggerPressed)
{
pointer.transform.localScale = new Vector3(thickness * 5f, thickness * 5f, dist);
}
else
{
pointer.transform.localScale = new Vector3(thickness, thickness, dist);
}
pointer.transform.localPosition = new Vector3(0f, 0f, dist/2f);
}
}
3、添加脚本查看效果
4、如何传送?
编写脚本进行设置
using UnityEngine;
using System.Collections;
public class Teleport : MonoBehaviour {
public GameObject LeftController;
private CatchPointer Pointer;
private SteamVR_TrackedController LeftSt;
ClickedEventHandler ce;
Transform currentTransform;
PointerEventArgs arg;
void Start () {
Pointer = LeftController.GetComponent<CatchPointer>();
LeftSt = LeftController.GetComponent<SteamVR_TrackedController>();
Pointer.PointerIn += LeftPointIn;
Pointer.PointerOut += LeftPointOut;
LeftSt.TriggerClicked += TriggerClicked;
}
void Update () {
}
void LeftPointOut(object sender, PointerEventArgs e)
{
currentTransform = null;
}
void LeftPointIn(object sender, PointerEventArgs e)
{ // 设置标识
currentTransform = e.target;
}
void TriggerClicked(object sender, ClickedEventArgs e)
{
if (currentTransform != null)
{
this.gameObject.transform.position = new Vector3(Pointer.HitPoint.x - LeftController.transform.localPosition.x, Pointer.HitPoint.y, Pointer.HitPoint.z - LeftController.transform.localPosition.z);
}
}
}