Update
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ddb8bcc1adc3e684581d3b60f5e5c069
|
||||
folderAsset: yes
|
||||
timeCreated: 1469805730
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,63 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using UnityEditor;
|
||||
using System.Text;
|
||||
namespace Invector
|
||||
{
|
||||
[CanEditMultipleObjects]
|
||||
[CustomEditor(typeof(vLookTarget))]
|
||||
public class vLookTargetEditor : UnityEditor.Editor
|
||||
{
|
||||
GUISkin skin;
|
||||
void OnEnable()
|
||||
{
|
||||
skin = Resources.Load("vSkin") as GUISkin;
|
||||
}
|
||||
public override void OnInspectorGUI()
|
||||
{ var oldSkin = GUI.skin;
|
||||
serializedObject.Update();
|
||||
|
||||
if (skin != null) GUI.skin = skin;
|
||||
vLookTarget lTarget = (vLookTarget)target;
|
||||
GUILayout.BeginVertical("Look Target", "window");
|
||||
|
||||
GUILayout.Space(30);
|
||||
EditorGUILayout.PropertyField(serializedObject.FindProperty("m_Script"));
|
||||
EditorGUILayout.HelpBox("This component works with the vHeadTrack. Create a Collider and check the Trigger option to limit the area range to detect with the vHeadTrack if this object can be look at. Make sure to add the tag in the tagsToDetect list", MessageType.Info);
|
||||
GUILayout.Space(10);
|
||||
lTarget.ignoreHeadTrackAngle = EditorGUILayout.Toggle("Ignore HeadTrack Angle Limit", lTarget.ignoreHeadTrackAngle);
|
||||
lTarget.visibleCheckType = (vLookTarget.VisibleCheckType)EditorGUILayout.EnumPopup("Visible check type", lTarget.visibleCheckType);
|
||||
lTarget.lookPointTarget = (Transform)EditorGUILayout.ObjectField("LookPointTarget", lTarget.lookPointTarget, typeof(Transform), true);
|
||||
lTarget.useLimitToDetect = EditorGUILayout.Toggle("Use Limit To Detect", lTarget.useLimitToDetect);
|
||||
if (lTarget.useLimitToDetect)
|
||||
lTarget.minDistanceToDetect = EditorGUILayout.FloatField("Min Distance To Detect", lTarget.minDistanceToDetect);
|
||||
EditorGUILayout.HelpBox("The LookPointTarget is actual position that your character will look at.", MessageType.Info);
|
||||
|
||||
if (lTarget.visibleCheckType != vLookTarget.VisibleCheckType.None)
|
||||
{
|
||||
GUILayout.BeginVertical("box");
|
||||
GUILayout.Box("Area to check if is visible", GUILayout.ExpandWidth(true));
|
||||
lTarget.centerArea = EditorGUILayout.Vector3Field("Center Area", lTarget.centerArea);
|
||||
if (lTarget.visibleCheckType == vLookTarget.VisibleCheckType.BoxCast)
|
||||
{
|
||||
lTarget.sizeArea = EditorGUILayout.Vector3Field("Size Area", lTarget.sizeArea);
|
||||
EditorGUILayout.HelpBox("The box area is usage for multiple raycast for box corners", MessageType.Info);
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.HelpBox("The center area is usage for single raycast\n See the green sphere gizmo", MessageType.Info);
|
||||
}
|
||||
GUILayout.EndVertical();
|
||||
}
|
||||
lTarget.HideObject = EditorGUILayout.Toggle("Is Hide", lTarget.HideObject);
|
||||
GUI.skin = oldSkin;
|
||||
EditorGUILayout.PropertyField(serializedObject.FindProperty("onEnterLook"));
|
||||
EditorGUILayout.PropertyField(serializedObject.FindProperty("onExitLook"));
|
||||
GUILayout.EndVertical();
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
if (GUI.changed) EditorUtility.SetDirty(target);
|
||||
GUI.skin = oldSkin;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 60c9f1dedbda5bf42a76dd1b7d0318f0
|
||||
timeCreated: 1469805765
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6a97b6b5dab06ea4b86e54d319d62c25
|
||||
folderAsset: yes
|
||||
timeCreated: 1469805716
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,736 @@
|
||||
using Invector.vEventSystems;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
|
||||
namespace Invector.vCharacterController
|
||||
{
|
||||
[vClassHeader("HEAD TRACK", iconName = "headTrackIcon")]
|
||||
public class vHeadTrack : vMonoBehaviour
|
||||
{
|
||||
#region variables
|
||||
|
||||
[vEditorToolbar("Settings")]
|
||||
|
||||
[vHelpBox("If your character is not looking up/down, try changing the axis", vHelpBoxAttribute.MessageType.Info)]
|
||||
public Vector3 upDownAxis = Vector3.right;
|
||||
|
||||
[Header("Head & Body Weight")]
|
||||
public float strafeHeadWeight = 0.6f;
|
||||
public float strafeBodyWeight = 0.6f;
|
||||
public float aimingHeadWeight = 0.8f;
|
||||
public float aimingBodyWeight = 0.8f;
|
||||
public float freeHeadWeight = 0.6f;
|
||||
public float freeBodyWeight = 0.6f;
|
||||
|
||||
[SerializeField] protected float smooth = 10f;
|
||||
|
||||
[Header("Default Offsets ")]
|
||||
[SerializeField] protected Vector2 defaultOffsetSpine;
|
||||
[SerializeField] protected Vector2 defaultOffsetHead;
|
||||
|
||||
[vReadOnly(true)]
|
||||
public Vector2 offsetSpine;
|
||||
[vReadOnly(true)]
|
||||
public Vector2 offsetHead;
|
||||
|
||||
[Header("Tracking")]
|
||||
[Tooltip("Follow the Camera Forward")]
|
||||
public bool followCamera = true;
|
||||
public bool _freezeLookPoint = false;
|
||||
[vHideInInspector("followCamera")]
|
||||
[Tooltip("Force to follow camera")]
|
||||
[SerializeField] protected bool _alwaysFollowCamera = false;
|
||||
public virtual bool alwaysFollowCamera { get { return _alwaysFollowCamera; } set { _alwaysFollowCamera = value; } }
|
||||
[Tooltip("Ignore the Limits and continue to follow the camera")]
|
||||
public bool cancelTrackOutOfAngle = true;
|
||||
[Tooltip("Considerer the head animation forward while tracking, try it to see different results")]
|
||||
public bool considerHeadAnimationForward;
|
||||
|
||||
[Header("Limits")]
|
||||
[vMinMax(minLimit = -180f, maxLimit = 180f)] public Vector2 horizontalAngleLimit = new Vector2(-100, 100);
|
||||
[vMinMax(minLimit = -90f, maxLimit = 90f)] public Vector2 verticalAngleLimit = new Vector2(-80, 80);
|
||||
|
||||
[vHelpBox("Animations with vAnimatorTag Behavior will ignore the HeadTrack while is being played")]
|
||||
[Header("Ignore AnimatorTags")]
|
||||
public List<string> animatorIgnoreTags = new List<string>() { "Attack", "LockMovement", "CustomAction", "IsEquipping", "IgnoreHeadtrack" };
|
||||
|
||||
[vEditorToolbar("Bones")]
|
||||
[vHelpBox("Auto Find Bones using Humanoid")]
|
||||
public bool autoFindBones = true;
|
||||
public Transform head;
|
||||
public List<Transform> spine = new List<Transform>();
|
||||
|
||||
[vEditorToolbar("Detection")]
|
||||
public float updateTargetInteraction = 1;
|
||||
public float distanceToDetect = 10f;
|
||||
public LayerMask obstacleLayer = 1 << 0;
|
||||
[vHelpBox("Gameobjects Tags to detect")]
|
||||
public List<string> tagsToDetect = new List<string>() { "LookAt" };
|
||||
|
||||
[vEditorToolbar("HeadTrack Angles")]
|
||||
|
||||
[vHelpBox("Angle between character forward and camera forward")]
|
||||
[SerializeField, vReadOnly(false)]
|
||||
protected Vector2 _desiredlookAngle;
|
||||
[vHelpBox("Angle between head forward and character forward")]
|
||||
[SerializeField, vReadOnly(false)]
|
||||
protected Vector2 _currentLookAngle;
|
||||
[vHelpBox("Angle between head forward and camera forward")]
|
||||
[SerializeField, vReadOnly(false)]
|
||||
protected Vector2 _relativeLookAngle;
|
||||
|
||||
[vSeparator("Optinal Animator paramenters")]
|
||||
[vHelpBox("This is an optional to use and update paramenters in the animator using the look angles of the headtrack")]
|
||||
|
||||
|
||||
|
||||
[Tooltip("When enable this. The headtrack will update the angles relative to the character forward and camera forward")]
|
||||
public bool useDesiredLookAngle;
|
||||
[vHideInInspector("useDesiredLookAngle")]
|
||||
public string desiredLookAngleH = "HorizontalLookAngle";
|
||||
[vHideInInspector("useDesiredLookAngle")]
|
||||
public string desiredLookAngleV = "VerticalLookAngle";
|
||||
|
||||
[Tooltip("When enable this. The headtrack will update the angles relative to the Head forward and Character forward")]
|
||||
public bool useCurrentAngle;
|
||||
[vHideInInspector("useCurrentAngle")]
|
||||
public string currentAngleH = "CurrentHorizontalLookAngle";
|
||||
[vHideInInspector("useCurrentAngle")]
|
||||
public string currentAngleV = "CurrentVerticalLookAngle";
|
||||
|
||||
[Tooltip("When enable this. The headtrack will update the angles relative to the character head forward and camera forward")]
|
||||
public bool useRelativeLookAngle;
|
||||
[vHideInInspector("useRelativeLookAngle")]
|
||||
public string relativeLookAngleH ="HorizontalLookAngleRelative";
|
||||
[vHideInInspector("useRelativeLookAngle")]
|
||||
public string relativeLookAngleV = "VerticalLookAngleRelative";
|
||||
|
||||
|
||||
|
||||
internal UnityEvent onInitUpdate = new UnityEvent();
|
||||
internal UnityEvent onFinishUpdate = new UnityEvent();
|
||||
internal List<vLookTarget> targetsInArea = new List<vLookTarget>();
|
||||
|
||||
public virtual Camera cameraMain { get; set; }
|
||||
public virtual vLookTarget currentLookTarget { get; set; }
|
||||
public virtual vLookTarget lastLookTarget { get; set; }
|
||||
public virtual Quaternion currentLookRotation { get; set; }
|
||||
public virtual bool ignoreSmooth { get; set; }
|
||||
|
||||
protected virtual float yRotation { get; set; }
|
||||
protected virtual float xRotation { get; set; }
|
||||
protected virtual float _currentHeadWeight { get; set; }
|
||||
protected virtual float _currentBodyWeight { get; set; }
|
||||
protected virtual Animator animator { get; set; }
|
||||
protected virtual vIAnimatorStateInfoController animatorStateInfo { get; set; }
|
||||
protected virtual float headHeight { get; set; }
|
||||
protected virtual Transform simpleTarget { get; set; }
|
||||
protected virtual Vector3 temporaryLookPoint { get; set; }
|
||||
protected virtual float temporaryLookTime { get; set; }
|
||||
protected virtual vHeadTrackSensor sensor { get; set; }
|
||||
protected virtual float interaction { get; set; }
|
||||
protected virtual vICharacter vChar { get; set; }
|
||||
protected virtual Transform forwardReference { get; set; }
|
||||
|
||||
protected int currentLookAngleH_Hash = -1;
|
||||
protected int currentLookAngleV_Hash = -1;
|
||||
protected int desiredLookAngleH_Hash = -1;
|
||||
protected int desiredLookAngleV_Hash = -1;
|
||||
protected int relativeLookAngleH_Hash = -1;
|
||||
protected int relativeLookAngleV_Hash = -1;
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
public virtual float Smooth
|
||||
{
|
||||
get
|
||||
{
|
||||
return ignoreSmooth ? 1f : smooth * Time.deltaTime;
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual Vector3 _currentLocalLookPosition { get; set; }
|
||||
protected virtual Vector3 _lastLocalLookPosition { get; set; }
|
||||
|
||||
public virtual float currentVerticalLookAngle { get => _currentLookAngle.x; protected set => _currentLookAngle.x = value; }
|
||||
public virtual float currentHorizontalLookAngle { get => _currentLookAngle.y; protected set => _currentLookAngle.y = value; }
|
||||
|
||||
|
||||
public virtual float desiredVerticalLookAngle{ get => _desiredlookAngle.x; protected set => _desiredlookAngle.x = value; }
|
||||
public virtual float desiredHorizontalLookAngle { get => _desiredlookAngle.y; protected set => _desiredlookAngle.y = value; }
|
||||
|
||||
public virtual float relativeVerticalLookAngle{ get => _relativeLookAngle.x; protected set => _relativeLookAngle.x = value; }
|
||||
public virtual float relativeHorizontalLookAngle { get => _relativeLookAngle.y; protected set => _relativeLookAngle.y = value; }
|
||||
|
||||
public virtual bool freezeLookPoint { get => _freezeLookPoint; set => _freezeLookPoint = value; }
|
||||
|
||||
public virtual Vector3 currentLookPosition
|
||||
{
|
||||
get => freezeLookPoint ? transform.TransformPoint(_lastLocalLookPosition) : transform.TransformPoint(_currentLocalLookPosition);
|
||||
protected set
|
||||
{
|
||||
_currentLocalLookPosition = transform.InverseTransformPoint(value);
|
||||
if (!freezeLookPoint)
|
||||
{
|
||||
_lastLocalLookPosition = _currentLocalLookPosition;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void Start()
|
||||
{
|
||||
if (!sensor)
|
||||
{
|
||||
var sensorObj = new GameObject("HeadTrackSensor");
|
||||
sensor = sensorObj.AddComponent<vHeadTrackSensor>();
|
||||
}
|
||||
|
||||
// updates the headtrack using the late update of the tpinput so we don't need to create another one
|
||||
var tpInput = GetComponent<vThirdPersonInput>();
|
||||
if (tpInput)
|
||||
{
|
||||
tpInput.onLateUpdate -= UpdateHeadTrack;
|
||||
tpInput.onLateUpdate += UpdateHeadTrack;
|
||||
}
|
||||
|
||||
vChar = GetComponent<vICharacter>();
|
||||
sensor.headTrack = this;
|
||||
cameraMain = Camera.main;
|
||||
var layer = LayerMask.NameToLayer("HeadTrack");
|
||||
sensor.transform.parent = transform;
|
||||
sensor.gameObject.layer = layer;
|
||||
sensor.gameObject.tag = transform.tag;
|
||||
animatorStateInfo = GetComponent<vIAnimatorStateInfoController>();
|
||||
|
||||
|
||||
|
||||
Init();
|
||||
}
|
||||
|
||||
public virtual void Init()
|
||||
{
|
||||
currentLookPosition = GetLookPoint();
|
||||
_lastLocalLookPosition = _currentLocalLookPosition;
|
||||
if (animator == null)
|
||||
{
|
||||
animator = GetComponentInChildren<Animator>();
|
||||
}
|
||||
if (animator.GetValidParameter(currentAngleH, out AnimatorControllerParameter p)) currentLookAngleH_Hash = p.nameHash;
|
||||
if (animator.GetValidParameter(currentAngleV, out p)) currentLookAngleV_Hash = p.nameHash;
|
||||
|
||||
if (animator.GetValidParameter(desiredLookAngleH, out p)) desiredLookAngleH_Hash = p.nameHash;
|
||||
if (animator.GetValidParameter(desiredLookAngleV, out p)) desiredLookAngleV_Hash = p.nameHash;
|
||||
|
||||
if (animator.GetValidParameter(relativeLookAngleH, out p)) relativeLookAngleH_Hash = p.nameHash;
|
||||
if (animator.GetValidParameter(relativeLookAngleV, out p)) relativeLookAngleV_Hash = p.nameHash;
|
||||
if (autoFindBones)
|
||||
{
|
||||
spine.Clear();
|
||||
head = animator.GetBoneTransform(HumanBodyBones.Head);
|
||||
if (head)
|
||||
{
|
||||
if (!forwardReference)
|
||||
{
|
||||
forwardReference = new GameObject("FWRF").transform;
|
||||
}
|
||||
|
||||
forwardReference.SetParent(head);
|
||||
forwardReference.transform.localPosition = Vector3.zero;
|
||||
forwardReference.transform.rotation = transform.rotation;
|
||||
var hips = animator.GetBoneTransform(HumanBodyBones.Hips);
|
||||
if (hips)
|
||||
{
|
||||
var target = head;
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
if (target.parent && target.parent.gameObject != hips.gameObject)
|
||||
{
|
||||
spine.Add(target.parent);
|
||||
target = target.parent;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (head)
|
||||
{
|
||||
headHeight = Vector3.Distance(transform.position, head.position);
|
||||
sensor.transform.position = head.transform.position;
|
||||
}
|
||||
else
|
||||
{
|
||||
headHeight = 1f;
|
||||
sensor.transform.position = transform.position;
|
||||
}
|
||||
if (spine.Count == 0)
|
||||
{
|
||||
Debug.Log("Headtrack Spines missing");
|
||||
}
|
||||
|
||||
spine.Reverse();
|
||||
}
|
||||
|
||||
protected virtual Vector3 headPoint { get { return transform.position + (transform.up * headHeight); } }
|
||||
|
||||
public virtual void UpdateHeadTrack()
|
||||
{
|
||||
if (animator == null || !animator.enabled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (vChar != null && vChar.currentHealth > 0f && animator != null && !vChar.ragdolled)
|
||||
{
|
||||
onInitUpdate.Invoke();
|
||||
if (!freezeLookPoint)
|
||||
{
|
||||
currentLookPosition = GetLookPoint();
|
||||
}
|
||||
|
||||
SetLookAtPosition(currentLookPosition, _currentHeadWeight, _currentBodyWeight);
|
||||
UpdateAngles();
|
||||
onFinishUpdate.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void SetLookAtPosition(Vector3 point, float headWeight, float spineWeight)
|
||||
{
|
||||
var lookRotation = Quaternion.LookRotation(point - headPoint);
|
||||
currentLookRotation = lookRotation;
|
||||
var euler = lookRotation.eulerAngles - transform.rotation.eulerAngles;
|
||||
var y = NormalizeAngle(euler.y);
|
||||
var x = NormalizeAngle(euler.x);
|
||||
var eulerB = considerHeadAnimationForward ? forwardReference.eulerAngles - transform.eulerAngles : Vector3.zero;
|
||||
currentVerticalLookAngle = Mathf.Clamp(Mathf.Lerp(currentVerticalLookAngle, ((x) - eulerB.NormalizeAngle().x) + Quaternion.Euler(offsetSpine + defaultOffsetSpine).eulerAngles.NormalizeAngle().x, Smooth), verticalAngleLimit.x, verticalAngleLimit.y);
|
||||
currentHorizontalLookAngle = Mathf.Clamp(Mathf.Lerp(currentHorizontalLookAngle, ((y) - eulerB.NormalizeAngle().y) + Quaternion.Euler(offsetSpine + defaultOffsetSpine).eulerAngles.NormalizeAngle().y, Smooth), horizontalAngleLimit.x, horizontalAngleLimit.y);
|
||||
|
||||
var xSpine = NormalizeAngle(currentVerticalLookAngle);
|
||||
var ySpine = NormalizeAngle(currentHorizontalLookAngle);
|
||||
|
||||
foreach (Transform segment in spine)
|
||||
{
|
||||
var rotY = Quaternion.AngleAxis((ySpine * spineWeight) / spine.Count, segment.InverseTransformDirection(transform.up));
|
||||
segment.rotation *= rotY;
|
||||
var rotX = Quaternion.AngleAxis((xSpine * spineWeight) / spine.Count, segment.InverseTransformDirection(transform.TransformDirection(upDownAxis)));
|
||||
segment.rotation *= rotX;
|
||||
}
|
||||
if (head)
|
||||
{
|
||||
var xHead = NormalizeAngle(currentVerticalLookAngle - (xSpine * spineWeight) + Quaternion.Euler(offsetHead + defaultOffsetHead).eulerAngles.NormalizeAngle().x);
|
||||
var yHead = NormalizeAngle(currentHorizontalLookAngle - (ySpine * spineWeight) + Quaternion.Euler(offsetHead + defaultOffsetHead).eulerAngles.NormalizeAngle().y);
|
||||
var _rotY = Quaternion.AngleAxis(yHead * headWeight, head.InverseTransformDirection(transform.up));
|
||||
head.rotation *= _rotY;
|
||||
var _rotX = Quaternion.AngleAxis(xHead * headWeight, head.InverseTransformDirection(transform.TransformDirection(upDownAxis)));
|
||||
head.rotation *= _rotX;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void UpdateAngles()
|
||||
{
|
||||
if (useCurrentAngle)
|
||||
{
|
||||
if (currentLookAngleH_Hash != -1) animator.SetFloat(currentLookAngleH_Hash, currentHorizontalLookAngle);
|
||||
if (currentLookAngleV_Hash != -1) animator.SetFloat(currentLookAngleV_Hash, currentVerticalLookAngle);
|
||||
}
|
||||
|
||||
if (useDesiredLookAngle)
|
||||
{
|
||||
if (desiredLookAngleH_Hash != -1) animator.SetFloat(desiredLookAngleH_Hash, desiredHorizontalLookAngle);
|
||||
|
||||
if (desiredLookAngleV_Hash != -1) animator.SetFloat(desiredLookAngleV_Hash, desiredVerticalLookAngle);
|
||||
}
|
||||
|
||||
if(useRelativeLookAngle)
|
||||
{
|
||||
if (relativeLookAngleH_Hash != -1) animator.SetFloat(relativeLookAngleH_Hash, relativeHorizontalLookAngle);
|
||||
if (relativeLookAngleV_Hash != -1) animator.SetFloat(relativeLookAngleV_Hash, relativeVerticalLookAngle);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rotate the spine using angles
|
||||
/// </summary>
|
||||
/// <param name="angleX">Vertical angle</param>
|
||||
/// <param name="angleY">Horizontal angle</param>
|
||||
public virtual void RotateSpine(float angleX, float angleY)
|
||||
{
|
||||
var xSpine = NormalizeAngle(angleX);
|
||||
var ySpine = NormalizeAngle(angleY);
|
||||
|
||||
foreach (Transform segment in spine)
|
||||
{
|
||||
var rotY = Quaternion.AngleAxis((ySpine) / spine.Count, segment.InverseTransformDirection(transform.up));
|
||||
segment.rotation *= rotY;
|
||||
var rotX = Quaternion.AngleAxis((xSpine) / spine.Count, segment.InverseTransformDirection(transform.TransformDirection(upDownAxis)));
|
||||
segment.rotation *= rotX;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual Vector3 desiredLookDirection { get; protected set; }
|
||||
|
||||
public virtual Vector3 LookDirection { get; protected set; }
|
||||
|
||||
protected virtual bool lookConditions
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!cameraMain)
|
||||
{
|
||||
cameraMain = Camera.main;
|
||||
}
|
||||
return head != null && (followCamera && cameraMain != null) || (!followCamera && (currentLookTarget || simpleTarget)) || temporaryLookTime > 0;
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual Vector3 GetLookPoint()
|
||||
{
|
||||
if (animator == null)
|
||||
{
|
||||
return Vector3.zero;
|
||||
}
|
||||
|
||||
var distanceToLook = 100;
|
||||
if (lookConditions && !IgnoreHeadTrack())
|
||||
{
|
||||
desiredLookDirection = transform.forward;
|
||||
if (temporaryLookTime <= 0)
|
||||
{
|
||||
var lookPosition = headPoint + (transform.forward * distanceToLook);
|
||||
if (followCamera)
|
||||
{
|
||||
lookPosition = (cameraMain.transform.position + (cameraMain.transform.forward * distanceToLook));
|
||||
}
|
||||
|
||||
desiredLookDirection = lookPosition - headPoint;
|
||||
|
||||
if ((followCamera && !alwaysFollowCamera) || !followCamera)
|
||||
{
|
||||
|
||||
if (simpleTarget != null)
|
||||
{
|
||||
desiredLookDirection = simpleTarget.position - headPoint;
|
||||
if (currentLookTarget && currentLookTarget == lastLookTarget)
|
||||
{
|
||||
currentLookTarget.ExitLook(this);
|
||||
lastLookTarget = null;
|
||||
}
|
||||
}
|
||||
else if (currentLookTarget != null && (currentLookTarget.ignoreHeadTrackAngle || TargetIsOnRange(currentLookTarget.lookPoint - headPoint)) && currentLookTarget.IsVisible(headPoint, obstacleLayer))
|
||||
{
|
||||
desiredLookDirection = currentLookTarget.lookPoint - headPoint;
|
||||
if (currentLookTarget != lastLookTarget)
|
||||
{
|
||||
currentLookTarget.EnterLook(this);
|
||||
lastLookTarget = currentLookTarget;
|
||||
}
|
||||
}
|
||||
else if (currentLookTarget && currentLookTarget == lastLookTarget)
|
||||
{
|
||||
currentLookTarget.ExitLook(this);
|
||||
lastLookTarget = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
desiredLookDirection = temporaryLookPoint - headPoint;
|
||||
temporaryLookTime -= Time.deltaTime;
|
||||
if (currentLookTarget && currentLookTarget == lastLookTarget)
|
||||
{
|
||||
currentLookTarget.ExitLook(this);
|
||||
lastLookTarget = null;
|
||||
}
|
||||
}
|
||||
|
||||
var angle = GetTargetAngle(desiredLookDirection);
|
||||
if (cancelTrackOutOfAngle && (lastLookTarget == null || !lastLookTarget.ignoreHeadTrackAngle))
|
||||
{
|
||||
if (TargetIsOnRange(desiredLookDirection))
|
||||
{
|
||||
if (animator.GetBool("IsStrafing") && !IsAnimatorTag("Upperbody Pose"))
|
||||
{
|
||||
SmoothValues(strafeHeadWeight, strafeBodyWeight, angle.x, angle.y);
|
||||
}
|
||||
else if (animator.GetBool("IsStrafing") && IsAnimatorTag("Upperbody Pose"))
|
||||
{
|
||||
SmoothValues(aimingHeadWeight, aimingBodyWeight, angle.x, angle.y);
|
||||
}
|
||||
else
|
||||
{
|
||||
SmoothValues(freeHeadWeight, freeBodyWeight, angle.x, angle.y);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SmoothValues();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (animator.GetBool("IsStrafing") && !IsAnimatorTag("Upperbody Pose"))
|
||||
{
|
||||
SmoothValues(strafeHeadWeight, strafeBodyWeight, angle.x, angle.y);
|
||||
}
|
||||
else if (animator.GetBool("IsStrafing") && IsAnimatorTag("Upperbody Pose"))
|
||||
{
|
||||
SmoothValues(aimingHeadWeight, aimingBodyWeight, angle.x, angle.y);
|
||||
}
|
||||
else
|
||||
{
|
||||
SmoothValues(freeHeadWeight, freeBodyWeight, angle.x, angle.y);
|
||||
}
|
||||
}
|
||||
if (targetsInArea.Count > 1)
|
||||
{
|
||||
SortTargets();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SmoothValues();
|
||||
if (targetsInArea.Count > 1)
|
||||
{
|
||||
SortTargets();
|
||||
}
|
||||
}
|
||||
|
||||
var rotA = Quaternion.AngleAxis(yRotation, transform.up);
|
||||
var rotB = Quaternion.AngleAxis(xRotation, transform.right);
|
||||
var finalRotation = (rotA * rotB);
|
||||
var lookDirection = finalRotation * transform.forward;
|
||||
LookDirection = lookDirection;
|
||||
_desiredlookAngle = GetTargetAngle(cameraMain.transform.forward);
|
||||
_relativeLookAngle = -(GetTargetAngle(lookDirection) - _desiredlookAngle);
|
||||
|
||||
|
||||
return headPoint + (lookDirection * distanceToLook);
|
||||
}
|
||||
|
||||
protected virtual Vector2 GetTargetAngle(Vector3 direction)
|
||||
{
|
||||
if (direction.magnitude == 0) return Vector2.zero;
|
||||
var lookRotation = Quaternion.LookRotation(direction, Vector3.up);
|
||||
var angleResult = lookRotation.eulerAngles - transform.eulerAngles;
|
||||
|
||||
return new Vector2(angleResult.NormalizeAngle().x, angleResult.NormalizeAngle().y);
|
||||
}
|
||||
|
||||
protected virtual bool TargetIsOnRange(Vector3 direction)
|
||||
{
|
||||
var angle = GetTargetAngle(direction);
|
||||
return (angle.x >= verticalAngleLimit.x && angle.x <= verticalAngleLimit.y && angle.y >= horizontalAngleLimit.x && angle.y <= horizontalAngleLimit.y);
|
||||
}
|
||||
|
||||
public virtual void SetAlwaysFollowCamera(bool value)
|
||||
{
|
||||
alwaysFollowCamera = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set vLookTarget
|
||||
/// </summary>
|
||||
/// <param name="target"></param>
|
||||
public virtual void SetLookTarget(vLookTarget target, bool priority = false)
|
||||
{
|
||||
if (!targetsInArea.Contains(target))
|
||||
{
|
||||
targetsInArea.Add(target);
|
||||
}
|
||||
|
||||
if (priority)
|
||||
{
|
||||
currentLookTarget = target;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set Simple target
|
||||
/// </summary>
|
||||
/// <param name="target"></param>
|
||||
public virtual void SetLookTarget(Transform target)
|
||||
{
|
||||
simpleTarget = target;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set a temporary look point to headtrack
|
||||
/// </summary>
|
||||
/// <param name="point">look point</param>
|
||||
/// <param name="time">time to stay looking</param>
|
||||
public virtual void SetTemporaryLookPoint(Vector3 point, float time = 1f)
|
||||
{
|
||||
temporaryLookPoint = point;
|
||||
temporaryLookTime = time;
|
||||
}
|
||||
|
||||
public virtual void RemoveLookTarget(vLookTarget target)
|
||||
{
|
||||
if (targetsInArea.Contains(target))
|
||||
{
|
||||
targetsInArea.Remove(target);
|
||||
}
|
||||
|
||||
if (currentLookTarget == target)
|
||||
{
|
||||
currentLookTarget = null;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void RemoveLookTarget(Transform target)
|
||||
{
|
||||
if (simpleTarget == target)
|
||||
{
|
||||
simpleTarget = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Make angle to work with -180 and 180
|
||||
/// </summary>
|
||||
/// <param name="angle"></param>
|
||||
/// <returns></returns>
|
||||
protected virtual float NormalizeAngle(float angle)
|
||||
{
|
||||
if (angle > 180)
|
||||
{
|
||||
angle -= 360;
|
||||
}
|
||||
else if (angle < -180)
|
||||
{
|
||||
angle += 360;
|
||||
}
|
||||
|
||||
return angle;
|
||||
}
|
||||
|
||||
protected virtual void ResetValues()
|
||||
{
|
||||
_currentHeadWeight = 0;
|
||||
_currentBodyWeight = 0;
|
||||
yRotation = 0;
|
||||
xRotation = 0;
|
||||
}
|
||||
|
||||
protected virtual void SmoothValues(float _headWeight = 0, float _bodyWeight = 0, float _x = 0, float _y = 0)
|
||||
{
|
||||
_currentHeadWeight = Mathf.Lerp(_currentHeadWeight, _headWeight, Smooth);
|
||||
_currentBodyWeight = Mathf.Lerp(_currentBodyWeight, _bodyWeight, Smooth);
|
||||
yRotation = Mathf.Lerp(yRotation, _y, Smooth);
|
||||
xRotation = Mathf.Lerp(xRotation, _x, Smooth);
|
||||
yRotation = Mathf.Clamp(yRotation, horizontalAngleLimit.x, horizontalAngleLimit.y);
|
||||
xRotation = Mathf.Clamp(xRotation, verticalAngleLimit.x, verticalAngleLimit.y);
|
||||
}
|
||||
|
||||
protected virtual void SortTargets()
|
||||
{
|
||||
interaction += Time.deltaTime;
|
||||
if (interaction > updateTargetInteraction)
|
||||
{
|
||||
interaction -= updateTargetInteraction;
|
||||
if (targetsInArea == null || targetsInArea.Count < 2)
|
||||
{
|
||||
if (targetsInArea != null && targetsInArea.Count > 0)
|
||||
{
|
||||
currentLookTarget = targetsInArea[0];
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = targetsInArea.Count - 1; i >= 0; i--)
|
||||
{
|
||||
if (targetsInArea[i] == null)
|
||||
{
|
||||
targetsInArea.RemoveAt(i);
|
||||
}
|
||||
}
|
||||
targetsInArea.Sort(delegate (vLookTarget c1, vLookTarget c2)
|
||||
{
|
||||
return Vector3.Distance(this.transform.position, c1 != null ? c1.transform.position : Vector3.one * Mathf.Infinity).CompareTo
|
||||
((Vector3.Distance(this.transform.position, c2 != null ? c2.transform.position : Vector3.one * Mathf.Infinity)));
|
||||
});
|
||||
if (targetsInArea.Count > 0)
|
||||
{
|
||||
currentLookTarget = targetsInArea[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void OnDetect(Collider other)
|
||||
{
|
||||
if (tagsToDetect.Contains(other.gameObject.tag) && other.GetComponent<vLookTarget>() != null)
|
||||
{
|
||||
currentLookTarget = other.GetComponent<vLookTarget>();
|
||||
var headTrack = other.GetComponentInParent<vHeadTrack>();
|
||||
if (!targetsInArea.Contains(currentLookTarget) && (headTrack == null || headTrack != this))
|
||||
{
|
||||
targetsInArea.Add(currentLookTarget);
|
||||
SortTargets();
|
||||
currentLookTarget = targetsInArea[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void OnLost(Collider other)
|
||||
{
|
||||
if (tagsToDetect.Contains(other.gameObject.tag) && other.GetComponentInParent<vLookTarget>() != null)
|
||||
{
|
||||
var _currentLookTarget = other.GetComponentInParent<vLookTarget>();
|
||||
|
||||
if (targetsInArea.Contains(_currentLookTarget))
|
||||
{
|
||||
targetsInArea.Remove(_currentLookTarget);
|
||||
|
||||
|
||||
if (_currentLookTarget == lastLookTarget)
|
||||
{
|
||||
_currentLookTarget.ExitLook(this);
|
||||
}
|
||||
}
|
||||
SortTargets();
|
||||
if (targetsInArea.Count > 0)
|
||||
{
|
||||
currentLookTarget = targetsInArea[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
currentLookTarget = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool IgnoreHeadTrack()
|
||||
{
|
||||
if (animatorIgnoreTags.Exists(tag => IsAnimatorTag(tag)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public virtual bool IsAnimatorTag(string tag)
|
||||
{
|
||||
if (animator == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (animatorStateInfo.isValid())
|
||||
{
|
||||
if (animatorStateInfo.animatorStateInfos.HasTag(tag))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 61a5d2516d5dbbc40b1cfb5cbf17758a
|
||||
timeCreated: 1469474947
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,42 @@
|
||||
using UnityEngine;
|
||||
namespace Invector.vCharacterController
|
||||
{
|
||||
[RequireComponent(typeof(SphereCollider))]
|
||||
[RequireComponent(typeof(Rigidbody))]
|
||||
public class vHeadTrackSensor : MonoBehaviour
|
||||
{
|
||||
[HideInInspector]
|
||||
public vHeadTrack headTrack;
|
||||
public SphereCollider sphere;
|
||||
|
||||
void OnDrawGizmos()
|
||||
{
|
||||
if (Application.isPlaying && sphere && headTrack)
|
||||
{
|
||||
sphere.radius = headTrack.distanceToDetect;
|
||||
}
|
||||
}
|
||||
|
||||
void Start()
|
||||
{
|
||||
var _rigidB = GetComponent<Rigidbody>();
|
||||
sphere = GetComponent<SphereCollider>();
|
||||
sphere.isTrigger = true;
|
||||
_rigidB.useGravity = false;
|
||||
_rigidB.isKinematic = true;
|
||||
_rigidB.constraints = RigidbodyConstraints.FreezeAll;
|
||||
if (headTrack) sphere.radius = headTrack.distanceToDetect;
|
||||
}
|
||||
|
||||
void OnTriggerEnter(Collider other)
|
||||
{
|
||||
if (headTrack != null) headTrack.OnDetect(other);
|
||||
}
|
||||
|
||||
void OnTriggerExit(Collider other)
|
||||
{
|
||||
if (headTrack != null) headTrack.OnLost(other);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6f8827d96877cdc4bb6f1b8126c504de
|
||||
timeCreated: 1472314528
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,271 @@
|
||||
using UnityEngine;
|
||||
|
||||
using Invector.vCharacterController;
|
||||
|
||||
namespace Invector
|
||||
{
|
||||
public class vLookTarget : MonoBehaviour
|
||||
{
|
||||
public bool ignoreHeadTrackAngle;
|
||||
[Header("Set this to assign a different point to look")]
|
||||
public Transform lookPointTarget;
|
||||
[Header("Area to check if is visible")]
|
||||
public Vector3 centerArea = Vector3.zero;
|
||||
public Vector3 sizeArea = Vector3.one;
|
||||
public bool useLimitToDetect = true;
|
||||
public float minDistanceToDetect = 2f;
|
||||
public VisibleCheckType visibleCheckType;
|
||||
[Tooltip("use this to turn the object undetectable")]
|
||||
public bool HideObject;
|
||||
[System.Serializable]
|
||||
public class OnLookEvent : UnityEngine.Events.UnityEvent<vHeadTrack> { }
|
||||
public OnLookEvent onEnterLook, onExitLook;
|
||||
|
||||
|
||||
public enum VisibleCheckType
|
||||
{
|
||||
None, SingleCast, BoxCast
|
||||
}
|
||||
|
||||
void OnDrawGizmosSelected()
|
||||
{
|
||||
DrawBox();
|
||||
}
|
||||
|
||||
void Start()
|
||||
{
|
||||
var layer = LayerMask.NameToLayer("HeadTrack");
|
||||
gameObject.layer = layer;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Point to look
|
||||
/// </summary>
|
||||
public Vector3 lookPoint
|
||||
{
|
||||
get
|
||||
{
|
||||
if (lookPointTarget)
|
||||
{
|
||||
return lookPointTarget.position;
|
||||
}
|
||||
else
|
||||
return transform.TransformPoint(centerArea);
|
||||
}
|
||||
}
|
||||
|
||||
void DrawBox()
|
||||
{
|
||||
Gizmos.color = new Color(1, 0, 0, 1f);
|
||||
Gizmos.DrawSphere(lookPoint, 0.05f);
|
||||
if (visibleCheckType == VisibleCheckType.BoxCast)
|
||||
{
|
||||
var sizeX = transform.lossyScale.x * sizeArea.x;
|
||||
var sizeY = transform.lossyScale.y * sizeArea.y;
|
||||
var sizeZ = transform.lossyScale.z * sizeArea.z;
|
||||
var centerX = transform.lossyScale.x * centerArea.x;
|
||||
var centerY = transform.lossyScale.y * centerArea.y;
|
||||
var centerZ = transform.lossyScale.z * centerArea.z;
|
||||
Matrix4x4 rotationMatrix = Matrix4x4.TRS(transform.position + new Vector3(centerX, centerY, centerZ), transform.rotation, new Vector3(sizeX, sizeY, sizeZ) * 2f);
|
||||
Gizmos.matrix = rotationMatrix;
|
||||
Gizmos.color = new Color(0, 1, 0, 0.2f);
|
||||
Gizmos.DrawCube(Vector3.zero, Vector3.one);
|
||||
Gizmos.color = new Color(0, 1, 0, 1f);
|
||||
Gizmos.DrawWireCube(Vector3.zero, Vector3.one);
|
||||
|
||||
}
|
||||
else if (visibleCheckType == VisibleCheckType.SingleCast)
|
||||
{
|
||||
var point = transform.TransformPoint(centerArea);
|
||||
Gizmos.color = new Color(0, 1, 0, 1f);
|
||||
Gizmos.DrawSphere(point, 0.05f);
|
||||
}
|
||||
}
|
||||
|
||||
internal void EnterLook(vHeadTrack vHeadTrack)
|
||||
{
|
||||
onEnterLook.Invoke(vHeadTrack);
|
||||
}
|
||||
|
||||
internal void ExitLook(vHeadTrack vHeadTrack)
|
||||
{
|
||||
onExitLook.Invoke(vHeadTrack);
|
||||
}
|
||||
}
|
||||
|
||||
#region Helper
|
||||
public static class vLookTargetHelper
|
||||
{
|
||||
struct LookPoints
|
||||
{
|
||||
public Vector3 frontTopLeft;
|
||||
public Vector3 frontTopRight;
|
||||
public Vector3 frontBottomLeft;
|
||||
public Vector3 frontBottomRight;
|
||||
public Vector3 backTopLeft;
|
||||
public Vector3 backTopRight;
|
||||
public Vector3 backBottomLeft;
|
||||
public Vector3 backBottomRight;
|
||||
}
|
||||
|
||||
static LookPoints GetLookPoints(vLookTarget lookTarget)
|
||||
{
|
||||
LookPoints points = new LookPoints();
|
||||
var centerArea = lookTarget.centerArea;
|
||||
var sizeArea = lookTarget.sizeArea;
|
||||
var lookTransform = lookTarget.transform;
|
||||
points.frontTopLeft = new Vector3(centerArea.x - sizeArea.x, centerArea.y + sizeArea.y, centerArea.z - sizeArea.z);
|
||||
points.frontTopRight = new Vector3(centerArea.x + sizeArea.x, centerArea.y + sizeArea.y, centerArea.z - sizeArea.z);
|
||||
points.frontBottomLeft = new Vector3(centerArea.x - sizeArea.x, centerArea.y - sizeArea.y, centerArea.z - sizeArea.z);
|
||||
points.frontBottomRight = new Vector3(centerArea.x + sizeArea.x, centerArea.y - sizeArea.y, centerArea.z - sizeArea.z);
|
||||
points.backTopLeft = new Vector3(centerArea.x - sizeArea.x, centerArea.y + sizeArea.y, centerArea.z + sizeArea.z);
|
||||
points.backTopRight = new Vector3(centerArea.x + sizeArea.x, centerArea.y + sizeArea.y, centerArea.z + sizeArea.z);
|
||||
points.backBottomLeft = new Vector3(centerArea.x - sizeArea.x, centerArea.y - sizeArea.y, centerArea.z + sizeArea.z);
|
||||
points.backBottomRight = new Vector3(centerArea.x + sizeArea.x, centerArea.y - sizeArea.y, centerArea.z + sizeArea.z);
|
||||
|
||||
points.frontTopLeft = lookTransform.TransformPoint(points.frontTopLeft);
|
||||
points.frontTopRight = lookTransform.TransformPoint(points.frontTopRight);
|
||||
points.frontBottomLeft = lookTransform.TransformPoint(points.frontBottomLeft);
|
||||
points.frontBottomRight = lookTransform.TransformPoint(points.frontBottomRight);
|
||||
points.backTopLeft = lookTransform.TransformPoint(points.backTopLeft);
|
||||
points.backTopRight = lookTransform.TransformPoint(points.backTopRight);
|
||||
points.backBottomLeft = lookTransform.TransformPoint(points.backBottomLeft);
|
||||
points.backBottomRight = lookTransform.TransformPoint(points.backBottomRight);
|
||||
return points;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if anny corner points of LookTarget area is visible from observer
|
||||
/// </summary>
|
||||
/// <param name="lookTarget">principal transform of lookTarget</param>
|
||||
/// <param name="from">observer point</param>
|
||||
/// <param name="layerMask">Layer to check</param>
|
||||
/// <param name="debug">Draw lines </param>
|
||||
/// <returns></returns>
|
||||
public static bool IsVisible(this vLookTarget lookTarget, Vector3 from, LayerMask layerMask, bool debug = false)
|
||||
{
|
||||
|
||||
if (lookTarget.HideObject) return false;
|
||||
|
||||
if (lookTarget.visibleCheckType == vLookTarget.VisibleCheckType.None)
|
||||
{
|
||||
if (lookTarget.useLimitToDetect && Vector3.Distance(from, lookTarget.transform.position) > lookTarget.minDistanceToDetect) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (lookTarget.visibleCheckType == vLookTarget.VisibleCheckType.SingleCast)
|
||||
{
|
||||
if (lookTarget.useLimitToDetect && Vector3.Distance(from, lookTarget.centerArea) > lookTarget.minDistanceToDetect) return false;
|
||||
if (CastPoint(from, lookTarget.transform.TransformPoint(lookTarget.centerArea), lookTarget.transform, layerMask, debug)) return true; else return false;
|
||||
}
|
||||
else if (lookTarget.visibleCheckType == vLookTarget.VisibleCheckType.BoxCast)
|
||||
{
|
||||
if (lookTarget.useLimitToDetect && Vector3.Distance(from, lookTarget.transform.position) > lookTarget.minDistanceToDetect) return false;
|
||||
LookPoints points = GetLookPoints(lookTarget);
|
||||
|
||||
if (CastPoint(from, points.frontTopLeft, lookTarget.transform, layerMask, debug)) return true;
|
||||
|
||||
if (CastPoint(from, points.frontTopRight, lookTarget.transform, layerMask, debug)) return true;
|
||||
|
||||
if (CastPoint(from, points.frontBottomLeft, lookTarget.transform, layerMask, debug)) return true;
|
||||
|
||||
if (CastPoint(from, points.frontBottomRight, lookTarget.transform, layerMask, debug)) return true;
|
||||
|
||||
if (CastPoint(from, points.backTopLeft, lookTarget.transform, layerMask, debug)) return true;
|
||||
|
||||
if (CastPoint(from, points.backTopRight, lookTarget.transform, layerMask, debug)) return true;
|
||||
|
||||
if (CastPoint(from, points.backBottomLeft, lookTarget.transform, layerMask, debug)) return true;
|
||||
|
||||
if (CastPoint(from, points.backBottomRight, lookTarget.transform, layerMask, debug)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if anny corner points of LookTarget area is visible from observer
|
||||
/// </summary>
|
||||
/// <param name="lookTarget">principal transform of lookTarget</param>
|
||||
/// <param name="from">observer point</param>
|
||||
/// <param name="debug">Draw lines </param>
|
||||
/// <returns></returns>
|
||||
public static bool IsVisible(this vLookTarget lookTarget, Vector3 from, bool debug = false)
|
||||
{
|
||||
if (lookTarget.HideObject) return false;
|
||||
LookPoints points = GetLookPoints(lookTarget);
|
||||
if (lookTarget.visibleCheckType == vLookTarget.VisibleCheckType.None)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (lookTarget.visibleCheckType == vLookTarget.VisibleCheckType.SingleCast)
|
||||
{
|
||||
if (CastPoint(from, lookTarget.transform.TransformPoint(lookTarget.centerArea), lookTarget.transform, debug)) return true; else return false;
|
||||
}
|
||||
else if (lookTarget.visibleCheckType == vLookTarget.VisibleCheckType.BoxCast)
|
||||
{
|
||||
if (CastPoint(from, points.frontTopLeft, lookTarget.transform, debug)) return true;
|
||||
|
||||
if (CastPoint(from, points.frontTopRight, lookTarget.transform, debug)) return true;
|
||||
|
||||
if (CastPoint(from, points.frontBottomLeft, lookTarget.transform, debug)) return true;
|
||||
|
||||
if (CastPoint(from, points.frontBottomRight, lookTarget.transform, debug)) return true;
|
||||
|
||||
if (CastPoint(from, points.backTopLeft, lookTarget.transform, debug)) return true;
|
||||
|
||||
if (CastPoint(from, points.backTopRight, lookTarget.transform, debug)) return true;
|
||||
|
||||
if (CastPoint(from, points.backBottomLeft, lookTarget.transform, debug)) return true;
|
||||
|
||||
if (CastPoint(from, points.backBottomRight, lookTarget.transform, debug)) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool CastPoint(Vector3 from, Vector3 point, Transform lookTarget, LayerMask layerMask, bool debug = false)
|
||||
{
|
||||
RaycastHit hit;
|
||||
|
||||
if (Physics.Linecast(from, point, out hit, layerMask))
|
||||
{
|
||||
if (hit.transform != lookTarget.transform)
|
||||
{
|
||||
if (debug) Debug.DrawLine(from, hit.point, Color.red);
|
||||
return false;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
if (debug) Debug.DrawLine(from, hit.point, Color.green);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (debug) Debug.DrawLine(from, point, Color.green);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool CastPoint(Vector3 from, Vector3 point, Transform lookTarget, bool debug = false)
|
||||
{
|
||||
RaycastHit hit;
|
||||
|
||||
if (Physics.Linecast(from, point, out hit))
|
||||
{
|
||||
if (hit.transform != lookTarget.transform)
|
||||
{
|
||||
if (debug) Debug.DrawLine(from, hit.point, Color.red);
|
||||
return false;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
if (debug) Debug.DrawLine(from, hit.point, Color.green);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (debug) Debug.DrawLine(from, point, Color.green);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 079af0928a59a2a489c3eb00c58cd2f4
|
||||
timeCreated: 1469630605
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user