Add ultimate xr

This commit is contained in:
2024-08-06 21:58:35 +02:00
parent 864033bf10
commit 7165bacd9d
3952 changed files with 2162037 additions and 35 deletions

View File

@@ -0,0 +1,206 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="UxrProjectileSource.cs" company="VRMADA">
// Copyright (c) VRMADA, All rights reserved.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
using System.Collections.Generic;
using UltimateXR.Core.Caching;
using UltimateXR.Core.Components;
using UnityEngine;
namespace UltimateXR.Mechanics.Weapons
{
/// <summary>
/// Component that has the ability to fire shots.
/// </summary>
public class UxrProjectileSource : UxrComponent<UxrProjectileSource>, IUxrPrecacheable
{
#region Inspector Properties/Serialized Fields
[SerializeField] private Animator _weaponAnimator;
[SerializeField] private List<UxrShotDescriptor> _shotTypes;
#endregion
#region Public Types & Data
/// <summary>
/// The different shots that can be fired using the component.
/// </summary>
public IReadOnlyList<UxrShotDescriptor> ShotTypes => _shotTypes;
#endregion
#region Implicit IUxrPrecacheable
/// <inheritdoc />
public IEnumerable<GameObject> PrecachedInstances
{
get
{
foreach (UxrShotDescriptor shotType in _shotTypes)
{
if (shotType.PrefabInstantiateOnImpact)
{
yield return shotType.PrefabInstantiateOnImpact;
}
if (shotType.PrefabInstantiateOnTipWhenShot)
{
yield return shotType.PrefabInstantiateOnTipWhenShot;
}
if (shotType.PrefabScenarioImpactDecal && shotType.PrefabScenarioImpactDecal.gameObject)
{
yield return shotType.PrefabScenarioImpactDecal.gameObject;
}
if (shotType.ProjectilePrefab)
{
yield return shotType.ProjectilePrefab;
}
}
}
}
#endregion
#region Public Methods
/// <summary>
/// Tries to get the <see cref="UxrActor" /> that holds the <see cref="UxrWeapon" /> that has the
/// <see cref="UxrProjectileSource" /> component.
/// </summary>
/// <returns>Actor component or null if it wasn't found</returns>
public UxrActor TryGetWeaponOwner()
{
UxrWeapon weapon = GetComponentInParent<UxrWeapon>();
if (weapon)
{
return weapon.Owner;
}
return GetComponentInParent<UxrActor>();
}
/// <summary>
/// Shoots a round.
/// </summary>
/// <param name="shotTypeIndex">Index in <see cref="ShotTypes" />, telling which shot type to fire</param>
public void Shoot(int shotTypeIndex)
{
if (shotTypeIndex >= 0 && shotTypeIndex < _shotTypes.Count)
{
Shoot(shotTypeIndex, _shotTypes[shotTypeIndex].ShotSource.position, _shotTypes[shotTypeIndex].ShotSource.rotation);
}
}
/// <summary>
/// Shoots a round, overriding the source position and orientation.
/// </summary>
/// <param name="shotTypeIndex">Index in <see cref="ShotTypes" />, telling which shot type to fire</param>
/// <param name="projectileSource">Source shot position</param>
/// <param name="projectileOrientation">Shot source orientation. The shot will be fired in the z (forward) direction</param>
public void Shoot(int shotTypeIndex, Vector3 projectileSource, Quaternion projectileOrientation)
{
if (shotTypeIndex >= 0 && shotTypeIndex < _shotTypes.Count)
{
if (_shotTypes[shotTypeIndex].PrefabInstantiateOnTipWhenShot)
{
GameObject newInstance = Instantiate(_shotTypes[shotTypeIndex].PrefabInstantiateOnTipWhenShot, _shotTypes[shotTypeIndex].Tip.position, _shotTypes[shotTypeIndex].Tip.rotation);
if (_shotTypes[shotTypeIndex].PrefabInstantiateOnTipParent)
{
newInstance.transform.parent = transform;
}
else
{
newInstance.transform.parent = null;
}
if (_shotTypes[shotTypeIndex].PrefabInstantiateOnTipLife >= 0.0f)
{
Destroy(newInstance, _shotTypes[shotTypeIndex].PrefabInstantiateOnTipLife);
}
}
UxrWeaponManager.Instance.RegisterNewProjectileShot(this, _shotTypes[shotTypeIndex], projectileSource, projectileOrientation);
if (_weaponAnimator != null && string.IsNullOrEmpty(_shotTypes[shotTypeIndex].ShotAnimationVarName) == false)
{
_weaponAnimator.SetTrigger(_shotTypes[shotTypeIndex].ShotAnimationVarName);
}
}
}
/// <summary>
/// Shoots a round pointing to the given target.
/// </summary>
/// <param name="shotTypeIndex">Index in <see cref="ShotTypes" />, telling which shot type to fire</param>
/// <param name="target">Position where the shot will be going towards</param>
public void ShootTo(int shotTypeIndex, Vector3 target)
{
if (shotTypeIndex >= 0 && shotTypeIndex < _shotTypes.Count)
{
Vector3 direction = (target - _shotTypes[shotTypeIndex].ShotSource.position).normalized;
Shoot(shotTypeIndex, _shotTypes[shotTypeIndex].ShotSource.position, Quaternion.LookRotation(direction));
}
}
/// <summary>
/// Gets the distance where a shot using the current position and orientation will impact.
/// </summary>
/// <param name="shotTypeIndex">Index in <see cref="ShotTypes" />, telling which shot type to use</param>
/// <returns>Shot distance or a negative value telling the current target is out of range</returns>
public float ShotRaycastDistance(int shotTypeIndex)
{
if (shotTypeIndex >= 0 && shotTypeIndex < _shotTypes.Count)
{
if (Physics.Raycast(_shotTypes[shotTypeIndex].ShotSource.position,
_shotTypes[shotTypeIndex].ShotSource.forward,
out RaycastHit raycastHit,
_shotTypes[shotTypeIndex].ProjectileMaxDistance,
_shotTypes[shotTypeIndex].CollisionLayerMask,
QueryTriggerInteraction.Ignore))
{
return raycastHit.distance;
}
}
return -1.0f;
}
/// <summary>
/// Gets the current world-space origin of projectiles fired using the given shot type.
/// </summary>
/// <param name="shotTypeIndex">Index in <see cref="ShotTypes" />, telling which shot type to use</param>
/// <returns>Projectile world-space source</returns>
public Vector3 GetShotOrigin(int shotTypeIndex)
{
if (shotTypeIndex >= 0 && shotTypeIndex < _shotTypes.Count)
{
return _shotTypes[shotTypeIndex].ShotSource.position;
}
return Vector3.zero;
}
/// <summary>
/// Gets the current world-space direction of projectiles fired using the given shot type.
/// </summary>
/// <param name="shotTypeIndex">Index in <see cref="ShotTypes" />, telling which shot type to use</param>
/// <returns>Projectile world-space direction</returns>
public Vector3 GetShotDirection(int shotTypeIndex)
{
if (shotTypeIndex >= 0 && shotTypeIndex < _shotTypes.Count)
{
return _shotTypes[shotTypeIndex].ShotSource.forward;
}
return Vector3.zero;
}
#endregion
}
}