Add bow and arrow
This commit is contained in:
8
Assets/Scripts/Bow.meta
Normal file
8
Assets/Scripts/Bow.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 63448578dbbb7944ba1a093819bf4d4c
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
102
Assets/Scripts/Bow/Arrow.cs
Normal file
102
Assets/Scripts/Bow/Arrow.cs
Normal file
@@ -0,0 +1,102 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
using UnityEngine.XR.Interaction.Toolkit;
|
||||
|
||||
namespace Bow
|
||||
{
|
||||
public class Arrow : XRGrabInteractable
|
||||
{
|
||||
public float speed = 2000.0f;
|
||||
public Transform tip = null;
|
||||
|
||||
private bool _inAir = false;
|
||||
private Vector3 _lastPosition = Vector3.zero;
|
||||
|
||||
private Rigidbody _rigidbody = null;
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
_rigidbody = GetComponent<Rigidbody>();
|
||||
}
|
||||
|
||||
private void FixedUpdate()
|
||||
{
|
||||
if (!_inAir) return;
|
||||
CheckForCollision();
|
||||
_lastPosition = tip.position;
|
||||
}
|
||||
|
||||
private void CheckForCollision()
|
||||
{
|
||||
RaycastHit hit;
|
||||
if (Physics.Linecast(_lastPosition, tip.position, out hit, LayerMask.GetMask("Default"),
|
||||
QueryTriggerInteraction.Ignore))
|
||||
{
|
||||
Stop();
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/Bow/Arrow.cs.meta
Normal file
11
Assets/Scripts/Bow/Arrow.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4efde785f55475d4faf016df659306fa
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
34
Assets/Scripts/Bow/Bow.cs
Normal file
34
Assets/Scripts/Bow/Bow.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/Bow/Bow.cs.meta
Normal file
11
Assets/Scripts/Bow/Bow.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bed6d8822a925ec43a36f07d632808d7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
69
Assets/Scripts/Bow/Notch.cs
Normal file
69
Assets/Scripts/Bow/Notch.cs
Normal file
@@ -0,0 +1,69 @@
|
||||
using UnityEngine.XR.Interaction.Toolkit;
|
||||
|
||||
namespace Bow
|
||||
{
|
||||
public class Notch : XRSocketInteractor
|
||||
{
|
||||
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)
|
||||
{
|
||||
_currentArrow = arrow;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
public override XRBaseInteractable.MovementType? selectedInteractableMovementTypeOverride =>
|
||||
XRBaseInteractable.MovementType.Instantaneous;
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/Bow/Notch.cs.meta
Normal file
11
Assets/Scripts/Bow/Notch.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 477605e3da91f604aaf76799722140f9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
52
Assets/Scripts/Bow/Puller.cs
Normal file
52
Assets/Scripts/Bow/Puller.cs
Normal file
@@ -0,0 +1,52 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.XR.Interaction.Toolkit;
|
||||
|
||||
namespace Bow
|
||||
{
|
||||
public class Puller : XRBaseInteractable
|
||||
{
|
||||
public float PullAmount { get; private set; } = 0.0f;
|
||||
|
||||
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;
|
||||
PullAmount = CalculatePull(pullPosition);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/Bow/Puller.cs.meta
Normal file
11
Assets/Scripts/Bow/Puller.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d5bad711d8ab0cb4db20eab960967d66
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
51
Assets/Scripts/Bow/Quiver.cs
Normal file
51
Assets/Scripts/Bow/Quiver.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/Bow/Quiver.cs.meta
Normal file
11
Assets/Scripts/Bow/Quiver.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8e5f8d9f9b7680c4ea92da637174b928
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user