243 lines
8.0 KiB
C#
243 lines
8.0 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using Beyond;
|
|
using Invector;
|
|
using Invector.vCharacterController;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
|
|
namespace Beyond
|
|
{
|
|
[vClassHeader("MELEE LOCK-ON")]
|
|
public class bLockOn : vLockOnBehaviour
|
|
{
|
|
#region variables
|
|
|
|
[System.Serializable]
|
|
public class LockOnEvent : UnityEngine.Events.UnityEvent<Transform>
|
|
{ }
|
|
|
|
[Tooltip("Make sure to disable or change the StrafeInput to a different key at the Player Input component")]
|
|
public bool strafeWhileLockOn = true;
|
|
|
|
[Tooltip("Create a Image inside the UI and assign here")]
|
|
public RectTransform aimImagePrefab;
|
|
|
|
public Canvas aimImageContainer;
|
|
public Vector2 aimImageSize = new Vector2(30, 30);
|
|
|
|
[Tooltip("True: Hide the sprite when not Lock On, False: Always show the Sprite")]
|
|
public bool hideSprite = true;
|
|
|
|
[Tooltip("Create a offset for the sprite based at the center of the target")]
|
|
[Range(-0.5f, 0.5f)]
|
|
public float spriteHeight = 0.25f;
|
|
|
|
[Tooltip("Offset for the camera height")]
|
|
public float cameraHeightOffset;
|
|
|
|
[Tooltip("Transition Speed for the Camera")]
|
|
public float lockSpeed = 0.5f;
|
|
|
|
[Header("LockOn Inputs")]
|
|
public GenericInput lockOnInput = new GenericInput("Tab", "RightStickClick", "RightStickClick");
|
|
|
|
public GenericInput nexTargetInput = new GenericInput("X", false, false, "RightAnalogHorizontal", true, false, "X", false, false);
|
|
public GenericInput previousTargetInput = new GenericInput("Z", false, false, "RightAnalogHorizontal", true, true, "Z", false, false);
|
|
|
|
internal bool isLockingOn;
|
|
public LockOnEvent onLockOnTarget;
|
|
public LockOnEvent onUnLockOnTarget;
|
|
private Canvas _aimCanvas;
|
|
private RectTransform _aimImage;
|
|
|
|
protected bool inTarget;
|
|
protected bMeleeCombatInput tpInput;
|
|
|
|
#endregion variables
|
|
|
|
protected virtual void Start()
|
|
{
|
|
Init();
|
|
tpInput = GetComponent<bMeleeCombatInput>();
|
|
if (tpInput)
|
|
{
|
|
tpInput.onUpdate -= UpdateLockOn;
|
|
tpInput.onUpdate += UpdateLockOn;
|
|
|
|
// access the HealthController to Reset the LockOn when Dead
|
|
GetComponent<vHealthController>().onDead.AddListener((GameObject g) =>
|
|
{
|
|
// action to reset lockOn
|
|
isLockingOn = false;
|
|
LockOn(false);
|
|
UpdateLockOn();
|
|
});
|
|
}
|
|
|
|
if (!aimImageContainer)
|
|
{
|
|
aimImageContainer = gameObject.GetComponentInChildren<Canvas>(true);
|
|
}
|
|
}
|
|
|
|
public RectTransform aimImage
|
|
{
|
|
get
|
|
{
|
|
if (_aimImage) return _aimImage;
|
|
if (aimImageContainer)
|
|
{
|
|
_aimImage = Instantiate(aimImagePrefab, Vector2.zero, Quaternion.identity) as RectTransform;
|
|
_aimImage.SetParent(aimImageContainer.transform);
|
|
return _aimImage;
|
|
}
|
|
else
|
|
{
|
|
Debug.LogWarning("Missing UI Canvas in the scene, please add one");
|
|
}
|
|
return null;
|
|
}
|
|
}
|
|
|
|
protected virtual void UpdateLockOn()
|
|
{
|
|
if (this.tpInput == null) return;
|
|
LockOnInput();
|
|
SwitchTargetsInput();
|
|
CheckForCharacterAlive();
|
|
UpdateAimImage();
|
|
}
|
|
|
|
protected virtual void LockOnInput()
|
|
{
|
|
if (tpInput.tpCamera == null || tpInput.cc == null) return;
|
|
|
|
// lock the camera into a target, if there is any around
|
|
if (lockOnInput.GetButtonDown() && !tpInput.cc.customAction)
|
|
{
|
|
isLockingOn = !isLockingOn;
|
|
LockOn(isLockingOn);
|
|
}
|
|
// unlock the camera if the target is null
|
|
else if (isLockingOn && (tpInput.tpCamera.lockTarget == null))
|
|
{
|
|
isLockingOn = false;
|
|
LockOn(false);
|
|
}
|
|
// choose to use lock-on with strafe of free movement
|
|
if (strafeWhileLockOn && !tpInput.cc.locomotionType.Equals(vThirdPersonMotor.LocomotionType.OnlyStrafe))
|
|
{
|
|
if (isLockingOn && tpInput.tpCamera.lockTarget != null)
|
|
{
|
|
tpInput.cc.lockInStrafe = true;
|
|
tpInput.cc.isStrafing = true;
|
|
}
|
|
else
|
|
{
|
|
tpInput.cc.lockInStrafe = false;
|
|
tpInput.cc.isStrafing = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
protected override void SetTarget()
|
|
{
|
|
if (tpInput.tpCamera != null)
|
|
{
|
|
tpInput.tpCamera.SetLockTarget(currentTarget.transform, cameraHeightOffset, lockSpeed);
|
|
onLockOnTarget.Invoke(currentTarget);
|
|
}
|
|
}
|
|
|
|
protected virtual void SwitchTargetsInput()
|
|
{
|
|
if (tpInput.tpCamera == null) return;
|
|
|
|
if (tpInput.tpCamera.lockTarget)
|
|
{
|
|
// switch between targets using Keyboard
|
|
if (previousTargetInput.GetButtonDown()) PreviousTarget();
|
|
else if (nexTargetInput.GetButtonDown()) NextTarget();
|
|
}
|
|
}
|
|
|
|
protected virtual void CheckForCharacterAlive()
|
|
{
|
|
if (currentTarget && !isCharacterAlive() && inTarget || (inTarget && !isCharacterAlive()))
|
|
{
|
|
ResetLockOn();
|
|
inTarget = false;
|
|
LockOn(true);
|
|
StopLockOn();
|
|
}
|
|
}
|
|
|
|
protected virtual void LockOn(bool value)
|
|
{
|
|
base.UpdateLockOn(value);
|
|
if (!inTarget && currentTarget)
|
|
{
|
|
inTarget = true;
|
|
// send current target if inTarget
|
|
SetTarget();
|
|
}
|
|
else if (inTarget && !currentTarget)
|
|
{
|
|
inTarget = false;
|
|
// send message to clear current target
|
|
StopLockOn();
|
|
}
|
|
}
|
|
|
|
public void SetLockOnToFalse()
|
|
{
|
|
LockOn(false);
|
|
}
|
|
|
|
protected virtual void UpdateAimImage()
|
|
{
|
|
if (!aimImageContainer || !aimImage) return;
|
|
if (hideSprite)
|
|
{
|
|
aimImage.sizeDelta = aimImageSize;
|
|
if (currentTarget && !aimImage.transform.gameObject.activeSelf && isCharacterAlive())
|
|
aimImage.transform.gameObject.SetActive(true);
|
|
else if (!currentTarget && aimImage.transform.gameObject.activeSelf)
|
|
aimImage.transform.gameObject.SetActive(false);
|
|
else if (_aimImage.transform.gameObject.activeSelf && !isCharacterAlive())
|
|
aimImage.transform.gameObject.SetActive(false);
|
|
}
|
|
if (currentTarget && aimImage && aimImageContainer)
|
|
aimImage.anchoredPosition = currentTarget.GetScreenPointOffBoundsCenter(aimImageContainer, tpCamera.targetCamera, spriteHeight);
|
|
else if (aimImageContainer)
|
|
aimImage.anchoredPosition = Vector2.zero;
|
|
}
|
|
|
|
public virtual void StopLockOn()
|
|
{
|
|
if (currentTarget == null && tpInput.tpCamera != null)
|
|
{
|
|
onUnLockOnTarget.Invoke(tpInput.tpCamera.lockTarget);
|
|
tpInput.tpCamera.RemoveLockTarget();
|
|
isLockingOn = false;
|
|
inTarget = false;
|
|
}
|
|
}
|
|
|
|
public virtual void NextTarget()
|
|
{
|
|
base.ChangeTarget(1);
|
|
}
|
|
|
|
public virtual void PreviousTarget()
|
|
{
|
|
base.ChangeTarget(-1);
|
|
}
|
|
|
|
public List<Transform> GetNearbyTargets()
|
|
{
|
|
return base.GetPossibleTargets();
|
|
}
|
|
}
|
|
} |