Update
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
using UnityEngine;
|
||||
namespace Invector.Throw
|
||||
{
|
||||
public class vThrowAnimatorEvent : StateMachineBehaviour
|
||||
{
|
||||
public enum ThrowEventType
|
||||
{
|
||||
EquipThrowable, EnableAiming, CancelAiming, StartLaunch, FinishLaunch
|
||||
}
|
||||
|
||||
public ThrowEventType eventType;
|
||||
[Range(0, 1f)]
|
||||
public float time;
|
||||
bool isTrigger;
|
||||
vThrowManagerBase manager;
|
||||
public override void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
|
||||
{
|
||||
manager = animator.GetComponentInChildren<vThrowManagerBase>();
|
||||
isTrigger = false;
|
||||
}
|
||||
|
||||
public override void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
|
||||
{
|
||||
if (stateInfo.normalizedTime >= time && !isTrigger)
|
||||
{
|
||||
OnTrigger();
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void OnTrigger()
|
||||
{
|
||||
isTrigger = true;
|
||||
manager.TriggerAnimatorEvent(eventType);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ae7ca1bbf9c554a49ae313dd3cd99c21
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
116
Assets/Scripts/Player/ThrowSystem/Scripts/vThrowCollectable.cs
Normal file
116
Assets/Scripts/Player/ThrowSystem/Scripts/vThrowCollectable.cs
Normal file
@@ -0,0 +1,116 @@
|
||||
using UnityEngine;
|
||||
namespace Invector.Throw
|
||||
{
|
||||
[vClassHeader("THROW COLLECTABLE", false)]
|
||||
public class vThrowCollectable : vMonoBehaviour
|
||||
{
|
||||
public string throwableName;
|
||||
public int amount = 1;
|
||||
public bool destroyAfter = true;
|
||||
|
||||
public UnityEngine.Events.UnityEvent onCanCollect;
|
||||
public UnityEngine.Events.UnityEvent onCanCollectFromInventory;
|
||||
public UnityEngine.Events.UnityEvent onIsStandAloneManager;
|
||||
public UnityEngine.Events.UnityEvent onIsInventoryManager;
|
||||
public UnityEngine.Events.UnityEvent onCollectObject;
|
||||
public UnityEngine.Events.UnityEvent onReachMaxObjects;
|
||||
public UnityEngine.Events.UnityEvent onEnterTrigger;
|
||||
public UnityEngine.Events.UnityEvent onExitTrigger;
|
||||
|
||||
vThrowManagerBase throwManager;
|
||||
bool isInventory => throwManager != null && throwManager is vThrowManagerInventory;
|
||||
|
||||
Collider _throwManagerCollider;
|
||||
|
||||
protected bool canCollect;
|
||||
|
||||
bool _isInventory;
|
||||
private void OnTriggerStay(Collider other)
|
||||
{
|
||||
if (throwManager != null)
|
||||
{
|
||||
UpdateThrowInfo(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (other.gameObject.CompareTag("Player"))
|
||||
throwManager = other.GetComponentInChildren<vThrowManagerBase>();
|
||||
|
||||
if (throwManager != null)
|
||||
{
|
||||
|
||||
_throwManagerCollider = other;
|
||||
onEnterTrigger.Invoke();
|
||||
}
|
||||
|
||||
UpdateThrowInfo(true);
|
||||
}
|
||||
|
||||
private void OnTriggerExit(Collider other)
|
||||
{
|
||||
if (_throwManagerCollider != null && other.gameObject == _throwManagerCollider.gameObject)
|
||||
{
|
||||
_throwManagerCollider = null;
|
||||
throwManager = null;
|
||||
onExitTrigger.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateThrowInfo(bool firstEnter)
|
||||
{
|
||||
if (throwManager != null)
|
||||
{
|
||||
if (isInventory != _isInventory || firstEnter)
|
||||
{
|
||||
if (isInventory)
|
||||
{
|
||||
onIsInventoryManager.Invoke();
|
||||
}
|
||||
else onIsStandAloneManager.Invoke();
|
||||
_isInventory = isInventory;
|
||||
}
|
||||
|
||||
var _canCollect = throwManager.CanCollectThrowable(throwableName, out int remainingAmount);
|
||||
if (canCollect != _canCollect || firstEnter)
|
||||
{
|
||||
canCollect = _canCollect;
|
||||
if (_canCollect)
|
||||
{
|
||||
if (isInventory) onCanCollectFromInventory.Invoke();
|
||||
else onCanCollect.Invoke();
|
||||
}
|
||||
else
|
||||
{
|
||||
onReachMaxObjects.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateThrowObj()
|
||||
{
|
||||
if (throwManager.CanCollectThrowable(throwableName, out int remainingAmount))
|
||||
{
|
||||
throwManager.OnCollectThrowable(throwableName, amount);
|
||||
|
||||
if (amount <= remainingAmount)
|
||||
{
|
||||
if (destroyAfter) Destroy(this.gameObject);
|
||||
}
|
||||
else
|
||||
{
|
||||
amount -= remainingAmount;
|
||||
if (amount <= 0)
|
||||
{
|
||||
if (destroyAfter) Destroy(this.gameObject);
|
||||
}
|
||||
}
|
||||
onCollectObject.Invoke();
|
||||
}
|
||||
else
|
||||
{
|
||||
onReachMaxObjects.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4c9fbd7863561794c92d957d0295c2ec
|
||||
timeCreated: 1501612221
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,64 @@
|
||||
using UnityEngine;
|
||||
namespace Invector.Throw
|
||||
{
|
||||
[RequireComponent(typeof(LineRenderer))]
|
||||
[vClassHeader("Line Controller", openClose = false)]
|
||||
public class vThrowLineController : vThrowVisualControlBase
|
||||
{
|
||||
protected LineRenderer line;
|
||||
public string materialTextureChannel = "_MainTex";
|
||||
public string materialColorChannel = "_Color";
|
||||
|
||||
public float lineWidthMultiplier = 1f;
|
||||
|
||||
protected override void OnInit(vThrowManagerBase tm)
|
||||
{
|
||||
line = GetComponent<LineRenderer>();
|
||||
}
|
||||
|
||||
public override void OnChangeVisual(vThrowVisualSettings settings)
|
||||
{
|
||||
if (settings != null && line)
|
||||
{
|
||||
line.enabled = settings.useLine;
|
||||
SetLineColor(settings.lineRendererColor);
|
||||
SetLineWidth(settings.lineRendererWidth);
|
||||
SetLineTexture(settings.lineTexture);
|
||||
SetLineAlignment(settings.lineAlignment);
|
||||
SetLineTextureMode(settings.lineTextureMode);
|
||||
SetLineTextureScale(settings.lineTile);
|
||||
SetLineTextureOffset(settings.lineOffset);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void SetLineColor(Color color)
|
||||
{
|
||||
|
||||
line.material.SetColor(materialColorChannel, color);
|
||||
}
|
||||
public virtual void SetLineAlignment(LineAlignment alignment)
|
||||
{
|
||||
line.alignment = alignment;
|
||||
}
|
||||
public virtual void SetLineWidth(float size)
|
||||
{
|
||||
line.widthMultiplier = size * lineWidthMultiplier;
|
||||
}
|
||||
public virtual void SetLineTexture(Texture2D texture)
|
||||
{
|
||||
line.material.SetTexture(materialTextureChannel, texture);
|
||||
}
|
||||
public virtual void SetLineTextureMode(LineTextureMode lineTextureMode)
|
||||
{
|
||||
line.textureMode = lineTextureMode;
|
||||
}
|
||||
public virtual void SetLineTextureScale(Vector2 scale)
|
||||
{
|
||||
line.material.SetTextureScale(materialTextureChannel, scale);
|
||||
}
|
||||
public virtual void SetLineTextureOffset(Vector2 offset)
|
||||
{
|
||||
line.material.SetTextureOffset(materialTextureChannel, offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 907d2082a34283146a0864cc35094936
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
279
Assets/Scripts/Player/ThrowSystem/Scripts/vThrowManager.cs
Normal file
279
Assets/Scripts/Player/ThrowSystem/Scripts/vThrowManager.cs
Normal file
@@ -0,0 +1,279 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
namespace Invector.Throw
|
||||
{
|
||||
[vClassHeader("THROW MANAGER STANDALONE")]
|
||||
public class vThrowManager : vThrowManagerBase
|
||||
{
|
||||
[System.Serializable]
|
||||
public class Throwable
|
||||
{
|
||||
public string name = "ThrowableName";
|
||||
public Transform handler;
|
||||
public vThrowableObject throwable;
|
||||
public Sprite sprite;
|
||||
public int amount;
|
||||
public int maxAmount;
|
||||
vThrowableObject _throwableInHandler;
|
||||
internal vThrowableObject throwableInHandler
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_throwableInHandler == null)
|
||||
{
|
||||
_throwableInHandler = Instantiate(throwable, handler);
|
||||
_throwableInHandler.transform.localPosition = Vector3.zero;
|
||||
_throwableInHandler.transform.localEulerAngles = Vector3.zero;
|
||||
_throwableInHandler.gameObject.SetActive(false);
|
||||
|
||||
}
|
||||
|
||||
return _throwableInHandler;
|
||||
}
|
||||
|
||||
}
|
||||
public void ResetThrowable()
|
||||
{
|
||||
_throwableInHandler = null;
|
||||
}
|
||||
|
||||
internal void SetActive(bool value)
|
||||
{
|
||||
if (_throwableInHandler)
|
||||
{
|
||||
_throwableInHandler.gameObject.SetActive(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[vEditorToolbar("Throwables")]
|
||||
[SerializeField]
|
||||
protected List<Throwable> throwables;
|
||||
|
||||
[SerializeField] protected int defaultMaxAmount = 6;
|
||||
|
||||
public int indexOfCurrentThrowable;
|
||||
public virtual List<Throwable> Throwables { get => throwables; }
|
||||
|
||||
protected Throwable _currentThrowable;
|
||||
protected vThrowUI _ui;
|
||||
public virtual vThrowUI ui
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!_ui)
|
||||
{
|
||||
_ui = GetComponentInChildren<vThrowUI>();
|
||||
if (_ui)
|
||||
{
|
||||
_ui.UpdateCount(this);
|
||||
}
|
||||
}
|
||||
return _ui;
|
||||
}
|
||||
}
|
||||
|
||||
protected override IEnumerator Start()
|
||||
{
|
||||
yield return base.Start();
|
||||
if (ui != null)
|
||||
{
|
||||
ui.UpdateCount(this);
|
||||
}
|
||||
onThrowObject.AddListener(UpdateUI);
|
||||
|
||||
for (int i = 0; i < Throwables.Count; i++)
|
||||
{
|
||||
Throwables[i].throwableInHandler.gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void StartThrow()
|
||||
{
|
||||
base.StartThrow();
|
||||
CurrentThrowable.amount--;
|
||||
}
|
||||
|
||||
protected override void Throw()
|
||||
{
|
||||
base.Throw();
|
||||
CurrentThrowable.ResetThrowable();
|
||||
}
|
||||
|
||||
protected override void DisableAimMode()
|
||||
{
|
||||
base.DisableAimMode();
|
||||
if (CurrentThrowable != null && !isThrowing) CurrentThrowable.SetActive(false);
|
||||
}
|
||||
|
||||
protected override void EquipThrowObject()
|
||||
{
|
||||
base.EquipThrowObject();
|
||||
if (CurrentThrowable != null) CurrentThrowable.SetActive(true);
|
||||
}
|
||||
|
||||
protected override vThrowableObject GetInstanceOfThrowable()
|
||||
{
|
||||
return ObjectToThrow;
|
||||
}
|
||||
|
||||
public override int MaxThrowObjects { get => CurrentThrowable != null ? CurrentThrowable.maxAmount : 0; }
|
||||
public override Sprite CurrentThrowableSprite { get => CurrentThrowable != null ? CurrentThrowable.sprite : null; }
|
||||
public override int CurrentThrowAmount { get => CurrentThrowable != null ? CurrentThrowable.amount : 0; }
|
||||
public override vThrowableObject ObjectToThrow { get => CurrentThrowable != null ? CurrentThrowable.throwableInHandler : null; }
|
||||
public Throwable CurrentThrowable
|
||||
{
|
||||
get
|
||||
{
|
||||
if (indexOfCurrentThrowable < throwables.Count)
|
||||
{
|
||||
return throwables[indexOfCurrentThrowable];
|
||||
}
|
||||
else
|
||||
{
|
||||
indexOfCurrentThrowable = 0;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void NextThrowable()
|
||||
{
|
||||
var _index = 0;
|
||||
if (indexOfCurrentThrowable + 1 < throwables.Count)
|
||||
{
|
||||
_index = indexOfCurrentThrowable + 1;
|
||||
}
|
||||
if (throwables[_index].amount > 0 || !isAiming)
|
||||
{
|
||||
SelectThrowable(_index);
|
||||
}
|
||||
else if (isAiming)
|
||||
{
|
||||
if (throwables.Exists(t => t.amount > 0))
|
||||
{
|
||||
for (int i = 0; i < throwables.Count; i++)
|
||||
{
|
||||
if (_index + 1 < throwables.Count)
|
||||
{
|
||||
_index++;
|
||||
}
|
||||
else
|
||||
{
|
||||
_index = 0;
|
||||
}
|
||||
if (throwables[_index].amount > 0)
|
||||
{
|
||||
SelectThrowable(_index);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UpdateUI();
|
||||
}
|
||||
|
||||
public void PreviousThrowable()
|
||||
{
|
||||
var _index = throwables.Count - 1;
|
||||
if (indexOfCurrentThrowable - 1 >= 0)
|
||||
{
|
||||
_index = indexOfCurrentThrowable - 1;
|
||||
}
|
||||
if (throwables[_index].amount > 0 || !isAiming)
|
||||
{
|
||||
SelectThrowable(_index);
|
||||
}
|
||||
else if (isAiming)
|
||||
{
|
||||
if (throwables.Exists(t => t.amount > 0))
|
||||
{
|
||||
for (int i = 0; i < throwables.Count; i++)
|
||||
{
|
||||
if (_index - 1 >= 0)
|
||||
{
|
||||
_index--;
|
||||
}
|
||||
else
|
||||
{
|
||||
_index = throwables.Count - 1;
|
||||
}
|
||||
if (throwables[_index].amount > 0)
|
||||
{
|
||||
SelectThrowable(_index);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UpdateUI();
|
||||
}
|
||||
|
||||
public void SelectThrowable(int indexOfThrowable)
|
||||
{
|
||||
if (inEnterThrowMode || isThrowing) return;
|
||||
|
||||
bool wasAiming = isAiming;
|
||||
DisableAimMode();
|
||||
ExitThrowMode();
|
||||
if (indexOfThrowable >= 0 && indexOfThrowable < throwables.Count)
|
||||
{
|
||||
indexOfCurrentThrowable = indexOfThrowable;
|
||||
}
|
||||
if (wasAiming && CurrentThrowAmount > 0)
|
||||
{
|
||||
EnterThrowMode();
|
||||
}
|
||||
UpdateUI();
|
||||
}
|
||||
|
||||
public override bool CanCollectThrowable(string throwableName, out int remainingAmount)
|
||||
{
|
||||
var throwable = throwables.Find(t => t.name.Equals(throwableName));
|
||||
if (throwable != null)
|
||||
{
|
||||
remainingAmount = throwable.maxAmount - throwable.amount;
|
||||
|
||||
return remainingAmount > 0;
|
||||
}
|
||||
remainingAmount = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void OnCollectThrowable(string throwableName, int amount = 1)
|
||||
{
|
||||
var throwable = throwables.Find(t => t.name.Equals(throwableName));
|
||||
|
||||
if (throwable != null)
|
||||
{
|
||||
int remainingAmount = throwable.maxAmount - throwable.amount;
|
||||
|
||||
if (remainingAmount > 0)
|
||||
{
|
||||
int targetAmount = 0;
|
||||
if (remainingAmount >= amount)
|
||||
{
|
||||
targetAmount = amount;
|
||||
}
|
||||
else
|
||||
{
|
||||
targetAmount = remainingAmount;
|
||||
}
|
||||
throwable.amount += targetAmount;
|
||||
UpdateUI();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void UpdateUI()
|
||||
{
|
||||
if (ui != null)
|
||||
{
|
||||
ui.UpdateCount(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3488aeb9d116a01419bf76222e7bf1d4
|
||||
timeCreated: 1490915601
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
666
Assets/Scripts/Player/ThrowSystem/Scripts/vThrowManagerBase.cs
Normal file
666
Assets/Scripts/Player/ThrowSystem/Scripts/vThrowManagerBase.cs
Normal file
@@ -0,0 +1,666 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
namespace Invector.Throw
|
||||
{
|
||||
using Invector.vCharacterController;
|
||||
public abstract class vThrowManagerBase : vMonoBehaviour
|
||||
{
|
||||
[System.Serializable]
|
||||
public class VisualEvent : UnityEngine.Events.UnityEvent<vThrowVisualSettings> { }
|
||||
[System.Serializable]
|
||||
public class SettingsEvent : UnityEngine.Events.UnityEvent<vThrowSettings> { }
|
||||
[System.Serializable]
|
||||
public class ActiveEvent : UnityEngine.Events.UnityEvent<bool> { }
|
||||
|
||||
#region Variables
|
||||
|
||||
public enum CameraStyle
|
||||
{
|
||||
ThirdPerson, TopDown, SideScroll
|
||||
}
|
||||
|
||||
[vEditorToolbar("Settings")]
|
||||
public CameraStyle cameraStyle;
|
||||
|
||||
[Tooltip("Use this to enable/disable if you can or not enter ThrowMode")]
|
||||
public bool canUseThrow;
|
||||
|
||||
[Tooltip("Check this to use the Line that draws the Throw Trajectory")]
|
||||
public bool drawTrajectory = true;
|
||||
public LineRenderer lineRenderer;
|
||||
|
||||
[Tooltip("This is the Starting point of the Throw")]
|
||||
public Transform throwStartPoint;
|
||||
|
||||
[Tooltip("This is the Ending point (landing) of the Throw")]
|
||||
public GameObject throwEnd;
|
||||
public LayerMask obstacles = 1 << 0;
|
||||
public vThrowSettings defaultSettings;
|
||||
public vThrowVisualSettings defaultVisualSettings;
|
||||
|
||||
[Tooltip("Set ignore collision to the grenade to not collide with the Player")]
|
||||
public bool setIgnoreCollision;
|
||||
public bool debugMode;
|
||||
|
||||
[vSeparator("Only for ThirdPerson Camera Style")]
|
||||
[Tooltip("The Third person camera right will be applied as offset to throw start point")]
|
||||
public bool useThrowStartRightOffset;
|
||||
|
||||
[Tooltip("Sets a Offset right for the Throw Start Point"), vHideInInspector("useThrowStartRightOffset")]
|
||||
public float throwStartRightOffsetMultiplier = 1f;
|
||||
|
||||
[vSeparator("Controller Settings")]
|
||||
|
||||
[Tooltip("Force the controller to walk while aiming")]
|
||||
public bool walkWhileAiming;
|
||||
|
||||
[Tooltip("Rotate to aim point while aiming")]
|
||||
public bool rotateWhileAiming = true;
|
||||
public bool rotateWhileThrowing = true;
|
||||
public bool strafeWhileAiming = true;
|
||||
|
||||
[vEditorToolbar("Inputs")]
|
||||
public GenericInput throwInput = new GenericInput("Mouse0", "RB", "RB");
|
||||
public GenericInput aimThrowInput = new GenericInput("G", "LB", "LB");
|
||||
public bool aimHoldingButton = true;
|
||||
|
||||
[vEditorToolbar("Events")]
|
||||
public UnityEngine.Events.UnityEvent onEquipThrowable;
|
||||
public UnityEngine.Events.UnityEvent onEnableAim;
|
||||
public UnityEngine.Events.UnityEvent onCancelAim;
|
||||
public UnityEngine.Events.UnityEvent onStartThrowObject;
|
||||
public UnityEngine.Events.UnityEvent onThrowObject;
|
||||
public UnityEngine.Events.UnityEvent onCollectObject;
|
||||
public UnityEngine.Events.UnityEvent onFinishThrow;
|
||||
|
||||
[vEditorToolbar("Visual Effect Events")]
|
||||
|
||||
[vSeparator("Line")]
|
||||
public ActiveEvent onSetActiveLine;
|
||||
|
||||
[vSeparator("Indicator")]
|
||||
public ActiveEvent onSetActiveIndicator;
|
||||
public SettingsEvent onChangeSettings;
|
||||
public VisualEvent onChangeVisualSettings;
|
||||
|
||||
public virtual int MaxThrowObjects { get; }
|
||||
public abstract int CurrentThrowAmount { get; }
|
||||
public virtual Sprite CurrentThrowableSprite { get; }
|
||||
|
||||
protected virtual Collider[] selfColliders { get; set; }
|
||||
/// <summary>
|
||||
/// Enter Aiming ThrowMode
|
||||
/// </summary>
|
||||
protected virtual bool isAiming { get; set; }
|
||||
/// <summary>
|
||||
/// "ThrowObject" animation is playing
|
||||
/// </summary>
|
||||
protected virtual bool isThrowing { get; set; }
|
||||
/// <summary>
|
||||
/// The moment you press the throwInput
|
||||
/// </summary>
|
||||
protected virtual bool pressThrowInput { get; set; }
|
||||
protected virtual bool wasAiming { get; set; }
|
||||
protected virtual bool inEnterThrowMode { get; set; }
|
||||
|
||||
protected virtual Vector3 surfaceNormal { get; set; }
|
||||
|
||||
protected virtual Transform rightUpperArm { get; set; }
|
||||
protected virtual vThirdPersonInput tpInput { get; set; }
|
||||
public abstract vThrowableObject ObjectToThrow { get; }
|
||||
protected virtual vThrowableObject lastThrowObject { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Settings
|
||||
public virtual vThrowSettings CurrentSettings
|
||||
{
|
||||
get
|
||||
{
|
||||
var settings = ObjectToThrow && ObjectToThrow.throwSettings ? ObjectToThrow.throwSettings : defaultSettings;
|
||||
if (settings != lastSettings)
|
||||
{
|
||||
lastSettings = settings;
|
||||
onChangeSettings.Invoke(lastSettings);
|
||||
}
|
||||
return settings;
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual vThrowSettings lastSettings { get; set; }
|
||||
|
||||
public virtual string cameraState => tpInput.cc.isCrouching ? CurrentSettings.cameraStateCrouching : CurrentSettings.cameraStateStanding;
|
||||
public virtual bool alignToSurfaceNormal => CurrentSettings.alignToSurfaceNormal;
|
||||
public virtual bool alignToViewWhenNotHit => CurrentSettings.alignToViewWhenNotHit;
|
||||
public virtual bool disableEndPointWhenNotHit => CurrentSettings.disableEndPointWhenNotHit;
|
||||
public virtual float alignmentSmooth => CurrentSettings.alignmentSmooth;
|
||||
public virtual float metersPerSeconds => CurrentSettings.metersPerSeconds;
|
||||
public virtual Vector2 minMaxTime => CurrentSettings.minMaxTime;
|
||||
public virtual float maxDistance => CurrentSettings.maxDistance;
|
||||
public virtual float maxVelocity => CurrentSettings.maxVelocity;
|
||||
public virtual float throwMaxForce => CurrentSettings.throwMaxForce;
|
||||
public virtual float throwDelayTime => CurrentSettings.throwDelayTime;
|
||||
public virtual float lineStepPerTime => CurrentSettings.lineStepPerTime;
|
||||
public virtual float lineMaxLength => CurrentSettings.maxLineLength;
|
||||
public virtual float exitThrowModeDelay => CurrentSettings.exitThrowModeDelay;
|
||||
public virtual string throwAnimation => CurrentSettings.throwAnimation;
|
||||
public virtual string holdingAnimation => CurrentSettings.holdingAnimation;
|
||||
public virtual string cancelAnimation => CurrentSettings.cancelAnimation;
|
||||
#endregion
|
||||
|
||||
#region Visual
|
||||
public virtual vThrowVisualSettings CurrentVisualSettings
|
||||
{
|
||||
get
|
||||
{
|
||||
var settings = ObjectToThrow && ObjectToThrow.throwVisualSettings ? ObjectToThrow.throwVisualSettings : defaultVisualSettings;
|
||||
if (settings != lastSettings)
|
||||
{
|
||||
lastVisualSettings = settings;
|
||||
onChangeVisualSettings.Invoke(lastVisualSettings);
|
||||
}
|
||||
return settings;
|
||||
}
|
||||
}
|
||||
protected virtual vThrowVisualSettings lastVisualSettings { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
protected virtual IEnumerator Start()
|
||||
{
|
||||
yield return new WaitForEndOfFrame();
|
||||
|
||||
if (lineRenderer == null) lineRenderer = GetComponentInChildren<LineRenderer>(true);
|
||||
|
||||
if (lineRenderer)
|
||||
{
|
||||
lineRenderer.useWorldSpace = false;
|
||||
}
|
||||
if (lineRenderer && lineRenderer.gameObject.activeInHierarchy)
|
||||
{
|
||||
lineRenderer.gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
|
||||
if (throwEnd && throwEnd.activeSelf)
|
||||
{
|
||||
throwEnd.SetActive(false);
|
||||
}
|
||||
|
||||
if (transform.root.TryGetComponent(out vDrawHideMeleeWeapons drawHide))
|
||||
{
|
||||
onEquipThrowable.AddListener(() => drawHide.HideWeapons(true));
|
||||
}
|
||||
|
||||
canUseThrow = true;
|
||||
|
||||
tpInput = GetComponentInParent<vThirdPersonInput>();
|
||||
|
||||
if (tpInput)
|
||||
{
|
||||
selfColliders = tpInput.GetComponentsInChildren<Collider>(true);
|
||||
tpInput.onUpdate -= UpdateThrowInput;
|
||||
tpInput.onUpdate += UpdateThrowInput;
|
||||
tpInput.onFixedUpdate -= UpdateThrowBehavior;
|
||||
tpInput.onFixedUpdate += UpdateThrowBehavior;
|
||||
rightUpperArm = tpInput.animator.GetBoneTransform(HumanBodyBones.RightUpperArm);
|
||||
|
||||
if (cameraStyle == CameraStyle.SideScroll)
|
||||
{
|
||||
rotateWhileAiming = true;
|
||||
}
|
||||
|
||||
}
|
||||
if (cameraStyle != CameraStyle.ThirdPerson)
|
||||
{
|
||||
useThrowStartRightOffset = false;
|
||||
rotateWhileAiming = true;
|
||||
strafeWhileAiming = true;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void CanUseThrow(bool value)
|
||||
{
|
||||
canUseThrow = value;
|
||||
}
|
||||
|
||||
protected virtual bool ThrowConditions => !(ObjectToThrow == null || CurrentThrowAmount <= 0 || !tpInput.enabled || tpInput.cc.customAction || canUseThrow == false);
|
||||
|
||||
protected virtual void UpdateThrowBehavior()
|
||||
{
|
||||
CheckThrowObjectChanges();
|
||||
UpdateThrow();
|
||||
MoveAndRotate();
|
||||
}
|
||||
|
||||
protected virtual void CheckThrowObjectChanges()
|
||||
{
|
||||
if (ObjectToThrow != lastThrowObject)
|
||||
{
|
||||
lastThrowObject = ObjectToThrow;
|
||||
onSetActiveLine.Invoke(CurrentVisualSettings.useLine);
|
||||
onSetActiveIndicator.Invoke(CurrentVisualSettings.useIndicator);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void UpdateThrow()
|
||||
{
|
||||
|
||||
if (isAiming)
|
||||
{
|
||||
tpInput.CrouchInput();
|
||||
wasAiming = true;
|
||||
tpInput.SetWalkByDefault(walkWhileAiming);
|
||||
if (string.IsNullOrEmpty(cameraState) == false && tpInput.customCameraState != cameraState) tpInput.ChangeCameraStateWithLerp(cameraState);
|
||||
CalculateAimPoint();
|
||||
if (drawTrajectory) DrawTrajectory();
|
||||
if (debugMode) Debug.DrawLine(startPoint, aimPoint, Color.cyan);
|
||||
}
|
||||
else if (!inEnterThrowMode)
|
||||
{
|
||||
if (wasAiming)
|
||||
{
|
||||
tpInput.ResetWalkByDefault();
|
||||
if (string.IsNullOrEmpty(cameraState) == false && tpInput.customCameraState == cameraState) tpInput.ResetCameraState();
|
||||
if (lineRenderer && lineRenderer.gameObject.activeInHierarchy)
|
||||
{
|
||||
lineRenderer.gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
if (throwEnd && throwEnd.activeSelf)
|
||||
{
|
||||
throwEnd.SetActive(false);
|
||||
}
|
||||
}
|
||||
wasAiming = false;
|
||||
}
|
||||
|
||||
if (pressThrowInput)
|
||||
{
|
||||
isThrowing = true;
|
||||
pressThrowInput = false;
|
||||
tpInput.animator.SetBool("IsAiming", false);
|
||||
tpInput.animator.CrossFadeInFixedTime(throwAnimation, 0.2f);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void MoveAndRotate()
|
||||
{
|
||||
if (isAiming || isThrowing || inEnterThrowMode)
|
||||
{
|
||||
tpInput.MoveInput();
|
||||
|
||||
switch (cameraStyle)
|
||||
{
|
||||
case CameraStyle.ThirdPerson:
|
||||
if (rotateWhileAiming && !isThrowing || (isThrowing && rotateWhileThrowing))
|
||||
{
|
||||
|
||||
tpInput.cc.RotateToDirection(tpInput.cameraMain.transform.forward);
|
||||
}
|
||||
break;
|
||||
case CameraStyle.TopDown:
|
||||
var dir = aimDirection;
|
||||
dir.y = 0;
|
||||
if (isThrowing || rotateWhileAiming) tpInput.cc.RotateToDirection(dir);
|
||||
break;
|
||||
case CameraStyle.SideScroll:
|
||||
///
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void UpdateThrowInput()
|
||||
{
|
||||
if (!ThrowConditions)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (aimThrowInput.GetButtonDown() && !inEnterThrowMode && !isThrowing && !isAiming)
|
||||
{
|
||||
EnterThrowMode();
|
||||
return;
|
||||
}
|
||||
|
||||
if (aimThrowInput.GetButtonUp() && aimHoldingButton && (isAiming || inEnterThrowMode) && !isThrowing)
|
||||
{
|
||||
ExitThrowMode();
|
||||
}
|
||||
|
||||
if (isAiming && !isThrowing && !pressThrowInput)
|
||||
{
|
||||
if (throwInput.GetButtonDown())
|
||||
{
|
||||
pressThrowInput = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!aimHoldingButton && aimThrowInput.GetButtonDown() && !pressThrowInput && (isAiming || inEnterThrowMode) && !isThrowing)
|
||||
{
|
||||
ExitThrowMode();
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual vThrowableObject GetInstanceOfThrowable()
|
||||
{
|
||||
return Instantiate(ObjectToThrow, startPoint, Quaternion.identity);
|
||||
}
|
||||
|
||||
protected virtual void Throw()
|
||||
{
|
||||
LaunchObject(GetInstanceOfThrowable());
|
||||
ExitThrowMode();
|
||||
}
|
||||
|
||||
protected virtual void LaunchObject(vThrowableObject throwable)
|
||||
{
|
||||
|
||||
if (setIgnoreCollision)
|
||||
{
|
||||
var _colliders = throwable.GetComponentsInChildren<Collider>();
|
||||
if (_colliders.Length > 0)
|
||||
{
|
||||
foreach (var _collider in _colliders)
|
||||
for (int i = 0; i < selfColliders.Length; i++)
|
||||
{
|
||||
Physics.IgnoreCollision(_collider, selfColliders[i], true);
|
||||
}
|
||||
}
|
||||
}
|
||||
throwable.transform.position = startPoint;
|
||||
throwable.isKinematic = false;
|
||||
throwable.transform.parent = null;
|
||||
throwable.onThrow.Invoke(tpInput.transform);
|
||||
throwable.selfRigidbody.linearVelocity = StartVelocity;
|
||||
onThrowObject.Invoke();
|
||||
}
|
||||
|
||||
protected virtual void DrawTrajectory()
|
||||
{
|
||||
float time = Vector3.Distance(startPoint, aimPoint) * metersPerSeconds;
|
||||
time = Mathf.Clamp(time, minMaxTime.x, minMaxTime.y);
|
||||
Vector3? hitPoint = null;
|
||||
|
||||
var points = GetTrajectoryPoints(startPoint, StartVelocity, lineStepPerTime, lineMaxLength, ref hitPoint);
|
||||
if (lineRenderer)
|
||||
{
|
||||
lineRenderer.transform.rotation = Quaternion.LookRotation(Quaternion.AngleAxis(90, transform.right) * (points[points.Count - 1] - startPoint).normalized);
|
||||
if (!lineRenderer.gameObject.activeInHierarchy)
|
||||
{
|
||||
lineRenderer.gameObject.SetActive(true);
|
||||
}
|
||||
|
||||
lineRenderer.positionCount = points.Count;
|
||||
for (int i = 0; i < lineRenderer.positionCount; i++)
|
||||
{
|
||||
lineRenderer.SetPosition(i, lineRenderer.transform.InverseTransformPoint(points[i]));
|
||||
}
|
||||
|
||||
}
|
||||
if (throwEnd)
|
||||
{
|
||||
if (!throwEnd.activeSelf)
|
||||
{
|
||||
if ((!disableEndPointWhenNotHit || hitPoint != null))
|
||||
throwEnd.SetActive(true);
|
||||
}
|
||||
else if (!(!disableEndPointWhenNotHit || hitPoint != null))
|
||||
{
|
||||
throwEnd.SetActive(false);
|
||||
}
|
||||
if (points.Count > 1)
|
||||
{
|
||||
throwEnd.transform.position = points[points.Count - 1];
|
||||
throwEnd.transform.rotation = Quaternion.Lerp(throwEnd.transform.rotation, Quaternion.LookRotation(surfaceNormal, transform.up), alignmentSmooth * Time.deltaTime);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal virtual void TriggerAnimatorEvent(vThrowAnimatorEvent.ThrowEventType eventType)
|
||||
{
|
||||
switch (eventType)
|
||||
{
|
||||
case vThrowAnimatorEvent.ThrowEventType.EquipThrowable:
|
||||
onEquipThrowable.Invoke();
|
||||
EquipThrowObject();
|
||||
break;
|
||||
case vThrowAnimatorEvent.ThrowEventType.EnableAiming:
|
||||
EnableAimMode();
|
||||
break;
|
||||
case vThrowAnimatorEvent.ThrowEventType.CancelAiming:
|
||||
DisableAimMode();
|
||||
ExitThrowMode();
|
||||
break;
|
||||
case vThrowAnimatorEvent.ThrowEventType.StartLaunch:
|
||||
DisableAimMode();
|
||||
StartThrow();
|
||||
break;
|
||||
case vThrowAnimatorEvent.ThrowEventType.FinishLaunch:
|
||||
Throw();
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected virtual void EquipThrowObject()
|
||||
{
|
||||
onEquipThrowable.Invoke();
|
||||
}
|
||||
|
||||
protected virtual void EnableAimMode()
|
||||
{
|
||||
inEnterThrowMode = false;
|
||||
isAiming = true;
|
||||
onEnableAim.Invoke();
|
||||
}
|
||||
|
||||
protected virtual void DisableAimMode()
|
||||
{
|
||||
inEnterThrowMode = false;
|
||||
isAiming = false;
|
||||
onCancelAim.Invoke();
|
||||
}
|
||||
|
||||
protected virtual void EnterThrowMode()
|
||||
{
|
||||
inEnterThrowMode = true;
|
||||
tpInput.animator.CrossFadeInFixedTime(holdingAnimation, 0.2f);
|
||||
tpInput.SetLockAllInput(true);
|
||||
tpInput.SetStrafeLocomotion(strafeWhileAiming);
|
||||
if (string.IsNullOrEmpty(cameraState) == false && tpInput.customCameraState != cameraState) tpInput.ChangeCameraStateWithLerp(cameraState);
|
||||
tpInput.cc.isSprinting = false;
|
||||
tpInput.animator.SetInteger("ActionState", 1);
|
||||
if (cameraStyle == CameraStyle.SideScroll)
|
||||
{
|
||||
tpInput.cc.strafeSpeed.rotateWithCamera = true;
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void StartThrow()
|
||||
{
|
||||
onStartThrowObject.Invoke();
|
||||
}
|
||||
|
||||
protected virtual void ExitThrowMode()
|
||||
{
|
||||
isThrowing = false;
|
||||
tpInput.SetLockAllInput(false);
|
||||
tpInput.SetStrafeLocomotion(false);
|
||||
tpInput.cc.isSprinting = false;
|
||||
tpInput.animator.SetInteger("ActionState", 0);
|
||||
onFinishThrow.Invoke();
|
||||
}
|
||||
|
||||
public virtual bool CanCollectThrowable(string throwableName, out int remainingAmount) { remainingAmount = 0; return false; }
|
||||
|
||||
public virtual void OnCollectThrowable(string throwableName, int amount = 1) { }
|
||||
|
||||
protected virtual Vector3 thirdPersonAimPoint
|
||||
{
|
||||
get
|
||||
{
|
||||
Vector3 endPoint = tpInput.cameraMain.transform.position + tpInput.cameraMain.transform.forward * maxDistance;
|
||||
if (Physics.Linecast(tpInput.cameraMain.transform.position, endPoint, out RaycastHit hit, obstacles))
|
||||
{
|
||||
endPoint = hit.point;
|
||||
}
|
||||
return endPoint;
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual Vector3 topDownAimPoint
|
||||
{
|
||||
get
|
||||
{
|
||||
var pos = vMousePositionHandler.Instance.WorldMousePosition(obstacles);
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual Vector3 sideScrollAimPoint
|
||||
{
|
||||
get
|
||||
{
|
||||
Vector3 screen = vMousePositionHandler.Instance.mousePosition;
|
||||
screen.z = tpInput.cameraMain.WorldToScreenPoint(startPoint).z;
|
||||
var world = tpInput.cameraMain.ScreenToWorldPoint(screen, Camera.MonoOrStereoscopicEye.Mono);
|
||||
var local = transform.InverseTransformVector(world);
|
||||
var localStart = transform.InverseTransformVector(startPoint);
|
||||
local.x = localStart.x;
|
||||
return transform.TransformVector(local);
|
||||
}
|
||||
}
|
||||
protected virtual Vector3 startPoint
|
||||
{
|
||||
get
|
||||
{
|
||||
Vector3 startPosition = throwStartPoint.position;
|
||||
var direction = aimPoint - throwStartPoint.position;
|
||||
|
||||
var localPoint = Vector3.zero;
|
||||
localPoint.y = throwStartPoint.localPosition.y;
|
||||
var localStartPoint = transform.InverseTransformPoint(startPosition);
|
||||
Vector3 point = transform.TransformPoint(localPoint) + direction.normalized * localStartPoint.z;
|
||||
if (useThrowStartRightOffset && tpInput && tpInput.tpCamera && tpInput.tpCamera.lerpState != null)
|
||||
{
|
||||
point += tpInput.tpCamera.transform.right * tpInput.tpCamera.lerpState.right * throwStartRightOffsetMultiplier * tpInput.tpCamera.switchRight;
|
||||
}
|
||||
var directionFromCenter = point - transform.TransformPoint(localPoint);
|
||||
if (Physics.Linecast(transform.TransformPoint(localPoint), point, out RaycastHit hit, obstacles))
|
||||
point = hit.point - directionFromCenter.normalized * 0.2f;
|
||||
return point;
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual Vector3 StartVelocity
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetStartVelocity();
|
||||
//if (cameraStyle != CameraStyle.SideScroll)
|
||||
//{
|
||||
// return GetStartVelocity();
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// var force = throwMaxForce;
|
||||
// return aimDirection.normalized * force;
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void CalculateAimPoint()
|
||||
{
|
||||
switch (cameraStyle)
|
||||
{
|
||||
case CameraStyle.ThirdPerson:
|
||||
aimPoint = thirdPersonAimPoint;
|
||||
break;
|
||||
case CameraStyle.TopDown:
|
||||
aimPoint = topDownAimPoint;
|
||||
break;
|
||||
case CameraStyle.SideScroll:
|
||||
aimPoint = sideScrollAimPoint;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual Vector3 GetStartVelocity(Vector3? startPoint = null)
|
||||
{
|
||||
var endPoint = this.aimPoint;
|
||||
Vector3 distance = endPoint - (startPoint != null ? (Vector3)startPoint : this.startPoint);
|
||||
Vector3 distanceXZ = distance;
|
||||
// distanceXZ.y = 0;
|
||||
|
||||
float Sy = distance.y;
|
||||
float Sxz = distanceXZ.magnitude;
|
||||
float time = Mathf.Clamp(distance.magnitude / metersPerSeconds, minMaxTime.x, minMaxTime.y);
|
||||
float Vxz = Sxz / time;
|
||||
float Vy = Sy / time + 0.5f * Mathf.Abs(Physics.gravity.y) * time;
|
||||
|
||||
Vector3 result = distanceXZ.normalized;
|
||||
|
||||
result *= Vxz;
|
||||
result.y = Vy;
|
||||
return result.normalized * Mathf.Min(maxVelocity, result.magnitude);
|
||||
}
|
||||
|
||||
protected virtual Vector3 PlotTrajectoryAtTime(Vector3 start, Vector3 startVelocity, float time)
|
||||
{
|
||||
return start + startVelocity * time + Physics.gravity * time * time * 0.5f;
|
||||
}
|
||||
|
||||
protected virtual List<Vector3> GetTrajectoryPoints(Vector3 start, Vector3 startVelocity, float timestep, float maxLength, ref Vector3? hitPoint)
|
||||
{
|
||||
Vector3 prev = start;
|
||||
List<Vector3> points = new List<Vector3>();
|
||||
points.Add(prev);
|
||||
|
||||
surfaceNormal = alignToViewWhenNotHit ? (tpInput.cameraMain.transform.position - aimPoint).normalized : Vector3.up;
|
||||
float distance = 0;
|
||||
|
||||
for (int i = 1; ; i++)
|
||||
{
|
||||
float t = timestep * i;
|
||||
Vector3 pos = PlotTrajectoryAtTime(start, startVelocity, t);
|
||||
RaycastHit hit;
|
||||
var dir = (pos - prev).normalized;
|
||||
if (Physics.Linecast(prev, pos + dir * 0.1f, out hit, obstacles))
|
||||
{
|
||||
points.Add(hit.point);
|
||||
if (alignToSurfaceNormal) surfaceNormal = hit.normal;
|
||||
hitPoint = hit.point;
|
||||
if (debugMode) Debug.DrawLine(prev, hit.point, Color.red);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (debugMode) Debug.DrawLine(prev, pos, Color.red);
|
||||
points.Add(pos);
|
||||
distance += (pos - prev).magnitude;
|
||||
prev = pos;
|
||||
if (distance > maxLength) break;
|
||||
}
|
||||
}
|
||||
return points;
|
||||
}
|
||||
|
||||
public virtual Vector3 aimPoint
|
||||
{
|
||||
get; protected set;
|
||||
}
|
||||
|
||||
public virtual Vector3 aimDirection
|
||||
{
|
||||
get
|
||||
{
|
||||
return aimPoint - startPoint;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8241b7fda1fc27640810e55b17ca859f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- lineRenderer: {instanceID: 0}
|
||||
- throwStartPoint: {instanceID: 0}
|
||||
- throwEnd: {instanceID: 0}
|
||||
- defaultSettings: {fileID: 11400000, guid: 8caa7855be6643747a8251ca4ca9a1c9, type: 2}
|
||||
- defaultVisualSettings: {instanceID: 0}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,374 @@
|
||||
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Invector.Throw
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using vItemManager;
|
||||
|
||||
[vClassHeader("THROW MANAGER WITH INVENTORY")]
|
||||
public class vThrowManagerInventory : vThrowManagerBase
|
||||
{
|
||||
[vEditorToolbar("Throwable")]
|
||||
public bool useEquipArea;
|
||||
[vHideInInspector("useEquipArea")]
|
||||
public int indexOfEquipmentArea;
|
||||
[vHideInInspector("useEquipArea", true)]
|
||||
public vItemType itemType = vItemType.Consumable;
|
||||
|
||||
public Transform defaultHandler;
|
||||
public Transform[] customHandlers;
|
||||
|
||||
protected override IEnumerator Start()
|
||||
{
|
||||
yield return base.Start();
|
||||
itemManager = GetComponentInParent<vItemManager>();
|
||||
itemManager.inventory.OnUpdateInventory += UpdateThrowableItems;
|
||||
targetEquipArea = itemManager.inventory.equipAreas[indexOfEquipmentArea];
|
||||
if (useEquipArea == false)
|
||||
{
|
||||
if (itemManager.items.Count > 0)
|
||||
{
|
||||
var items = itemManager.items.FindAll(item => item.originalObject != null && item.originalObject.TryGetComponent(out vThrowableObject throwableObject));
|
||||
|
||||
for (int i = 0; i < items.Count; i++)
|
||||
{
|
||||
items[i].canBeEquipped = false;
|
||||
}
|
||||
}
|
||||
itemManager.onAddItem.AddListener((vItem item) =>
|
||||
{
|
||||
if (item.originalObject != null && item.originalObject.TryGetComponent(out vThrowableObject throwableObject))
|
||||
{
|
||||
item.canBeEquipped = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
UpdateThrowableItems();
|
||||
UpdateCurrentThrowableItem();
|
||||
}
|
||||
|
||||
protected virtual vItemManager itemManager
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
protected virtual vThrowUI _ui
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public virtual vThrowUI ui
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!_ui)
|
||||
{
|
||||
_ui = GetComponentInChildren<vThrowUI>();
|
||||
if (_ui)
|
||||
{
|
||||
_ui.UpdateCount(this);
|
||||
}
|
||||
}
|
||||
return _ui;
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual int lastItemID { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// All throwables used to show in hand and to be launch
|
||||
/// </summary>
|
||||
public Dictionary<int, vThrowableObject> throwableInHandler = new Dictionary<int, vThrowableObject>();
|
||||
|
||||
/// <summary>
|
||||
/// Used to store all items in the <see cref="vItemManager.itemListData"/> that contains a <see cref="vThrowableObject"/>.
|
||||
/// </summary>
|
||||
public virtual List<vItem> throwables { get; set; }
|
||||
[vEditorToolbar("Debug"), SerializeField]
|
||||
protected /*virtual*/ vItem _throwableItem; /*{ get; set; }*/
|
||||
|
||||
public virtual vItem CurrentThrowableItem
|
||||
{
|
||||
get
|
||||
{
|
||||
UpdateCurrentThrowableItem();
|
||||
return _throwableItem;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual Transform GetHandler(string name)
|
||||
{
|
||||
Transform handler = System.Array.Find(customHandlers, c => c.gameObject.name == name);
|
||||
if (handler == null) handler = defaultHandler;
|
||||
return handler;
|
||||
}
|
||||
|
||||
public virtual vEquipArea targetEquipArea { get; set; }
|
||||
[vEditorToolbar("Debug"), SerializeField]
|
||||
protected /*virtual*/ vThrowableObject _objectToThrow;// { get; set; }
|
||||
|
||||
public virtual int indexOfCurrentThrowable { get; set; }
|
||||
|
||||
public virtual void UpdateThrowableItems()
|
||||
{
|
||||
if (!useEquipArea)
|
||||
throwables = itemManager.itemListData.items.FindAll(i => i.type == itemType && i.originalObject != null && i.originalObject.TryGetComponent<vThrowableObject>(out vThrowableObject t));
|
||||
|
||||
if (useEquipArea && (targetEquipArea.currentEquippedItem != _throwableItem) && !isThrowing)
|
||||
{
|
||||
bool wasAiming = isAiming;
|
||||
DisableAimMode();
|
||||
ExitThrowMode();
|
||||
UpdateCurrentThrowableItem();
|
||||
if (wasAiming && CurrentThrowAmount > 0)
|
||||
{
|
||||
EnterThrowMode();
|
||||
}
|
||||
}
|
||||
|
||||
UpdateUI();
|
||||
}
|
||||
|
||||
public virtual void UpdateCurrentThrowableItem()
|
||||
{
|
||||
if (isThrowing) return;
|
||||
|
||||
if (useEquipArea)
|
||||
{
|
||||
if (targetEquipArea.currentEquippedItem != _throwableItem)
|
||||
{
|
||||
_throwableItem = targetEquipArea.currentEquippedItem;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
_throwableItem = throwables[indexOfCurrentThrowable];
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
if (_throwableItem != null)
|
||||
{
|
||||
|
||||
lastItemID = _throwableItem.id;
|
||||
if (defaultHandler == null)
|
||||
{
|
||||
Debug.LogWarning("THROWMANAGER NEEDS A HANDLER ASSIGNED IN THE INSPECTOR", this);
|
||||
return;
|
||||
}
|
||||
|
||||
if (_throwableItem.originalObject && _throwableItem.originalObject.TryGetComponent(out vThrowableObject _throwable))
|
||||
{
|
||||
if (!throwableInHandler.ContainsKey(lastItemID))
|
||||
{
|
||||
throwableInHandler.Add(lastItemID, null);
|
||||
}
|
||||
if (throwableInHandler[lastItemID] == null)
|
||||
{
|
||||
throwableInHandler[lastItemID] = InstantiateNewThrowable(_throwable, GetHandler(_throwableItem.customHandler));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if (_throwableItem && throwableInHandler.ContainsKey(lastItemID))
|
||||
_objectToThrow = throwableInHandler[lastItemID];
|
||||
else if (useEquipArea && !inEnterThrowMode && !isThrowing)
|
||||
{
|
||||
_objectToThrow = null;
|
||||
DisableAimMode();
|
||||
ExitThrowMode();
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual vThrowableObject InstantiateNewThrowable(vThrowableObject _throwable, Transform _handler)
|
||||
{
|
||||
var throwable = Instantiate(_throwable, _handler);
|
||||
throwable.gameObject.SetActive(false);
|
||||
throwable.transform.localPosition = Vector3.zero;
|
||||
throwable.transform.localEulerAngles = Vector3.zero;
|
||||
return throwable;
|
||||
}
|
||||
|
||||
public virtual void NextThrowable()
|
||||
{
|
||||
var _index = 0;
|
||||
if (indexOfCurrentThrowable + 1 < throwables.Count)
|
||||
{
|
||||
_index = indexOfCurrentThrowable + 1;
|
||||
}
|
||||
if (itemManager.GetAllAmount(throwables[_index].id) > 0 || !isAiming)
|
||||
{
|
||||
SelectThrowable(_index);
|
||||
}
|
||||
else if (isAiming)
|
||||
{
|
||||
if (throwables.Exists(t => itemManager.GetAllAmount(t.id) > 0))
|
||||
{
|
||||
for (int i = 0; i < throwables.Count; i++)
|
||||
{
|
||||
if (_index + 1 < throwables.Count)
|
||||
{
|
||||
_index++;
|
||||
}
|
||||
else
|
||||
{
|
||||
_index = 0;
|
||||
}
|
||||
if (itemManager.GetAllAmount(throwables[_index].id) > 0)
|
||||
{
|
||||
SelectThrowable(_index);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UpdateUI();
|
||||
}
|
||||
|
||||
public virtual void PreviousThrowable()
|
||||
{
|
||||
var _index = throwables.Count - 1;
|
||||
if (indexOfCurrentThrowable - 1 >= 0)
|
||||
{
|
||||
_index = indexOfCurrentThrowable - 1;
|
||||
}
|
||||
if (itemManager.GetAllAmount(throwables[_index].id) > 0 || !isAiming)
|
||||
{
|
||||
SelectThrowable(_index);
|
||||
}
|
||||
else if (isAiming)
|
||||
{
|
||||
if (throwables.Exists(t => itemManager.GetAllAmount(t.id) > 0))
|
||||
{
|
||||
for (int i = 0; i < throwables.Count; i++)
|
||||
{
|
||||
if (_index - 1 >= 0)
|
||||
{
|
||||
_index--;
|
||||
}
|
||||
else
|
||||
{
|
||||
_index = throwables.Count - 1;
|
||||
}
|
||||
if (itemManager.GetAllAmount(throwables[_index].id) > 0)
|
||||
{
|
||||
SelectThrowable(_index);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UpdateUI();
|
||||
}
|
||||
|
||||
public virtual void SelectThrowable(int indexOfThrowable)
|
||||
{
|
||||
if (useEquipArea || inEnterThrowMode || isThrowing) return;
|
||||
|
||||
bool wasAiming = isAiming;
|
||||
DisableAimMode();
|
||||
ExitThrowMode();
|
||||
if (indexOfThrowable >= 0 && indexOfThrowable < throwables.Count)
|
||||
{
|
||||
indexOfCurrentThrowable = indexOfThrowable;
|
||||
}
|
||||
if (wasAiming && CurrentThrowAmount > 0)
|
||||
{
|
||||
EnterThrowMode();
|
||||
}
|
||||
UpdateUI();
|
||||
}
|
||||
|
||||
public virtual void UpdateUI()
|
||||
{
|
||||
if (ui != null)
|
||||
{
|
||||
ui.UpdateCount(this, false);
|
||||
}
|
||||
}
|
||||
|
||||
#region Overrides
|
||||
public override int MaxThrowObjects { get => CurrentThrowableItem != null ? CurrentThrowableItem.maxStack : 0; }
|
||||
|
||||
public override Sprite CurrentThrowableSprite { get => CurrentThrowableItem != null ? CurrentThrowableItem.icon : null; }
|
||||
|
||||
public override int CurrentThrowAmount
|
||||
{
|
||||
get
|
||||
{
|
||||
if (CurrentThrowableItem)
|
||||
{
|
||||
if (useEquipArea == false)
|
||||
return itemManager.GetAllAmount(CurrentThrowableItem.id);
|
||||
else return CurrentThrowableItem.amount;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public override vThrowableObject ObjectToThrow { get { return _objectToThrow; } }
|
||||
|
||||
protected override void StartThrow()
|
||||
{
|
||||
itemManager.LockInventoryInput(true);
|
||||
base.StartThrow();
|
||||
if (itemManager)
|
||||
{
|
||||
if (CurrentThrowableItem && throwableInHandler.ContainsKey(lastItemID) && throwableInHandler[lastItemID])
|
||||
{
|
||||
throwableInHandler[lastItemID] = null;
|
||||
}
|
||||
itemManager.DestroyItem(itemManager.GetItem(lastItemID), 1);
|
||||
}
|
||||
|
||||
if (!useEquipArea)
|
||||
UpdateUI();
|
||||
}
|
||||
protected override void Throw()
|
||||
{
|
||||
base.Throw();
|
||||
itemManager.LockInventoryInput(false);
|
||||
}
|
||||
|
||||
protected override void DisableAimMode()
|
||||
{
|
||||
base.DisableAimMode();
|
||||
if (!isThrowing && throwableInHandler.ContainsKey(lastItemID) && throwableInHandler[lastItemID])
|
||||
{
|
||||
throwableInHandler[lastItemID].gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void EquipThrowObject()
|
||||
{
|
||||
if (throwableInHandler.ContainsKey(lastItemID) && throwableInHandler[lastItemID])
|
||||
{
|
||||
throwableInHandler[lastItemID].gameObject.SetActive(true);
|
||||
}
|
||||
base.EquipThrowObject();
|
||||
}
|
||||
|
||||
protected override vThrowableObject GetInstanceOfThrowable()
|
||||
{
|
||||
return ObjectToThrow;
|
||||
}
|
||||
|
||||
public override bool CanCollectThrowable(string throwableName, out int remainingAmount)
|
||||
{
|
||||
remainingAmount = 99999;
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void OnCollectThrowable(string throwableName, int amount = 1)
|
||||
{
|
||||
/// Override to ignore this method to get throwables only from inventory
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: eb61a71d8f68e2c4ea71e5f66c4c2db0
|
||||
timeCreated: 1490915601
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,46 @@
|
||||
using UnityEngine;
|
||||
namespace Invector.Throw
|
||||
{
|
||||
[RequireComponent(typeof(Projector))]
|
||||
[vClassHeader("Range Projector Controller", openClose = false)]
|
||||
public class vThrowRangeProjectorController : vThrowVisualControlBase
|
||||
{
|
||||
protected Projector projector;
|
||||
public string materialTextureChannel = "_MainTex";
|
||||
public string materialColorChannel = "_Color";
|
||||
public float projectorSizeMultiplier = 1f;
|
||||
|
||||
protected override void OnInit(vThrowManagerBase tm)
|
||||
{
|
||||
projector = GetComponent<Projector>();
|
||||
|
||||
if (tm)
|
||||
{
|
||||
tm.onSetActiveIndicator.AddListener((bool active) => projector.enabled = active);
|
||||
}
|
||||
}
|
||||
public override void OnChangeVisual(vThrowVisualSettings settings)
|
||||
{
|
||||
if (settings != null && projector)
|
||||
{
|
||||
projector.enabled = settings.useIndicator;
|
||||
SetProjectorColor(settings.indicatorColor);
|
||||
SetProjectorSize(settings.indicatorRange);
|
||||
SetProjectorTexture(settings.indicatorTexture);
|
||||
}
|
||||
}
|
||||
public void SetProjectorColor(Color color)
|
||||
{
|
||||
projector.material.SetColor(materialColorChannel, color);
|
||||
}
|
||||
public void SetProjectorSize(float size)
|
||||
{
|
||||
if(tm.ObjectToThrow!=null)
|
||||
projector.orthographicSize = size * projectorSizeMultiplier * tm.ObjectToThrow.indicatorRangeMultiplier;
|
||||
}
|
||||
public void SetProjectorTexture(Texture2D texture)
|
||||
{
|
||||
projector.material.SetTexture(materialTextureChannel, texture);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b94288e1b7f8e3a4888a6629c3c1223f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
34
Assets/Scripts/Player/ThrowSystem/Scripts/vThrowSettings.cs
Normal file
34
Assets/Scripts/Player/ThrowSystem/Scripts/vThrowSettings.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
using UnityEngine;
|
||||
namespace Invector.Throw
|
||||
{
|
||||
[CreateAssetMenu(menuName = "Invector/Throw/New ThrowSettings")]
|
||||
public class vThrowSettings : ScriptableObject
|
||||
{
|
||||
[Tooltip("Align End point UP to surface normal direction")]
|
||||
public bool alignToSurfaceNormal = true;
|
||||
[Tooltip("End point UP always face to the view direction when don't has a surface")]
|
||||
public bool alignToViewWhenNotHit = true;
|
||||
public bool disableEndPointWhenNotHit = true;
|
||||
[Tooltip("End point alignment smooth")]
|
||||
public float alignmentSmooth = 20f;
|
||||
[Min(0.001f)]
|
||||
public float metersPerSeconds = 0.1f;
|
||||
[vMinMax(0.0001f, 10)]
|
||||
public Vector2 minMaxTime = new Vector2(0.1f, 1);
|
||||
public float maxDistance = 100;
|
||||
public float maxVelocity = 10;
|
||||
public float throwMaxForce = 15f;
|
||||
public float throwDelayTime = .25f;
|
||||
[Min(0.001f)]
|
||||
public float lineStepPerTime = .1f;
|
||||
public float maxLineLength = 100;
|
||||
public float exitThrowModeDelay = 0.5f;
|
||||
|
||||
public string cameraStateStanding = "ThrowStanding";
|
||||
public string cameraStateCrouching = "ThrowCrouching";
|
||||
|
||||
public string throwAnimation = "ThrowObject";
|
||||
public string holdingAnimation = "HoldingObject";
|
||||
public string cancelAnimation = "CancelThrow";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7fb5203a5ac07dd4989daca90a70c804
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
18
Assets/Scripts/Player/ThrowSystem/Scripts/vThrowUI.cs
Normal file
18
Assets/Scripts/Player/ThrowSystem/Scripts/vThrowUI.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Invector.Throw
|
||||
{
|
||||
public class vThrowUI : MonoBehaviour
|
||||
{
|
||||
public Text maxThrowCount;
|
||||
public Text currentThrowCount;
|
||||
public Image display;
|
||||
internal virtual void UpdateCount(vThrowManagerBase throwManager,bool showMaxAmount = true)
|
||||
{
|
||||
if (currentThrowCount) currentThrowCount.text = throwManager.CurrentThrowAmount.ToString();
|
||||
if (maxThrowCount) maxThrowCount.text = showMaxAmount? throwManager.MaxThrowObjects.ToString():"";
|
||||
if (display) display.sprite = throwManager.CurrentThrowableSprite;
|
||||
}
|
||||
}
|
||||
}
|
||||
12
Assets/Scripts/Player/ThrowSystem/Scripts/vThrowUI.cs.meta
Normal file
12
Assets/Scripts/Player/ThrowSystem/Scripts/vThrowUI.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8c62d44258c35b24a90d91f36f02bcb5
|
||||
timeCreated: 1501614917
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,18 @@
|
||||
namespace Invector.Throw
|
||||
{
|
||||
public abstract partial class vThrowVisualControlBase : vMonoBehaviour
|
||||
{
|
||||
protected vThrowManagerBase tm;
|
||||
protected virtual void Awake()
|
||||
{
|
||||
tm = GetComponentInParent<vThrowManagerBase>();
|
||||
if (tm)
|
||||
{
|
||||
OnInit(tm);
|
||||
tm.onChangeVisualSettings.AddListener(OnChangeVisual);
|
||||
}
|
||||
}
|
||||
protected abstract void OnInit(vThrowManagerBase manager);
|
||||
public abstract void OnChangeVisual(vThrowVisualSettings settings);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9c6fa38254eb5544785fc0e59af9e70a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,24 @@
|
||||
using UnityEngine;
|
||||
namespace Invector.Throw
|
||||
{
|
||||
[CreateAssetMenu(menuName = "Invector/Throw/New ThrowVisualSettings")]
|
||||
public class vThrowVisualSettings : ScriptableObject
|
||||
{
|
||||
[vSeparator("Visual Line")]
|
||||
public bool useLine;
|
||||
[ColorUsage(true, true)]
|
||||
public Color lineRendererColor = Color.white;
|
||||
public float lineRendererWidth = 1f;
|
||||
internal LineAlignment lineAlignment = LineAlignment.TransformZ;
|
||||
public Texture2D lineTexture;
|
||||
public LineTextureMode lineTextureMode = LineTextureMode.Stretch;
|
||||
public Vector2 lineTile = Vector2.one;
|
||||
public Vector2 lineOffset = Vector2.zero;
|
||||
[vSeparator("Visual Indicator")]
|
||||
public bool useIndicator;
|
||||
[ColorUsage(true, true)]
|
||||
public Color indicatorColor = Color.white;
|
||||
public float indicatorRange = 1f;
|
||||
public Texture2D indicatorTexture;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d854fe8482a859c49abe5b9575ff1321
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,45 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Invector.Throw
|
||||
{
|
||||
[DisallowMultipleComponent]
|
||||
[RequireComponent(typeof(Rigidbody))]
|
||||
[vClassHeader("Throwable Object", openClose = false)]
|
||||
public class vThrowableObject : vMonoBehaviour
|
||||
{
|
||||
[System.Serializable]
|
||||
public class ThrowSenderEvent : UnityEngine.Events.UnityEvent<Transform> { }
|
||||
|
||||
protected Rigidbody _rigidbody;
|
||||
public vThrowSettings throwSettings;
|
||||
public vThrowVisualSettings throwVisualSettings;
|
||||
public float indicatorRangeMultiplier = 1f;
|
||||
public ThrowSenderEvent onThrow;
|
||||
public virtual Rigidbody selfRigidbody
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_rigidbody == null)
|
||||
{
|
||||
if (TryGetComponent(out Rigidbody r)) _rigidbody = r;
|
||||
else _rigidbody = gameObject.AddComponent<Rigidbody>();
|
||||
}
|
||||
return _rigidbody;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static implicit operator Rigidbody(vThrowableObject throwable) => throwable.selfRigidbody;
|
||||
public virtual bool isKinematic
|
||||
{
|
||||
get
|
||||
{
|
||||
return selfRigidbody.isKinematic;
|
||||
}
|
||||
set
|
||||
{
|
||||
selfRigidbody.isKinematic = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9b862849ae0308c439b127a1f3778273
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- indicatorTexture: {fileID: 2800000, guid: db48e0e5caa2999469a4f3aa249c188b, type: 3}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user