deltavr multiplayer 2.0
This commit is contained in:
@@ -1,8 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0ea0fa8b0421d3b498cea1682e63e99c
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,43 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Audio
|
||||
{
|
||||
[CreateAssetMenu(menuName = "AudioClipGroup")]
|
||||
public class AudioClipGroup : ScriptableObject
|
||||
{
|
||||
[Range(0, 2)] public float volumeMin = 1;
|
||||
[Range(0, 2)] public float volumeMax = 1;
|
||||
[Range(0, 2)] public float pitchMin = 1;
|
||||
[Range(0, 2)] public float pitchMax = 1;
|
||||
|
||||
public float delay = 0.1f;
|
||||
public List<AudioClip> audioClips;
|
||||
|
||||
private float _timestamp;
|
||||
|
||||
public void OnEnable()
|
||||
{
|
||||
_timestamp = 0;
|
||||
}
|
||||
|
||||
public void Play()
|
||||
{
|
||||
if (AudioSourcePool.Instance == null) return;
|
||||
|
||||
Play(AudioSourcePool.Instance.GetAudioSource());
|
||||
}
|
||||
|
||||
public void Play(AudioSource source)
|
||||
{
|
||||
if (audioClips.Count <= 0) return;
|
||||
if (_timestamp > Time.time) return;
|
||||
_timestamp = Time.time + delay;
|
||||
|
||||
source.volume = Random.Range(volumeMin, volumeMax);
|
||||
source.pitch = Random.Range(pitchMin, pitchMax);
|
||||
source.clip = audioClips[Random.Range(0, audioClips.Count)];
|
||||
source.Play();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e4f2dd8befe0f4a48b0c418911ffa5c0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,34 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Audio
|
||||
{
|
||||
public class AudioSourcePool : MonoBehaviour
|
||||
{
|
||||
public static AudioSourcePool Instance;
|
||||
public AudioSource audioSourcePrefab;
|
||||
|
||||
private List<AudioSource> _audioSources;
|
||||
|
||||
public void Awake()
|
||||
{
|
||||
Instance = this;
|
||||
_audioSources = new List<AudioSource>();
|
||||
}
|
||||
|
||||
public AudioSource GetAudioSource()
|
||||
{
|
||||
foreach (AudioSource source in _audioSources)
|
||||
{
|
||||
if (!source.isPlaying)
|
||||
{
|
||||
return source;
|
||||
}
|
||||
}
|
||||
|
||||
AudioSource newSource = Instantiate(audioSourcePrefab, this.transform);
|
||||
_audioSources.Add(newSource);
|
||||
return newSource;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 20146867efb6b0c4ab2cf17e2d044c63
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,8 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 63448578dbbb7944ba1a093819bf4d4c
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,120 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using Photon.Pun;
|
||||
using Random = UnityEngine.Random;
|
||||
|
||||
namespace Bow
|
||||
{
|
||||
public class ArcheryRange : MonoBehaviourPunCallbacks
|
||||
{
|
||||
public TMP_Text highScoreText;
|
||||
public TMP_Text timeLeftText;
|
||||
public TMP_Text scoreText;
|
||||
|
||||
public Transform targetStartPosition;
|
||||
public Transform targetEndPosition;
|
||||
public GameObject targetPrefab;
|
||||
public StartTarget startTarget;
|
||||
|
||||
public Vector3 minRandomOffset = new Vector3(0f, -2f, -5f);
|
||||
public Vector3 maxRandomOffset = new Vector3(0f, 2f, 5f);
|
||||
public float roundLength = 60f;
|
||||
public float targetSpawnTime = 3f;
|
||||
|
||||
|
||||
private List<ArcheryTarget> _targets;
|
||||
private float _score;
|
||||
private float _maxScore;
|
||||
private float _roundEndTime;
|
||||
private float _nextTargetTime;
|
||||
private float _startEndDistance;
|
||||
private bool _roundActive;
|
||||
|
||||
// Start is called before the first frame update
|
||||
void Start()
|
||||
{
|
||||
highScoreText.text = "High Score: 0";
|
||||
_roundActive = false;
|
||||
_targets = new List<ArcheryTarget>();
|
||||
_score = 0;
|
||||
_maxScore = 0;
|
||||
_roundEndTime = 0f;
|
||||
_startEndDistance = Vector3.Distance(targetStartPosition.position, targetEndPosition.position);
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
if (!_roundActive) return;
|
||||
|
||||
if (Time.time >= _roundEndTime)
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
else
|
||||
{
|
||||
timeLeftText.text = $"Time Left: {Math.Ceiling((_roundEndTime - Time.time) % 60)}";
|
||||
if (Time.time >= _nextTargetTime)
|
||||
{
|
||||
_nextTargetTime = Time.time + targetSpawnTime;
|
||||
SpawnTarget();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SpawnTarget()
|
||||
{
|
||||
var randomPos = targetStartPosition.position + new Vector3(
|
||||
Random.Range(minRandomOffset.x, maxRandomOffset.x),
|
||||
(float) Math.Round(Random.Range(minRandomOffset.y, maxRandomOffset.y)),
|
||||
Random.Range(minRandomOffset.z, maxRandomOffset.z));
|
||||
|
||||
//var prefab = Instantiate(targetPrefab, randomPos, Quaternion.identity, null);
|
||||
var prefab = PhotonNetwork.Instantiate("TargetUFO_Network", randomPos, Quaternion.identity);
|
||||
|
||||
ArcheryTarget target = prefab.GetComponent<ArcheryTarget>();
|
||||
|
||||
target.endPosition = targetEndPosition.position;
|
||||
target.minRandomOffset = minRandomOffset;
|
||||
target.maxRandomOffset = maxRandomOffset;
|
||||
target.archeryRange = this;
|
||||
|
||||
_targets.Add(target);
|
||||
}
|
||||
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
foreach (var target in _targets.Where(target => target != null))
|
||||
{
|
||||
//Destroy(target.gameObject);
|
||||
PhotonNetwork.Destroy(target.gameObject.GetPhotonView());
|
||||
}
|
||||
|
||||
|
||||
_targets = new List<ArcheryTarget>();
|
||||
if (_maxScore < _score) _maxScore = _score;
|
||||
_score = 0;
|
||||
highScoreText.text = $"High Score: {_maxScore}";
|
||||
startTarget.ShowTarget();
|
||||
_roundActive = false;
|
||||
timeLeftText.text = "";
|
||||
}
|
||||
|
||||
public void StartRound()
|
||||
{
|
||||
_roundEndTime = Time.time + roundLength;
|
||||
_nextTargetTime = Time.time;
|
||||
_roundActive = true;
|
||||
}
|
||||
|
||||
public void AddScore(float distance)
|
||||
{
|
||||
_score += distance;
|
||||
scoreText.text = $"Score: {_score}";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 592ba278f86ebec478622d8cf05c309d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,79 +0,0 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using Photon.Pun;
|
||||
using Random = UnityEngine.Random;
|
||||
|
||||
namespace Bow
|
||||
{
|
||||
public class ArcheryTarget : MonoBehaviourPun
|
||||
{
|
||||
public GameObject pointsText;
|
||||
public Vector3 endPosition;
|
||||
public float forwardSpeed = 2f;
|
||||
public float sidewaysSpeed = 1f;
|
||||
public ArcheryRange archeryRange;
|
||||
|
||||
public Vector3 minRandomOffset = new Vector3();
|
||||
public Vector3 maxRandomOffset = new Vector3();
|
||||
|
||||
private bool _flipDirection;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
_flipDirection = Random.value > 0.5f;
|
||||
|
||||
var position = transform.position;
|
||||
|
||||
minRandomOffset.z += position.z;
|
||||
maxRandomOffset.z += position.z;
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
float step = forwardSpeed * Time.deltaTime;
|
||||
var position = transform.position;
|
||||
|
||||
if (Math.Abs(position.x - endPosition.x) < 0.1) Destroy(gameObject);
|
||||
|
||||
if (Math.Abs(position.z - maxRandomOffset.z) < 0.1)
|
||||
{
|
||||
_flipDirection = true;
|
||||
}
|
||||
|
||||
if (Math.Abs(position.z - minRandomOffset.z) < 0.1)
|
||||
{
|
||||
_flipDirection = false;
|
||||
}
|
||||
|
||||
float desiredZ = _flipDirection ? maxRandomOffset.z : minRandomOffset.z;
|
||||
|
||||
transform.position = Vector3.MoveTowards(position,
|
||||
new Vector3(endPosition.x, position.y, desiredZ), step);
|
||||
}
|
||||
|
||||
[PunRPC]
|
||||
public void OnArrowHitPun()
|
||||
{
|
||||
var position = transform.position;
|
||||
|
||||
float score = (float) Math.Round(Vector3.Distance(position, endPosition));
|
||||
archeryRange.AddScore(score);
|
||||
|
||||
GameObject prefab = Instantiate(pointsText, position, Quaternion.Euler(0, 90f, 0), null);
|
||||
PointsText target = prefab.GetComponent<PointsText>();
|
||||
|
||||
target.SetPoints(score);
|
||||
|
||||
}
|
||||
|
||||
public void OnArrowHit(Arrow arrow)
|
||||
{
|
||||
if (arrow == null) return;
|
||||
Destroy(arrow.gameObject);
|
||||
|
||||
photonView.RPC("OnArrowHitPun", RpcTarget.All);
|
||||
PhotonNetwork.Destroy(photonView);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3b311379c72a5ae4b8936e3b7283dd7a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,17 +0,0 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Bow
|
||||
{
|
||||
public class ArcheryTargetCollisionProxy : MonoBehaviour
|
||||
{
|
||||
public ArcheryTarget target;
|
||||
|
||||
public void OnArrowHit(Arrow arrow)
|
||||
{
|
||||
if (arrow == null) return;
|
||||
if (target == null) return;
|
||||
|
||||
target.OnArrowHit(arrow);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 73aeda0595622964483dee49ba435380
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,124 +0,0 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using Audio;
|
||||
using UnityEngine;
|
||||
using UnityEngine.XR.Interaction.Toolkit;
|
||||
|
||||
namespace Bow
|
||||
{
|
||||
public class Arrow : XRGrabInteractable
|
||||
{
|
||||
public AudioClipGroup hitSounds;
|
||||
|
||||
public float speed = 2000.0f;
|
||||
public Transform tip = null;
|
||||
|
||||
public float maxLifetimeAfterShot = 60f;
|
||||
|
||||
private bool _inAir = false;
|
||||
private Vector3 _lastPosition = Vector3.zero;
|
||||
|
||||
private Rigidbody _rigidbody = null;
|
||||
|
||||
private float _timeToDestroyOn;
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
_rigidbody = GetComponent<Rigidbody>();
|
||||
_timeToDestroyOn = float.MaxValue;
|
||||
}
|
||||
|
||||
private void FixedUpdate()
|
||||
{
|
||||
if (!_inAir) return;
|
||||
CheckForCollision();
|
||||
_lastPosition = tip.position;
|
||||
|
||||
if (_timeToDestroyOn <= Time.time)
|
||||
{
|
||||
Destroy(gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
private void CheckForCollision()
|
||||
{
|
||||
RaycastHit hit;
|
||||
if (Physics.Linecast(_lastPosition, tip.position, out hit, LayerMask.GetMask("Default"),
|
||||
QueryTriggerInteraction.Ignore))
|
||||
{
|
||||
hit.collider.gameObject.SendMessage("OnArrowHit", this,
|
||||
SendMessageOptions.DontRequireReceiver);
|
||||
Stop();
|
||||
hitSounds.Play();
|
||||
}
|
||||
}
|
||||
|
||||
private void Stop()
|
||||
{
|
||||
_inAir = false;
|
||||
SetPhysics(false);
|
||||
}
|
||||
|
||||
public void Release(float pullValue)
|
||||
{
|
||||
_inAir = true;
|
||||
SetPhysics(true);
|
||||
|
||||
MaskAndFire(pullValue);
|
||||
StartCoroutine(RotateWithVelocity());
|
||||
|
||||
_lastPosition = tip.position;
|
||||
}
|
||||
|
||||
private void SetPhysics(bool usePhysics)
|
||||
{
|
||||
_rigidbody.isKinematic = !usePhysics;
|
||||
_rigidbody.useGravity = usePhysics;
|
||||
}
|
||||
|
||||
private void MaskAndFire(float power)
|
||||
{
|
||||
colliders[0].enabled = false;
|
||||
interactionLayerMask = 1 << LayerMask.NameToLayer("IgnoreInteraction");
|
||||
|
||||
Vector3 force = transform.forward * (power * speed);
|
||||
|
||||
_rigidbody.AddForce(force);
|
||||
_timeToDestroyOn = Time.time + maxLifetimeAfterShot;
|
||||
}
|
||||
|
||||
private IEnumerator RotateWithVelocity()
|
||||
{
|
||||
yield return new WaitForFixedUpdate();
|
||||
|
||||
while (_inAir)
|
||||
{
|
||||
Quaternion newRotation = Quaternion.LookRotation(_rigidbody.velocity, transform.up);
|
||||
transform.rotation = newRotation;
|
||||
yield return null;
|
||||
}
|
||||
}
|
||||
|
||||
public new void OnSelectEntered(XRBaseInteractor interactor)
|
||||
{
|
||||
base.OnSelectEntered(interactor);
|
||||
}
|
||||
|
||||
public new void OnSelectExited(XRBaseInteractor interactor)
|
||||
{
|
||||
base.OnSelectExited(interactor);
|
||||
}
|
||||
|
||||
public new void OnSelectExiting(XRBaseInteractor interactor)
|
||||
{
|
||||
base.OnSelectExiting(interactor);
|
||||
}
|
||||
|
||||
protected override void OnDestroy()
|
||||
{
|
||||
base.OnDestroy();
|
||||
colliders.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4efde785f55475d4faf016df659306fa
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,124 +0,0 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using Audio;
|
||||
using UnityEngine;
|
||||
using UnityEngine.XR.Interaction.Toolkit;
|
||||
|
||||
namespace Bow
|
||||
{
|
||||
public class Arrow_Network : XRGrabInteractable
|
||||
{
|
||||
public AudioClipGroup hitSounds;
|
||||
|
||||
public float speed = 2000.0f;
|
||||
public Transform tip = null;
|
||||
|
||||
public float maxLifetimeAfterShot = 60f;
|
||||
|
||||
private bool _inAir = false;
|
||||
private Vector3 _lastPosition = Vector3.zero;
|
||||
|
||||
private Rigidbody _rigidbody = null;
|
||||
|
||||
private float _timeToDestroyOn;
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
_rigidbody = GetComponent<Rigidbody>();
|
||||
_timeToDestroyOn = float.MaxValue;
|
||||
}
|
||||
|
||||
private void FixedUpdate()
|
||||
{
|
||||
if (!_inAir) return;
|
||||
CheckForCollision();
|
||||
_lastPosition = tip.position;
|
||||
|
||||
if (_timeToDestroyOn <= Time.time)
|
||||
{
|
||||
Destroy(gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
private void CheckForCollision()
|
||||
{
|
||||
RaycastHit hit;
|
||||
if (Physics.Linecast(_lastPosition, tip.position, out hit, LayerMask.GetMask("Default"),
|
||||
QueryTriggerInteraction.Ignore))
|
||||
{
|
||||
hit.collider.gameObject.SendMessage("OnArrowHit", this,
|
||||
SendMessageOptions.DontRequireReceiver);
|
||||
Stop();
|
||||
hitSounds.Play();
|
||||
}
|
||||
}
|
||||
|
||||
private void Stop()
|
||||
{
|
||||
_inAir = false;
|
||||
SetPhysics(false);
|
||||
}
|
||||
|
||||
public void Release(float pullValue)
|
||||
{
|
||||
_inAir = true;
|
||||
SetPhysics(true);
|
||||
|
||||
MaskAndFire(pullValue);
|
||||
StartCoroutine(RotateWithVelocity());
|
||||
|
||||
_lastPosition = tip.position;
|
||||
}
|
||||
|
||||
private void SetPhysics(bool usePhysics)
|
||||
{
|
||||
_rigidbody.isKinematic = !usePhysics;
|
||||
_rigidbody.useGravity = usePhysics;
|
||||
}
|
||||
|
||||
private void MaskAndFire(float power)
|
||||
{
|
||||
colliders[0].enabled = false;
|
||||
interactionLayerMask = 1 << LayerMask.NameToLayer("IgnoreInteraction");
|
||||
|
||||
Vector3 force = transform.forward * (power * speed);
|
||||
|
||||
_rigidbody.AddForce(force);
|
||||
_timeToDestroyOn = Time.time + maxLifetimeAfterShot;
|
||||
}
|
||||
|
||||
private IEnumerator RotateWithVelocity()
|
||||
{
|
||||
yield return new WaitForFixedUpdate();
|
||||
|
||||
while (_inAir)
|
||||
{
|
||||
Quaternion newRotation = Quaternion.LookRotation(_rigidbody.velocity, transform.up);
|
||||
transform.rotation = newRotation;
|
||||
yield return null;
|
||||
}
|
||||
}
|
||||
|
||||
public new void OnSelectEntered(XRBaseInteractor interactor)
|
||||
{
|
||||
base.OnSelectEntered(interactor);
|
||||
}
|
||||
|
||||
public new void OnSelectExited(XRBaseInteractor interactor)
|
||||
{
|
||||
base.OnSelectExited(interactor);
|
||||
}
|
||||
|
||||
public new void OnSelectExiting(XRBaseInteractor interactor)
|
||||
{
|
||||
base.OnSelectExiting(interactor);
|
||||
}
|
||||
|
||||
protected override void OnDestroy()
|
||||
{
|
||||
base.OnDestroy();
|
||||
colliders.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3b7c8b14231b4ca409541c41bd62389b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,34 +0,0 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.XR.Interaction.Toolkit;
|
||||
|
||||
namespace Bow
|
||||
{
|
||||
public class Bow : XRGrabInteractable
|
||||
{
|
||||
private Animator _animator = null;
|
||||
private Puller _puller = null;
|
||||
private static readonly int Blend = Animator.StringToHash("Blend");
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
_animator = GetComponent<Animator>();
|
||||
_puller = GetComponentInChildren<Puller>();
|
||||
}
|
||||
|
||||
public override void ProcessInteractable(XRInteractionUpdateOrder.UpdatePhase updatePhase)
|
||||
{
|
||||
base.ProcessInteractable(updatePhase);
|
||||
|
||||
if (updatePhase != XRInteractionUpdateOrder.UpdatePhase.Dynamic) return;
|
||||
if (!isSelected) return;
|
||||
|
||||
AnimateBow(_puller.PullAmount);
|
||||
}
|
||||
|
||||
private void AnimateBow(float value)
|
||||
{
|
||||
_animator.SetFloat(Blend, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bed6d8822a925ec43a36f07d632808d7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,72 +0,0 @@
|
||||
using Audio;
|
||||
using UnityEngine.XR.Interaction.Toolkit;
|
||||
|
||||
namespace Bow
|
||||
{
|
||||
public class Notch : XRSocketInteractor
|
||||
{
|
||||
public AudioClipGroup nockSounds;
|
||||
public AudioClipGroup releaseSounds;
|
||||
|
||||
private Puller _puller = null;
|
||||
private Arrow _currentArrow = null;
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
_puller = GetComponent<Puller>();
|
||||
}
|
||||
|
||||
protected override void OnEnable()
|
||||
{
|
||||
base.OnEnable();
|
||||
_puller.onSelectExited.AddListener(TryToReleaseArrow);
|
||||
}
|
||||
|
||||
protected override void OnDisable()
|
||||
{
|
||||
base.OnDisable();
|
||||
_puller.onSelectExited.RemoveListener(TryToReleaseArrow);
|
||||
}
|
||||
|
||||
protected override void OnSelectEntered(XRBaseInteractable interactable)
|
||||
{
|
||||
base.OnSelectEntered(interactable);
|
||||
StoreArrow(interactable);
|
||||
}
|
||||
|
||||
private void StoreArrow(XRBaseInteractable interactable)
|
||||
{
|
||||
if (!(interactable is Arrow arrow)) return;
|
||||
|
||||
_currentArrow = arrow;
|
||||
nockSounds.Play();
|
||||
}
|
||||
|
||||
private void TryToReleaseArrow(XRBaseInteractor interactor)
|
||||
{
|
||||
if (!_currentArrow) return;
|
||||
|
||||
ForceDeselect();
|
||||
ReleaseArrow();
|
||||
}
|
||||
|
||||
private void ForceDeselect()
|
||||
{
|
||||
_currentArrow.OnSelectExiting(this);
|
||||
_currentArrow.OnSelectExited(this);
|
||||
base.OnSelectExiting(_currentArrow);
|
||||
base.OnSelectExited(_currentArrow);
|
||||
}
|
||||
|
||||
private void ReleaseArrow()
|
||||
{
|
||||
_currentArrow.Release(_puller.PullAmount);
|
||||
_currentArrow = null;
|
||||
releaseSounds.Play();
|
||||
}
|
||||
|
||||
public override XRBaseInteractable.MovementType? selectedInteractableMovementTypeOverride =>
|
||||
XRBaseInteractable.MovementType.Instantaneous;
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 477605e3da91f604aaf76799722140f9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,37 +0,0 @@
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Bow
|
||||
{
|
||||
public class PointsText : MonoBehaviour
|
||||
{
|
||||
public TMP_Text text;
|
||||
public float destroyTime = 2f;
|
||||
public float upSpeed = 2f;
|
||||
|
||||
private float _destroyOnTime;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
_destroyOnTime = Time.time + destroyTime;
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
if (_destroyOnTime <= Time.time)
|
||||
{
|
||||
Destroy(gameObject);
|
||||
}
|
||||
|
||||
float step = upSpeed * Time.deltaTime;
|
||||
var position = transform.position;
|
||||
transform.position = Vector3.MoveTowards(position,
|
||||
new Vector3(position.x, position.y + 1f, position.z), step);
|
||||
}
|
||||
|
||||
public void SetPoints(float points)
|
||||
{
|
||||
text.text = $"+{points}";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f90b4cb440f999542a12d794b33ef22f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,68 +0,0 @@
|
||||
using Audio;
|
||||
using UnityEngine;
|
||||
using UnityEngine.XR.Interaction.Toolkit;
|
||||
|
||||
namespace Bow
|
||||
{
|
||||
public class Puller : XRBaseInteractable
|
||||
{
|
||||
public float PullAmount { get; private set; } = 0.0f;
|
||||
public AudioClipGroup pullSounds;
|
||||
public AudioClipGroup maxPullSounds;
|
||||
|
||||
|
||||
public Transform start = null;
|
||||
public Transform end = null;
|
||||
|
||||
private XRBaseInteractor _pullingInteractor = null;
|
||||
|
||||
protected override void OnSelectEntered(XRBaseInteractor interactor)
|
||||
{
|
||||
base.OnSelectEntered(interactor);
|
||||
_pullingInteractor = interactor;
|
||||
}
|
||||
|
||||
protected override void OnSelectExited(XRBaseInteractor interactor)
|
||||
{
|
||||
base.OnSelectExited(interactor);
|
||||
_pullingInteractor = null;
|
||||
PullAmount = 0.0f;
|
||||
}
|
||||
|
||||
public override void ProcessInteractable(XRInteractionUpdateOrder.UpdatePhase updatePhase)
|
||||
{
|
||||
base.ProcessInteractable(updatePhase);
|
||||
|
||||
if (updatePhase != XRInteractionUpdateOrder.UpdatePhase.Dynamic) return;
|
||||
if (!isSelected) return;
|
||||
|
||||
Vector3 pullPosition = _pullingInteractor.transform.position;
|
||||
|
||||
float newPull = CalculatePull(pullPosition);
|
||||
if (PullAmount == 0 & newPull > 0)
|
||||
{
|
||||
pullSounds.Play();
|
||||
}
|
||||
|
||||
if (PullAmount < 0.98f & newPull >= 0.98f)
|
||||
{
|
||||
maxPullSounds.Play();
|
||||
}
|
||||
|
||||
PullAmount = newPull;
|
||||
}
|
||||
|
||||
private float CalculatePull(Vector3 pullPosition)
|
||||
{
|
||||
var startPosition = start.position;
|
||||
Vector3 pullDirection = pullPosition - startPosition;
|
||||
Vector3 targetDirection = end.position - startPosition;
|
||||
float maxLength = targetDirection.magnitude;
|
||||
|
||||
targetDirection.Normalize();
|
||||
float pullValue = Vector3.Dot(pullDirection, targetDirection) / maxLength;
|
||||
|
||||
return Mathf.Clamp(pullValue, 0, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d5bad711d8ab0cb4db20eab960967d66
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,51 +0,0 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.XR.Interaction.Toolkit;
|
||||
|
||||
namespace Bow
|
||||
{
|
||||
public class Quiver : XRSocketInteractor
|
||||
{
|
||||
public GameObject arrowPrefab = null;
|
||||
private Vector3 _attachOffset = Vector3.zero;
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
CreateAndSelectArrow();
|
||||
SetAttachOffset();
|
||||
}
|
||||
|
||||
protected override void OnSelectExited(XRBaseInteractable interactable)
|
||||
{
|
||||
base.OnSelectExited(interactable);
|
||||
CreateAndSelectArrow();
|
||||
}
|
||||
|
||||
private void CreateAndSelectArrow()
|
||||
{
|
||||
Arrow arrow = CreateArrow();
|
||||
interactionManager.ForceSelect(this, arrow);
|
||||
}
|
||||
|
||||
private Arrow CreateArrow()
|
||||
{
|
||||
var transform1 = transform;
|
||||
GameObject arrowObject = Instantiate(arrowPrefab, transform1.position - _attachOffset, transform1.rotation);
|
||||
return arrowObject.GetComponent<Arrow>();
|
||||
}
|
||||
|
||||
private void SelectArrow(Arrow arrow)
|
||||
{
|
||||
OnSelectEntered(arrow);
|
||||
arrow.OnSelectEntered(this);
|
||||
}
|
||||
|
||||
private void SetAttachOffset()
|
||||
{
|
||||
if (selectTarget is XRGrabInteractable interactable)
|
||||
{
|
||||
_attachOffset = interactable.attachTransform.localPosition;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8e5f8d9f9b7680c4ea92da637174b928
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,59 +0,0 @@
|
||||
using UnityEngine;
|
||||
using Photon.Pun;
|
||||
|
||||
namespace Bow
|
||||
{
|
||||
public class StartTarget : MonoBehaviourPun
|
||||
{
|
||||
public ArcheryRange archeryRange;
|
||||
public Canvas textCanvas;
|
||||
private MeshRenderer _meshRenderer;
|
||||
private BoxCollider _boxCollider;
|
||||
|
||||
// Start is called before the first frame update
|
||||
void Start()
|
||||
{
|
||||
_meshRenderer = GetComponent<MeshRenderer>();
|
||||
_boxCollider = GetComponent<BoxCollider>();
|
||||
}
|
||||
|
||||
|
||||
public void OnArrowHitPun()
|
||||
{
|
||||
HideTarget();
|
||||
archeryRange.StartRound();
|
||||
}
|
||||
[PunRPC]
|
||||
private void HideTargetPun()
|
||||
{
|
||||
_meshRenderer.enabled = false;
|
||||
_boxCollider.enabled = false;
|
||||
textCanvas.enabled = false;
|
||||
}
|
||||
[PunRPC]
|
||||
public void ShowTargetPun()
|
||||
{
|
||||
_meshRenderer.enabled = true;
|
||||
_boxCollider.enabled = true;
|
||||
textCanvas.enabled = true;
|
||||
}
|
||||
|
||||
public void OnArrowHit(Arrow arrow)
|
||||
{
|
||||
if (arrow == null) return;
|
||||
|
||||
Destroy(arrow.gameObject);
|
||||
OnArrowHitPun();
|
||||
}
|
||||
|
||||
private void HideTarget()
|
||||
{
|
||||
photonView.RPC("HideTargetPun", RpcTarget.AllBuffered);
|
||||
}
|
||||
|
||||
public void ShowTarget()
|
||||
{
|
||||
photonView.RPC("ShowTargetPun", RpcTarget.AllBuffered);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c25614c8b9ec3ef40963a7887bf26792
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,8 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 89d3a05ad04982945b581cb2b7146965
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,93 +0,0 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using Oculus.Platform.Models;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Assertions.Must;
|
||||
using Random = UnityEngine.Random;
|
||||
|
||||
namespace Breakout
|
||||
{
|
||||
public class BreakableCube : MonoBehaviour
|
||||
{
|
||||
public Vector3 speed;
|
||||
public bool spawnBall;
|
||||
public GameObject ballPrefab;
|
||||
public float fadeTime = 2f;
|
||||
|
||||
private bool _hasSpawnedBall;
|
||||
private static readonly int Dissolve = Shader.PropertyToID("Vector1_b97048ce40a9495091dbb3eb2c84769e"); // From Dissolve Shader Graph
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
Events.OnBreakoutEndGame += EventDestroyCube;
|
||||
Events.OnBreakoutSetSpeed += SetSpeed;
|
||||
_hasSpawnedBall = false;
|
||||
}
|
||||
|
||||
private void EventDestroyCube()
|
||||
{
|
||||
DestroyCube(false);
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
Events.OnBreakoutEndGame -= EventDestroyCube;
|
||||
Events.OnBreakoutSetSpeed -= SetSpeed;
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
transform.position += (speed * Time.deltaTime);
|
||||
}
|
||||
|
||||
private void OnCollisionEnter(Collision other)
|
||||
{
|
||||
BreakoutBall ball = other.gameObject.GetComponent<BreakoutBall>();
|
||||
|
||||
if (ball == null) return;
|
||||
DestroyCube(true);
|
||||
}
|
||||
|
||||
private void DestroyCube(bool allowBallSpawn)
|
||||
{
|
||||
|
||||
if (spawnBall & !_hasSpawnedBall & allowBallSpawn)
|
||||
{
|
||||
_hasSpawnedBall = true;
|
||||
var ball = Instantiate(ballPrefab, transform.position, Quaternion.identity, null);
|
||||
|
||||
ball.GetComponent<Rigidbody>().AddForce(
|
||||
new Vector3(
|
||||
Random.Range(-2.0f, 2.0f),
|
||||
Random.Range(-2.0f, 2.0f),
|
||||
Random.Range(-2.0f, 2.0f)
|
||||
));
|
||||
|
||||
Events.AddBalls();
|
||||
}
|
||||
|
||||
speed.x = 0;
|
||||
|
||||
StartCoroutine(FadeMaterial(GetComponent<MeshRenderer>().material, fadeTime));
|
||||
|
||||
//Destroy(gameObject, Time.maximumDeltaTime);
|
||||
}
|
||||
|
||||
private void SetSpeed(float newspeed)
|
||||
{
|
||||
speed.x = newspeed;
|
||||
}
|
||||
|
||||
private IEnumerator FadeMaterial(Material material, float fadeTime)
|
||||
{
|
||||
while (material.GetFloat(Dissolve) < 0.9)
|
||||
{
|
||||
var newDissolve = Mathf.MoveTowards(material.GetFloat(Dissolve), 1, fadeTime * Time.deltaTime);
|
||||
material.SetFloat(Dissolve, newDissolve);
|
||||
yield return null;
|
||||
}
|
||||
|
||||
Destroy(gameObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 937cad764c6bfd649a75d521269ae995
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,49 +0,0 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Breakout
|
||||
{
|
||||
public class BreakoutBall : MonoBehaviour
|
||||
{
|
||||
public float speed = 2f;
|
||||
private Rigidbody _rigidbody;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
Events.OnBreakoutEndGame += DestroyBall;
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
Events.OnBreakoutEndGame -= DestroyBall;
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
_rigidbody = GetComponent<Rigidbody>();
|
||||
}
|
||||
|
||||
void FixedUpdate()
|
||||
{
|
||||
// Fix velocity on X axis so ball is more predictable.
|
||||
var velocity = _rigidbody.velocity;
|
||||
velocity.x = Math.Sign(velocity.x) * speed;
|
||||
velocity = velocity.normalized * (speed * 1.5f);
|
||||
_rigidbody.velocity = velocity;
|
||||
}
|
||||
|
||||
private void DestroyBall()
|
||||
{
|
||||
Destroy(gameObject);
|
||||
}
|
||||
|
||||
private void OnCollisionEnter(Collision other)
|
||||
{
|
||||
KinematicSpeedTransfer kst = other.gameObject.GetComponent<KinematicSpeedTransfer>();
|
||||
|
||||
if (kst == null) return;
|
||||
|
||||
Events.BreakoutStartGame();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 83f379a702a6eff48b7a38d9e14b79af
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,132 +0,0 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using Breakout;
|
||||
using Unity.Mathematics;
|
||||
using UnityEngine;
|
||||
using Photon.Pun;
|
||||
using Random = UnityEngine.Random;
|
||||
|
||||
public class BreakoutManager : MonoBehaviourPunCallbacks
|
||||
{
|
||||
public GameObject defaultBreakablePrefab;
|
||||
public GameObject extraBallBreakablePrefab;
|
||||
|
||||
public GameObject startBallSpawnPoint;
|
||||
public GameObject ballPrefab;
|
||||
|
||||
public List<Transform> spawnPoints;
|
||||
|
||||
public float timeBetweenRows = 5f;
|
||||
public float startRowSpeed = 0.15f;
|
||||
//private float _speedIncreasePerRow = 0.01f;
|
||||
public float extraBallBreakableChance = 0.1f;
|
||||
|
||||
private float _nextRowTime;
|
||||
private float _currentRowSpeed;
|
||||
|
||||
private int _ballCount;
|
||||
|
||||
private bool _gameStarted;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
_gameStarted = false;
|
||||
_ballCount = 1;
|
||||
_nextRowTime = Time.time;
|
||||
_currentRowSpeed = startRowSpeed;
|
||||
|
||||
Events.OnBreakoutEndGame += EndGame;
|
||||
Events.OnBreakoutStartGame += StartGame;
|
||||
|
||||
Events.OnBreakoutReduceBalls += ReduceBalls;
|
||||
Events.OnBreakoutAddBalls += AddBalls;
|
||||
}
|
||||
|
||||
void OnDestroy()
|
||||
{
|
||||
Events.OnBreakoutEndGame -= EndGame;
|
||||
Events.OnBreakoutStartGame -= StartGame;
|
||||
|
||||
Events.OnBreakoutReduceBalls -= ReduceBalls;
|
||||
Events.OnBreakoutAddBalls -= AddBalls;
|
||||
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
if (!_gameStarted) return;
|
||||
|
||||
if (_nextRowTime < Time.time)
|
||||
{
|
||||
SpawnRow();
|
||||
}
|
||||
}
|
||||
|
||||
void StartGame()
|
||||
{
|
||||
if (_gameStarted) return;
|
||||
_gameStarted = true;
|
||||
_nextRowTime = Time.time;
|
||||
}
|
||||
|
||||
private void SpawnBall()
|
||||
{
|
||||
PhotonNetwork.Instantiate("Ball_Network", startBallSpawnPoint.transform.position, Quaternion.identity);
|
||||
//Instantiate(ballPrefab, startBallSpawnPoint.transform.position, Quaternion.identity, null);
|
||||
_ballCount += 1;
|
||||
}
|
||||
|
||||
void EndGame()
|
||||
{
|
||||
if (!_gameStarted) return;
|
||||
_gameStarted = false;
|
||||
|
||||
SpawnBall();
|
||||
_ballCount = 1;
|
||||
}
|
||||
|
||||
void SpawnRow()
|
||||
{
|
||||
_nextRowTime = Time.time + timeBetweenRows;
|
||||
//currentRowSpeed += speedIncreasePerRow;
|
||||
|
||||
foreach (var point in spawnPoints)
|
||||
{
|
||||
GameObject box;
|
||||
|
||||
if (Random.value <= extraBallBreakableChance)
|
||||
{
|
||||
box = PhotonNetwork.Instantiate("Breakable Cube Extra Ball_Network", point.position, Quaternion.identity);
|
||||
//box = Instantiate(extraBallBreakablePrefab, point.position, Quaternion.identity, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
box = PhotonNetwork.Instantiate("Breakable Cube_Network", point.position, Quaternion.identity);
|
||||
//box = Instantiate(defaultBreakablePrefab, point.position, Quaternion.identity, null);
|
||||
}
|
||||
|
||||
var cube = box.GetComponent<BreakableCube>();
|
||||
|
||||
cube.speed.x = _currentRowSpeed;
|
||||
}
|
||||
|
||||
Events.BreakoutSetSpeed(_currentRowSpeed);
|
||||
|
||||
}
|
||||
|
||||
void ReduceBalls()
|
||||
{
|
||||
_ballCount -= 1;
|
||||
|
||||
if (_ballCount <= 0)
|
||||
{
|
||||
Events.BreakoutEndGame();
|
||||
}
|
||||
}
|
||||
|
||||
void AddBalls()
|
||||
{
|
||||
_ballCount += 1;
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f772d08c29771b8478a4d0a9f4ba07eb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,16 +0,0 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Breakout;
|
||||
using UnityEngine;
|
||||
|
||||
public class DestroyBallForcefield : MonoBehaviour
|
||||
{
|
||||
private void OnCollisionEnter(Collision other)
|
||||
{
|
||||
BreakoutBall ball = other.gameObject.GetComponent<BreakoutBall>();
|
||||
|
||||
if (ball == null) return;
|
||||
Events.ReduceBalls();
|
||||
Destroy(ball.gameObject);
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9acb76ffa96cc784e9f873c1c22c695c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,17 +0,0 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Breakout
|
||||
{
|
||||
public class EndForcefield : MonoBehaviour
|
||||
{
|
||||
private void OnCollisionEnter(Collision other)
|
||||
{
|
||||
BreakableCube breakableCube = other.gameObject.GetComponent<BreakableCube>();
|
||||
|
||||
if (breakableCube != null)
|
||||
{
|
||||
Events.BreakoutEndGame();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9028d8e31a1966540aff16d72263c97d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,35 +0,0 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class KinematicSpeedTransfer : MonoBehaviour
|
||||
{
|
||||
public float amplification = 1f;
|
||||
|
||||
private Vector3 _oldPosition;
|
||||
private Vector3 _velocity;
|
||||
|
||||
// Start is called before the first frame update
|
||||
void Start()
|
||||
{
|
||||
_oldPosition = transform.position;
|
||||
_velocity = Vector3.zero;
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
Vector3 newPosition = transform.position;
|
||||
Vector3 posDiff = newPosition - _oldPosition;
|
||||
_velocity = posDiff / Time.deltaTime;
|
||||
_oldPosition = newPosition;
|
||||
}
|
||||
|
||||
private void OnCollisionEnter(Collision other)
|
||||
{
|
||||
if (other.rigidbody.isKinematic) return;
|
||||
|
||||
other.rigidbody.AddRelativeForce(_velocity * amplification, ForceMode.Impulse);
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ad1c1fb4f4c956040a341a0dbda221c7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,33 +0,0 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using Random = UnityEngine.Random;
|
||||
|
||||
public class OffsetOnDirectHit : MonoBehaviour
|
||||
{
|
||||
public float minAngle = 0;
|
||||
public float maxAngle = 20;
|
||||
|
||||
private Rigidbody _rigidbody;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
_rigidbody = new Rigidbody();
|
||||
}
|
||||
|
||||
private void OnCollisionEnter(Collision other)
|
||||
{
|
||||
Vector3 normal = other.contacts[0].normal;
|
||||
Vector3 velocity = _rigidbody.velocity;
|
||||
|
||||
// Get Angle
|
||||
float angle = Vector3.Angle(velocity, -normal);
|
||||
|
||||
if (angle > minAngle & angle < maxAngle)
|
||||
{
|
||||
// Add random torque to randomize direction
|
||||
_rigidbody.AddTorque(new Vector3(Random.Range(0, 1f), Random.Range(0, 1f), Random.Range(0, 1f)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d37534609f68e284b8080930a495d1f7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,20 +0,0 @@
|
||||
using System;
|
||||
|
||||
public static class Events
|
||||
{
|
||||
public static event Action OnBreakoutEndGame;
|
||||
public static void BreakoutEndGame() => OnBreakoutEndGame?.Invoke();
|
||||
public static event Action OnBreakoutStartGame;
|
||||
public static void BreakoutStartGame() => OnBreakoutStartGame?.Invoke();
|
||||
|
||||
public static event Action<float> OnBreakoutSetSpeed;
|
||||
public static void BreakoutSetSpeed(float speed) => OnBreakoutSetSpeed?.Invoke(speed);
|
||||
|
||||
public static event Action OnBreakoutReduceBalls;
|
||||
public static void ReduceBalls() => OnBreakoutReduceBalls?.Invoke();
|
||||
|
||||
public static event Action OnBreakoutAddBalls;
|
||||
public static void AddBalls() => OnBreakoutAddBalls?.Invoke();
|
||||
|
||||
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 477321c71b8018040b003b5fa6f17c34
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,44 +0,0 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class Poster : MonoBehaviour
|
||||
{
|
||||
// Start is called before the first frame update
|
||||
void Start()
|
||||
{
|
||||
Vector2[] uvSingleFace = {
|
||||
new Vector2(0, 0),
|
||||
new Vector2(1, 0),
|
||||
new Vector2(0, 1),
|
||||
new Vector2(1, 1),
|
||||
|
||||
new Vector2(-1, -1),
|
||||
new Vector2(-1, -1),
|
||||
new Vector2(-1, -1),
|
||||
new Vector2(-1, -1),
|
||||
|
||||
new Vector2(-1, -1),
|
||||
new Vector2(-1, -1),
|
||||
new Vector2(-1, -1),
|
||||
new Vector2(-1, -1),
|
||||
|
||||
new Vector2(-1, -1),
|
||||
new Vector2(-1, -1),
|
||||
new Vector2(-1, -1),
|
||||
new Vector2(-1, -1),
|
||||
|
||||
new Vector2(-1, -1),
|
||||
new Vector2(-1, -1),
|
||||
new Vector2(-1, -1),
|
||||
new Vector2(-1, -1),
|
||||
|
||||
new Vector2(-1, -1),
|
||||
new Vector2(-1, -1),
|
||||
new Vector2(-1, -1),
|
||||
new Vector2(-1, -1)
|
||||
};
|
||||
|
||||
GetComponent<MeshFilter>().mesh.uv = uvSingleFace;
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dac1c67daec8f264da85a77c48bf5f0d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1 +0,0 @@
|
||||
C# scripts, shaders etc go here.
|
||||
@@ -1,7 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b2eba341b0ca0ae49889cc9ba59875eb
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,8 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bd9f7a9938a4bf24a84872811c68d93f
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,22 +0,0 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class NavPoint : MonoBehaviour
|
||||
{
|
||||
public NavPoint previous;
|
||||
public NavPoint next;
|
||||
|
||||
public NavPoint GetNext()
|
||||
{
|
||||
return next;
|
||||
}
|
||||
|
||||
void OnDrawGizmos()
|
||||
{
|
||||
if (next == null) return;
|
||||
Gizmos.color = Color.yellow;
|
||||
Gizmos.DrawLine(transform.position, next.transform.position);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e665a34866aa84947a9189411e8b1f63
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,41 +0,0 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Unity.Mathematics;
|
||||
using UnityEngine;
|
||||
|
||||
public class NavPointFollower : MonoBehaviour
|
||||
{
|
||||
public NavPoint startNavPoint;
|
||||
public float rotationSpeed = 1f;
|
||||
public float speed = 1f;
|
||||
|
||||
private Rigidbody _rigidbody;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
_rigidbody = GetComponent<Rigidbody>();
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
var transform1 = transform;
|
||||
var position = transform1.position;
|
||||
_rigidbody.MovePosition(position + transform1.forward * (speed * Time.deltaTime));
|
||||
|
||||
var direction = (startNavPoint.transform.position - position).normalized;
|
||||
|
||||
direction.y = 0;
|
||||
|
||||
var lookRotation = Quaternion.LookRotation(direction);
|
||||
|
||||
transform.rotation = Quaternion.Slerp(transform.rotation, lookRotation, Time.deltaTime * rotationSpeed);
|
||||
|
||||
|
||||
if (Vector3.Distance(transform.position, startNavPoint.transform.position) < 0.3f)
|
||||
{
|
||||
startNavPoint = startNavPoint.GetNext();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5ce1c79856036c740b25a576b37e4476
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,32 +0,0 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class RGB : MonoBehaviour
|
||||
{
|
||||
public float colorChangeInterval = 2f;
|
||||
public float minColor = 0;
|
||||
public float maxColor = 100;
|
||||
private Light _light;
|
||||
|
||||
private float _nextColorChange;
|
||||
// Start is called before the first frame update
|
||||
void Start()
|
||||
{
|
||||
_light = GetComponent<Light>();
|
||||
_nextColorChange = Time.time;
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
if (!(_nextColorChange <= Time.time)) return;
|
||||
var r = Random.Range(minColor, maxColor);
|
||||
var g = Random.Range(minColor, maxColor);
|
||||
var b = Random.Range(minColor, maxColor);
|
||||
|
||||
_light.color = new Color(r, g, b);
|
||||
|
||||
_nextColorChange = Time.time + colorChangeInterval;
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a78c20c4f2fa24043a42f6640a85fb21
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,8 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 61a331e7954a1664098fa22a504a0384
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,626 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
using UnityEngine.XR.Interaction.Toolkit;
|
||||
using UnityEngine.InputSystem;
|
||||
using UnityEngine.Serialization;
|
||||
|
||||
/// <summary>
|
||||
/// Use this class to map input actions to each controller state (mode)
|
||||
/// and set up the transitions between controller states (modes).
|
||||
/// </summary>
|
||||
[AddComponentMenu("XR/Action Based Controller Manager")]
|
||||
[DefaultExecutionOrder(kControllerManagerUpdateOrder)]
|
||||
public class ActionBasedControllerManager : MonoBehaviour
|
||||
{
|
||||
public const int kControllerManagerUpdateOrder = 10;
|
||||
|
||||
public enum StateId
|
||||
{
|
||||
None,
|
||||
Select,
|
||||
Teleport,
|
||||
Interact,
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class StateEnterEvent : UnityEvent<StateId>
|
||||
{
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class StateUpdateEvent : UnityEvent
|
||||
{
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class StateExitEvent : UnityEvent<StateId>
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use this class to create a controller state and set up its enter, update, and exit events.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class ControllerState
|
||||
{
|
||||
[SerializeField]
|
||||
[Tooltip("Sets the controller state to be active. " +
|
||||
"For the default states, setting this value to true will automatically update their StateUpdateEvent.")]
|
||||
bool m_Enabled;
|
||||
|
||||
/// <summary>
|
||||
/// Sets the controller state to be active.
|
||||
/// For the default states, setting this value to true will automatically update their <see cref="StateUpdateEvent"/>.
|
||||
/// </summary>
|
||||
public bool enabled
|
||||
{
|
||||
get => m_Enabled;
|
||||
set => m_Enabled = value;
|
||||
}
|
||||
|
||||
[SerializeField] [HideInInspector] StateId m_Id;
|
||||
|
||||
/// <summary>
|
||||
/// Sets the identifier of the <see cref="ControllerState"/> from all the optional Controller States that the <see cref="ActionBasedControllerManager"/> holds.
|
||||
/// </summary>
|
||||
public StateId id
|
||||
{
|
||||
get => m_Id;
|
||||
set => m_Id = value;
|
||||
}
|
||||
|
||||
[SerializeField] StateEnterEvent m_OnEnter = new StateEnterEvent();
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="StateEnterEvent"/> that will be invoked when entering the controller state.
|
||||
/// </summary>
|
||||
public StateEnterEvent onEnter
|
||||
{
|
||||
get => m_OnEnter;
|
||||
set => m_OnEnter = value;
|
||||
}
|
||||
|
||||
[SerializeField] StateUpdateEvent m_OnUpdate = new StateUpdateEvent();
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="StateUpdateEvent"/> that will be invoked when updating the controller state.
|
||||
/// </summary>
|
||||
public StateUpdateEvent onUpdate
|
||||
{
|
||||
get => m_OnUpdate;
|
||||
set => m_OnUpdate = value;
|
||||
}
|
||||
|
||||
[SerializeField] StateExitEvent m_OnExit = new StateExitEvent();
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="StateExitEvent"/> that will be invoked when exiting the controller state.
|
||||
/// </summary>
|
||||
public StateExitEvent onExit
|
||||
{
|
||||
get => m_OnExit;
|
||||
set => m_OnExit = value;
|
||||
}
|
||||
|
||||
public ControllerState(StateId defaultId = StateId.None) => this.id = defaultId;
|
||||
}
|
||||
|
||||
[Space]
|
||||
[Header("Controller GameObjects")]
|
||||
[SerializeField, FormerlySerializedAs("m_BaseControllerGO")]
|
||||
[Tooltip(
|
||||
"The base controller GameObject, used for changing default settings on its components during state transitions.")]
|
||||
GameObject m_BaseControllerGameObject;
|
||||
|
||||
/// <summary>
|
||||
/// The base controller <see cref="GameObject"/>, used for changing default settings on its components during state transitions.
|
||||
/// </summary>
|
||||
public GameObject baseControllerGameObject
|
||||
{
|
||||
get => m_BaseControllerGameObject;
|
||||
set => m_BaseControllerGameObject = value;
|
||||
}
|
||||
|
||||
[SerializeField, FormerlySerializedAs("m_TeleportControllerGO")]
|
||||
[Tooltip(
|
||||
"The teleport controller GameObject, used for changing default settings on its components during state transitions.")]
|
||||
GameObject m_TeleportControllerGameObject;
|
||||
|
||||
/// <summary>
|
||||
/// The teleport controller <see cref="GameObject"/>, used for changing default settings on its components during state transitions.
|
||||
/// </summary>
|
||||
public GameObject teleportControllerGameObject
|
||||
{
|
||||
get => m_TeleportControllerGameObject;
|
||||
set => m_TeleportControllerGameObject = value;
|
||||
}
|
||||
|
||||
[Space]
|
||||
[Header("Controller Actions")]
|
||||
|
||||
// State transition actions
|
||||
[SerializeField]
|
||||
[Tooltip("The reference to the action of activating the teleport mode for this controller.")]
|
||||
InputActionReference m_TeleportModeActivate;
|
||||
|
||||
/// <summary>
|
||||
/// The reference to the action of activating the teleport mode for this controller."
|
||||
/// </summary>
|
||||
public InputActionReference teleportModeActivate
|
||||
{
|
||||
get => m_TeleportModeActivate;
|
||||
set => m_TeleportModeActivate = value;
|
||||
}
|
||||
|
||||
// State transition actions
|
||||
[SerializeField] [Tooltip("The reference to the action of listening to teleport actions.")]
|
||||
InputActionReference m_NagivationModifier;
|
||||
|
||||
/// <summary>
|
||||
/// The reference to the action of activating the teleport mode for this controller."
|
||||
/// </summary>
|
||||
public InputActionReference navigationModifier
|
||||
{
|
||||
get => m_NagivationModifier;
|
||||
set => m_NagivationModifier = value;
|
||||
}
|
||||
|
||||
|
||||
[SerializeField] [Tooltip("The reference to the action of canceling the teleport mode for this controller.")]
|
||||
InputActionReference m_TeleportModeCancel;
|
||||
|
||||
/// <summary>
|
||||
/// The reference to the action of canceling the teleport mode for this controller."
|
||||
/// </summary>
|
||||
public InputActionReference teleportModeCancel
|
||||
{
|
||||
get => m_TeleportModeCancel;
|
||||
set => m_TeleportModeCancel = value;
|
||||
}
|
||||
|
||||
// Character movement actions
|
||||
[SerializeField] [Tooltip("The reference to the action of turning the XR rig with this controller.")]
|
||||
InputActionReference m_Turn;
|
||||
|
||||
/// <summary>
|
||||
/// The reference to the action of turning the XR rig with this controller.
|
||||
/// </summary>
|
||||
public InputActionReference turn
|
||||
{
|
||||
get => m_Turn;
|
||||
set => m_Turn = value;
|
||||
}
|
||||
|
||||
[SerializeField] [Tooltip("The reference to the action of moving the XR rig with this controller.")]
|
||||
InputActionReference m_Move;
|
||||
|
||||
/// <summary>
|
||||
/// The reference to the action of moving the XR rig with this controller.
|
||||
/// </summary>
|
||||
public InputActionReference move
|
||||
{
|
||||
get => m_Move;
|
||||
set => m_Move = value;
|
||||
}
|
||||
|
||||
// Object control actions
|
||||
[SerializeField, FormerlySerializedAs("m_TranslateObject")]
|
||||
[Tooltip("The reference to the action of translating the selected object of this controller.")]
|
||||
InputActionReference m_TranslateAnchor;
|
||||
|
||||
/// <summary>
|
||||
/// The reference to the action of translating the selected object of this controller.
|
||||
/// </summary>
|
||||
public InputActionReference translateAnchor
|
||||
{
|
||||
get => m_TranslateAnchor;
|
||||
set => m_TranslateAnchor = value;
|
||||
}
|
||||
|
||||
[SerializeField, FormerlySerializedAs("m_RotateObject")]
|
||||
[Tooltip("The reference to the action of rotating the selected object of this controller.")]
|
||||
InputActionReference m_RotateAnchor;
|
||||
|
||||
/// <summary>
|
||||
/// The reference to the action of rotating the selected object of this controller.
|
||||
/// </summary>
|
||||
public InputActionReference rotateAnchor
|
||||
{
|
||||
get => m_RotateAnchor;
|
||||
set => m_RotateAnchor = value;
|
||||
}
|
||||
|
||||
[Space]
|
||||
[Header("Default States")]
|
||||
#pragma warning disable IDE0044 // Add readonly modifier -- readonly fields cannot be serialized by Unity
|
||||
[SerializeField]
|
||||
[Tooltip("The default Select state and events for the controller.")]
|
||||
ControllerState m_SelectState = new ControllerState(StateId.Select);
|
||||
|
||||
/// <summary>
|
||||
/// (Read Only) The default Select state.
|
||||
/// </summary>
|
||||
public ControllerState selectState => m_SelectState;
|
||||
|
||||
[SerializeField] [Tooltip("The default Teleport state and events for the controller.")]
|
||||
ControllerState m_TeleportState = new ControllerState(StateId.Teleport);
|
||||
|
||||
/// <summary>
|
||||
/// (Read Only) The default Teleport state.
|
||||
/// </summary>
|
||||
public ControllerState teleportState => m_TeleportState;
|
||||
|
||||
[SerializeField] [Tooltip("The default Interact state and events for the controller.")]
|
||||
ControllerState m_InteractState = new ControllerState(StateId.Interact);
|
||||
|
||||
/// <summary>
|
||||
/// (Read Only) The default Interact state.
|
||||
/// </summary>
|
||||
public ControllerState interactState => m_InteractState;
|
||||
#pragma warning restore IDE0044
|
||||
|
||||
// The list to store and run the default states
|
||||
readonly List<ControllerState> m_DefaultStates = new List<ControllerState>();
|
||||
|
||||
// Components of the controller to switch on and off for different states
|
||||
XRBaseController m_BaseController;
|
||||
XRBaseInteractor m_BaseInteractor;
|
||||
XRInteractorLineVisual m_BaseLineVisual;
|
||||
|
||||
XRBaseController m_TeleportController;
|
||||
XRBaseInteractor m_TeleportInteractor;
|
||||
XRInteractorLineVisual m_TeleportLineVisual;
|
||||
|
||||
protected void OnEnable()
|
||||
{
|
||||
FindBaseControllerComponents();
|
||||
FindTeleportControllerComponents();
|
||||
|
||||
// Add default state events.
|
||||
m_SelectState.onEnter.AddListener(OnEnterSelectState);
|
||||
m_SelectState.onUpdate.AddListener(OnUpdateSelectState);
|
||||
m_SelectState.onExit.AddListener(OnExitSelectState);
|
||||
|
||||
m_TeleportState.onEnter.AddListener(OnEnterTeleportState);
|
||||
m_TeleportState.onUpdate.AddListener(OnUpdateTeleportState);
|
||||
m_TeleportState.onExit.AddListener(OnExitTeleportState);
|
||||
|
||||
m_InteractState.onEnter.AddListener(OnEnterInteractState);
|
||||
m_InteractState.onUpdate.AddListener(OnUpdateInteractState);
|
||||
m_InteractState.onExit.AddListener(OnExitInteractState);
|
||||
}
|
||||
|
||||
protected void OnDisable()
|
||||
{
|
||||
// Remove default state events.
|
||||
m_SelectState.onEnter.RemoveListener(OnEnterSelectState);
|
||||
m_SelectState.onUpdate.RemoveListener(OnUpdateSelectState);
|
||||
m_SelectState.onExit.RemoveListener(OnExitSelectState);
|
||||
|
||||
m_TeleportState.onEnter.RemoveListener(OnEnterTeleportState);
|
||||
m_TeleportState.onUpdate.RemoveListener(OnUpdateTeleportState);
|
||||
m_TeleportState.onExit.RemoveListener(OnExitTeleportState);
|
||||
|
||||
m_InteractState.onEnter.RemoveListener(OnEnterInteractState);
|
||||
m_InteractState.onUpdate.RemoveListener(OnUpdateInteractState);
|
||||
m_InteractState.onExit.RemoveListener(OnExitInteractState);
|
||||
}
|
||||
|
||||
// Start is called before the first frame update
|
||||
protected void Start()
|
||||
{
|
||||
// Add states to the list
|
||||
m_DefaultStates.Add(m_SelectState);
|
||||
m_DefaultStates.Add(m_TeleportState);
|
||||
m_DefaultStates.Add(m_InteractState);
|
||||
|
||||
// Initialize to start in m_SelectState
|
||||
TransitionState(null, m_SelectState);
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
protected void Update()
|
||||
{
|
||||
foreach (var state in m_DefaultStates)
|
||||
{
|
||||
if (state.enabled)
|
||||
{
|
||||
state.onUpdate.Invoke();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TransitionState(ControllerState fromState, ControllerState toState)
|
||||
{
|
||||
if (fromState != null)
|
||||
{
|
||||
fromState.enabled = false;
|
||||
fromState.onExit.Invoke(toState?.id ?? StateId.None);
|
||||
}
|
||||
|
||||
if (toState != null)
|
||||
{
|
||||
toState.onEnter.Invoke(fromState?.id ?? StateId.None);
|
||||
toState.enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
void FindBaseControllerComponents()
|
||||
{
|
||||
if (m_BaseControllerGameObject == null)
|
||||
{
|
||||
Debug.LogWarning("Missing reference to Base Controller GameObject.", this);
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_BaseController == null)
|
||||
{
|
||||
m_BaseController = m_BaseControllerGameObject.GetComponent<XRBaseController>();
|
||||
if (m_BaseController == null)
|
||||
Debug.LogWarning(
|
||||
$"Cannot find any {nameof(XRBaseController)} component on the Base Controller GameObject.", this);
|
||||
}
|
||||
|
||||
if (m_BaseInteractor == null)
|
||||
{
|
||||
m_BaseInteractor = m_BaseControllerGameObject.GetComponent<XRBaseInteractor>();
|
||||
if (m_BaseInteractor == null)
|
||||
Debug.LogWarning(
|
||||
$"Cannot find any {nameof(XRBaseInteractor)} component on the Base Controller GameObject.", this);
|
||||
}
|
||||
|
||||
// Only check the line visual component for RayInteractor, since DirectInteractor does not use the line visual component
|
||||
if (m_BaseInteractor is XRRayInteractor && m_BaseLineVisual == null)
|
||||
{
|
||||
m_BaseLineVisual = m_BaseControllerGameObject.GetComponent<XRInteractorLineVisual>();
|
||||
if (m_BaseLineVisual == null)
|
||||
Debug.LogWarning(
|
||||
$"Cannot find any {nameof(XRInteractorLineVisual)} component on the Base Controller GameObject.",
|
||||
this);
|
||||
}
|
||||
}
|
||||
|
||||
void FindTeleportControllerComponents()
|
||||
{
|
||||
if (m_TeleportControllerGameObject == null)
|
||||
{
|
||||
Debug.LogWarning("Missing reference to the Teleport Controller GameObject.", this);
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_TeleportController == null)
|
||||
{
|
||||
m_TeleportController = m_TeleportControllerGameObject.GetComponent<XRBaseController>();
|
||||
if (m_TeleportController == null)
|
||||
Debug.LogWarning(
|
||||
$"Cannot find {nameof(XRBaseController)} component on the Teleport Controller GameObject.", this);
|
||||
}
|
||||
|
||||
if (m_TeleportLineVisual == null)
|
||||
{
|
||||
m_TeleportLineVisual = m_TeleportControllerGameObject.GetComponent<XRInteractorLineVisual>();
|
||||
if (m_TeleportLineVisual == null)
|
||||
Debug.LogWarning(
|
||||
$"Cannot find {nameof(XRInteractorLineVisual)} component on the Teleport Controller GameObject.",
|
||||
this);
|
||||
}
|
||||
|
||||
if (m_TeleportInteractor == null)
|
||||
{
|
||||
m_TeleportInteractor = m_TeleportControllerGameObject.GetComponent<XRRayInteractor>();
|
||||
if (m_TeleportInteractor == null)
|
||||
Debug.LogWarning(
|
||||
$"Cannot find {nameof(XRRayInteractor)} component on the Teleport Controller GameObject.", this);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Find and configure the components on the base controller.
|
||||
/// </summary>
|
||||
/// <param name="enable"> Set it true to enable the base controller, false to disable it. </param>
|
||||
void SetBaseController(bool enable)
|
||||
{
|
||||
FindBaseControllerComponents();
|
||||
|
||||
if (m_BaseController != null)
|
||||
m_BaseController.enableInputActions = enable;
|
||||
|
||||
if (m_BaseInteractor != null)
|
||||
m_BaseInteractor.enabled = enable;
|
||||
|
||||
if (m_BaseInteractor is XRRayInteractor && m_BaseLineVisual != null)
|
||||
m_BaseLineVisual.enabled = enable;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Find and configure the components on the teleport controller.
|
||||
/// </summary>
|
||||
/// <param name="enable"> Set it true to enable the teleport controller, false to disable it. </param>
|
||||
void SetTeleportController(bool enable)
|
||||
{
|
||||
FindTeleportControllerComponents();
|
||||
|
||||
if (m_TeleportLineVisual != null)
|
||||
m_TeleportLineVisual.enabled = enable;
|
||||
|
||||
if (m_TeleportController != null)
|
||||
m_TeleportController.enableInputActions = enable;
|
||||
|
||||
if (m_TeleportInteractor != null)
|
||||
m_TeleportInteractor.enabled = enable;
|
||||
}
|
||||
|
||||
void OnEnterSelectState(StateId previousStateId)
|
||||
{
|
||||
// Change controller and enable actions depending on the previous state
|
||||
switch (previousStateId)
|
||||
{
|
||||
case StateId.None:
|
||||
// Enable transitions to Teleport state
|
||||
EnableAction(m_TeleportModeActivate);
|
||||
EnableAction(m_TeleportModeCancel);
|
||||
EnableAction(m_NagivationModifier);
|
||||
|
||||
// Enable turn and move actions
|
||||
EnableAction(m_Turn);
|
||||
EnableAction(m_Move);
|
||||
|
||||
// Enable base controller components
|
||||
SetBaseController(true);
|
||||
break;
|
||||
case StateId.Select:
|
||||
break;
|
||||
case StateId.Teleport:
|
||||
EnableAction(m_Turn);
|
||||
EnableAction(m_Move);
|
||||
SetBaseController(true);
|
||||
break;
|
||||
case StateId.Interact:
|
||||
EnableAction(m_Turn);
|
||||
EnableAction(m_Move);
|
||||
break;
|
||||
default:
|
||||
Debug.Assert(false, $"Unhandled case when entering Select from {previousStateId}.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OnExitSelectState(StateId nextStateId)
|
||||
{
|
||||
// Change controller and disable actions depending on the next state
|
||||
switch (nextStateId)
|
||||
{
|
||||
case StateId.None:
|
||||
break;
|
||||
case StateId.Select:
|
||||
break;
|
||||
case StateId.Teleport:
|
||||
DisableAction(m_Turn);
|
||||
DisableAction(m_Move);
|
||||
SetBaseController(false);
|
||||
break;
|
||||
case StateId.Interact:
|
||||
DisableAction(m_Turn);
|
||||
DisableAction(m_Move);
|
||||
break;
|
||||
default:
|
||||
Debug.Assert(false, $"Unhandled case when exiting Select to {nextStateId}.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OnEnterTeleportState(StateId previousStateId) => SetTeleportController(true);
|
||||
|
||||
void OnExitTeleportState(StateId nextStateId) => SetTeleportController(false);
|
||||
|
||||
void OnEnterInteractState(StateId previousStateId)
|
||||
{
|
||||
// Enable object control actions
|
||||
EnableAction(m_TranslateAnchor);
|
||||
EnableAction(m_RotateAnchor);
|
||||
}
|
||||
|
||||
void OnExitInteractState(StateId nextStateId)
|
||||
{
|
||||
// Disable object control actions
|
||||
DisableAction(m_TranslateAnchor);
|
||||
DisableAction(m_RotateAnchor);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method is automatically called each frame to handle initiating transitions out of the Select state.
|
||||
/// </summary>
|
||||
void OnUpdateSelectState()
|
||||
{
|
||||
// Transition from Select state to Teleport state when the user triggers the "Teleport Mode Activate" action but not the "Cancel Teleport" action
|
||||
var teleportModeAction = GetInputAction(m_TeleportModeActivate);
|
||||
var cancelTeleportModeAction = GetInputAction(m_TeleportModeCancel);
|
||||
var allowNavigationAction = GetInputAction(m_NagivationModifier);
|
||||
|
||||
|
||||
var triggerTeleportMode = teleportModeAction != null && teleportModeAction.IsPressed();
|
||||
var cancelTeleport = cancelTeleportModeAction != null && cancelTeleportModeAction.IsPressed();
|
||||
var allowNavigation = allowNavigationAction != null && allowNavigationAction.IsPressed();
|
||||
|
||||
#region Check if teleport vector is north
|
||||
|
||||
Vector2 teleportAxis = teleportModeAction.ReadValue<Vector2>();
|
||||
bool isNorth = teleportAxis.y > 0.8;
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
if (triggerTeleportMode && !cancelTeleport && allowNavigation && isNorth)
|
||||
{
|
||||
TransitionState(m_SelectState, m_TeleportState);
|
||||
return;
|
||||
}
|
||||
|
||||
// Transition from Select state to Interact state when the interactor has a selectTarget
|
||||
FindBaseControllerComponents();
|
||||
|
||||
if (m_BaseInteractor.selectTarget != null)
|
||||
TransitionState(m_SelectState, m_InteractState);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updated every frame to handle the transition to m_SelectState state.
|
||||
/// </summary>
|
||||
void OnUpdateTeleportState()
|
||||
{
|
||||
// Transition from Teleport state to Select state when we release the Teleport trigger or cancel Teleport mode
|
||||
|
||||
var teleportModeAction = GetInputAction(m_TeleportModeActivate);
|
||||
var cancelTeleportModeAction = GetInputAction(m_TeleportModeCancel);
|
||||
var allowNavigationAction = GetInputAction(m_NagivationModifier);
|
||||
|
||||
var cancelTeleport = cancelTeleportModeAction != null && cancelTeleportModeAction.triggered;
|
||||
var releasedTeleport = teleportModeAction != null && teleportModeAction.phase == InputActionPhase.Waiting;
|
||||
var allowNavigation = allowNavigationAction != null && allowNavigationAction.IsPressed();
|
||||
|
||||
|
||||
if (cancelTeleport || releasedTeleport || !allowNavigation)
|
||||
{
|
||||
if (!cancelTeleport)
|
||||
{
|
||||
// Force teleportation
|
||||
XRRayInteractor interactor = m_TeleportControllerGameObject.GetComponent<XRRayInteractor>();
|
||||
if (interactor.selectTarget != null)
|
||||
interactor.interactionManager.ForceSelect(interactor, interactor.selectTarget);
|
||||
}
|
||||
|
||||
TransitionState(m_TeleportState, m_SelectState);
|
||||
}
|
||||
}
|
||||
|
||||
void OnUpdateInteractState()
|
||||
{
|
||||
// Transition from Interact state to Select state when the base interactor no longer has a select target
|
||||
if (m_BaseInteractor.selectTarget == null)
|
||||
TransitionState(m_InteractState, m_SelectState);
|
||||
}
|
||||
|
||||
static void EnableAction(InputActionReference actionReference)
|
||||
{
|
||||
var action = GetInputAction(actionReference);
|
||||
if (action != null && !action.enabled)
|
||||
action.Enable();
|
||||
}
|
||||
|
||||
static void DisableAction(InputActionReference actionReference)
|
||||
{
|
||||
var action = GetInputAction(actionReference);
|
||||
if (action != null && action.enabled)
|
||||
action.Disable();
|
||||
}
|
||||
|
||||
static InputAction GetInputAction(InputActionReference actionReference)
|
||||
{
|
||||
#pragma warning disable IDE0031 // Use null propagation -- Do not use for UnityEngine.Object types
|
||||
return actionReference != null ? actionReference.action : null;
|
||||
#pragma warning restore IDE0031
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 12033173ed091b74fa75a5170d257435
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,37 +0,0 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.InputSystem;
|
||||
using UnityEngine.XR.Interaction.Toolkit;
|
||||
using UnityEngine.XR.Interaction.Toolkit.Inputs;
|
||||
|
||||
public class CustomSnapTurnProvider : ActionBasedSnapTurnProvider
|
||||
{
|
||||
[SerializeField]
|
||||
[Tooltip("The Input System Action that will be used to read Snap Turn data from the left hand controller. Must be a Value Vector2 Control.")]
|
||||
InputActionProperty m_allowNavigation;
|
||||
/// <summary>
|
||||
/// The Input System Action that will be used to read Snap Turn data sent from the left hand controller. Must be a <see cref="InputActionType.Value"/> <see cref="Vector2Control"/> Control.
|
||||
/// </summary>
|
||||
public InputActionProperty allowNavigation
|
||||
{
|
||||
get => m_allowNavigation;
|
||||
set => SetInputActionProperty(ref m_allowNavigation, value);
|
||||
}
|
||||
|
||||
void SetInputActionProperty(ref InputActionProperty property, InputActionProperty value)
|
||||
{
|
||||
if (Application.isPlaying)
|
||||
property.DisableDirectAction();
|
||||
|
||||
property = value;
|
||||
|
||||
if (Application.isPlaying && isActiveAndEnabled)
|
||||
property.EnableDirectAction();
|
||||
}
|
||||
|
||||
protected override Vector2 ReadInput()
|
||||
{
|
||||
return m_allowNavigation.action.IsPressed() ? base.ReadInput() : Vector2.zero;
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c7e3391cd1a2c7e428f26aba850dd78f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,80 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.XR;
|
||||
|
||||
namespace UnityXR
|
||||
{
|
||||
public class HandPresence : MonoBehaviour
|
||||
{
|
||||
public bool showController = false;
|
||||
public InputDeviceCharacteristics controllerCharacteristics;
|
||||
public List<GameObject> controllerPrefabs;
|
||||
public GameObject handModelPrefab;
|
||||
|
||||
private InputDevice _targetDevice;
|
||||
private GameObject _spawnedController;
|
||||
private GameObject _spawnedHandModel;
|
||||
private Animator _handAnimator;
|
||||
|
||||
private static readonly int Trigger = Animator.StringToHash("Trigger");
|
||||
private static readonly int Grip = Animator.StringToHash("Grip");
|
||||
|
||||
private void TryInitialize()
|
||||
{
|
||||
var devices = new List<InputDevice>();
|
||||
InputDevices.GetDevicesWithCharacteristics(controllerCharacteristics, devices);
|
||||
if (devices.Count <= 0) return;
|
||||
|
||||
_targetDevice = devices[0];
|
||||
GameObject prefab = controllerPrefabs.Find(controller => controller.name == _targetDevice.name);
|
||||
_spawnedController = Instantiate(prefab ? prefab : controllerPrefabs[0], transform);
|
||||
|
||||
_spawnedHandModel = Instantiate(handModelPrefab, transform);
|
||||
_handAnimator = _spawnedHandModel.GetComponent<Animator>();
|
||||
}
|
||||
|
||||
private void UpdateHandAnimation()
|
||||
{
|
||||
if (_targetDevice.TryGetFeatureValue(CommonUsages.trigger, out float triggerValue))
|
||||
{
|
||||
_handAnimator.SetFloat(Trigger, triggerValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
_handAnimator.SetFloat(Trigger, 0);
|
||||
}
|
||||
|
||||
if (_targetDevice.TryGetFeatureValue(CommonUsages.grip, out float gripValue))
|
||||
{
|
||||
_handAnimator.SetFloat(Grip, gripValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
_handAnimator.SetFloat(Grip, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
if (!_targetDevice.isValid)
|
||||
{
|
||||
TryInitialize();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (showController)
|
||||
{
|
||||
_spawnedHandModel.SetActive(false);
|
||||
_spawnedController.SetActive(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
_spawnedHandModel.SetActive(true);
|
||||
_spawnedController.SetActive(false);
|
||||
UpdateHandAnimation();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: df6b462fef11acb4fb7d56a91c73b4b5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,18 +0,0 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.XR.Interaction.Toolkit;
|
||||
|
||||
namespace UnityXR
|
||||
{
|
||||
public class TeleportWorldArea : TeleportationArea
|
||||
{
|
||||
// Override the teleport request to use the world rotation and not our gameObject's transform
|
||||
protected override bool GenerateTeleportRequest(XRBaseInteractor interactor, RaycastHit raycastHit,
|
||||
ref TeleportRequest teleportRequest)
|
||||
{
|
||||
teleportRequest.destinationPosition = raycastHit.point;
|
||||
teleportRequest.matchOrientation = MatchOrientation.WorldSpaceUp; // use the area transform for data.
|
||||
teleportRequest.destinationRotation = Quaternion.identity;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9bc374ab13b4e224384b965358d295cb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,26 +0,0 @@
|
||||
using UnityEngine.XR.Interaction.Toolkit;
|
||||
|
||||
public class XRGrabVelocityTracked : XRGrabInteractable
|
||||
{
|
||||
protected override void OnSelectEntered(XRBaseInteractor interactor)
|
||||
{
|
||||
SetParentToXRRig();
|
||||
base.OnSelectEntered(interactor);
|
||||
}
|
||||
|
||||
protected override void OnSelectExited(XRBaseInteractor interactor)
|
||||
{
|
||||
SetParentToWorld();
|
||||
base.OnSelectExited(interactor);
|
||||
}
|
||||
|
||||
public void SetParentToXRRig()
|
||||
{
|
||||
transform.SetParent(selectingInteractor.transform);
|
||||
}
|
||||
|
||||
public void SetParentToWorld()
|
||||
{
|
||||
transform.SetParent(null);
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c96c5d5e9ecc35d4b8732d567d0c8458
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9be41c0129d74704ca81497976da049c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user