Remove useless files, add hands
This commit is contained in:
@@ -1,91 +0,0 @@
|
||||
/************************************************************************************
|
||||
|
||||
Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved.
|
||||
|
||||
See SampleFramework license.txt for license terms. Unless required by applicable law
|
||||
or agreed to in writing, the sample code is provided “AS IS” WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied. See the license for specific
|
||||
language governing permissions and limitations under the license.
|
||||
|
||||
************************************************************************************/
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEngine.Assertions;
|
||||
|
||||
namespace OculusSampleFramework
|
||||
{
|
||||
public class ControllerBoxController : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private TrainLocomotive _locomotive = null;
|
||||
[SerializeField] private CowController _cowController = null;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
Assert.IsNotNull(_locomotive);
|
||||
Assert.IsNotNull(_cowController);
|
||||
}
|
||||
public void StartStopStateChanged(InteractableStateArgs obj)
|
||||
{
|
||||
if (obj.NewInteractableState == InteractableState.ActionState)
|
||||
{
|
||||
_locomotive.StartStopStateChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public void DecreaseSpeedStateChanged(InteractableStateArgs obj)
|
||||
{
|
||||
if (obj.NewInteractableState == InteractableState.ActionState)
|
||||
{
|
||||
_locomotive.DecreaseSpeedStateChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public void IncreaseSpeedStateChanged(InteractableStateArgs obj)
|
||||
{
|
||||
if (obj.NewInteractableState == InteractableState.ActionState)
|
||||
{
|
||||
_locomotive.IncreaseSpeedStateChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public void SmokeButtonStateChanged(InteractableStateArgs obj)
|
||||
{
|
||||
if (obj.NewInteractableState == InteractableState.ActionState)
|
||||
{
|
||||
_locomotive.SmokeButtonStateChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public void WhistleButtonStateChanged(InteractableStateArgs obj)
|
||||
{
|
||||
if (obj.NewInteractableState == InteractableState.ActionState)
|
||||
{
|
||||
_locomotive.WhistleButtonStateChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public void ReverseButtonStateChanged(InteractableStateArgs obj)
|
||||
{
|
||||
if (obj.NewInteractableState == InteractableState.ActionState)
|
||||
{
|
||||
_locomotive.ReverseButtonStateChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public void SwitchVisualization(InteractableStateArgs obj)
|
||||
{
|
||||
if (obj.NewInteractableState == InteractableState.ActionState)
|
||||
{
|
||||
HandsManager.Instance.SwitchVisualization();
|
||||
}
|
||||
}
|
||||
|
||||
public void GoMoo(InteractableStateArgs obj)
|
||||
{
|
||||
if (obj.NewInteractableState == InteractableState.ActionState)
|
||||
{
|
||||
_cowController.GoMooCowGo();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 069b40e3538ec5846bcfdcd838058ca0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,38 +0,0 @@
|
||||
/************************************************************************************
|
||||
|
||||
See SampleFramework license.txt for license terms. Unless required by applicable law
|
||||
or agreed to in writing, the sample code is provided “AS IS” WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied. See the license for specific
|
||||
language governing permissions and limitations under the license.
|
||||
|
||||
************************************************************************************/
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEngine.Assertions;
|
||||
|
||||
namespace OculusSampleFramework
|
||||
{
|
||||
public class CowController : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private Animation _cowAnimation = null;
|
||||
[SerializeField] private AudioSource _mooCowAudioSource = null;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
Assert.IsNotNull(_cowAnimation);
|
||||
Assert.IsNotNull(_mooCowAudioSource);
|
||||
}
|
||||
|
||||
public void PlayMooSound()
|
||||
{
|
||||
_mooCowAudioSource.timeSamples = 0;
|
||||
_mooCowAudioSource.Play();
|
||||
}
|
||||
|
||||
public void GoMooCowGo()
|
||||
{
|
||||
_cowAnimation.Rewind();
|
||||
_cowAnimation.Play();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 68a26abcaa6c9634681e21c3d4eb1efe
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,62 +0,0 @@
|
||||
/************************************************************************************
|
||||
|
||||
Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved.
|
||||
|
||||
See SampleFramework license.txt for license terms. Unless required by applicable law
|
||||
or agreed to in writing, the sample code is provided “AS IS” WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied. See the license for specific
|
||||
language governing permissions and limitations under the license.
|
||||
|
||||
************************************************************************************/
|
||||
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Assertions;
|
||||
|
||||
public class HandsActiveChecker : MonoBehaviour
|
||||
{
|
||||
[SerializeField]
|
||||
private GameObject _notificationPrefab = null;
|
||||
|
||||
private GameObject _notification = null;
|
||||
private OVRCameraRig _cameraRig = null;
|
||||
private Transform _centerEye = null;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
Assert.IsNotNull(_notificationPrefab);
|
||||
_notification = Instantiate(_notificationPrefab);
|
||||
StartCoroutine(GetCenterEye());
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (OVRPlugin.GetHandTrackingEnabled())
|
||||
{
|
||||
_notification.SetActive(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
_notification.SetActive(true);
|
||||
if (_centerEye) {
|
||||
_notification.transform.position = _centerEye.position + _centerEye.forward * 0.5f;
|
||||
_notification.transform.rotation = _centerEye.rotation;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private IEnumerator GetCenterEye()
|
||||
{
|
||||
if ((_cameraRig = FindObjectOfType<OVRCameraRig>()) != null)
|
||||
{
|
||||
while (!_centerEye)
|
||||
{
|
||||
_centerEye = _cameraRig.centerEyeAnchor;
|
||||
yield return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8637f636fa870e644a30016d21a3ca03
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,87 +0,0 @@
|
||||
/************************************************************************************
|
||||
|
||||
Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved.
|
||||
|
||||
See SampleFramework license.txt for license terms. Unless required by applicable law
|
||||
or agreed to in writing, the sample code is provided “AS IS” WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied. See the license for specific
|
||||
language governing permissions and limitations under the license.
|
||||
|
||||
************************************************************************************/
|
||||
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
|
||||
namespace OculusSampleFramework
|
||||
{
|
||||
public class PanelHMDFollower : MonoBehaviour
|
||||
{
|
||||
private const float TOTAL_DURATION = 3.0f;
|
||||
private const float HMD_MOVEMENT_THRESHOLD = 0.3f;
|
||||
|
||||
[SerializeField] private float _maxDistance = 0.3f;
|
||||
[SerializeField] private float _minDistance = 0.05f;
|
||||
[SerializeField] private float _minZDistance = 0.05f;
|
||||
|
||||
private OVRCameraRig _cameraRig;
|
||||
private Vector3 _panelInitialPosition = Vector3.zero;
|
||||
private Coroutine _coroutine = null;
|
||||
private Vector3 _prevPos = Vector3.zero;
|
||||
private Vector3 _lastMovedToPos = Vector3.zero;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
_cameraRig = FindObjectOfType<OVRCameraRig>();
|
||||
_panelInitialPosition = transform.position;
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
var centerEyeAnchorPos = _cameraRig.centerEyeAnchor.position;
|
||||
var myPosition = transform.position;
|
||||
//Distance from centereye since last time we updated panel position.
|
||||
float distanceFromLastMovement = Vector3.Distance(centerEyeAnchorPos, _lastMovedToPos);
|
||||
float headMovementSpeed = (_cameraRig.centerEyeAnchor.position - _prevPos).magnitude / Time.deltaTime;
|
||||
var currDiffFromCenterEye = transform.position - centerEyeAnchorPos;
|
||||
var currDistanceFromCenterEye = currDiffFromCenterEye.magnitude;
|
||||
|
||||
|
||||
// 1) wait for center eye to stabilize after distance gets too large
|
||||
// 2) check if center eye is too close to panel
|
||||
// 3) check if depth isn't too close
|
||||
if (((distanceFromLastMovement > _maxDistance) || (_minZDistance > currDiffFromCenterEye.z) || (_minDistance > currDistanceFromCenterEye)) &&
|
||||
headMovementSpeed < HMD_MOVEMENT_THRESHOLD && _coroutine == null)
|
||||
{
|
||||
if (_coroutine == null)
|
||||
{
|
||||
_coroutine = StartCoroutine(LerpToHMD());
|
||||
}
|
||||
}
|
||||
|
||||
_prevPos = _cameraRig.centerEyeAnchor.position;
|
||||
}
|
||||
|
||||
private Vector3 CalculateIdealAnchorPosition()
|
||||
{
|
||||
return _cameraRig.centerEyeAnchor.position + _panelInitialPosition;
|
||||
}
|
||||
|
||||
private IEnumerator LerpToHMD()
|
||||
{
|
||||
Vector3 newPanelPosition = CalculateIdealAnchorPosition();
|
||||
_lastMovedToPos = _cameraRig.centerEyeAnchor.position;
|
||||
float startTime = Time.time;
|
||||
float endTime = Time.time + TOTAL_DURATION;
|
||||
|
||||
while (Time.time < endTime)
|
||||
{
|
||||
transform.position =
|
||||
Vector3.Lerp(transform.position, newPanelPosition, (Time.time - startTime) / TOTAL_DURATION);
|
||||
yield return null;
|
||||
}
|
||||
|
||||
transform.position = newPanelPosition;
|
||||
_coroutine = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 53159ccc00b5ed74b8e54ec5df70448f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,96 +0,0 @@
|
||||
/************************************************************************************
|
||||
|
||||
Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved.
|
||||
|
||||
See SampleFramework license.txt for license terms. Unless required by applicable law
|
||||
or agreed to in writing, the sample code is provided ?AS IS? WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied. See the license for specific
|
||||
language governing permissions and limitations under the license.
|
||||
|
||||
************************************************************************************/
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
namespace OculusSampleFramework
|
||||
{
|
||||
public class SelectionCylinder : MonoBehaviour
|
||||
{
|
||||
public enum SelectionState
|
||||
{
|
||||
Off = 0,
|
||||
Selected,
|
||||
Highlighted
|
||||
}
|
||||
|
||||
[SerializeField] private MeshRenderer _selectionMeshRenderer = null;
|
||||
|
||||
private static int _colorId = Shader.PropertyToID("_Color");
|
||||
private Material[] _selectionMaterials;
|
||||
private Color[] _defaultSelectionColors = null, _highlightColors = null;
|
||||
|
||||
private SelectionState _currSelectionState = SelectionState.Off;
|
||||
|
||||
public SelectionState CurrSelectionState
|
||||
{
|
||||
get { return _currSelectionState; }
|
||||
set
|
||||
{
|
||||
var oldState = _currSelectionState;
|
||||
_currSelectionState = value;
|
||||
|
||||
if (oldState != _currSelectionState)
|
||||
{
|
||||
if (_currSelectionState > SelectionState.Off)
|
||||
{
|
||||
_selectionMeshRenderer.enabled = true;
|
||||
AffectSelectionColor(_currSelectionState == SelectionState.Selected
|
||||
? _defaultSelectionColors
|
||||
: _highlightColors);
|
||||
}
|
||||
else
|
||||
{
|
||||
_selectionMeshRenderer.enabled = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
_selectionMaterials = _selectionMeshRenderer.materials;
|
||||
int numColors = _selectionMaterials.Length;
|
||||
_defaultSelectionColors = new Color[numColors];
|
||||
_highlightColors = new Color[numColors];
|
||||
for (int i = 0; i < numColors; i++)
|
||||
{
|
||||
_defaultSelectionColors[i] = _selectionMaterials[i].GetColor(_colorId);
|
||||
_highlightColors[i] = new Color(1.0f, 1.0f, 1.0f, _defaultSelectionColors[i].a);
|
||||
}
|
||||
|
||||
CurrSelectionState = SelectionState.Off;
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
if (_selectionMaterials != null)
|
||||
{
|
||||
foreach (var selectionMaterial in _selectionMaterials)
|
||||
{
|
||||
if (selectionMaterial != null)
|
||||
{
|
||||
Destroy(selectionMaterial);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void AffectSelectionColor(Color[] newColors)
|
||||
{
|
||||
int numColors = newColors.Length;
|
||||
for (int i = 0; i < numColors; i++)
|
||||
{
|
||||
_selectionMaterials[i].SetColor(_colorId, newColors[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6d778f6e8fb868247b9f0c8ef05dfe41
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,236 +0,0 @@
|
||||
/************************************************************************************
|
||||
|
||||
Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved.
|
||||
|
||||
See SampleFramework license.txt for license terms. Unless required by applicable law
|
||||
or agreed to in writing, the sample code is provided “AS IS” WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied. See the license for specific
|
||||
language governing permissions and limitations under the license.
|
||||
|
||||
************************************************************************************/
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEngine.Assertions;
|
||||
|
||||
namespace OculusSampleFramework
|
||||
{
|
||||
public class TrackSegment : MonoBehaviour
|
||||
{
|
||||
public enum SegmentType
|
||||
{
|
||||
Straight = 0,
|
||||
LeftTurn,
|
||||
RightTurn,
|
||||
Switch
|
||||
}
|
||||
|
||||
[SerializeField] private SegmentType _segmentType = SegmentType.Straight;
|
||||
[SerializeField] private MeshFilter _straight = null;
|
||||
[SerializeField] private MeshFilter _leftTurn = null;
|
||||
[SerializeField] private MeshFilter _rightTurn = null;
|
||||
private float _gridSize = 0.8f;
|
||||
private int _subDivCount = 20;
|
||||
private const float _originalGridSize = 0.8f;
|
||||
private const float _trackWidth = 0.15f;
|
||||
private GameObject _mesh = null;
|
||||
public float StartDistance { get; set; }
|
||||
|
||||
// create variables here to avoid realtime allocation
|
||||
private Pose _p1 = new Pose();
|
||||
private Pose _p2 = new Pose();
|
||||
|
||||
public float GridSize
|
||||
{
|
||||
get
|
||||
{
|
||||
return _gridSize;
|
||||
}
|
||||
private set
|
||||
{
|
||||
_gridSize = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int SubDivCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return _subDivCount;
|
||||
}
|
||||
set
|
||||
{
|
||||
_subDivCount = value;
|
||||
}
|
||||
}
|
||||
|
||||
public SegmentType Type
|
||||
{
|
||||
get
|
||||
{
|
||||
return _segmentType;
|
||||
}
|
||||
}
|
||||
|
||||
private Pose _endPose = new Pose();
|
||||
public Pose EndPose
|
||||
{
|
||||
get
|
||||
{
|
||||
UpdatePose(SegmentLength, _endPose);
|
||||
return _endPose;
|
||||
}
|
||||
}
|
||||
public float Radius
|
||||
{
|
||||
get
|
||||
{
|
||||
return 0.5f * GridSize;
|
||||
}
|
||||
}
|
||||
|
||||
public float setGridSize(float size)
|
||||
{
|
||||
GridSize = size;
|
||||
return GridSize / _originalGridSize;
|
||||
}
|
||||
|
||||
public float SegmentLength
|
||||
{
|
||||
get
|
||||
{
|
||||
switch (Type)
|
||||
{
|
||||
case SegmentType.Straight:
|
||||
return GridSize;
|
||||
case SegmentType.LeftTurn:
|
||||
case SegmentType.RightTurn:
|
||||
// return quarter of circumference.
|
||||
return 0.5f * Mathf.PI * Radius;
|
||||
}
|
||||
|
||||
return 1f;
|
||||
}
|
||||
}
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
Assert.IsNotNull(_straight);
|
||||
Assert.IsNotNull(_leftTurn);
|
||||
Assert.IsNotNull(_rightTurn);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates pose given distance into segment. While this mutates a value,
|
||||
/// it avoids generating a new object.
|
||||
/// </summary>
|
||||
public void UpdatePose(float distanceIntoSegment, Pose pose)
|
||||
{
|
||||
if (Type == SegmentType.Straight)
|
||||
{
|
||||
pose.Position = transform.position + distanceIntoSegment * transform.forward;
|
||||
pose.Rotation = transform.rotation;
|
||||
}
|
||||
else if (Type == SegmentType.LeftTurn)
|
||||
{
|
||||
float normalizedDistanceIntoSegment = distanceIntoSegment / SegmentLength;
|
||||
// the turn is 90 degrees, so find out how far we are into it
|
||||
float angle = 0.5f * Mathf.PI * normalizedDistanceIntoSegment;
|
||||
// unity is left handed so the rotations go the opposite directions in X for left turns --
|
||||
// invert that by subtracting by radius. also note the angle negation below
|
||||
Vector3 localPosition = new Vector3(Radius * Mathf.Cos(angle) - Radius, 0, Radius * Mathf.Sin(angle));
|
||||
Quaternion localRotation = Quaternion.Euler(0, -angle * Mathf.Rad2Deg, 0);
|
||||
pose.Position = transform.TransformPoint(localPosition);
|
||||
pose.Rotation = transform.rotation * localRotation;
|
||||
}
|
||||
else if (Type == SegmentType.RightTurn)
|
||||
{
|
||||
// when going to right, start from PI (180) and go toward 90
|
||||
float angle = Mathf.PI - 0.5f * Mathf.PI * distanceIntoSegment / SegmentLength;
|
||||
// going right means we start at radius distance away, and decrease toward zero
|
||||
Vector3 localPosition = new Vector3(Radius * Mathf.Cos(angle) + Radius, 0, Radius * Mathf.Sin(angle));
|
||||
Quaternion localRotation = Quaternion.Euler(0, (Mathf.PI - angle) * Mathf.Rad2Deg, 0);
|
||||
pose.Position = transform.TransformPoint(localPosition);
|
||||
pose.Rotation = transform.rotation * localRotation;
|
||||
}
|
||||
else
|
||||
{
|
||||
pose.Position = Vector3.zero;
|
||||
pose.Rotation = Quaternion.identity;
|
||||
}
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
// uncomment to debug the track path
|
||||
//DrawDebugLines();
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
Destroy(_mesh);
|
||||
}
|
||||
|
||||
private void DrawDebugLines()
|
||||
{
|
||||
for (int i = 1; i < SubDivCount + 1; i++)
|
||||
{
|
||||
float len = SegmentLength / SubDivCount;
|
||||
UpdatePose((i - 1) * len, _p1);
|
||||
UpdatePose(i * len, _p2);
|
||||
// right segment from p1 to p2
|
||||
var halfTrackWidth = 0.5f * _trackWidth;
|
||||
Debug.DrawLine(_p1.Position + halfTrackWidth * (_p1.Rotation * Vector3.right),
|
||||
_p2.Position + halfTrackWidth * (_p2.Rotation * Vector3.right));
|
||||
// left segment from p1 to p2
|
||||
Debug.DrawLine(_p1.Position - halfTrackWidth * (_p1.Rotation * Vector3.right),
|
||||
_p2.Position - halfTrackWidth * (_p2.Rotation * Vector3.right));
|
||||
}
|
||||
|
||||
// bottom bound
|
||||
Debug.DrawLine(transform.position - 0.5f * GridSize * transform.right,
|
||||
transform.position + 0.5f * GridSize * transform.right, Color.yellow);
|
||||
// left bound
|
||||
Debug.DrawLine(transform.position - 0.5f * GridSize * transform.right,
|
||||
transform.position - 0.5f * GridSize * transform.right + GridSize * transform.forward, Color.yellow);
|
||||
// right bound
|
||||
Debug.DrawLine(transform.position + 0.5f * GridSize * transform.right,
|
||||
transform.position + 0.5f * GridSize * transform.right + GridSize * transform.forward, Color.yellow);
|
||||
// top bound
|
||||
Debug.DrawLine(transform.position - 0.5f * GridSize * transform.right +
|
||||
GridSize * transform.forward, transform.position +
|
||||
0.5f * GridSize * transform.right + GridSize * transform.forward,
|
||||
Color.yellow);
|
||||
}
|
||||
|
||||
public void RegenerateTrackAndMesh()
|
||||
{
|
||||
if (transform.childCount > 0 && !_mesh)
|
||||
{
|
||||
_mesh = transform.GetChild(0).gameObject;
|
||||
}
|
||||
|
||||
if (_mesh)
|
||||
{
|
||||
DestroyImmediate(_mesh);
|
||||
}
|
||||
|
||||
if (_segmentType == SegmentType.LeftTurn)
|
||||
{
|
||||
_mesh = Instantiate(_leftTurn.gameObject);
|
||||
}
|
||||
else if (_segmentType == SegmentType.RightTurn)
|
||||
{
|
||||
_mesh = Instantiate(_rightTurn.gameObject);
|
||||
}
|
||||
else
|
||||
{
|
||||
_mesh = Instantiate(_straight.gameObject);
|
||||
}
|
||||
|
||||
_mesh.transform.SetParent(transform, false);
|
||||
_mesh.transform.position += GridSize / 2.0f * transform.forward;
|
||||
_mesh.transform.localScale = new Vector3(GridSize / _originalGridSize, GridSize / _originalGridSize,
|
||||
GridSize / _originalGridSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bda88dc9eddd741f78044258de538161
|
||||
timeCreated: 1568352043
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,191 +0,0 @@
|
||||
/************************************************************************************
|
||||
|
||||
Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved.
|
||||
|
||||
See SampleFramework license.txt for license terms. Unless required by applicable law
|
||||
or agreed to in writing, the sample code is provided “AS IS” WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied. See the license for specific
|
||||
language governing permissions and limitations under the license.
|
||||
|
||||
************************************************************************************/
|
||||
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Assertions;
|
||||
|
||||
namespace OculusSampleFramework
|
||||
{
|
||||
/// <summary>
|
||||
/// An example visual controller for a button intended for the train sample scene.
|
||||
/// </summary>
|
||||
public class TrainButtonVisualController : MonoBehaviour
|
||||
{
|
||||
private const float LERP_TO_OLD_POS_DURATION = 1.0f;
|
||||
private const float LOCAL_SIZE_HALVED = 0.5f;
|
||||
|
||||
[SerializeField] private MeshRenderer _meshRenderer = null;
|
||||
[SerializeField] private MeshRenderer _glowRenderer = null;
|
||||
[SerializeField] private ButtonController _buttonController = null;
|
||||
[SerializeField] private Color _buttonContactColor = new Color(0.51f, 0.78f, 0.92f, 1.0f);
|
||||
[SerializeField] private Color _buttonActionColor = new Color(0.24f, 0.72f, 0.98f, 1.0f);
|
||||
|
||||
[SerializeField] private AudioSource _audioSource = null;
|
||||
[SerializeField] private AudioClip _actionSoundEffect = null;
|
||||
|
||||
[SerializeField] private Transform _buttonContactTransform = null;
|
||||
[SerializeField] private float _contactMaxDisplacementDistance = 0.0141f;
|
||||
|
||||
private Material _buttonMaterial;
|
||||
private Color _buttonDefaultColor;
|
||||
private int _materialColorId;
|
||||
|
||||
private bool _buttonInContactOrActionStates = false;
|
||||
|
||||
private Coroutine _lerpToOldPositionCr = null;
|
||||
private Vector3 _oldPosition;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
Assert.IsNotNull(_meshRenderer);
|
||||
Assert.IsNotNull(_glowRenderer);
|
||||
Assert.IsNotNull(_buttonController);
|
||||
Assert.IsNotNull(_audioSource);
|
||||
Assert.IsNotNull(_actionSoundEffect);
|
||||
|
||||
Assert.IsNotNull(_buttonContactTransform);
|
||||
_materialColorId = Shader.PropertyToID("_Color");
|
||||
_buttonMaterial = _meshRenderer.material;
|
||||
_buttonDefaultColor = _buttonMaterial.GetColor(_materialColorId);
|
||||
|
||||
_oldPosition = transform.localPosition;
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
if (_buttonMaterial != null)
|
||||
{
|
||||
Destroy(_buttonMaterial);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
_buttonController.InteractableStateChanged.AddListener(InteractableStateChanged);
|
||||
_buttonController.ContactZoneEvent += ActionOrInContactZoneStayEvent;
|
||||
_buttonController.ActionZoneEvent += ActionOrInContactZoneStayEvent;
|
||||
_buttonInContactOrActionStates = false;
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
if (_buttonController != null)
|
||||
{
|
||||
_buttonController.InteractableStateChanged.RemoveListener(InteractableStateChanged);
|
||||
_buttonController.ContactZoneEvent -= ActionOrInContactZoneStayEvent;
|
||||
_buttonController.ActionZoneEvent -= ActionOrInContactZoneStayEvent;
|
||||
}
|
||||
}
|
||||
|
||||
private void ActionOrInContactZoneStayEvent(ColliderZoneArgs collisionArgs)
|
||||
{
|
||||
if (!_buttonInContactOrActionStates || collisionArgs.CollidingTool.IsFarFieldTool)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// calculate how much the button should be pushed inwards. based on contact zone.
|
||||
// assume collider is uniform 1x1x1 cube, and all scaling, etc is done on transform component
|
||||
// another way to test distances is to measure distance to plane that represents where
|
||||
// button translation must stop
|
||||
Vector3 buttonScale = _buttonContactTransform.localScale;
|
||||
Vector3 interactionPosition = collisionArgs.CollidingTool.InteractionPosition;
|
||||
Vector3 localSpacePosition = _buttonContactTransform.InverseTransformPoint(
|
||||
interactionPosition);
|
||||
// calculate offset in local space. so bias coordinates from 0.5,-0.5 to 0, -1.
|
||||
// 0 is no offset, 1.0 in local space is max offset pushing inwards
|
||||
Vector3 offsetVector = localSpacePosition - LOCAL_SIZE_HALVED * Vector3.one;
|
||||
// affect offset by button scale. only care about y (since y goes inwards)
|
||||
float scaledLocalSpaceOffset = offsetVector.y * buttonScale.y;
|
||||
|
||||
// restrict button movement. can only go so far in negative direction, and cannot
|
||||
// be positive (which would cause the button to "stick out")
|
||||
if (scaledLocalSpaceOffset > -_contactMaxDisplacementDistance && scaledLocalSpaceOffset
|
||||
<= 0.0f)
|
||||
{
|
||||
transform.localPosition = new Vector3(_oldPosition.x, _oldPosition.y +
|
||||
scaledLocalSpaceOffset, _oldPosition.z);
|
||||
}
|
||||
}
|
||||
|
||||
private void InteractableStateChanged(InteractableStateArgs obj)
|
||||
{
|
||||
_buttonInContactOrActionStates = false;
|
||||
_glowRenderer.gameObject.SetActive(obj.NewInteractableState >
|
||||
InteractableState.Default);
|
||||
switch (obj.NewInteractableState)
|
||||
{
|
||||
case InteractableState.ContactState:
|
||||
StopResetLerping();
|
||||
_buttonMaterial.SetColor(_materialColorId, _buttonContactColor);
|
||||
_buttonInContactOrActionStates = true;
|
||||
break;
|
||||
case InteractableState.ProximityState:
|
||||
_buttonMaterial.SetColor(_materialColorId, _buttonDefaultColor);
|
||||
LerpToOldPosition();
|
||||
break;
|
||||
case InteractableState.ActionState:
|
||||
StopResetLerping();
|
||||
_buttonMaterial.SetColor(_materialColorId, _buttonActionColor);
|
||||
PlaySound(_actionSoundEffect);
|
||||
_buttonInContactOrActionStates = true;
|
||||
break;
|
||||
default:
|
||||
_buttonMaterial.SetColor(_materialColorId, _buttonDefaultColor);
|
||||
LerpToOldPosition();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void PlaySound(AudioClip clip)
|
||||
{
|
||||
_audioSource.timeSamples = 0;
|
||||
_audioSource.clip = clip;
|
||||
_audioSource.Play();
|
||||
}
|
||||
|
||||
private void StopResetLerping()
|
||||
{
|
||||
if (_lerpToOldPositionCr != null)
|
||||
{
|
||||
StopCoroutine(_lerpToOldPositionCr);
|
||||
}
|
||||
}
|
||||
|
||||
private void LerpToOldPosition()
|
||||
{
|
||||
if ((transform.localPosition - _oldPosition).sqrMagnitude < Mathf.Epsilon)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
StopResetLerping();
|
||||
_lerpToOldPositionCr = StartCoroutine(ResetPosition());
|
||||
}
|
||||
|
||||
private IEnumerator ResetPosition()
|
||||
{
|
||||
var startTime = Time.time;
|
||||
var endTime = Time.time + LERP_TO_OLD_POS_DURATION;
|
||||
|
||||
while (Time.time < endTime)
|
||||
{
|
||||
transform.localPosition = Vector3.Lerp(transform.localPosition, _oldPosition,
|
||||
(Time.time - startTime) / LERP_TO_OLD_POS_DURATION);
|
||||
yield return null;
|
||||
}
|
||||
|
||||
transform.localPosition = _oldPosition;
|
||||
_lerpToOldPositionCr = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 605a8ce1870f78943ac552405ac9888b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,40 +0,0 @@
|
||||
/************************************************************************************
|
||||
|
||||
Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved.
|
||||
|
||||
See SampleFramework license.txt for license terms. Unless required by applicable law
|
||||
or agreed to in writing, the sample code is provided “AS IS” WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied. See the license for specific
|
||||
language governing permissions and limitations under the license.
|
||||
|
||||
************************************************************************************/
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEngine.Assertions;
|
||||
|
||||
namespace OculusSampleFramework
|
||||
{
|
||||
public class TrainCar : TrainCarBase
|
||||
{
|
||||
[SerializeField] private TrainCarBase _parentLocomotive = null;
|
||||
[SerializeField] protected float _distanceBehindParent = 0.1f;
|
||||
|
||||
public float DistanceBehindParentScaled
|
||||
{
|
||||
get { return scale * _distanceBehindParent; }
|
||||
}
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
Assert.IsNotNull(_parentLocomotive);
|
||||
}
|
||||
|
||||
public override void UpdatePosition()
|
||||
{
|
||||
Distance = _parentLocomotive.Distance - DistanceBehindParentScaled;
|
||||
UpdateCarPosition();
|
||||
RotateCarWheels();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: eb6cbb133f32d4c4092ba08e3b449db4
|
||||
timeCreated: 1568359591
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,92 +0,0 @@
|
||||
/************************************************************************************
|
||||
|
||||
Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved.
|
||||
|
||||
See SampleFramework license.txt for license terms. Unless required by applicable law
|
||||
or agreed to in writing, the sample code is provided “AS IS” WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied. See the license for specific
|
||||
language governing permissions and limitations under the license.
|
||||
|
||||
************************************************************************************/
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEngine.Assertions;
|
||||
|
||||
namespace OculusSampleFramework
|
||||
{
|
||||
public abstract class TrainCarBase : MonoBehaviour
|
||||
{
|
||||
private static Vector3 OFFSET = new Vector3(0f, 0.0195f, 0f);
|
||||
private const float WHEEL_RADIUS = 0.027f;
|
||||
private const float TWO_PI = Mathf.PI * 2.0f;
|
||||
|
||||
[SerializeField] protected Transform _frontWheels = null;
|
||||
[SerializeField] protected Transform _rearWheels = null;
|
||||
[SerializeField] protected TrainTrack _trainTrack = null;
|
||||
[SerializeField] protected Transform[] _individualWheels = null;
|
||||
|
||||
public float Distance { get; protected set; }
|
||||
protected float scale = 1.0f;
|
||||
|
||||
private Pose _frontPose = new Pose(), _rearPose = new Pose();
|
||||
|
||||
public float Scale
|
||||
{
|
||||
get { return scale; }
|
||||
set { scale = value; }
|
||||
}
|
||||
|
||||
protected virtual void Awake()
|
||||
{
|
||||
Assert.IsNotNull(_frontWheels);
|
||||
Assert.IsNotNull(_rearWheels);
|
||||
Assert.IsNotNull(_trainTrack);
|
||||
Assert.IsNotNull(_individualWheels);
|
||||
}
|
||||
|
||||
public void UpdatePose(float distance, TrainCarBase train, Pose pose)
|
||||
{
|
||||
// distance could be negative; add track length to it in case that happens
|
||||
distance = (train._trainTrack.TrackLength + distance) % train._trainTrack.TrackLength;
|
||||
if (distance < 0)
|
||||
{
|
||||
distance += train._trainTrack.TrackLength;
|
||||
}
|
||||
|
||||
var currentSegment = train._trainTrack.GetSegment(distance);
|
||||
var distanceInto = distance - currentSegment.StartDistance;
|
||||
|
||||
currentSegment.UpdatePose(distanceInto, pose);
|
||||
}
|
||||
|
||||
protected void UpdateCarPosition()
|
||||
{
|
||||
UpdatePose(Distance + _frontWheels.transform.localPosition.z * scale,
|
||||
this, _frontPose);
|
||||
UpdatePose(Distance + _rearWheels.transform.localPosition.z * scale,
|
||||
this, _rearPose);
|
||||
|
||||
var midPoint = 0.5f * (_frontPose.Position + _rearPose.Position);
|
||||
var carLookDirection = _frontPose.Position - _rearPose.Position;
|
||||
|
||||
transform.position = midPoint + OFFSET;
|
||||
transform.rotation = Quaternion.LookRotation(carLookDirection, transform.up);
|
||||
_frontWheels.transform.rotation = _frontPose.Rotation;
|
||||
_rearWheels.transform.rotation = _rearPose.Rotation;
|
||||
}
|
||||
|
||||
protected void RotateCarWheels()
|
||||
{
|
||||
// divide by radius to get angle
|
||||
float angleOfRot = (Distance / WHEEL_RADIUS) % TWO_PI;
|
||||
|
||||
foreach (var individualWheel in _individualWheels)
|
||||
{
|
||||
individualWheel.localRotation = Quaternion.AngleAxis(Mathf.Rad2Deg * angleOfRot,
|
||||
Vector3.right);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void UpdatePosition();
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8cdf7e059dbb0a74c8ac7af28555f169
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,149 +0,0 @@
|
||||
/************************************************************************************
|
||||
|
||||
Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved.
|
||||
|
||||
See SampleFramework license.txt for license terms. Unless required by applicable law
|
||||
or agreed to in writing, the sample code is provided “AS IS” WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied. See the license for specific
|
||||
language governing permissions and limitations under the license.
|
||||
|
||||
************************************************************************************/
|
||||
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Assertions;
|
||||
|
||||
namespace OculusSampleFramework
|
||||
{
|
||||
public class TrainCrossingController : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private AudioSource _audioSource = null;
|
||||
[SerializeField] private AudioClip[] _crossingSounds = null;
|
||||
[SerializeField] private MeshRenderer _lightSide1Renderer = null;
|
||||
[SerializeField] private MeshRenderer _lightSide2Renderer = null;
|
||||
[SerializeField] private SelectionCylinder _selectionCylinder = null;
|
||||
|
||||
private Material _lightsSide1Mat;
|
||||
private Material _lightsSide2Mat;
|
||||
private int _colorId = Shader.PropertyToID("_Color");
|
||||
|
||||
private Coroutine _xingAnimationCr = null;
|
||||
private InteractableTool _toolInteractingWithMe = null;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
Assert.IsNotNull(_audioSource);
|
||||
Assert.IsNotNull(_crossingSounds);
|
||||
Assert.IsNotNull(_lightSide1Renderer);
|
||||
Assert.IsNotNull(_lightSide2Renderer);
|
||||
Assert.IsNotNull(_selectionCylinder);
|
||||
|
||||
_lightsSide1Mat = _lightSide1Renderer.material;
|
||||
_lightsSide2Mat = _lightSide2Renderer.material;
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
if (_lightsSide1Mat != null)
|
||||
{
|
||||
Destroy(_lightsSide1Mat);
|
||||
}
|
||||
if (_lightsSide2Mat != null)
|
||||
{
|
||||
Destroy(_lightsSide2Mat);
|
||||
}
|
||||
}
|
||||
|
||||
public void CrossingButtonStateChanged(InteractableStateArgs obj)
|
||||
{
|
||||
bool inActionState = obj.NewInteractableState == InteractableState.ActionState;
|
||||
if (inActionState)
|
||||
{
|
||||
ActivateTrainCrossing();
|
||||
}
|
||||
|
||||
_toolInteractingWithMe = obj.NewInteractableState > InteractableState.Default ?
|
||||
obj.Tool : null;
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (_toolInteractingWithMe == null)
|
||||
{
|
||||
_selectionCylinder.CurrSelectionState = SelectionCylinder.SelectionState.Off;
|
||||
}
|
||||
else
|
||||
{
|
||||
_selectionCylinder.CurrSelectionState = (
|
||||
_toolInteractingWithMe.ToolInputState == ToolInputState.PrimaryInputDown ||
|
||||
_toolInteractingWithMe.ToolInputState == ToolInputState.PrimaryInputDownStay)
|
||||
? SelectionCylinder.SelectionState.Highlighted
|
||||
: SelectionCylinder.SelectionState.Selected;
|
||||
}
|
||||
}
|
||||
|
||||
private void ActivateTrainCrossing()
|
||||
{
|
||||
int maxSoundIndex = _crossingSounds.Length - 1;
|
||||
var audioClip = _crossingSounds[(int)(Random.value * maxSoundIndex)];
|
||||
_audioSource.clip = audioClip;
|
||||
_audioSource.timeSamples = 0;
|
||||
_audioSource.Play();
|
||||
if (_xingAnimationCr != null)
|
||||
{
|
||||
StopCoroutine(_xingAnimationCr);
|
||||
}
|
||||
_xingAnimationCr = StartCoroutine(AnimateCrossing(audioClip.length * 0.75f));
|
||||
}
|
||||
|
||||
private IEnumerator AnimateCrossing(float animationLength)
|
||||
{
|
||||
ToggleLightObjects(true);
|
||||
|
||||
float animationEndTime = Time.time + animationLength;
|
||||
|
||||
float lightBlinkDuration = animationLength * 0.1f;
|
||||
float lightBlinkStartTime = Time.time;
|
||||
float lightBlinkEndTime = Time.time + lightBlinkDuration;
|
||||
Material lightToBlinkOn = _lightsSide1Mat;
|
||||
Material lightToBlinkOff = _lightsSide2Mat;
|
||||
Color onColor = new Color(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
Color offColor = new Color(1.0f, 1.0f, 1.0f, 0.0f);
|
||||
|
||||
while (Time.time < animationEndTime)
|
||||
{
|
||||
float t = (Time.time - lightBlinkStartTime) / lightBlinkDuration;
|
||||
lightToBlinkOn.SetColor(_colorId, Color.Lerp(offColor, onColor, t));
|
||||
lightToBlinkOff.SetColor(_colorId, Color.Lerp(onColor, offColor, t));
|
||||
|
||||
// switch which lights blink on and off when time runs out
|
||||
if (Time.time > lightBlinkEndTime)
|
||||
{
|
||||
Material temp = lightToBlinkOn;
|
||||
lightToBlinkOn = lightToBlinkOff;
|
||||
lightToBlinkOff = temp;
|
||||
lightBlinkStartTime = Time.time;
|
||||
lightBlinkEndTime = Time.time + lightBlinkDuration;
|
||||
}
|
||||
|
||||
yield return null;
|
||||
}
|
||||
|
||||
ToggleLightObjects(false);
|
||||
}
|
||||
|
||||
private void AffectMaterials(Material[] materials, Color newColor)
|
||||
{
|
||||
foreach (var material in materials)
|
||||
{
|
||||
material.SetColor(_colorId, newColor);
|
||||
}
|
||||
}
|
||||
|
||||
private void ToggleLightObjects(bool enableState)
|
||||
{
|
||||
_lightSide1Renderer.gameObject.SetActive(enableState);
|
||||
_lightSide2Renderer.gameObject.SetActive(enableState);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2a7acab7bf364b344bf233c928f66c16
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,281 +0,0 @@
|
||||
/************************************************************************************
|
||||
|
||||
See SampleFramework license.txt for license terms. Unless required by applicable law
|
||||
or agreed to in writing, the sample code is provided “AS IS” WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied. See the license for specific
|
||||
language governing permissions and limitations under the license.
|
||||
|
||||
************************************************************************************/
|
||||
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Assertions;
|
||||
|
||||
namespace OculusSampleFramework
|
||||
{
|
||||
public class TrainLocomotive : TrainCarBase
|
||||
{
|
||||
private const float MIN_SPEED = 0.2f;
|
||||
private const float MAX_SPEED = 2.7f;
|
||||
private const float SMOKE_SPEED_MULTIPLIER = 8f;
|
||||
private const int MAX_PARTICLES_MULTIPLIER = 3;
|
||||
|
||||
private enum EngineSoundState
|
||||
{
|
||||
Start = 0,
|
||||
AccelerateOrSetProperSpeed,
|
||||
Stop
|
||||
};
|
||||
|
||||
[SerializeField]
|
||||
[Range(MIN_SPEED, MAX_SPEED)]
|
||||
protected float _initialSpeed = 0f;
|
||||
|
||||
[SerializeField] private GameObject _startStopButton = null;
|
||||
[SerializeField] private GameObject _decreaseSpeedButton = null;
|
||||
[SerializeField] private GameObject _increaseSpeedButton = null;
|
||||
[SerializeField] private GameObject _smokeButton = null;
|
||||
[SerializeField] private GameObject _whistleButton = null;
|
||||
[SerializeField] private GameObject _reverseButton = null;
|
||||
[SerializeField] private AudioSource _whistleAudioSource = null;
|
||||
[SerializeField] private AudioClip _whistleSound = null;
|
||||
[SerializeField] private AudioSource _engineAudioSource = null;
|
||||
[SerializeField] private AudioClip[] _accelerationSounds = null;
|
||||
[SerializeField] private AudioClip[] _decelerationSounds = null;
|
||||
[SerializeField] private AudioClip _startUpSound = null;
|
||||
|
||||
[SerializeField] private AudioSource _smokeStackAudioSource = null;
|
||||
[SerializeField] private AudioClip _smokeSound = null;
|
||||
|
||||
[SerializeField] private ParticleSystem _smoke1 = null;
|
||||
[SerializeField] private ParticleSystem _smoke2 = null;
|
||||
[SerializeField] private TrainCarBase[] _childCars = null;
|
||||
|
||||
private bool _isMoving = true;
|
||||
private bool _reverse = false;
|
||||
private float _currentSpeed, _speedDiv;
|
||||
|
||||
private float _standardRateOverTimeMultiplier;
|
||||
private int _standardMaxParticles;
|
||||
|
||||
private Coroutine _startStopTrainCr;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
Assert.IsNotNull(_startStopButton);
|
||||
Assert.IsNotNull(_decreaseSpeedButton);
|
||||
Assert.IsNotNull(_increaseSpeedButton);
|
||||
Assert.IsNotNull(_smokeButton);
|
||||
Assert.IsNotNull(_whistleButton);
|
||||
Assert.IsNotNull(_reverseButton);
|
||||
Assert.IsNotNull(_whistleAudioSource);
|
||||
Assert.IsNotNull(_whistleSound);
|
||||
Assert.IsNotNull(_smoke1);
|
||||
|
||||
Assert.IsNotNull(_engineAudioSource);
|
||||
Assert.IsNotNull(_accelerationSounds);
|
||||
Assert.IsNotNull(_decelerationSounds);
|
||||
Assert.IsNotNull(_startUpSound);
|
||||
|
||||
Assert.IsNotNull(_smokeStackAudioSource);
|
||||
Assert.IsNotNull(_smokeSound);
|
||||
|
||||
|
||||
_standardRateOverTimeMultiplier = _smoke1.emission.rateOverTimeMultiplier;
|
||||
_standardMaxParticles = _smoke1.main.maxParticles;
|
||||
|
||||
Distance = 0.0f;
|
||||
_speedDiv = (MAX_SPEED - MIN_SPEED) / _accelerationSounds.Length;
|
||||
_currentSpeed = _initialSpeed;
|
||||
UpdateCarPosition();
|
||||
|
||||
_smoke1.Stop();
|
||||
_startStopTrainCr = StartCoroutine(StartStopTrain(true));
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
UpdatePosition();
|
||||
}
|
||||
|
||||
public override void UpdatePosition()
|
||||
{
|
||||
if (!_isMoving)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_trainTrack != null)
|
||||
{
|
||||
UpdateDistance();
|
||||
UpdateCarPosition();
|
||||
RotateCarWheels();
|
||||
}
|
||||
|
||||
foreach (var trainCarBase in _childCars)
|
||||
{
|
||||
trainCarBase.UpdatePosition();
|
||||
}
|
||||
}
|
||||
|
||||
public void StartStopStateChanged()
|
||||
{
|
||||
if (_startStopTrainCr == null)
|
||||
{
|
||||
_startStopTrainCr = StartCoroutine(StartStopTrain(!_isMoving));
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerator StartStopTrain(bool startTrain)
|
||||
{
|
||||
float endSpeed = startTrain ? _initialSpeed : 0.0f;
|
||||
|
||||
var timePeriodForSpeedChange = 3.0f;
|
||||
if (startTrain)
|
||||
{
|
||||
_smoke1.Play();
|
||||
_isMoving = true;
|
||||
var emissionModule1 = _smoke1.emission;
|
||||
var mainModule = _smoke1.main;
|
||||
emissionModule1.rateOverTimeMultiplier = _standardRateOverTimeMultiplier;
|
||||
mainModule.maxParticles = _standardMaxParticles;
|
||||
timePeriodForSpeedChange = PlayEngineSound(EngineSoundState.Start);
|
||||
}
|
||||
else
|
||||
{
|
||||
timePeriodForSpeedChange = PlayEngineSound(EngineSoundState.Stop);
|
||||
}
|
||||
|
||||
// don't loop audio at first; only do when train continues movement below
|
||||
_engineAudioSource.loop = false;
|
||||
|
||||
// make time period a tad shorter so that if it's not looping, we don't
|
||||
// catch the beginning of the sound
|
||||
timePeriodForSpeedChange = timePeriodForSpeedChange * 0.9f;
|
||||
float startTime = Time.time;
|
||||
float endTime = Time.time + timePeriodForSpeedChange;
|
||||
float startSpeed = _currentSpeed;
|
||||
while (Time.time < endTime)
|
||||
{
|
||||
float t = (Time.time - startTime) / timePeriodForSpeedChange;
|
||||
_currentSpeed = startSpeed * (1.0f - t) + endSpeed * t;
|
||||
UpdateSmokeEmissionBasedOnSpeed();
|
||||
yield return null;
|
||||
}
|
||||
|
||||
_currentSpeed = endSpeed;
|
||||
_startStopTrainCr = null;
|
||||
_isMoving = startTrain;
|
||||
if (!_isMoving)
|
||||
{
|
||||
_smoke1.Stop();
|
||||
}
|
||||
else
|
||||
{
|
||||
_engineAudioSource.loop = true;
|
||||
PlayEngineSound(EngineSoundState.AccelerateOrSetProperSpeed);
|
||||
}
|
||||
}
|
||||
|
||||
private float PlayEngineSound(EngineSoundState engineSoundState)
|
||||
{
|
||||
AudioClip audioClip = null;
|
||||
|
||||
if (engineSoundState == EngineSoundState.Start)
|
||||
{
|
||||
audioClip = _startUpSound;
|
||||
}
|
||||
else
|
||||
{
|
||||
AudioClip[] audioClips = engineSoundState == EngineSoundState.AccelerateOrSetProperSpeed
|
||||
? _accelerationSounds
|
||||
: _decelerationSounds;
|
||||
int numSounds = audioClips.Length;
|
||||
int speedIndex = (int)Mathf.Round((_currentSpeed - MIN_SPEED) / _speedDiv);
|
||||
audioClip = audioClips[Mathf.Clamp(speedIndex, 0, numSounds - 1)];
|
||||
}
|
||||
|
||||
// if audio is already playing and we are playing the same track, don't interrupt it
|
||||
if (_engineAudioSource.clip == audioClip && _engineAudioSource.isPlaying &&
|
||||
engineSoundState == EngineSoundState.AccelerateOrSetProperSpeed)
|
||||
{
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
_engineAudioSource.clip = audioClip;
|
||||
_engineAudioSource.timeSamples = 0;
|
||||
_engineAudioSource.Play();
|
||||
|
||||
return audioClip.length;
|
||||
}
|
||||
|
||||
private void UpdateDistance()
|
||||
{
|
||||
var signedSpeed = _reverse ? -_currentSpeed : _currentSpeed;
|
||||
Distance = (Distance + signedSpeed * Time.deltaTime) % _trainTrack.TrackLength;
|
||||
}
|
||||
|
||||
public void DecreaseSpeedStateChanged()
|
||||
{
|
||||
if (_startStopTrainCr == null && _isMoving)
|
||||
{
|
||||
_currentSpeed = Mathf.Clamp(_currentSpeed - _speedDiv, MIN_SPEED, MAX_SPEED);
|
||||
UpdateSmokeEmissionBasedOnSpeed();
|
||||
PlayEngineSound(EngineSoundState.AccelerateOrSetProperSpeed);
|
||||
}
|
||||
}
|
||||
|
||||
public void IncreaseSpeedStateChanged()
|
||||
{
|
||||
if (_startStopTrainCr == null && _isMoving)
|
||||
{
|
||||
_currentSpeed = Mathf.Clamp(_currentSpeed + _speedDiv, MIN_SPEED, MAX_SPEED);
|
||||
UpdateSmokeEmissionBasedOnSpeed();
|
||||
PlayEngineSound(EngineSoundState.AccelerateOrSetProperSpeed);
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateSmokeEmissionBasedOnSpeed()
|
||||
{
|
||||
var emissionModule = _smoke1.emission;
|
||||
emissionModule.rateOverTimeMultiplier = GetCurrentSmokeEmission();
|
||||
var mainModule = _smoke1.main;
|
||||
mainModule.maxParticles = (int)Mathf.Lerp(_standardMaxParticles, _standardMaxParticles * MAX_PARTICLES_MULTIPLIER,
|
||||
_currentSpeed / (MAX_SPEED - MIN_SPEED));
|
||||
}
|
||||
|
||||
private float GetCurrentSmokeEmission()
|
||||
{
|
||||
return Mathf.Lerp(_standardRateOverTimeMultiplier, _standardRateOverTimeMultiplier * SMOKE_SPEED_MULTIPLIER,
|
||||
_currentSpeed / (MAX_SPEED - MIN_SPEED));
|
||||
}
|
||||
|
||||
public void SmokeButtonStateChanged()
|
||||
{
|
||||
if (_isMoving)
|
||||
{
|
||||
_smokeStackAudioSource.clip = _smokeSound;
|
||||
_smokeStackAudioSource.timeSamples = 0;
|
||||
_smokeStackAudioSource.Play();
|
||||
|
||||
_smoke2.time = 0.0f;
|
||||
_smoke2.Play();
|
||||
}
|
||||
}
|
||||
|
||||
public void WhistleButtonStateChanged()
|
||||
{
|
||||
if (_whistleSound != null)
|
||||
{
|
||||
_whistleAudioSource.clip = _whistleSound;
|
||||
_whistleAudioSource.timeSamples = 0;
|
||||
_whistleAudioSource.Play();
|
||||
}
|
||||
}
|
||||
|
||||
public void ReverseButtonStateChanged()
|
||||
{
|
||||
_reverse = !_reverse;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5433fd5e0ec48eb49bc3800898ea0f0c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,110 +0,0 @@
|
||||
/************************************************************************************
|
||||
|
||||
Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved.
|
||||
|
||||
See SampleFramework license.txt for license terms. Unless required by applicable law
|
||||
or agreed to in writing, the sample code is provided “AS IS” WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied. See the license for specific
|
||||
language governing permissions and limitations under the license.
|
||||
|
||||
************************************************************************************/
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEngine.Assertions;
|
||||
|
||||
namespace OculusSampleFramework
|
||||
{
|
||||
public class TrainTrack : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private float _gridSize = 0.5f;
|
||||
[SerializeField] private int _subDivCount = 20;
|
||||
[SerializeField] private Transform _segmentParent = null;
|
||||
[SerializeField] private Transform _trainParent = null;
|
||||
// regeneration is optional
|
||||
[SerializeField] private bool _regnerateTrackMeshOnAwake = false;
|
||||
|
||||
private float _trainLength = -1.0f;
|
||||
private TrackSegment[] _trackSegments = null;
|
||||
|
||||
public float TrackLength
|
||||
{
|
||||
get
|
||||
{
|
||||
return _trainLength;
|
||||
}
|
||||
private set
|
||||
{
|
||||
_trainLength = value;
|
||||
}
|
||||
}
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
Assert.IsNotNull(_segmentParent);
|
||||
Assert.IsNotNull(_trainParent);
|
||||
Regenerate();
|
||||
}
|
||||
|
||||
public TrackSegment GetSegment(float distance)
|
||||
{
|
||||
int childCount = _segmentParent.childCount;
|
||||
|
||||
for (int i = 0; i < childCount; i++)
|
||||
{
|
||||
var segment = _trackSegments[i];
|
||||
var nextSegment = _trackSegments[(i + 1) % childCount];
|
||||
if (distance >= segment.StartDistance && (distance < nextSegment.StartDistance || i == childCount - 1))
|
||||
{
|
||||
return segment;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void Regenerate()
|
||||
{
|
||||
_trackSegments = _segmentParent.GetComponentsInChildren<TrackSegment>();
|
||||
TrackLength = 0;
|
||||
int childCount = _segmentParent.childCount;
|
||||
TrackSegment lastSegment = null;
|
||||
|
||||
var ratio = 0.0f;
|
||||
for (int i = 0; i < childCount; i++)
|
||||
{
|
||||
var segment = _trackSegments[i];
|
||||
segment.SubDivCount = _subDivCount;
|
||||
ratio = segment.setGridSize(_gridSize);
|
||||
if (lastSegment != null)
|
||||
{
|
||||
var endPose = lastSegment.EndPose;
|
||||
segment.transform.position = endPose.Position;
|
||||
segment.transform.rotation = endPose.Rotation;
|
||||
segment.StartDistance = TrackLength;
|
||||
}
|
||||
|
||||
if (_regnerateTrackMeshOnAwake)
|
||||
{
|
||||
segment.RegenerateTrackAndMesh();
|
||||
}
|
||||
|
||||
TrackLength += segment.SegmentLength;
|
||||
lastSegment = segment;
|
||||
}
|
||||
|
||||
SetScale(ratio);
|
||||
}
|
||||
|
||||
private void SetScale(float ratio)
|
||||
{
|
||||
_trainParent.localScale = new Vector3(ratio, ratio, ratio);
|
||||
var cars = _trainParent.GetComponentsInChildren<TrainCar>();
|
||||
var locomotive = _trainParent.GetComponentInChildren<TrainLocomotive>();
|
||||
locomotive.Scale = ratio;
|
||||
foreach (var car in cars)
|
||||
{
|
||||
car.Scale = ratio;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ff89fc657eb094e5a8516b7747bfae69
|
||||
timeCreated: 1568354237
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,8 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5303b529ef89d3446b9dc9c6847d453b
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,33 +0,0 @@
|
||||
/************************************************************************************
|
||||
|
||||
Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved.
|
||||
|
||||
See SampleFramework license.txt for license terms. Unless required by applicable law
|
||||
or agreed to in writing, the sample code is provided “AS IS” WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied. See the license for specific
|
||||
language governing permissions and limitations under the license.
|
||||
|
||||
************************************************************************************/
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
namespace OculusSampleFramework
|
||||
{
|
||||
public class Pose
|
||||
{
|
||||
public Vector3 Position;
|
||||
public Quaternion Rotation;
|
||||
|
||||
public Pose()
|
||||
{
|
||||
Position = Vector3.zero;
|
||||
Rotation = Quaternion.identity;
|
||||
}
|
||||
|
||||
public Pose(Vector3 position, Quaternion rotation)
|
||||
{
|
||||
Position = position;
|
||||
Rotation = rotation;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 985a678dde6384652ad328432133e05c
|
||||
timeCreated: 1568352276
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,114 +0,0 @@
|
||||
/************************************************************************************
|
||||
|
||||
Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved.
|
||||
|
||||
See SampleFramework license.txt for license terms. Unless required by applicable law
|
||||
or agreed to in writing, the sample code is provided “AS IS” WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied. See the license for specific
|
||||
language governing permissions and limitations under the license.
|
||||
|
||||
************************************************************************************/
|
||||
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Assertions;
|
||||
|
||||
namespace OculusSampleFramework
|
||||
{
|
||||
public class WindmillBladesController : MonoBehaviour
|
||||
{
|
||||
private const float MAX_TIME = 1f;
|
||||
|
||||
[SerializeField] private AudioSource _audioSource = null;
|
||||
[SerializeField] private AudioClip _windMillRotationSound = null;
|
||||
[SerializeField] private AudioClip _windMillStartSound = null;
|
||||
[SerializeField] private AudioClip _windMillStopSound = null;
|
||||
|
||||
public bool IsMoving { get; private set; }
|
||||
|
||||
private float _currentSpeed = 0f;
|
||||
private Coroutine _lerpSpeedCoroutine;
|
||||
private Coroutine _audioChangeCr;
|
||||
private Quaternion _originalRotation;
|
||||
private float _rotAngle = 0.0f;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
Assert.IsNotNull(_audioSource);
|
||||
Assert.IsNotNull(_windMillRotationSound);
|
||||
Assert.IsNotNull(_windMillStartSound);
|
||||
Assert.IsNotNull(_windMillStopSound);
|
||||
|
||||
_originalRotation = transform.localRotation;
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
_rotAngle += _currentSpeed * Time.deltaTime;
|
||||
if (_rotAngle > 360.0f)
|
||||
{
|
||||
_rotAngle = 0.0f;
|
||||
}
|
||||
|
||||
transform.localRotation = _originalRotation * Quaternion.AngleAxis(_rotAngle, Vector3.forward);
|
||||
}
|
||||
|
||||
public void SetMoveState(bool newMoveState, float goalSpeed)
|
||||
{
|
||||
IsMoving = newMoveState;
|
||||
if (_lerpSpeedCoroutine != null)
|
||||
{
|
||||
StopCoroutine(_lerpSpeedCoroutine);
|
||||
}
|
||||
_lerpSpeedCoroutine = StartCoroutine(LerpToSpeed(goalSpeed));
|
||||
}
|
||||
|
||||
private IEnumerator LerpToSpeed(float goalSpeed)
|
||||
{
|
||||
var totalTime = 0f;
|
||||
var startSpeed = _currentSpeed;
|
||||
|
||||
if (_audioChangeCr != null)
|
||||
{
|
||||
StopCoroutine(_audioChangeCr);
|
||||
}
|
||||
|
||||
// start up
|
||||
if (IsMoving)
|
||||
{
|
||||
_audioChangeCr = StartCoroutine(PlaySoundDelayed(_windMillStartSound,
|
||||
_windMillRotationSound, _windMillStartSound.length * 0.95f));
|
||||
} // stop
|
||||
else
|
||||
{
|
||||
PlaySound(_windMillStopSound);
|
||||
}
|
||||
|
||||
var diffSpeeds = Mathf.Abs(_currentSpeed - goalSpeed);
|
||||
while (diffSpeeds > Mathf.Epsilon)
|
||||
{
|
||||
_currentSpeed = Mathf.Lerp(startSpeed, goalSpeed, totalTime / MAX_TIME);
|
||||
totalTime += Time.deltaTime;
|
||||
yield return null;
|
||||
diffSpeeds = Mathf.Abs(_currentSpeed - goalSpeed);
|
||||
}
|
||||
|
||||
_lerpSpeedCoroutine = null;
|
||||
}
|
||||
|
||||
private IEnumerator PlaySoundDelayed(AudioClip initial, AudioClip clip, float timeDelayAfterInitial)
|
||||
{
|
||||
PlaySound(initial, false);
|
||||
yield return new WaitForSeconds(timeDelayAfterInitial);
|
||||
PlaySound(clip, true);
|
||||
}
|
||||
|
||||
private void PlaySound(AudioClip clip, bool loop = false)
|
||||
{
|
||||
_audioSource.loop = loop;
|
||||
_audioSource.timeSamples = 0;
|
||||
_audioSource.clip = clip;
|
||||
_audioSource.Play();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5c4a207e5bbb3c044b6c3eb819981d8b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,84 +0,0 @@
|
||||
/************************************************************************************
|
||||
|
||||
Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved.
|
||||
|
||||
See SampleFramework license.txt for license terms. Unless required by applicable law
|
||||
or agreed to in writing, the sample code is provided “AS IS” WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied. See the license for specific
|
||||
language governing permissions and limitations under the license.
|
||||
|
||||
************************************************************************************/
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEngine.Assertions;
|
||||
|
||||
namespace OculusSampleFramework
|
||||
{
|
||||
public class WindmillController : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private GameObject _startStopButton = null;
|
||||
[SerializeField] float _maxSpeed = 10f;
|
||||
[SerializeField] private SelectionCylinder _selectionCylinder = null;
|
||||
|
||||
private WindmillBladesController _bladesRotation;
|
||||
private InteractableTool _toolInteractingWithMe = null;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
Assert.IsNotNull(_startStopButton);
|
||||
Assert.IsNotNull(_selectionCylinder);
|
||||
|
||||
_bladesRotation = GetComponentInChildren<WindmillBladesController>();
|
||||
|
||||
_bladesRotation.SetMoveState(true, _maxSpeed);
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
_startStopButton.GetComponent<Interactable>().InteractableStateChanged.AddListener(StartStopStateChanged);
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
if (_startStopButton != null)
|
||||
{
|
||||
_startStopButton.GetComponent<Interactable>().InteractableStateChanged.RemoveListener(StartStopStateChanged);
|
||||
}
|
||||
}
|
||||
|
||||
private void StartStopStateChanged(InteractableStateArgs obj)
|
||||
{
|
||||
bool inActionState = obj.NewInteractableState == InteractableState.ActionState;
|
||||
if (inActionState)
|
||||
{
|
||||
if (_bladesRotation.IsMoving)
|
||||
{
|
||||
_bladesRotation.SetMoveState(false, 0.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
_bladesRotation.SetMoveState(true, _maxSpeed);
|
||||
}
|
||||
}
|
||||
|
||||
_toolInteractingWithMe = obj.NewInteractableState > InteractableState.Default ?
|
||||
obj.Tool : null;
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (_toolInteractingWithMe == null)
|
||||
{
|
||||
_selectionCylinder.CurrSelectionState = SelectionCylinder.SelectionState.Off;
|
||||
}
|
||||
else
|
||||
{
|
||||
_selectionCylinder.CurrSelectionState = (
|
||||
_toolInteractingWithMe.ToolInputState == ToolInputState.PrimaryInputDown ||
|
||||
_toolInteractingWithMe.ToolInputState == ToolInputState.PrimaryInputDownStay)
|
||||
? SelectionCylinder.SelectionState.Highlighted
|
||||
: SelectionCylinder.SelectionState.Selected;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d8bfac2fa4b437b4e891bd82f393ff0f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user