WIP furniture picking
This commit is contained in:
@@ -0,0 +1,358 @@
|
||||
//====================================================================================
|
||||
//
|
||||
// Purpose: Provide abstraction into projecting a raycast into the game world.
|
||||
// As this is an abstract class, it should never be used on it's own.
|
||||
//
|
||||
// Events Emitted:
|
||||
//
|
||||
// WorldPointerIn - is emitted when the pointer collides with an object
|
||||
// WorldPointerOut - is emitted when the pointer stops colliding with an object
|
||||
// WorldPointerDestinationSet - is emmited when the pointer is deactivated
|
||||
//
|
||||
// Event Payload:
|
||||
//
|
||||
// controllerIndex - The index of the controller the pointer is attached to
|
||||
// distance - The distance from the collided object the controller is
|
||||
// target - The Transform of the object the pointer has collided with
|
||||
// tipPosition - The world position of the beam tip
|
||||
//
|
||||
//====================================================================================
|
||||
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
|
||||
public struct WorldPointerEventArgs
|
||||
{
|
||||
public uint controllerIndex;
|
||||
public float distance;
|
||||
public Transform target;
|
||||
public Vector3 destinationPosition;
|
||||
public bool enableTeleport;
|
||||
}
|
||||
|
||||
public delegate void WorldPointerEventHandler(object sender, WorldPointerEventArgs e);
|
||||
|
||||
public class SteamVR_PlayAreaCollider : MonoBehaviour
|
||||
{
|
||||
private GameObject parent;
|
||||
|
||||
public void SetParent(GameObject setParent)
|
||||
{
|
||||
parent = setParent;
|
||||
}
|
||||
|
||||
void OnTriggerStay(Collider collider)
|
||||
{
|
||||
if (parent.GetComponent<SteamVR_WorldPointer>().IsActive() && !collider.name.Contains("PlayerObject_"))
|
||||
{
|
||||
parent.GetComponent<SteamVR_WorldPointer>().setPlayAreaCursorCollision(true);
|
||||
}
|
||||
}
|
||||
|
||||
void OnTriggerExit(Collider collider)
|
||||
{
|
||||
if (! collider.name.Contains("PlayerObject_")) {
|
||||
parent.GetComponent<SteamVR_WorldPointer>().setPlayAreaCursorCollision(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class SteamVR_WorldPointer : MonoBehaviour {
|
||||
public Color pointerHitColor = new Color(0f, 0.5f, 0f, 1f);
|
||||
public Color pointerMissColor = new Color(0.8f, 0f, 0f, 1f);
|
||||
public bool showPlayAreaCursor = false;
|
||||
public Vector2 playAreaCursorDimensions = Vector2.zero;
|
||||
public bool handlePlayAreaCursorCollisions = false;
|
||||
public bool enableTeleport = true;
|
||||
public bool beamAlwaysOn = false;
|
||||
public float activateDelay = 0f;
|
||||
|
||||
protected Vector3 destinationPosition;
|
||||
protected float pointerContactDistance = 0f;
|
||||
protected Transform pointerContactTarget = null;
|
||||
protected uint controllerIndex;
|
||||
|
||||
protected Material pointerMaterial;
|
||||
protected bool playAreaCursorCollided = false;
|
||||
|
||||
private SteamVR_PlayArea playArea;
|
||||
private GameObject playAreaCursor;
|
||||
private GameObject[] playAreaCursorBoundaries;
|
||||
private bool isActive;
|
||||
|
||||
private float activateDelayTimer = 0f;
|
||||
private float updatesPerSecond = 60f;
|
||||
|
||||
public event WorldPointerEventHandler WorldPointerIn;
|
||||
public event WorldPointerEventHandler WorldPointerOut;
|
||||
public event WorldPointerEventHandler WorldPointerDestinationSet;
|
||||
|
||||
public virtual void OnWorldPointerIn(WorldPointerEventArgs e)
|
||||
{
|
||||
if (WorldPointerIn != null)
|
||||
WorldPointerIn(this, e);
|
||||
}
|
||||
|
||||
public virtual void OnWorldPointerOut(WorldPointerEventArgs e)
|
||||
{
|
||||
if (WorldPointerOut != null)
|
||||
WorldPointerOut(this, e);
|
||||
}
|
||||
|
||||
public virtual void OnWorldPointerDestinationSet(WorldPointerEventArgs e)
|
||||
{
|
||||
if (WorldPointerDestinationSet != null)
|
||||
WorldPointerDestinationSet(this, e);
|
||||
}
|
||||
|
||||
public virtual void setPlayAreaCursorCollision(bool state)
|
||||
{
|
||||
if (handlePlayAreaCursorCollisions)
|
||||
{
|
||||
playAreaCursorCollided = state;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool IsActive()
|
||||
{
|
||||
return isActive;
|
||||
}
|
||||
|
||||
public virtual bool CanActivate()
|
||||
{
|
||||
return (activateDelayTimer <= 0);
|
||||
}
|
||||
|
||||
protected WorldPointerEventArgs SetPointerEvent(uint controllerIndex, float distance, Transform target, Vector3 position)
|
||||
{
|
||||
WorldPointerEventArgs e;
|
||||
e.controllerIndex = controllerIndex;
|
||||
e.distance = distance;
|
||||
e.target = target;
|
||||
e.destinationPosition = position;
|
||||
e.enableTeleport = enableTeleport;
|
||||
return e;
|
||||
}
|
||||
|
||||
protected virtual void Start()
|
||||
{
|
||||
if (GetComponent<SteamVR_ControllerEvents>() == null)
|
||||
{
|
||||
Debug.LogError("SteamVR_WorldPointer is required to be attached to a SteamVR Controller that has the SteamVR_ControllerEvents script attached to it");
|
||||
return;
|
||||
}
|
||||
|
||||
this.name = "PlayerObject_" + this.name;
|
||||
|
||||
//Setup controller event listeners
|
||||
GetComponent<SteamVR_ControllerEvents>().AliasPointerOn += new ControllerClickedEventHandler(EnablePointerBeam);
|
||||
GetComponent<SteamVR_ControllerEvents>().AliasPointerOff += new ControllerClickedEventHandler(DisablePointerBeam);
|
||||
|
||||
playArea = GameObject.FindObjectOfType<SteamVR_PlayArea>();
|
||||
playAreaCursorBoundaries = new GameObject[4];
|
||||
|
||||
pointerMaterial = new Material(Shader.Find("Unlit/TransparentColor"));
|
||||
pointerMaterial.color = pointerMissColor;
|
||||
}
|
||||
|
||||
protected virtual void Update()
|
||||
{
|
||||
if (activateDelayTimer > 0)
|
||||
{
|
||||
activateDelayTimer--;
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void InitPointer()
|
||||
{
|
||||
InitPlayAreaCursor();
|
||||
}
|
||||
|
||||
protected virtual void SetPlayAreaCursorTransform(Vector3 destination)
|
||||
{
|
||||
playAreaCursor.transform.position = destination;
|
||||
}
|
||||
|
||||
protected virtual void EnablePointerBeam(object sender, ControllerClickedEventArgs e)
|
||||
{
|
||||
if (!isActive && activateDelayTimer <= 0)
|
||||
{
|
||||
setPlayAreaCursorCollision(false);
|
||||
controllerIndex = e.controllerIndex;
|
||||
TogglePointer(true);
|
||||
isActive = true;
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void DisablePointerBeam(object sender, ControllerClickedEventArgs e)
|
||||
{
|
||||
if (isActive && activateDelayTimer <= 0)
|
||||
{
|
||||
activateDelayTimer = activateDelay * updatesPerSecond;
|
||||
controllerIndex = e.controllerIndex;
|
||||
TogglePointer(false);
|
||||
isActive = false;
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void PointerIn()
|
||||
{
|
||||
if (!pointerContactTarget)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
OnWorldPointerIn(SetPointerEvent(controllerIndex, pointerContactDistance, pointerContactTarget, destinationPosition));
|
||||
|
||||
SteamVR_InteractableObject interactableObject = pointerContactTarget.GetComponent<SteamVR_InteractableObject>();
|
||||
if (interactableObject && interactableObject.pointerActivatesUseAction && interactableObject.holdButtonToUse)
|
||||
{
|
||||
interactableObject.StartUsing(this.gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void PointerOut()
|
||||
{
|
||||
if (!pointerContactTarget)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
OnWorldPointerOut(SetPointerEvent(controllerIndex, pointerContactDistance, pointerContactTarget, destinationPosition));
|
||||
|
||||
SteamVR_InteractableObject interactableObject = pointerContactTarget.GetComponent<SteamVR_InteractableObject>();
|
||||
if (interactableObject && interactableObject.pointerActivatesUseAction && interactableObject.holdButtonToUse)
|
||||
{
|
||||
interactableObject.StopUsing(this.gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void PointerSet()
|
||||
{
|
||||
if (!isActive || !pointerContactTarget)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SteamVR_InteractableObject interactableObject = pointerContactTarget.GetComponent<SteamVR_InteractableObject>();
|
||||
if (interactableObject && interactableObject.pointerActivatesUseAction)
|
||||
{
|
||||
if (interactableObject.IsUsing())
|
||||
{
|
||||
interactableObject.StopUsing(this.gameObject);
|
||||
} else if (!interactableObject.holdButtonToUse)
|
||||
{
|
||||
interactableObject.StartUsing(this.gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
if (!playAreaCursorCollided && (interactableObject == null || !interactableObject.pointerActivatesUseAction))
|
||||
{
|
||||
OnWorldPointerDestinationSet(SetPointerEvent(controllerIndex, pointerContactDistance, pointerContactTarget, destinationPosition));
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void TogglePointer(bool state)
|
||||
{
|
||||
bool playAreaState = (showPlayAreaCursor ? state: false);
|
||||
playAreaCursor.gameObject.SetActive(playAreaState);
|
||||
}
|
||||
|
||||
protected virtual void SetPointerMaterial()
|
||||
{
|
||||
foreach(GameObject playAreaCursorBoundary in playAreaCursorBoundaries)
|
||||
{
|
||||
playAreaCursorBoundary.GetComponent<MeshRenderer>().material = pointerMaterial;
|
||||
}
|
||||
}
|
||||
|
||||
protected void UpdatePointerMaterial(Color color)
|
||||
{
|
||||
if (playAreaCursorCollided)
|
||||
{
|
||||
color = pointerMissColor;
|
||||
}
|
||||
pointerMaterial.color = color;
|
||||
SetPointerMaterial();
|
||||
}
|
||||
|
||||
private void DrawPlayAreaCursorBoundary(int index, float left, float right, float top, float bottom, float thickness, Vector3 localPosition)
|
||||
{
|
||||
|
||||
GameObject playAreaCursorBoundary = GameObject.CreatePrimitive(PrimitiveType.Cube);
|
||||
playAreaCursorBoundary.name = string.Format("[{0}]PlayerObject_WorldPointer_PlayAreaCursorBoundary_" + index, this.gameObject.name);
|
||||
|
||||
float width = (right - left) / 1.065f;
|
||||
float length = (top - bottom) / 1.08f;
|
||||
float height = thickness;
|
||||
|
||||
playAreaCursorBoundary.transform.localScale = new Vector3(width, height, length);
|
||||
Destroy(playAreaCursorBoundary.GetComponent<BoxCollider>());
|
||||
playAreaCursorBoundary.layer = 2;
|
||||
|
||||
playAreaCursorBoundary.transform.parent = playAreaCursor.transform;
|
||||
playAreaCursorBoundary.transform.localPosition = localPosition;
|
||||
|
||||
playAreaCursorBoundaries[index] = playAreaCursorBoundary;
|
||||
}
|
||||
|
||||
private void InitPlayAreaCursor()
|
||||
{
|
||||
int btmRightInner = 0;
|
||||
int btmLeftInner = 1;
|
||||
int topLeftInner = 2;
|
||||
int topRightInner = 3;
|
||||
|
||||
int btmRightOuter = 4;
|
||||
int btmLeftOuter = 5;
|
||||
int topLeftOuter = 6;
|
||||
int topRightOuter = 7;
|
||||
|
||||
Vector3[] cursorDrawVertices = playArea.vertices;
|
||||
|
||||
if (playAreaCursorDimensions != Vector2.zero)
|
||||
{
|
||||
float customAreaPadding = playArea.borderThickness;
|
||||
|
||||
cursorDrawVertices[btmRightOuter] = new Vector3(playAreaCursorDimensions.x / 2, 0f, (playAreaCursorDimensions.y / 2) * -1);
|
||||
cursorDrawVertices[btmLeftOuter] = new Vector3((playAreaCursorDimensions.x / 2) * -1, 0f, (playAreaCursorDimensions.y / 2) * -1);
|
||||
cursorDrawVertices[topLeftOuter] = new Vector3((playAreaCursorDimensions.x / 2) * -1, 0f, playAreaCursorDimensions.y / 2);
|
||||
cursorDrawVertices[topRightOuter] = new Vector3(playAreaCursorDimensions.x / 2, 0f, playAreaCursorDimensions.y / 2);
|
||||
|
||||
cursorDrawVertices[btmRightInner] = cursorDrawVertices[btmRightOuter] + new Vector3(-customAreaPadding, 0f, customAreaPadding);
|
||||
cursorDrawVertices[btmLeftInner] = cursorDrawVertices[btmLeftOuter] + new Vector3(customAreaPadding, 0f, customAreaPadding);
|
||||
cursorDrawVertices[topLeftInner] = cursorDrawVertices[topLeftOuter] + new Vector3(customAreaPadding, 0f, -customAreaPadding);
|
||||
cursorDrawVertices[topRightInner] = cursorDrawVertices[topRightOuter] + new Vector3(-customAreaPadding, 0f, -customAreaPadding);
|
||||
}
|
||||
|
||||
float width = cursorDrawVertices[btmRightOuter].x - cursorDrawVertices[topLeftOuter].x;
|
||||
float length = cursorDrawVertices[topLeftOuter].z - cursorDrawVertices[btmRightOuter].z;
|
||||
float height = 0.01f;
|
||||
|
||||
playAreaCursor = GameObject.CreatePrimitive(PrimitiveType.Cube);
|
||||
playAreaCursor.name = string.Format("[{0}]PlayerObject_WorldPointer_PlayAreaCursor", this.gameObject.name);
|
||||
playAreaCursor.transform.parent = null;
|
||||
playAreaCursor.transform.localScale = new Vector3(width, height, length);
|
||||
playAreaCursor.SetActive(false);
|
||||
|
||||
playAreaCursor.GetComponent<MeshRenderer>().enabled = false;
|
||||
|
||||
BoxCollider playAreaCursorCollider = playAreaCursor.GetComponent<BoxCollider>();
|
||||
playAreaCursorCollider.isTrigger = true;
|
||||
playAreaCursorCollider.center = new Vector3(0f, 65f, 0f);
|
||||
playAreaCursorCollider.size = new Vector3(1f, 100f, 1f);
|
||||
playAreaCursor.AddComponent<Rigidbody>().isKinematic = true;
|
||||
SteamVR_PlayAreaCollider playAreaCursorScript = playAreaCursor.AddComponent<SteamVR_PlayAreaCollider>();
|
||||
playAreaCursorScript.SetParent(this.gameObject);
|
||||
playAreaCursor.layer = 2;
|
||||
|
||||
float playAreaBoundaryX = playArea.transform.localScale.x / 2;
|
||||
float playAreaBoundaryZ = playArea.transform.localScale.z / 2;
|
||||
float heightOffset = 0f;
|
||||
|
||||
DrawPlayAreaCursorBoundary(0, cursorDrawVertices[btmLeftOuter].x, cursorDrawVertices[btmRightOuter].x, cursorDrawVertices[btmRightInner].z, cursorDrawVertices[btmRightOuter].z, height, new Vector3(0f, heightOffset, playAreaBoundaryZ));
|
||||
DrawPlayAreaCursorBoundary(1, cursorDrawVertices[btmLeftOuter].x, cursorDrawVertices[btmLeftInner].x, cursorDrawVertices[topLeftOuter].z, cursorDrawVertices[btmLeftOuter].z, height, new Vector3(playAreaBoundaryX, heightOffset, 0f));
|
||||
DrawPlayAreaCursorBoundary(2, cursorDrawVertices[btmLeftOuter].x, cursorDrawVertices[btmRightOuter].x, cursorDrawVertices[btmRightInner].z, cursorDrawVertices[btmRightOuter].z, height, new Vector3(0f, heightOffset, -playAreaBoundaryZ));
|
||||
DrawPlayAreaCursorBoundary(3, cursorDrawVertices[btmLeftOuter].x, cursorDrawVertices[btmLeftInner].x, cursorDrawVertices[topLeftOuter].z, cursorDrawVertices[btmLeftOuter].z, height, new Vector3(-playAreaBoundaryX, heightOffset, 0f));
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f2527c033c62a9d489bc580ce4ddda27
|
||||
timeCreated: 1461571032
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user