Remove useless files, add hands

This commit is contained in:
Toomas Tamm
2021-01-23 17:52:42 +02:00
parent 925d7f3b8a
commit 39ef3951cd
1378 changed files with 12541 additions and 195278 deletions

View File

@@ -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();
}
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 069b40e3538ec5846bcfdcd838058ca0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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();
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 68a26abcaa6c9634681e21c3d4eb1efe
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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;
}
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 8637f636fa870e644a30016d21a3ca03
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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;
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 53159ccc00b5ed74b8e54ec5df70448f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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]);
}
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 6d778f6e8fb868247b9f0c8ef05dfe41
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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);
}
}
}

View File

@@ -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:

View File

@@ -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;
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 605a8ce1870f78943ac552405ac9888b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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();
}
}
}

View File

@@ -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:

View File

@@ -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();
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 8cdf7e059dbb0a74c8ac7af28555f169
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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);
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 2a7acab7bf364b344bf233c928f66c16
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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;
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 5433fd5e0ec48eb49bc3800898ea0f0c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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;
}
}
}
}

View File

@@ -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:

View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 5303b529ef89d3446b9dc9c6847d453b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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;
}
}
}

View File

@@ -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:

View File

@@ -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();
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 5c4a207e5bbb3c044b6c3eb819981d8b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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;
}
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: d8bfac2fa4b437b4e891bd82f393ff0f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: