Update
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c2e3f8cd2ef673047b4fc676d660590b
|
||||
folderAsset: yes
|
||||
timeCreated: 1498604789
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,81 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1 &126414
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- component: {fileID: 22467274}
|
||||
- component: {fileID: 22212822}
|
||||
- component: {fileID: 11417396}
|
||||
m_Layer: 5
|
||||
m_Name: lockOnSprite
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!114 &11417396
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 126414}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: -765806418, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
|
||||
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
m_Sprite: {fileID: 21300000, guid: b10e654cb30db34489b832dbfbb54370, type: 3}
|
||||
m_Type: 0
|
||||
m_PreserveAspect: 0
|
||||
m_FillCenter: 1
|
||||
m_FillMethod: 4
|
||||
m_FillAmount: 1
|
||||
m_FillClockwise: 1
|
||||
m_FillOrigin: 0
|
||||
--- !u!222 &22212822
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 126414}
|
||||
--- !u!224 &22467274
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 126414}
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0.5, y: 0.5}
|
||||
m_AnchorMax: {x: 0.5, y: 0.5}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 35, y: 35}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!1001 &100100000
|
||||
Prefab:
|
||||
m_ObjectHideFlags: 1
|
||||
serializedVersion: 2
|
||||
m_Modification:
|
||||
m_TransformParent: {fileID: 0}
|
||||
m_Modifications: []
|
||||
m_RemovedComponents: []
|
||||
m_ParentPrefab: {fileID: 0}
|
||||
m_RootGameObject: {fileID: 126414}
|
||||
m_IsPrefabParent: 1
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f2c21a5084b380e45af41fac8083c307
|
||||
timeCreated: 1498604792
|
||||
licenseType: Store
|
||||
NativeFormatImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 50296ec695effaf4482ddb9d93c64826
|
||||
folderAsset: yes
|
||||
timeCreated: 1498606747
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 26 KiB |
@@ -0,0 +1,88 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b10e654cb30db34489b832dbfbb54370
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
externalObjects: {}
|
||||
serializedVersion: 9
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 1
|
||||
sRGBTexture: 1
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: -1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: 16
|
||||
mipBias: -100
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: 1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 1
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 8
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 2
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID: 42396f0bf693e9c4d90c7ab35295ab9d
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
spritePackingTag:
|
||||
pSDRemoveMatte: 0
|
||||
pSDShowRemoveMatteOption: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,243 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Invector.vCharacterController
|
||||
{
|
||||
[vClassHeader("MELEE LOCK-ON")]
|
||||
public class vLockOn : 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;
|
||||
protected Canvas _aimCanvas;
|
||||
protected RectTransform _aimImage;
|
||||
|
||||
protected bool _inTarget;
|
||||
protected virtual bool inTarget { get { return _inTarget; } set { _inTarget = value; } }
|
||||
protected vThirdPersonInput tpInput;
|
||||
|
||||
#endregion
|
||||
|
||||
protected override void Start()
|
||||
{
|
||||
base.Start();
|
||||
Init();
|
||||
|
||||
tpInput = GetComponent<vThirdPersonInput>();
|
||||
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();
|
||||
CheckForTargetDistance();
|
||||
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) || LostTargetDistance())
|
||||
{
|
||||
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 virtual bool LostTargetDistance()
|
||||
{
|
||||
if (!isLockingOn || currentTarget == null) return false;
|
||||
|
||||
float distance = Vector3.Distance(transform.position, currentTarget.position);
|
||||
|
||||
return distance > rangeToExitLockOn ? true : 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 CheckForTargetDistance()
|
||||
{
|
||||
if (!isLockingOn || currentTarget == null) return;
|
||||
|
||||
float distance = Vector3.Distance(transform.position, currentTarget.position);
|
||||
|
||||
if (distance > rangeToExitLockOn)
|
||||
{
|
||||
isLockingOn = false;
|
||||
LockOn(false);
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 47c91cac344662340bbbedbdbed00328
|
||||
timeCreated: 1498605023
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- aimImagePrefab: {fileID: 22467274, guid: f2c21a5084b380e45af41fac8083c307, type: 2}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,461 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Invector.vCharacterController
|
||||
{
|
||||
[vClassHeader("Lock-On")]
|
||||
public abstract class vLockOnBehaviour : vMonoBehaviour
|
||||
{
|
||||
#region properties
|
||||
|
||||
protected Transform watcher;
|
||||
[Tooltip("Tags of objects that can be found")]
|
||||
public string[] tagsToFind = new string[] { "Enemy" };
|
||||
[Tooltip("Check this option to only Lock into target within the camera field of view")]
|
||||
public bool withinCameraView = true;
|
||||
[vHideInInspector("withinCameraView"), Tooltip("Get only target inside screen margins")]
|
||||
public bool onlyInsideRect = true;
|
||||
[Tooltip("Layer of Obstacle to prevent the find for targets")]
|
||||
public LayerMask layerOfObstacles = 1 << 0;
|
||||
[Range(0, 1)]
|
||||
[Tooltip("Use this to set a margin of Aim point ")]
|
||||
public float screenMarginX = 0.8f;
|
||||
[Range(0, 1)]
|
||||
[Tooltip("Use this to set a margin of Aim point ")]
|
||||
public float screenMarginY = 0.1f;
|
||||
[Tooltip("Range of the search for targets")]
|
||||
public float rangeToEnterLockOn = 10f;
|
||||
[Tooltip("Range to auto exit lock")]
|
||||
public float rangeToExitLockOn = 15f;
|
||||
[Tooltip("Show the Gizmos and helpers")]
|
||||
public bool showDebug;
|
||||
public float timeToChangeTarget = 0.25f;
|
||||
|
||||
protected int index = 0;
|
||||
protected List<Transform> visibles;
|
||||
protected Transform _target;
|
||||
protected virtual Transform target { get { return _target; } set { _target = value; } }
|
||||
protected vCamera.vThirdPersonCamera tpCamera;
|
||||
protected Rect rect;
|
||||
protected bool _inLockOn;
|
||||
protected bool changingTarget;
|
||||
|
||||
#endregion
|
||||
|
||||
#region public methods
|
||||
|
||||
protected virtual void Start()
|
||||
{
|
||||
if (rangeToExitLockOn < rangeToEnterLockOn) rangeToExitLockOn = rangeToEnterLockOn;
|
||||
}
|
||||
/// <summary>
|
||||
/// change the current target to next target of possibles target
|
||||
/// if exist more than 1 target in list
|
||||
/// </summary>
|
||||
public virtual void ChangeTarget(int value)
|
||||
{
|
||||
StartCoroutine(ChangeTargetRoutine(value));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get current target
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public virtual Transform currentTarget
|
||||
{
|
||||
get { return target; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if Current target(vIHealthController) is Alive
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public virtual bool isCharacterAlive()
|
||||
{
|
||||
if (currentTarget == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var healthController = currentTarget.GetComponent<vIHealthController>();
|
||||
if (healthController == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
//if (ichar.ragdolled) return false;
|
||||
if (healthController.currentHealth > 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if target is a vIHealthController Alive
|
||||
/// </summary>
|
||||
/// <param name="other">target</param>
|
||||
/// <returns></returns>
|
||||
public virtual bool isCharacterAlive(Transform other)
|
||||
{
|
||||
var healthController = other.GetComponent<vIHealthController>();
|
||||
if (healthController == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
//if (ichar.ragdolled) return false;
|
||||
if (healthController.currentHealth > 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reset Lock on (removing currentTarget)
|
||||
/// </summary>
|
||||
public virtual void ResetLockOn()
|
||||
{
|
||||
target = null;
|
||||
_inLockOn = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get all target possibles
|
||||
/// </summary>
|
||||
public virtual List<Transform> allTargets
|
||||
{
|
||||
get { if (visibles != null && visibles.Count > 0) { return visibles; } return null; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region protected methods
|
||||
|
||||
protected virtual void UpdateLockOn(bool value)
|
||||
{
|
||||
if (value == true && value != _inLockOn)
|
||||
{
|
||||
_inLockOn = value;
|
||||
visibles = GetPossibleTargets();
|
||||
index = 0;
|
||||
if (visibles != null && visibles.Count > 0)
|
||||
{
|
||||
target = visibles[index];
|
||||
}
|
||||
}
|
||||
else if (value == false && value != _inLockOn)
|
||||
{
|
||||
_inLockOn = value;
|
||||
index = 0;
|
||||
target = null;
|
||||
if (visibles != null)
|
||||
{
|
||||
visibles.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual IEnumerator ChangeTargetRoutine(int value)
|
||||
{
|
||||
if (!changingTarget)
|
||||
{
|
||||
changingTarget = true;
|
||||
visibles = GetPossibleTargets();
|
||||
if ((_inLockOn == true && visibles != null && visibles.Count > 1))
|
||||
{
|
||||
if (index + value > visibles.Count - 1)
|
||||
{
|
||||
index = 0;
|
||||
}
|
||||
else if (index + value < 0)
|
||||
{
|
||||
index = visibles.Count - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
index += value;
|
||||
}
|
||||
|
||||
target = visibles[index];
|
||||
SetTarget();
|
||||
}
|
||||
yield return new WaitForSeconds(timeToChangeTarget);
|
||||
changingTarget = false;
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void SetTarget()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Draw GUI of Rect
|
||||
/// </summary>
|
||||
protected void OnGUI()
|
||||
{
|
||||
if (showDebug)
|
||||
{
|
||||
var width = Screen.width - (Screen.width * screenMarginX);
|
||||
var height = Screen.height - (Screen.height * screenMarginY);
|
||||
var posX = (Screen.width * 0.5f) - (width * 0.5f);
|
||||
var posY = (Screen.height * 0.5f) - (height * 0.5f);
|
||||
rect = new Rect(posX, posY, width, height);
|
||||
GUI.Box(rect, "");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Init the properts
|
||||
/// </summary>
|
||||
protected void Init()
|
||||
{
|
||||
if (Camera.main == null)
|
||||
{
|
||||
this.enabled = false;
|
||||
}
|
||||
|
||||
tpCamera = Camera.main.transform.root.GetComponent<vCamera.vThirdPersonCamera>();
|
||||
var width = Screen.width - (Screen.width * screenMarginX);
|
||||
var height = Screen.height - (Screen.height * screenMarginY);
|
||||
var posX = (Screen.width * 0.5f) - (width * 0.5f);
|
||||
var posY = (Screen.height * 0.5f) - (height * 0.5f);
|
||||
rect = new Rect(posX, posY, width, height);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Draw the range gizmo
|
||||
/// </summary>
|
||||
protected void OnDrawGizmos()
|
||||
{
|
||||
if (showDebug && watcher)
|
||||
{
|
||||
Gizmos.color = new Color(0, 1, 0, 0.2f);
|
||||
Gizmos.DrawSphere(watcher.position, rangeToEnterLockOn + 0.1f);
|
||||
if (visibles != null && visibles.Count > 0 && target != null)
|
||||
{
|
||||
visibles.ForEach(delegate (Transform _transform)
|
||||
{
|
||||
Gizmos.color = _transform.Equals(currentTarget) ? Color.red : Color.yellow;
|
||||
Gizmos.DrawSphere(_transform.GetComponent<Collider>().bounds.center, .5f);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// get all possible targets
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected virtual List<Transform> GetPossibleTargets()
|
||||
{
|
||||
if (tpCamera != null && tpCamera.mainTarget != null)
|
||||
{
|
||||
watcher = tpCamera.mainTarget;
|
||||
}
|
||||
else
|
||||
{
|
||||
watcher = transform;
|
||||
}
|
||||
|
||||
var listPrimary = new List<Transform>();
|
||||
var targets = Physics.SphereCastAll(watcher.position, rangeToEnterLockOn, watcher.forward, .01f);
|
||||
for (int i = 0; i < targets.Length; i++)
|
||||
{
|
||||
var hitOther = targets[i];
|
||||
if (tagsToFind.Contains(hitOther.transform.tag))
|
||||
{
|
||||
if (isCharacterAlive(hitOther.transform.GetComponent<Transform>()))
|
||||
{
|
||||
RaycastHit hit;
|
||||
var boundPoints = BoundPoints(hitOther.collider);
|
||||
for (int a = 0; a < boundPoints.Length; a++)
|
||||
{
|
||||
var point = boundPoints[a];
|
||||
if (Physics.Linecast(transform.position, point, out hit, layerOfObstacles))
|
||||
{
|
||||
if (hit.transform == hitOther.transform)
|
||||
{
|
||||
listPrimary.Add(hitOther.transform);
|
||||
|
||||
if (showDebug)
|
||||
{
|
||||
Debug.DrawLine(transform.position, point, Color.green, 2);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
else if (showDebug)
|
||||
{
|
||||
Debug.DrawLine(transform.position, point, Color.red, 2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
listPrimary.Add(hitOther.transform);
|
||||
|
||||
if (showDebug)
|
||||
{
|
||||
Debug.DrawLine(transform.position, point, Color.green, 2);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
SortTargets(ref listPrimary);
|
||||
return listPrimary;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sort the targets of possible targets by order of priority
|
||||
/// </summary>
|
||||
/// <param name="list"></param>
|
||||
protected void SortTargets(ref List<Transform> list)
|
||||
{
|
||||
if (tpCamera == null || tpCamera.targetCamera)
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
var lpriority_01 = new List<Transform>();
|
||||
var lpriority_02 = new List<Transform>();
|
||||
var lpriority_03 = new List<Transform>();
|
||||
Plane[] planes = GeometryUtility.CalculateFrustumPlanes(tpCamera.targetCamera);
|
||||
for (int i = 0; i < list.Count; i++)
|
||||
{
|
||||
var _transform = list[i];
|
||||
Vector2 screenPoint = tpCamera.targetCamera.WorldToScreenPoint(_transform.transform.position);
|
||||
//Check targets inside camera frustum
|
||||
if (GeometryUtility.TestPlanesAABB(planes, _transform.GetComponent<Collider>().bounds))
|
||||
{
|
||||
//target inside screenRect with margins
|
||||
if (rect.Contains(screenPoint))
|
||||
{
|
||||
lpriority_01.Add(_transform);
|
||||
}
|
||||
//targets only inside camera frustum
|
||||
else if (withinCameraView == false || (withinCameraView && !onlyInsideRect))
|
||||
{
|
||||
lpriority_02.Add(_transform);
|
||||
}
|
||||
}
|
||||
//targets outside camera frustum
|
||||
else if (withinCameraView == false)
|
||||
{
|
||||
lpriority_03.Add(_transform);
|
||||
}
|
||||
}
|
||||
|
||||
//targets only inside camera frustum
|
||||
//Order by screen center distance
|
||||
lpriority_01.Sort(delegate (Transform t1, Transform t2)
|
||||
{
|
||||
Vector2 screenPoint_01 = tpCamera.targetCamera.WorldToScreenPoint(t1.transform.position);
|
||||
Vector2 screenPoint_02 = tpCamera.targetCamera.WorldToScreenPoint(t2.transform.position);
|
||||
return Vector2.Distance(screenPoint_01, rect.center)
|
||||
.CompareTo(Vector2.Distance(screenPoint_02, rect.center));
|
||||
});
|
||||
//targets only inside camera frustum
|
||||
//Order by screen center distance
|
||||
lpriority_02.Sort(delegate (Transform t1, Transform t2)
|
||||
{
|
||||
Vector2 screenPoint_01 = tpCamera.targetCamera.WorldToScreenPoint(t1.transform.position);
|
||||
Vector2 screenPoint_02 = tpCamera.targetCamera.WorldToScreenPoint(t2.transform.position);
|
||||
return Vector2.Distance(screenPoint_01, rect.center)
|
||||
.CompareTo(Vector2.Distance(screenPoint_02, rect.center));
|
||||
});
|
||||
//targets outside camera frustum
|
||||
//Order by character distance
|
||||
lpriority_03.Sort(delegate (Transform t1, Transform t2)
|
||||
{
|
||||
return Vector3.Distance(t1.transform.position, transform.position)
|
||||
.CompareTo(Vector3.Distance(t2.transform.position, transform.position));
|
||||
});
|
||||
|
||||
list = lpriority_01.Union(lpriority_02).Union(lpriority_03).ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// return 8 bound points
|
||||
/// </summary>
|
||||
/// <param name="collider"></param>
|
||||
/// <returns></returns>
|
||||
protected Vector3[] BoundPoints(Collider collider)
|
||||
{
|
||||
var boundPoint1 = collider.bounds.min;
|
||||
var boundPoint2 = collider.bounds.max;
|
||||
var boundPoint3 = new Vector3(boundPoint1.x, boundPoint1.y, boundPoint2.z);
|
||||
var boundPoint4 = new Vector3(boundPoint1.x, boundPoint2.y, boundPoint1.z);
|
||||
var boundPoint5 = new Vector3(boundPoint2.x, boundPoint1.y, boundPoint1.z);
|
||||
var boundPoint6 = new Vector3(boundPoint1.x, boundPoint2.y, boundPoint2.z);
|
||||
var boundPoint7 = new Vector3(boundPoint2.x, boundPoint1.y, boundPoint2.z);
|
||||
var boundPoint8 = new Vector3(boundPoint2.x, boundPoint2.y, boundPoint1.z);
|
||||
var lineColor = Color.white;
|
||||
if (showDebug)
|
||||
{
|
||||
Debug.DrawLine(boundPoint6, boundPoint2, lineColor, 1);
|
||||
Debug.DrawLine(boundPoint2, boundPoint8, lineColor, 1);
|
||||
Debug.DrawLine(boundPoint8, boundPoint4, lineColor, 1);
|
||||
Debug.DrawLine(boundPoint4, boundPoint6, lineColor, 1);
|
||||
// bottom of rectangular cuboid (3-7-5-1)
|
||||
Debug.DrawLine(boundPoint3, boundPoint7, lineColor, 1);
|
||||
Debug.DrawLine(boundPoint7, boundPoint5, lineColor, 1);
|
||||
Debug.DrawLine(boundPoint5, boundPoint1, lineColor, 1);
|
||||
Debug.DrawLine(boundPoint1, boundPoint3, lineColor, 1);
|
||||
// legs (6-3, 2-7, 8-5, 4-1)
|
||||
Debug.DrawLine(boundPoint6, boundPoint3, lineColor, 1);
|
||||
Debug.DrawLine(boundPoint2, boundPoint7, lineColor, 1);
|
||||
Debug.DrawLine(boundPoint8, boundPoint5, lineColor, 1);
|
||||
Debug.DrawLine(boundPoint4, boundPoint1, lineColor, 1);
|
||||
}
|
||||
return new Vector3[] { boundPoint1, boundPoint2, boundPoint3, boundPoint4, boundPoint5, boundPoint6, boundPoint7, boundPoint8 };
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extencions for Help
|
||||
/// </summary>
|
||||
public static class vLockOnHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// Get point of Target relative to Screen
|
||||
/// </summary>
|
||||
/// <param name="canvas"></param>
|
||||
/// <param name="targetPoint"></param>
|
||||
/// <returns></returns>
|
||||
public static Vector2 GetScreenPointOffBoundsCenter(this Transform target, Canvas canvas, Camera cam, float _heightOffset)
|
||||
{
|
||||
var bounds = target.GetComponent<Collider>().bounds;
|
||||
var middle = bounds.center;
|
||||
var height = Vector3.Distance(bounds.min, bounds.max);
|
||||
|
||||
var point = middle + new Vector3(0, height * _heightOffset, 0);
|
||||
var rectTransform = canvas.transform as RectTransform;
|
||||
Vector2 ViewportPosition = cam.WorldToViewportPoint(point);
|
||||
Vector2 WorldObject_ScreenPosition = new Vector2(
|
||||
((ViewportPosition.x * rectTransform.sizeDelta.x) - (rectTransform.sizeDelta.x * 0.5f)),
|
||||
((ViewportPosition.y * rectTransform.sizeDelta.y) - (rectTransform.sizeDelta.y * 0.5f)));
|
||||
return WorldObject_ScreenPosition;
|
||||
}
|
||||
|
||||
public static Vector3 GetPointOffBoundsCenter(this Transform target, float _heightOffset)
|
||||
{
|
||||
var bounds = target.GetComponent<Collider>().bounds;
|
||||
var middle = bounds.center;
|
||||
var height = Vector3.Distance(bounds.min, bounds.max);
|
||||
|
||||
var point = middle + new Vector3(0, height * _heightOffset, 0);
|
||||
return point;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c54e41770d685f6418baa45eb8094332
|
||||
timeCreated: 1449791105
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user