Added Feel plugin
This commit is contained in:
BIN
Assets/External/Feel/MMTools/Accessories/MMVision/ConeOfVisionAlpha.png
vendored
Normal file
BIN
Assets/External/Feel/MMTools/Accessories/MMVision/ConeOfVisionAlpha.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 42 KiB |
95
Assets/External/Feel/MMTools/Accessories/MMVision/ConeOfVisionAlpha.png.meta
vendored
Normal file
95
Assets/External/Feel/MMTools/Accessories/MMVision/ConeOfVisionAlpha.png.meta
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 671b69569d53c4c47ba2a89fb544082f
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
externalObjects: {}
|
||||
serializedVersion: 7
|
||||
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: -1
|
||||
mipBias: -100
|
||||
wrapU: -1
|
||||
wrapV: -1
|
||||
wrapW: -1
|
||||
nPOTScale: 1
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
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: 0
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 0
|
||||
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:
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
spritePackingTag:
|
||||
pSDRemoveMatte: 0
|
||||
pSDShowRemoveMatteOption: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 183370
|
||||
packageName: Feel
|
||||
packageVersion: 5.9.1
|
||||
assetPath: Assets/Feel/MMTools/Accessories/MMVision/ConeOfVisionAlpha.png
|
||||
uploadId: 830868
|
||||
70
Assets/External/Feel/MMTools/Accessories/MMVision/MMConeOfLight.shader
vendored
Normal file
70
Assets/External/Feel/MMTools/Accessories/MMVision/MMConeOfLight.shader
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
Shader "MoreMountains/ConeOfLight"
|
||||
{
|
||||
Properties
|
||||
{
|
||||
_MainTex("Diffuse Texture", 2D) = "white" {}
|
||||
_Contrast("Contrast", Float) = 0.5
|
||||
_Color("Color", Color) = (1,1,1,1)
|
||||
}
|
||||
|
||||
SubShader
|
||||
{
|
||||
Tags
|
||||
{
|
||||
"ForceNoShadowCasting" = "True"
|
||||
"Queue" = "Transparent"
|
||||
"RenderType" = "Transparent"
|
||||
"IgnoreProjector" = "True"
|
||||
}
|
||||
|
||||
Pass
|
||||
{
|
||||
ZTest Always
|
||||
AlphaTest Greater 0.0
|
||||
Blend DstColor One
|
||||
Cull Off
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
uniform sampler2D _MainTex;
|
||||
uniform float _Contrast;
|
||||
uniform float4 _Color;
|
||||
|
||||
struct VertexInput
|
||||
{
|
||||
float4 vertex : POSITION;
|
||||
float4 uv : TEXCOORD0;
|
||||
float4 color : COLOR;
|
||||
};
|
||||
|
||||
struct VertexOutput
|
||||
{
|
||||
float4 pos : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
float4 color : COLOR;
|
||||
};
|
||||
|
||||
VertexOutput vert(VertexInput input)
|
||||
{
|
||||
VertexOutput output;
|
||||
output.uv = input.uv;
|
||||
output.color = input.color;
|
||||
output.pos = UnityObjectToClipPos(input.vertex);
|
||||
return output;
|
||||
}
|
||||
|
||||
float4 frag(VertexOutput input) : COLOR
|
||||
{
|
||||
float4 diffuse = tex2D(_MainTex, input.uv);
|
||||
diffuse.rgb = diffuse.rgb * _Color.rgb * input.color.rgb;
|
||||
diffuse.rgb *= diffuse.a * _Color.a * input.color.a;
|
||||
diffuse *= _Contrast;
|
||||
return float4(diffuse);
|
||||
}
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
}
|
||||
16
Assets/External/Feel/MMTools/Accessories/MMVision/MMConeOfLight.shader.meta
vendored
Normal file
16
Assets/External/Feel/MMTools/Accessories/MMVision/MMConeOfLight.shader.meta
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 07e5069cdf9ee934f8d7b768c461452c
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 183370
|
||||
packageName: Feel
|
||||
packageVersion: 5.9.1
|
||||
assetPath: Assets/Feel/MMTools/Accessories/MMVision/MMConeOfLight.shader
|
||||
uploadId: 830868
|
||||
265
Assets/External/Feel/MMTools/Accessories/MMVision/MMConeOfVision.cs
vendored
Normal file
265
Assets/External/Feel/MMTools/Accessories/MMVision/MMConeOfVision.cs
vendored
Normal file
@@ -0,0 +1,265 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using MoreMountains.Tools;
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
|
||||
namespace MoreMountains.Tools
|
||||
{
|
||||
/// <summary>
|
||||
/// This class will create a cone of vision defined by an angle and a distance around a point. It will look for targets within that field, and draw a mesh to show the cone of vision
|
||||
/// initially inspired by this great tutorial by Sebastian Lague : https://www.youtube.com/watch?v=rQG9aUWarwE - check out his tutorials, they're amazing!
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
[AddComponentMenu("More Mountains/Tools/Vision/MM Cone Of Vision")]
|
||||
public class MMConeOfVision : MonoBehaviour
|
||||
{
|
||||
/// <summary>
|
||||
/// A struct to store raycast data
|
||||
/// </summary>
|
||||
public struct RaycastData
|
||||
{
|
||||
public bool Hit;
|
||||
public Vector3 Point;
|
||||
public float Distance;
|
||||
public float Angle;
|
||||
|
||||
public RaycastData(bool hit, Vector3 point, float distance, float angle)
|
||||
{
|
||||
Hit = hit;
|
||||
Point = point;
|
||||
Distance = distance;
|
||||
Angle = angle;
|
||||
}
|
||||
}
|
||||
|
||||
public struct MeshEdgePosition
|
||||
{
|
||||
public Vector3 PointA;
|
||||
public Vector3 PointB;
|
||||
|
||||
public MeshEdgePosition(Vector3 pointA, Vector3 pointB)
|
||||
{
|
||||
PointA = pointA;
|
||||
PointB = pointB;
|
||||
}
|
||||
}
|
||||
|
||||
[Header("Vision")]
|
||||
public LayerMask ObstacleMask;
|
||||
public float VisionRadius = 5f;
|
||||
[Range(0f, 360f)]
|
||||
public float VisionAngle = 20f;
|
||||
[MMReadOnly]
|
||||
public Vector3 Direction;
|
||||
[MMReadOnly]
|
||||
public Vector3 EulerAngles;
|
||||
public Vector3 Offset;
|
||||
|
||||
[Header("Target scanning")]
|
||||
public bool ShouldScanForTargets = true;
|
||||
public LayerMask TargetMask;
|
||||
public float ScanFrequencyInSeconds = 1f;
|
||||
[MMReadOnly]
|
||||
public List<Transform> VisibleTargets = new List<Transform>();
|
||||
|
||||
[Header("Mesh")]
|
||||
public bool ShouldDrawMesh = true;
|
||||
public float MeshDensity = 0.2f;
|
||||
public int EdgePrecision = 3;
|
||||
public float EdgeThreshold = 0.5f;
|
||||
|
||||
public MeshFilter VisionMeshFilter;
|
||||
|
||||
protected Mesh _visionMesh;
|
||||
protected Collider[] _targetsWithinDistance;
|
||||
protected Transform _target;
|
||||
protected Vector3 _directionToTarget;
|
||||
protected float _distanceToTarget;
|
||||
protected float _lastScanTimestamp;
|
||||
|
||||
protected List<Vector3> _viewPoints = new List<Vector3>();
|
||||
protected RaycastData _oldViewCast = new RaycastData();
|
||||
protected RaycastData _viewCast = new RaycastData();
|
||||
protected Vector3[] _vertices;
|
||||
protected int[] _triangles;
|
||||
protected Vector3 _minPoint, _maxPoint, _direction;
|
||||
protected RaycastData _returnRaycastData;
|
||||
protected RaycastHit _raycastAtAngleHit;
|
||||
protected int _numberOfVerticesLastTime = 0;
|
||||
|
||||
public virtual Vector3 Center { get { return this.transform.position + Offset; } }
|
||||
|
||||
protected virtual void Awake()
|
||||
{
|
||||
_visionMesh = new Mesh();
|
||||
if (ShouldDrawMesh)
|
||||
{
|
||||
VisionMeshFilter.mesh = _visionMesh;
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void LateUpdate()
|
||||
{
|
||||
if ((Time.time - _lastScanTimestamp > ScanFrequencyInSeconds) && ShouldScanForTargets)
|
||||
{
|
||||
ScanForTargets();
|
||||
}
|
||||
DrawMesh();
|
||||
}
|
||||
|
||||
public virtual void SetDirectionAndAngles(Vector3 direction, Vector3 eulerAngles)
|
||||
{
|
||||
Direction = direction;
|
||||
EulerAngles = eulerAngles;
|
||||
}
|
||||
|
||||
protected virtual void ScanForTargets()
|
||||
{
|
||||
_lastScanTimestamp = Time.time;
|
||||
VisibleTargets.Clear();
|
||||
_targetsWithinDistance = Physics.OverlapSphere(Center, VisionRadius, TargetMask);
|
||||
foreach (Collider collider in _targetsWithinDistance)
|
||||
{
|
||||
_target = collider.transform;
|
||||
_directionToTarget = (_target.position - Center).normalized;
|
||||
if (Vector3.Angle(Direction, _directionToTarget) < VisionAngle / 2f)
|
||||
{
|
||||
_distanceToTarget = Vector3.Distance(Center, _target.position);
|
||||
|
||||
bool duplicate = false;
|
||||
foreach(Transform visibleTarget in VisibleTargets)
|
||||
{
|
||||
if (visibleTarget == _target)
|
||||
{
|
||||
duplicate = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ((!Physics.Raycast(Center, _directionToTarget, _distanceToTarget, ObstacleMask)) && !duplicate)
|
||||
{
|
||||
VisibleTargets.Add(_target);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void DrawMesh()
|
||||
{
|
||||
if (!ShouldDrawMesh)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int steps = Mathf.RoundToInt(MeshDensity * VisionAngle);
|
||||
float stepsAngle = VisionAngle / steps;
|
||||
|
||||
_viewPoints.Clear();
|
||||
|
||||
for (int i = 0; i <= steps; i++)
|
||||
{
|
||||
float angle = stepsAngle * i + EulerAngles.y - VisionAngle / 2f;
|
||||
_viewCast = RaycastAtAngle(angle);
|
||||
|
||||
if (i > 0)
|
||||
{
|
||||
bool thresholdExceeded = Mathf.Abs(_oldViewCast.Distance - _viewCast.Distance) > EdgeThreshold;
|
||||
|
||||
if ((_oldViewCast.Hit != _viewCast.Hit) || (_oldViewCast.Hit && _viewCast.Hit && thresholdExceeded))
|
||||
{
|
||||
MeshEdgePosition edge = FindMeshEdgePosition(_oldViewCast, _viewCast);
|
||||
if (edge.PointA != Vector3.zero)
|
||||
{
|
||||
_viewPoints.Add(edge.PointA);
|
||||
}
|
||||
if (edge.PointB != Vector3.zero)
|
||||
{
|
||||
_viewPoints.Add(edge.PointB);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_viewPoints.Add(_viewCast.Point);
|
||||
_oldViewCast = _viewCast;
|
||||
}
|
||||
|
||||
int numberOfVertices = _viewPoints.Count + 1;
|
||||
if (numberOfVertices != _numberOfVerticesLastTime)
|
||||
{
|
||||
Array.Resize(ref _vertices, numberOfVertices);
|
||||
Array.Resize(ref _triangles, (numberOfVertices - 2) * 3);
|
||||
}
|
||||
|
||||
_vertices[0] = Offset;
|
||||
for (int i = 0; i < numberOfVertices - 1; i++)
|
||||
{
|
||||
_vertices[i + 1] = this.transform.InverseTransformPoint(_viewPoints[i]);
|
||||
|
||||
if (i < numberOfVertices - 2)
|
||||
{
|
||||
_triangles[i * 3] = 0;
|
||||
_triangles[i * 3 + 1] = i + 1;
|
||||
_triangles[i * 3 + 2] = i + 2;
|
||||
}
|
||||
}
|
||||
|
||||
_visionMesh.Clear();
|
||||
_visionMesh.vertices = _vertices;
|
||||
_visionMesh.triangles = _triangles;
|
||||
_visionMesh.RecalculateNormals();
|
||||
|
||||
_numberOfVerticesLastTime = numberOfVertices;
|
||||
}
|
||||
|
||||
MeshEdgePosition FindMeshEdgePosition(RaycastData minimumViewCast, RaycastData maximumViewCast)
|
||||
{
|
||||
float minAngle = minimumViewCast.Angle;
|
||||
float maxAngle = maximumViewCast.Angle;
|
||||
_minPoint = minimumViewCast.Point;
|
||||
_maxPoint = maximumViewCast.Point;
|
||||
|
||||
for (int i = 0; i < EdgePrecision; i++)
|
||||
{
|
||||
float angle = (minAngle + maxAngle) / 2;
|
||||
RaycastData newViewCast = RaycastAtAngle(angle);
|
||||
|
||||
bool thresholdExceeded = Mathf.Abs(minimumViewCast.Distance - newViewCast.Distance) > EdgeThreshold;
|
||||
if (newViewCast.Hit == minimumViewCast.Hit && !thresholdExceeded)
|
||||
{
|
||||
minAngle = angle;
|
||||
_minPoint = newViewCast.Point;
|
||||
}
|
||||
else
|
||||
{
|
||||
maxAngle = angle;
|
||||
_maxPoint = newViewCast.Point;
|
||||
}
|
||||
}
|
||||
|
||||
return new MeshEdgePosition(_minPoint, _maxPoint);
|
||||
}
|
||||
|
||||
RaycastData RaycastAtAngle(float angle)
|
||||
{
|
||||
_direction = MMMaths.DirectionFromAngle(angle, 0f);
|
||||
|
||||
|
||||
if (Physics.Raycast(Center, _direction, out _raycastAtAngleHit, VisionRadius, ObstacleMask))
|
||||
{
|
||||
_returnRaycastData.Hit = true;
|
||||
_returnRaycastData.Point = _raycastAtAngleHit.point;
|
||||
_returnRaycastData.Distance = _raycastAtAngleHit.distance;
|
||||
_returnRaycastData.Angle = angle;
|
||||
}
|
||||
else
|
||||
{
|
||||
_returnRaycastData.Hit = false;
|
||||
_returnRaycastData.Point = Center + _direction * VisionRadius;
|
||||
_returnRaycastData.Distance = VisionRadius;
|
||||
_returnRaycastData.Angle = angle;
|
||||
}
|
||||
|
||||
return _returnRaycastData;
|
||||
}
|
||||
}
|
||||
}
|
||||
18
Assets/External/Feel/MMTools/Accessories/MMVision/MMConeOfVision.cs.meta
vendored
Normal file
18
Assets/External/Feel/MMTools/Accessories/MMVision/MMConeOfVision.cs.meta
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4fb9c8af0fcd0514e89d35554b6cae77
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 183370
|
||||
packageName: Feel
|
||||
packageVersion: 5.9.1
|
||||
assetPath: Assets/Feel/MMTools/Accessories/MMVision/MMConeOfVision.cs
|
||||
uploadId: 830868
|
||||
269
Assets/External/Feel/MMTools/Accessories/MMVision/MMConeOfVision2D.cs
vendored
Normal file
269
Assets/External/Feel/MMTools/Accessories/MMVision/MMConeOfVision2D.cs
vendored
Normal file
@@ -0,0 +1,269 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using MoreMountains.Tools;
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
|
||||
namespace MoreMountains.Tools
|
||||
{
|
||||
[Serializable]
|
||||
[AddComponentMenu("More Mountains/Tools/Vision/MM Cone Of Vision 2D")]
|
||||
public class MMConeOfVision2D : MonoBehaviour
|
||||
{
|
||||
public struct RaycastData
|
||||
{
|
||||
public bool Hit;
|
||||
public Vector3 Point;
|
||||
public float Distance;
|
||||
public float Angle;
|
||||
|
||||
public RaycastData(bool hit, Vector3 point, float distance, float angle)
|
||||
{
|
||||
Hit = hit;
|
||||
Point = point;
|
||||
Distance = distance;
|
||||
Angle = angle;
|
||||
}
|
||||
}
|
||||
|
||||
public struct MeshEdgePosition
|
||||
{
|
||||
public Vector3 PointA;
|
||||
public Vector3 PointB;
|
||||
|
||||
public MeshEdgePosition(Vector3 pointA, Vector3 pointB)
|
||||
{
|
||||
PointA = pointA;
|
||||
PointB = pointB;
|
||||
}
|
||||
}
|
||||
|
||||
[Header("Vision")]
|
||||
public LayerMask ObstacleMask;
|
||||
public float VisionRadius = 5f;
|
||||
[Range(0f, 360f)]
|
||||
public float VisionAngle = 20f;
|
||||
[Range(0f, 360f)]
|
||||
public float AngleOffset = 0f;
|
||||
[MMReadOnly]
|
||||
public Vector3 Direction;
|
||||
[MMReadOnly]
|
||||
public Vector3 EulerAngles;
|
||||
|
||||
[Header("Target scanning")]
|
||||
public bool ShouldScanForTargets = true;
|
||||
public LayerMask TargetMask;
|
||||
public float ScanFrequencyInSeconds = 1f;
|
||||
[MMReadOnly]
|
||||
public List<Transform> VisibleTargets = new List<Transform>();
|
||||
|
||||
[Header("Mesh")]
|
||||
public bool ShouldDrawMesh = true;
|
||||
public float MeshDensity = 0.2f;
|
||||
public int EdgePrecision = 3;
|
||||
public float EdgeThreshold = 0.5f;
|
||||
|
||||
public MeshFilter VisionMeshFilter;
|
||||
|
||||
#if MM_PHYSICS2D
|
||||
|
||||
protected Mesh _visionMesh;
|
||||
protected Collider2D[] _targetsWithinDistance;
|
||||
protected Transform _target;
|
||||
protected Vector3 _directionToTarget;
|
||||
protected float _distanceToTarget;
|
||||
protected float _lastScanTimestamp;
|
||||
|
||||
protected RaycastHit2D _scanForTargetsHit2D;
|
||||
protected List<Vector3> _viewPoints = new List<Vector3>();
|
||||
protected RaycastData _oldViewCast = new RaycastData();
|
||||
protected RaycastData _viewCast = new RaycastData();
|
||||
|
||||
protected Vector3[] _vertices;
|
||||
protected int[] _triangles;
|
||||
protected Vector3 _minPoint, _maxPoint, _direction;
|
||||
protected RaycastData _returnRaycastData;
|
||||
protected RaycastHit2D _raycastAtAngleHit2D;
|
||||
protected int _numberOfVerticesLastTime = 0;
|
||||
|
||||
protected virtual void Awake()
|
||||
{
|
||||
_visionMesh = new Mesh();
|
||||
Direction = Vector3.right;
|
||||
EulerAngles = Vector3.zero;
|
||||
if (ShouldDrawMesh)
|
||||
{
|
||||
VisionMeshFilter.mesh = _visionMesh;
|
||||
}
|
||||
SetDirectionAndAngles(Direction, EulerAngles);
|
||||
}
|
||||
|
||||
protected void OnValidate()
|
||||
{
|
||||
EulerAngles = Vector3.zero;
|
||||
SetDirectionAndAngles(Direction, EulerAngles);
|
||||
}
|
||||
|
||||
protected virtual void LateUpdate()
|
||||
{
|
||||
if ((Time.time - _lastScanTimestamp > ScanFrequencyInSeconds) && ShouldScanForTargets)
|
||||
{
|
||||
ScanForTargets();
|
||||
}
|
||||
DrawMesh();
|
||||
}
|
||||
|
||||
public virtual void SetDirectionAndAngles(Vector3 direction, Vector3 eulerAngles)
|
||||
{
|
||||
Direction = direction;
|
||||
EulerAngles = eulerAngles;
|
||||
EulerAngles.y += AngleOffset;
|
||||
}
|
||||
|
||||
protected virtual void ScanForTargets()
|
||||
{
|
||||
_lastScanTimestamp = Time.time;
|
||||
VisibleTargets.Clear();
|
||||
_targetsWithinDistance = Physics2D.OverlapCircleAll(this.transform.position, VisionRadius, TargetMask);
|
||||
foreach (Collider2D collider in _targetsWithinDistance)
|
||||
{
|
||||
_target = collider.transform;
|
||||
_directionToTarget = (_target.position - this.transform.position).normalized;
|
||||
if (Vector3.Angle(Direction, _directionToTarget) < VisionAngle / 2f)
|
||||
{
|
||||
_distanceToTarget = Vector3.Distance(this.transform.position, _target.position);
|
||||
|
||||
_scanForTargetsHit2D = Physics2D.Raycast(this.transform.position, _directionToTarget, _distanceToTarget, ObstacleMask);
|
||||
if (!_scanForTargetsHit2D)
|
||||
{
|
||||
VisibleTargets.Add(_target);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void DrawMesh()
|
||||
{
|
||||
if (!ShouldDrawMesh)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int steps = Mathf.RoundToInt(MeshDensity * VisionAngle);
|
||||
float stepsAngle = VisionAngle / steps;
|
||||
|
||||
_viewPoints.Clear();
|
||||
|
||||
for (int i = 0; i <= steps; i++)
|
||||
{
|
||||
float angle = stepsAngle * i + EulerAngles.y - VisionAngle / 2f;
|
||||
_viewCast = RaycastAtAngle(angle);
|
||||
|
||||
if (i > 0)
|
||||
{
|
||||
bool thresholdExceeded = Mathf.Abs(_oldViewCast.Distance - _viewCast.Distance) > EdgeThreshold;
|
||||
|
||||
if ((_oldViewCast.Hit != _viewCast.Hit) || (_oldViewCast.Hit && _viewCast.Hit && thresholdExceeded))
|
||||
{
|
||||
MeshEdgePosition edge = FindMeshEdgePosition(_oldViewCast, _viewCast);
|
||||
if (edge.PointA != Vector3.zero)
|
||||
{
|
||||
_viewPoints.Add(edge.PointA);
|
||||
}
|
||||
if (edge.PointB != Vector3.zero)
|
||||
{
|
||||
_viewPoints.Add(edge.PointB);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_viewPoints.Add(_viewCast.Point);
|
||||
_oldViewCast = _viewCast;
|
||||
}
|
||||
|
||||
int numberOfVertices = _viewPoints.Count + 1;
|
||||
if (numberOfVertices != _numberOfVerticesLastTime)
|
||||
{
|
||||
Array.Resize(ref _vertices, numberOfVertices);
|
||||
Array.Resize(ref _triangles, (numberOfVertices - 2) * 3);
|
||||
}
|
||||
|
||||
_vertices[0].x = 0;
|
||||
_vertices[0].y = 0;
|
||||
_vertices[0].z = 0;
|
||||
|
||||
for (int i = 0; i < numberOfVertices - 1; i++)
|
||||
{
|
||||
_vertices[i + 1] = this.transform.InverseTransformPoint(_viewPoints[i]);
|
||||
|
||||
if (i < numberOfVertices - 2)
|
||||
{
|
||||
_triangles[i * 3] = 0;
|
||||
_triangles[i * 3 + 1] = i + 1;
|
||||
_triangles[i * 3 + 2] = i + 2;
|
||||
}
|
||||
}
|
||||
|
||||
_visionMesh.Clear();
|
||||
_visionMesh.vertices = _vertices;
|
||||
_visionMesh.triangles = _triangles;
|
||||
_visionMesh.RecalculateNormals();
|
||||
|
||||
_numberOfVerticesLastTime = numberOfVertices;
|
||||
}
|
||||
|
||||
MeshEdgePosition FindMeshEdgePosition(RaycastData minimumViewCast, RaycastData maximumViewCast)
|
||||
{
|
||||
float minAngle = minimumViewCast.Angle;
|
||||
float maxAngle = maximumViewCast.Angle;
|
||||
_minPoint = minimumViewCast.Point;
|
||||
_maxPoint = maximumViewCast.Point;
|
||||
|
||||
for (int i = 0; i < EdgePrecision; i++)
|
||||
{
|
||||
float angle = (minAngle + maxAngle) / 2;
|
||||
RaycastData newViewCast = RaycastAtAngle(angle);
|
||||
|
||||
bool thresholdExceeded = Mathf.Abs(minimumViewCast.Distance - newViewCast.Distance) > EdgeThreshold;
|
||||
if (newViewCast.Hit == minimumViewCast.Hit && !thresholdExceeded)
|
||||
{
|
||||
minAngle = angle;
|
||||
_minPoint = newViewCast.Point;
|
||||
}
|
||||
else
|
||||
{
|
||||
maxAngle = angle;
|
||||
_maxPoint = newViewCast.Point;
|
||||
}
|
||||
}
|
||||
|
||||
return new MeshEdgePosition(_minPoint, _maxPoint);
|
||||
}
|
||||
|
||||
RaycastData RaycastAtAngle(float angle)
|
||||
{
|
||||
_direction = MMMaths.DirectionFromAngle2D(angle, 0f);
|
||||
|
||||
_raycastAtAngleHit2D = Physics2D.Raycast(this.transform.position, _direction, VisionRadius, ObstacleMask);
|
||||
|
||||
if (_raycastAtAngleHit2D)
|
||||
{
|
||||
_returnRaycastData.Hit = true;
|
||||
_returnRaycastData.Point = _raycastAtAngleHit2D.point;
|
||||
_returnRaycastData.Distance = _raycastAtAngleHit2D.distance;
|
||||
_returnRaycastData.Angle = angle;
|
||||
}
|
||||
else
|
||||
{
|
||||
_returnRaycastData.Hit = false;
|
||||
_returnRaycastData.Point = this.transform.position + _direction * VisionRadius;
|
||||
_returnRaycastData.Distance = VisionRadius;
|
||||
_returnRaycastData.Angle = angle;
|
||||
}
|
||||
|
||||
return _returnRaycastData;
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
18
Assets/External/Feel/MMTools/Accessories/MMVision/MMConeOfVision2D.cs.meta
vendored
Normal file
18
Assets/External/Feel/MMTools/Accessories/MMVision/MMConeOfVision2D.cs.meta
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ceea5d59c11750f4e8deb2c47ff8bcb4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 183370
|
||||
packageName: Feel
|
||||
packageVersion: 5.9.1
|
||||
assetPath: Assets/Feel/MMTools/Accessories/MMVision/MMConeOfVision2D.cs
|
||||
uploadId: 830868
|
||||
Reference in New Issue
Block a user