forked from cgvr/DeltaVR
deltavr multiplayer 2.0
This commit is contained in:
8
Assets/_PROJECT/Components/Bow/Scripts.meta
Normal file
8
Assets/_PROJECT/Components/Bow/Scripts.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 63448578dbbb7944ba1a093819bf4d4c
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
143
Assets/_PROJECT/Components/Bow/Scripts/ArcheryRange.cs
Normal file
143
Assets/_PROJECT/Components/Bow/Scripts/ArcheryRange.cs
Normal file
@@ -0,0 +1,143 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using _PROJECT.Scripts.Bow;
|
||||
using FishNet.Object;
|
||||
using FishNet.Object.Synchronizing;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using Random = UnityEngine.Random;
|
||||
|
||||
public class ArcheryRange : NetworkBehaviour
|
||||
{
|
||||
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;
|
||||
|
||||
[SyncVar]
|
||||
private float _score;
|
||||
private float _maxScore;
|
||||
private float _roundEndTime;
|
||||
private float _nextTargetTime;
|
||||
private bool _roundActive;
|
||||
|
||||
public override void OnStartServer()
|
||||
{
|
||||
base.OnStartServer();
|
||||
_roundActive = false;
|
||||
_targets = new List<ArcheryTarget>();
|
||||
_score = 0;
|
||||
_maxScore = 0;
|
||||
_roundEndTime = 0f;
|
||||
SetHighScoreText("High Score: 0");
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
if (!IsServer) return;
|
||||
|
||||
if (!_roundActive) return;
|
||||
|
||||
if (Time.time >= _roundEndTime)
|
||||
{
|
||||
ResetRange();
|
||||
}
|
||||
else
|
||||
{
|
||||
SetTimeLeftText($"Time Left: {Math.Ceiling((_roundEndTime - Time.time) % 60)}");
|
||||
if (Time.time >= _nextTargetTime)
|
||||
{
|
||||
_nextTargetTime = Time.time + targetSpawnTime;
|
||||
SpawnTarget();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SpawnTarget()
|
||||
{
|
||||
if (!IsServer) return;
|
||||
|
||||
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 target = SpawnTarget(randomPos);
|
||||
|
||||
_targets.Add(target);
|
||||
}
|
||||
|
||||
private ArcheryTarget SpawnTarget(Vector3 randomPos)
|
||||
{
|
||||
var prefab = Instantiate(targetPrefab, randomPos, Quaternion.identity, null);
|
||||
ArcheryTarget target = prefab.GetComponent<ArcheryTarget>();
|
||||
target.endPosition = targetEndPosition.position;
|
||||
target.addScore = AddScore;
|
||||
Spawn(prefab);
|
||||
return target;
|
||||
}
|
||||
|
||||
|
||||
public void ResetRange()
|
||||
{
|
||||
if (!IsServer) return;
|
||||
foreach (var target in _targets.Where(target => target != null))
|
||||
{
|
||||
Despawn(target.gameObject, DespawnType.Pool);
|
||||
}
|
||||
|
||||
_targets = new List<ArcheryTarget>();
|
||||
if (_maxScore < _score) _maxScore = _score;
|
||||
_score = 0;
|
||||
SetHighScoreText($"High Score: {_maxScore}");
|
||||
startTarget.ShowTarget();
|
||||
_roundActive = false;
|
||||
SetTimeLeftText("");
|
||||
}
|
||||
|
||||
public void StartRound()
|
||||
{
|
||||
if (!IsServer) return;
|
||||
_roundEndTime = Time.time + roundLength;
|
||||
_nextTargetTime = Time.time;
|
||||
_roundActive = true;
|
||||
}
|
||||
|
||||
public void AddScore(float distance)
|
||||
{
|
||||
if (!IsServer) return;
|
||||
_score += distance;
|
||||
SetScoreText($"Score: {_score}");
|
||||
}
|
||||
|
||||
[ObserversRpc]
|
||||
public void SetHighScoreText(string text)
|
||||
{
|
||||
highScoreText.text = text;
|
||||
}
|
||||
|
||||
[ObserversRpc]
|
||||
public void SetScoreText(string text)
|
||||
{
|
||||
scoreText.text = text;
|
||||
}
|
||||
|
||||
[ObserversRpc]
|
||||
public void SetTimeLeftText(string text)
|
||||
{
|
||||
timeLeftText.text = text;
|
||||
}
|
||||
}
|
||||
11
Assets/_PROJECT/Components/Bow/Scripts/ArcheryRange.cs.meta
Normal file
11
Assets/_PROJECT/Components/Bow/Scripts/ArcheryRange.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 592ba278f86ebec478622d8cf05c309d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
56
Assets/_PROJECT/Components/Bow/Scripts/ArcheryTarget.cs
Normal file
56
Assets/_PROJECT/Components/Bow/Scripts/ArcheryTarget.cs
Normal file
@@ -0,0 +1,56 @@
|
||||
using System;
|
||||
using _PROJECT.Scripts.Bow;
|
||||
using _PROJECT.Scripts.Bow.Extra;
|
||||
using FishNet.Object;
|
||||
using FishNet.Object.Synchronizing;
|
||||
using UnityEngine;
|
||||
using Random = UnityEngine.Random;
|
||||
|
||||
public class ArcheryTarget : NetworkBehaviour, IArrowHittable
|
||||
{
|
||||
public GameObject pointsText;
|
||||
[SyncVar]
|
||||
public Vector3 endPosition;
|
||||
public float forwardSpeed = 2f;
|
||||
public Action<float> addScore;
|
||||
|
||||
private bool _flipDirection;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
_flipDirection = Random.value > 0.5f;
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
if (!IsServer) return;
|
||||
float step = forwardSpeed * Time.deltaTime;
|
||||
var position = transform.position;
|
||||
|
||||
if (Math.Abs(position.x - endPosition.x) < 0.1) Destroy(gameObject);
|
||||
|
||||
|
||||
transform.position = Vector3.MoveTowards(position,
|
||||
new Vector3(endPosition.x, position.y, position.z), step);
|
||||
}
|
||||
|
||||
public void Hit(Arrow arrow)
|
||||
{
|
||||
if (!IsServer) return;
|
||||
if (arrow == null) return;
|
||||
|
||||
var position = transform.position;
|
||||
|
||||
float score = (float)Math.Round(Vector3.Distance(position, endPosition));
|
||||
addScore(score);
|
||||
|
||||
GameObject prefab = Instantiate(pointsText, position, Quaternion.Euler(0, 90f, 0), null);
|
||||
PointsText target = prefab.GetComponent<PointsText>();
|
||||
target.SetPoints(score);
|
||||
Spawn(prefab);
|
||||
|
||||
Despawn(arrow.gameObject, DespawnType.Pool);
|
||||
Despawn(gameObject, DespawnType.Pool);
|
||||
}
|
||||
}
|
||||
11
Assets/_PROJECT/Components/Bow/Scripts/ArcheryTarget.cs.meta
Normal file
11
Assets/_PROJECT/Components/Bow/Scripts/ArcheryTarget.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3b311379c72a5ae4b8936e3b7283dd7a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
33
Assets/_PROJECT/Components/Bow/Scripts/Arrow.cs
Normal file
33
Assets/_PROJECT/Components/Bow/Scripts/Arrow.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
using System.Collections;
|
||||
using _PROJECT.Multiplayer.NewBow;
|
||||
using _PROJECT.Scripts.Bow;
|
||||
using FishNet.Object;
|
||||
using UnityEngine;
|
||||
using UnityEngine.XR.Interaction.Toolkit;
|
||||
|
||||
public class Arrow : XRGrabInteractable
|
||||
{
|
||||
private ArrowCaster _caster;
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
_caster = GetComponent<ArrowCaster>();
|
||||
}
|
||||
|
||||
protected override void OnSelectExited(SelectExitEventArgs args)
|
||||
{
|
||||
base.OnSelectExited(args);
|
||||
if (!_caster.IsServer) return;
|
||||
Debug.Log("Arrow select exit by " + args.interactorObject);
|
||||
|
||||
if (args.interactorObject is not TwoHandedBowNotch notch)
|
||||
{
|
||||
Debug.Log("Arrow select exit not notch");
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.Log("Arrow select exit can release");
|
||||
_caster.LaunchArrow(notch);
|
||||
}
|
||||
}
|
||||
11
Assets/_PROJECT/Components/Bow/Scripts/Arrow.cs.meta
Normal file
11
Assets/_PROJECT/Components/Bow/Scripts/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:
|
||||
119
Assets/_PROJECT/Components/Bow/Scripts/ArrowCaster.cs
Normal file
119
Assets/_PROJECT/Components/Bow/Scripts/ArrowCaster.cs
Normal file
@@ -0,0 +1,119 @@
|
||||
using System.Collections;
|
||||
using _PROJECT.Multiplayer.NewBow;
|
||||
using _PROJECT.Scripts.Bow;
|
||||
using FishNet.Object;
|
||||
using UnityEngine;
|
||||
|
||||
public class ArrowCaster : NetworkBehaviour
|
||||
{
|
||||
[SerializeField] private Transform tip;
|
||||
[SerializeField] private LayerMask layerMask = ~0;
|
||||
[SerializeField] private float speed = 2000f;
|
||||
|
||||
private Vector3 lastPosition = Vector3.zero;
|
||||
|
||||
private readonly float _maxLifeTime = 30f;
|
||||
private float _lifeTime;
|
||||
private bool _launched;
|
||||
|
||||
private Rigidbody _rigidbody;
|
||||
private Arrow _arrow;
|
||||
|
||||
private RaycastHit _hit;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
_rigidbody = GetComponent<Rigidbody>();
|
||||
_arrow = GetComponent<Arrow>();
|
||||
_launched = false;
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (!IsServer) return;
|
||||
if (!_launched) return;
|
||||
if (Time.time - _lifeTime > _maxLifeTime)
|
||||
Despawn(DespawnType.Pool);
|
||||
}
|
||||
|
||||
private bool CheckForCollision(out RaycastHit hit)
|
||||
{
|
||||
if (lastPosition == Vector3.zero)
|
||||
lastPosition = tip.position;
|
||||
|
||||
bool collided = Physics.Linecast(lastPosition, tip.position, out hit, layerMask);
|
||||
|
||||
lastPosition = collided ? lastPosition : tip.position;
|
||||
|
||||
return collided;
|
||||
}
|
||||
|
||||
public void LaunchArrow(TwoHandedBowNotch notch)
|
||||
{
|
||||
if (!IsServer) return;
|
||||
Debug.Log("Launching arrow");
|
||||
|
||||
transform.rotation = Quaternion.LookRotation(notch.GetLaunchDirection());
|
||||
|
||||
Debug.Log("Launching arrow with direction " + notch.GetLaunchDirection());
|
||||
Debug.Log("Launching arrow with pull amount " + notch.GetLastKnownPullAmount());
|
||||
|
||||
LaunchArrow(notch.GetLaunchDirection().normalized * (notch.GetLastKnownPullAmount() * speed));
|
||||
}
|
||||
|
||||
private void LaunchArrow(Vector3 force)
|
||||
{
|
||||
_lifeTime = Time.time;
|
||||
_launched = true;
|
||||
RemoveOwnership();
|
||||
transform.parent = null;
|
||||
EnablePhysics();
|
||||
ApplyForce(force);
|
||||
StartCoroutine(LaunchRoutine());
|
||||
}
|
||||
|
||||
private void ApplyForce(Vector3 force)
|
||||
{
|
||||
_rigidbody.AddForce(force);
|
||||
}
|
||||
|
||||
private IEnumerator LaunchRoutine()
|
||||
{
|
||||
// Set direction while flying
|
||||
while (!CheckForCollision(out _hit))
|
||||
{
|
||||
SetDirection();
|
||||
yield return null;
|
||||
}
|
||||
|
||||
Debug.Log(_hit.transform.name);
|
||||
|
||||
// Once the arrow has stopped flying
|
||||
DisablePhysics();
|
||||
CheckForHittable(_hit);
|
||||
}
|
||||
|
||||
private void SetDirection()
|
||||
{
|
||||
if (_rigidbody.velocity.z > 0.5f)
|
||||
transform.forward = _rigidbody.velocity;
|
||||
}
|
||||
|
||||
private void DisablePhysics()
|
||||
{
|
||||
_rigidbody.isKinematic = true;
|
||||
_rigidbody.useGravity = false;
|
||||
}
|
||||
|
||||
private void EnablePhysics()
|
||||
{
|
||||
_rigidbody.isKinematic = false;
|
||||
_rigidbody.useGravity = true;
|
||||
}
|
||||
|
||||
private void CheckForHittable(RaycastHit hit)
|
||||
{
|
||||
if (hit.transform.TryGetComponent(out IArrowHittable hittable))
|
||||
hittable.Hit(_arrow);
|
||||
}
|
||||
}
|
||||
11
Assets/_PROJECT/Components/Bow/Scripts/ArrowCaster.cs.meta
Normal file
11
Assets/_PROJECT/Components/Bow/Scripts/ArrowCaster.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3186f8c7706ca9b4197d307b7d8bedc4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
85
Assets/_PROJECT/Components/Bow/Scripts/ArrowSpawner.cs
Normal file
85
Assets/_PROJECT/Components/Bow/Scripts/ArrowSpawner.cs
Normal file
@@ -0,0 +1,85 @@
|
||||
using System;
|
||||
using _PROJECT.Multiplayer;
|
||||
using FishNet.Connection;
|
||||
using FishNet.Object;
|
||||
using FishNet.Object.Synchronizing;
|
||||
using UnityEngine;
|
||||
using UnityEngine.XR.Interaction.Toolkit;
|
||||
|
||||
namespace _PROJECT.Scripts.Bow
|
||||
{
|
||||
public class ArrowSpawner : NetworkBehaviour
|
||||
{
|
||||
[SerializeField] private GameObject arrowPrefab;
|
||||
|
||||
private XRMultiplayerInteractionManager _interactionManager;
|
||||
private Notch _notch;
|
||||
|
||||
[SyncVar] private NetworkObject _arrowNetworkObject;
|
||||
|
||||
public override void OnStartServer()
|
||||
{
|
||||
base.OnStartServer();
|
||||
_interactionManager = GameObject.Find("XR Interaction Manager").GetComponent<XRMultiplayerInteractionManager>();
|
||||
_notch = GetComponent<Notch>();
|
||||
CreateArrowServer();
|
||||
}
|
||||
|
||||
public override void OnStartClient()
|
||||
{
|
||||
base.OnStartClient();
|
||||
_interactionManager = GameObject.Find("XR Interaction Manager").GetComponent<XRMultiplayerInteractionManager>();
|
||||
_notch = GetComponent<Notch>();
|
||||
}
|
||||
|
||||
public void LaunchArrow()
|
||||
{
|
||||
Debug.Log("Sending arrow RPC at ");
|
||||
LaunchArrowRPC();
|
||||
}
|
||||
|
||||
[ServerRpc(RequireOwnership = false)]
|
||||
private void LaunchArrowRPC()
|
||||
{
|
||||
if (!IsServer) return;
|
||||
Debug.Log("Got launch arrow RPC");
|
||||
if (_notch.hasSelection)
|
||||
{
|
||||
//OwnerDeselectRpc(Owner, _notch.firstInteractableSelected.transform.GetComponent<NetworkObject>());
|
||||
_interactionManager.SelectExit(_notch, _notch.firstInteractableSelected);
|
||||
}
|
||||
|
||||
_arrowNetworkObject = null;
|
||||
|
||||
Invoke(nameof(CreateArrowServer), _notch.recycleDelayTime + 0.1f);
|
||||
}
|
||||
|
||||
private void CreateArrowServer()
|
||||
{
|
||||
if (!IsServer) return;
|
||||
Debug.Log("Spawning arrow at " + transform.position);
|
||||
GameObject arrowObject = Instantiate(arrowPrefab, transform.position, transform.rotation);
|
||||
Spawn(arrowObject, Owner);
|
||||
Arrow arrow = arrowObject.GetComponent<Arrow>();
|
||||
_arrowNetworkObject = arrow.GetComponent<NetworkObject>();
|
||||
_interactionManager.SelectEnter(_notch as IXRSelectInteractor, arrow);
|
||||
//OwnerSelectRpc(Owner, arrowObject.GetComponent<NetworkObject>());
|
||||
}
|
||||
|
||||
public override void OnOwnershipClient(NetworkConnection prevOwner)
|
||||
{
|
||||
base.OnOwnershipClient(prevOwner);
|
||||
|
||||
if (IsOwner && _arrowNetworkObject != null)
|
||||
TakeArrowOwnershipRPC();
|
||||
}
|
||||
|
||||
[ServerRpc(RequireOwnership = false)]
|
||||
private void TakeArrowOwnershipRPC(NetworkConnection conn = null)
|
||||
{
|
||||
if (!IsServer) return;
|
||||
if (_arrowNetworkObject == null) return;
|
||||
_arrowNetworkObject.GiveOwnership(conn);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 29f557273d5348c2b3511dfc21f9a47c
|
||||
timeCreated: 1678626807
|
||||
6
Assets/_PROJECT/Components/Bow/Scripts/Bow.cs
Normal file
6
Assets/_PROJECT/Components/Bow/Scripts/Bow.cs
Normal file
@@ -0,0 +1,6 @@
|
||||
using _PROJECT.Scripts.Bow;
|
||||
using UnityEngine.XR.Interaction.Toolkit;
|
||||
|
||||
public class Bow : XRGrabInteractable
|
||||
{
|
||||
}
|
||||
11
Assets/_PROJECT/Components/Bow/Scripts/Bow.cs.meta
Normal file
11
Assets/_PROJECT/Components/Bow/Scripts/Bow.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0d01ceece15e8724fab22ba74c52eba3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/_PROJECT/Components/Bow/Scripts/Extra.meta
Normal file
8
Assets/_PROJECT/Components/Bow/Scripts/Extra.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b91caed8300a5f547b05c97499015821
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace _PROJECT.Scripts.Bow.Extra
|
||||
{
|
||||
public interface IArrowHittable
|
||||
{
|
||||
void Hit(Arrow arrow);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cfa6cad5516730442bdec89a52550144
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
28
Assets/_PROJECT/Components/Bow/Scripts/Extra/Target.cs
Normal file
28
Assets/_PROJECT/Components/Bow/Scripts/Extra/Target.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace _PROJECT.Scripts.Bow.Extra
|
||||
{
|
||||
public class Target : MonoBehaviour, IArrowHittable
|
||||
{
|
||||
public float forceAmount = 1.0f;
|
||||
public Material otherMaterial;
|
||||
|
||||
public void Hit(Arrow arrow)
|
||||
{
|
||||
ApplyMaterial();
|
||||
ApplyForce(arrow.transform.forward);
|
||||
}
|
||||
|
||||
private void ApplyMaterial()
|
||||
{
|
||||
MeshRenderer meshRenderer = GetComponent<MeshRenderer>();
|
||||
meshRenderer.material = otherMaterial;
|
||||
}
|
||||
|
||||
private void ApplyForce(Vector3 direction)
|
||||
{
|
||||
Rigidbody rBody = GetComponent<Rigidbody>();
|
||||
rBody.AddForce(direction * forceAmount);
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/_PROJECT/Components/Bow/Scripts/Extra/Target.cs.meta
Normal file
11
Assets/_PROJECT/Components/Bow/Scripts/Extra/Target.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 52e106f6721842f4fbabaeb95bc9c7c2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
4
Assets/_PROJECT/Components/Bow/Scripts/IArrowHittable.cs
Normal file
4
Assets/_PROJECT/Components/Bow/Scripts/IArrowHittable.cs
Normal file
@@ -0,0 +1,4 @@
|
||||
public interface IArrowHittable
|
||||
{
|
||||
void Hit(Arrow arrow);
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 54d4d1ff1043a6442a1bbda903315edd
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
69
Assets/_PROJECT/Components/Bow/Scripts/Notch.cs
Normal file
69
Assets/_PROJECT/Components/Bow/Scripts/Notch.cs
Normal file
@@ -0,0 +1,69 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.XR.Interaction.Toolkit;
|
||||
|
||||
namespace _PROJECT.Scripts.Bow
|
||||
{
|
||||
[RequireComponent(typeof(ArrowSpawner))]
|
||||
public class Notch : XRSocketInteractor
|
||||
{
|
||||
[SerializeField, Range(0, 1)] private float releaseThreshold = 0.25f;
|
||||
|
||||
public global::Bow Bow { get; private set; }
|
||||
public PullMeasurer PullMeasurer { get; private set; }
|
||||
|
||||
private ArrowSpawner _arrowSpawner;
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
Bow = GetComponentInParent<global::Bow>();
|
||||
_arrowSpawner = GetComponent<ArrowSpawner>();
|
||||
PullMeasurer = GetComponentInChildren<PullMeasurer>();
|
||||
}
|
||||
|
||||
protected override void OnEnable()
|
||||
{
|
||||
base.OnEnable();
|
||||
PullMeasurer.selectExited.AddListener(ReleaseArrow);
|
||||
}
|
||||
|
||||
protected override void OnDisable()
|
||||
{
|
||||
base.OnDisable();
|
||||
PullMeasurer.selectExited.RemoveListener(ReleaseArrow);
|
||||
}
|
||||
|
||||
public void ReleaseArrow(SelectExitEventArgs args)
|
||||
{
|
||||
Debug.Log("Requesting arrow launch...");
|
||||
_arrowSpawner.LaunchArrow();
|
||||
}
|
||||
|
||||
public override void ProcessInteractor(XRInteractionUpdateOrder.UpdatePhase updatePhase)
|
||||
{
|
||||
base.ProcessInteractor(updatePhase);
|
||||
|
||||
// Move attach when bow is pulled, this updates the renderer as well
|
||||
attachTransform.position = PullMeasurer.PullPosition;
|
||||
}
|
||||
|
||||
public override bool CanSelect(IXRSelectInteractable interactable)
|
||||
{
|
||||
return QuickSelect(interactable) && CanHover(interactable) && interactable is Arrow;
|
||||
}
|
||||
|
||||
private bool QuickSelect(IXRSelectInteractable interactable)
|
||||
{
|
||||
// This lets the Notch automatically grab the arrow
|
||||
return !hasSelection || IsSelecting(interactable);
|
||||
}
|
||||
|
||||
private bool CanHover(IXRSelectInteractable interactable)
|
||||
{
|
||||
if (interactable is IXRHoverInteractable hoverInteractable)
|
||||
return CanHover(hoverInteractable);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/_PROJECT/Components/Bow/Scripts/Notch.cs.meta
Normal file
11
Assets/_PROJECT/Components/Bow/Scripts/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:
|
||||
42
Assets/_PROJECT/Components/Bow/Scripts/PointsText.cs
Normal file
42
Assets/_PROJECT/Components/Bow/Scripts/PointsText.cs
Normal file
@@ -0,0 +1,42 @@
|
||||
using FishNet.Object;
|
||||
using FishNet.Object.Synchronizing;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
|
||||
public class PointsText : NetworkBehaviour
|
||||
{
|
||||
public TMP_Text text;
|
||||
[SyncVar]
|
||||
public float destroyTime = 2f;
|
||||
[SyncVar]
|
||||
public float upSpeed = 2f;
|
||||
|
||||
[SyncVar]
|
||||
private float _destroyOnTime;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
if (!IsServer) return;
|
||||
_destroyOnTime = Time.time + destroyTime;
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
if (!IsServer) return;
|
||||
if (_destroyOnTime <= Time.time)
|
||||
{
|
||||
Despawn(gameObject, DespawnType.Pool);
|
||||
}
|
||||
|
||||
float step = upSpeed * Time.deltaTime;
|
||||
var position = transform.position;
|
||||
transform.position = Vector3.MoveTowards(position,
|
||||
new Vector3(position.x, position.y + 1f, position.z), step);
|
||||
}
|
||||
|
||||
[ObserversRpc]
|
||||
public void SetPoints(float points)
|
||||
{
|
||||
text.text = $"+{points}";
|
||||
}
|
||||
}
|
||||
11
Assets/_PROJECT/Components/Bow/Scripts/PointsText.cs.meta
Normal file
11
Assets/_PROJECT/Components/Bow/Scripts/PointsText.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f90b4cb440f999542a12d794b33ef22f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
61
Assets/_PROJECT/Components/Bow/Scripts/PullMeasurer.cs
Normal file
61
Assets/_PROJECT/Components/Bow/Scripts/PullMeasurer.cs
Normal file
@@ -0,0 +1,61 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.XR.Interaction.Toolkit;
|
||||
|
||||
public class PullMeasurer : XRBaseInteractable
|
||||
{
|
||||
[SerializeField] private Transform start;
|
||||
[SerializeField] private Transform end;
|
||||
|
||||
public float PullAmount { get; private set; } = 0.0f;
|
||||
|
||||
public Vector3 PullPosition => Vector3.Lerp(start.position, end.position, PullAmount);
|
||||
|
||||
protected override void OnSelectExited(SelectExitEventArgs args)
|
||||
{
|
||||
base.OnSelectExited(args);
|
||||
PullAmount = 0;
|
||||
}
|
||||
|
||||
public override void ProcessInteractable(XRInteractionUpdateOrder.UpdatePhase updatePhase)
|
||||
{
|
||||
base.ProcessInteractable(updatePhase);
|
||||
|
||||
if (isSelected)
|
||||
{
|
||||
// Update pull values while the measurer is grabbed
|
||||
if (updatePhase == XRInteractionUpdateOrder.UpdatePhase.Dynamic)
|
||||
UpdatePull();
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdatePull()
|
||||
{
|
||||
// Use the interactor's position to calculate amount
|
||||
Vector3 interactorPosition = firstInteractorSelecting.transform.position;
|
||||
|
||||
// Figure out the new pull value, and it's position in space
|
||||
PullAmount = CalculatePull(interactorPosition);
|
||||
}
|
||||
|
||||
private float CalculatePull(Vector3 pullPosition)
|
||||
{
|
||||
// Direction, and length
|
||||
Vector3 pullDirection = pullPosition - start.position;
|
||||
Vector3 targetDirection = end.position - start.position;
|
||||
|
||||
// Figure out out the pull direction
|
||||
float maxLength = targetDirection.magnitude;
|
||||
targetDirection.Normalize();
|
||||
|
||||
// What's the actual distance?
|
||||
float pullValue = Vector3.Dot(pullDirection, targetDirection) / maxLength;
|
||||
return Mathf.Clamp(pullValue, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
private void OnDrawGizmos()
|
||||
{
|
||||
// Draw line from start to end point
|
||||
if (start && end)
|
||||
Gizmos.DrawLine(start.position, end.position);
|
||||
}
|
||||
}
|
||||
11
Assets/_PROJECT/Components/Bow/Scripts/PullMeasurer.cs.meta
Normal file
11
Assets/_PROJECT/Components/Bow/Scripts/PullMeasurer.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:
|
||||
27
Assets/_PROJECT/Components/Bow/Scripts/Quiver.cs
Normal file
27
Assets/_PROJECT/Components/Bow/Scripts/Quiver.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.XR.Interaction.Toolkit;
|
||||
|
||||
public class Quiver : XRBaseInteractable
|
||||
{
|
||||
[SerializeField] private GameObject arrowPrefab;
|
||||
|
||||
protected override void OnSelectEntered(SelectEnterEventArgs args)
|
||||
{
|
||||
base.OnSelectEntered(args);
|
||||
CreateAndSelectArrow(args);
|
||||
}
|
||||
|
||||
private void CreateAndSelectArrow(SelectEnterEventArgs args)
|
||||
{
|
||||
// Create arrow, force into interacting hand
|
||||
Arrow arrow = CreateArrow(args.interactorObject.transform);
|
||||
interactionManager.SelectEnter(args.interactorObject, arrow);
|
||||
}
|
||||
|
||||
private Arrow CreateArrow(Transform orientation)
|
||||
{
|
||||
// Create arrow, and get arrow component
|
||||
GameObject arrowObject = Instantiate(arrowPrefab, orientation.position, orientation.rotation);
|
||||
return arrowObject.GetComponent<Arrow>();
|
||||
}
|
||||
}
|
||||
11
Assets/_PROJECT/Components/Bow/Scripts/Quiver.cs.meta
Normal file
11
Assets/_PROJECT/Components/Bow/Scripts/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:
|
||||
46
Assets/_PROJECT/Components/Bow/Scripts/StartTarget.cs
Normal file
46
Assets/_PROJECT/Components/Bow/Scripts/StartTarget.cs
Normal file
@@ -0,0 +1,46 @@
|
||||
using FishNet.Object;
|
||||
using UnityEngine;
|
||||
|
||||
namespace _PROJECT.Scripts.Bow
|
||||
{
|
||||
public class StartTarget : NetworkBehaviour, IArrowHittable
|
||||
{
|
||||
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>();
|
||||
}
|
||||
|
||||
[ObserversRpc]
|
||||
private void HideTarget()
|
||||
{
|
||||
_meshRenderer.enabled = false;
|
||||
_boxCollider.enabled = false;
|
||||
textCanvas.enabled = false;
|
||||
}
|
||||
|
||||
[ObserversRpc]
|
||||
public void ShowTarget()
|
||||
{
|
||||
_meshRenderer.enabled = true;
|
||||
_boxCollider.enabled = true;
|
||||
textCanvas.enabled = true;
|
||||
}
|
||||
|
||||
public void Hit(Arrow arrow)
|
||||
{
|
||||
if (!IsServer) return;
|
||||
if (arrow == null) return;
|
||||
|
||||
Despawn(arrow.gameObject, DespawnType.Pool);
|
||||
HideTarget();
|
||||
archeryRange.StartRound();
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/_PROJECT/Components/Bow/Scripts/StartTarget.cs.meta
Normal file
11
Assets/_PROJECT/Components/Bow/Scripts/StartTarget.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c25614c8b9ec3ef40963a7887bf26792
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
47
Assets/_PROJECT/Components/Bow/Scripts/StringRenderer.cs
Normal file
47
Assets/_PROJECT/Components/Bow/Scripts/StringRenderer.cs
Normal file
@@ -0,0 +1,47 @@
|
||||
using UnityEngine;
|
||||
|
||||
[ExecuteInEditMode]
|
||||
public class StringRenderer : MonoBehaviour
|
||||
{
|
||||
[Header("Render Positions")] [SerializeField]
|
||||
private Transform start;
|
||||
|
||||
[SerializeField] private Transform middle;
|
||||
[SerializeField] private Transform end;
|
||||
|
||||
private LineRenderer _lineRenderer;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
_lineRenderer = GetComponent<LineRenderer>();
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
// While in editor, make sure the line renderer follows bow
|
||||
if (Application.isEditor && !Application.isPlaying)
|
||||
UpdatePositions();
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
Application.onBeforeRender += UpdatePositions;
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
Application.onBeforeRender -= UpdatePositions;
|
||||
}
|
||||
|
||||
private void UpdatePositions()
|
||||
{
|
||||
if (_lineRenderer == null) _lineRenderer = GetComponent<LineRenderer>();
|
||||
// Set positions of line renderer, middle position is the notch attach transform
|
||||
_lineRenderer.SetPositions(new Vector3[] { start.position, middle.position, end.position });
|
||||
}
|
||||
|
||||
public void UpdateString(Vector3 pullPosition)
|
||||
{
|
||||
middle.position = pullPosition;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a7bf39fa7cd40e94b94b00dec7e5d4d3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
32
Assets/_PROJECT/Components/Bow/Scripts/Target.cs
Normal file
32
Assets/_PROJECT/Components/Bow/Scripts/Target.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
using UnityEngine;
|
||||
|
||||
public class Target : MonoBehaviour, IArrowHittable
|
||||
{
|
||||
public float forceAmount = 1.0f;
|
||||
public Material otherMaterial = null;
|
||||
|
||||
public void Hit(Arrow arrow)
|
||||
{
|
||||
ApplyMaterial();
|
||||
ApplyForce(arrow);
|
||||
DisableCollider(arrow);
|
||||
}
|
||||
|
||||
private void ApplyMaterial()
|
||||
{
|
||||
if (TryGetComponent(out MeshRenderer meshRenderer))
|
||||
meshRenderer.material = otherMaterial;
|
||||
}
|
||||
|
||||
private void ApplyForce(Arrow arrow)
|
||||
{
|
||||
if (TryGetComponent(out Rigidbody rigidbody))
|
||||
rigidbody.AddForce(arrow.transform.forward * forceAmount);
|
||||
}
|
||||
|
||||
private void DisableCollider(Arrow arrow)
|
||||
{
|
||||
if (arrow.TryGetComponent(out Collider collider))
|
||||
collider.enabled = false;
|
||||
}
|
||||
}
|
||||
11
Assets/_PROJECT/Components/Bow/Scripts/Target.cs.meta
Normal file
11
Assets/_PROJECT/Components/Bow/Scripts/Target.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9811e177caf046348abcb84042ed1ac1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user