GitHub
5 年前
当前提交
2e6bab0d
共有 29 个文件被更改,包括 1569 次插入 和 1392 次删除
-
7UnitySDK/Assets/ML-Agents/Editor/BehaviorParametersEditor.cs
-
2UnitySDK/Assets/ML-Agents/Editor/Tests/DemonstrationTests.cs
-
1UnitySDK/Assets/ML-Agents/Editor/Tests/Sensor/WriterAdapterTests.cs
-
6UnitySDK/Assets/ML-Agents/Examples/FoodCollector/Scripts/FoodCollectorAgent.cs
-
15UnitySDK/Assets/ML-Agents/Examples/SharedAssets/Scripts/RayPerception.cs
-
59UnitySDK/Assets/ML-Agents/Examples/SharedAssets/Scripts/RayPerception2D.cs
-
69UnitySDK/Assets/ML-Agents/Examples/SharedAssets/Scripts/RayPerception3D.cs
-
52UnitySDK/Assets/ML-Agents/Examples/WallJump/Prefabs/WallJumpArea.prefab
-
2UnitySDK/Assets/ML-Agents/Examples/WallJump/Scenes/WallJump.unity
-
11UnitySDK/Assets/ML-Agents/Examples/WallJump/Scripts/WallJumpAgent.cs
-
1001UnitySDK/Assets/ML-Agents/Examples/WallJump/TFModels/BigWallJump.nn
-
1001UnitySDK/Assets/ML-Agents/Examples/WallJump/TFModels/SmallWallJump.nn
-
4UnitySDK/Assets/ML-Agents/Scripts/Agent.cs
-
164UnitySDK/Assets/ML-Agents/Scripts/InferenceBrain/BarracudaModelParamLoader.cs
-
5UnitySDK/Assets/ML-Agents/Scripts/Sensor/CameraSensorComponent.cs
-
2UnitySDK/Assets/ML-Agents/Scripts/Sensor/ISensor.cs
-
5UnitySDK/Assets/ML-Agents/Scripts/Sensor/RenderTextureSensorComponent.cs
-
18UnitySDK/Assets/ML-Agents/Scripts/Sensor/SensorComponent.cs
-
1UnitySDK/UnitySDK.sln.DotSettings
-
21UnitySDK/Assets/ML-Agents/Editor/Tests/Sensor/RayPerceptionSensorTests.cs
-
3UnitySDK/Assets/ML-Agents/Editor/Tests/Sensor/RayPerceptionSensorTests.cs.meta
-
315UnitySDK/Assets/ML-Agents/Scripts/Sensor/RayPerceptionSensor.cs
-
3UnitySDK/Assets/ML-Agents/Scripts/Sensor/RayPerceptionSensor.cs.meta
-
10UnitySDK/Assets/ML-Agents/Scripts/Sensor/RayPerceptionSensorComponent2D.cs
-
3UnitySDK/Assets/ML-Agents/Scripts/Sensor/RayPerceptionSensorComponent2D.cs.meta
-
32UnitySDK/Assets/ML-Agents/Scripts/Sensor/RayPerceptionSensorComponent3D.cs
-
3UnitySDK/Assets/ML-Agents/Scripts/Sensor/RayPerceptionSensorComponent3D.cs.meta
-
143UnitySDK/Assets/ML-Agents/Scripts/Sensor/RayPerceptionSensorComponentBase.cs
-
3UnitySDK/Assets/ML-Agents/Scripts/Sensor/RayPerceptionSensorComponentBase.cs.meta
|
|||
using System.Collections.Generic; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
protected List<float> m_PerceptionBuffer = new List<float>(); |
|||
protected float[] m_PerceptionBuffer; |
|||
abstract public List<float> Perceive(float rayDistance, |
|||
abstract public IList<float> Perceive(float rayDistance, |
|||
/// <summary>
|
|||
/// Converts degrees to radians.
|
|||
/// </summary>
|
|||
public static float DegreeToRadian(float degree) |
|||
{ |
|||
return degree * Mathf.PI / 180f; |
|||
} |
|||
|
|||
} |
1001
UnitySDK/Assets/ML-Agents/Examples/WallJump/TFModels/BigWallJump.nn
文件差异内容过多而无法显示
查看文件
文件差异内容过多而无法显示
查看文件
1001
UnitySDK/Assets/ML-Agents/Examples/WallJump/TFModels/SmallWallJump.nn
文件差异内容过多而无法显示
查看文件
文件差异内容过多而无法显示
查看文件
|
|||
using NUnit.Framework; |
|||
using UnityEngine; |
|||
using MLAgents.Sensor; |
|||
|
|||
namespace MLAgents.Tests |
|||
{ |
|||
public class RayPerceptionSensorTests |
|||
{ |
|||
[Test] |
|||
public void TestGetRayAngles() |
|||
{ |
|||
var angles = RayPerceptionSensorComponentBase.GetRayAngles(3, 90f); |
|||
var expectedAngles = new [] { 90f, 60f, 120f, 30f, 150f, 0f, 180f }; |
|||
Assert.AreEqual(expectedAngles.Length, angles.Length); |
|||
for (var i = 0; i < angles.Length; i++) |
|||
{ |
|||
Assert.AreEqual(expectedAngles[i], angles[i], .01); |
|||
} |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: d2983e2bca9a40398f287727dc0472a5 |
|||
timeCreated: 1573242741 |
|
|||
using System; |
|||
using System.Collections.Generic; |
|||
using UnityEngine; |
|||
|
|||
namespace MLAgents.Sensor |
|||
{ |
|||
public class RayPerceptionSensor : ISensor |
|||
{ |
|||
public enum CastType |
|||
{ |
|||
Cast2D, |
|||
Cast3D, |
|||
} |
|||
|
|||
float[] m_Observations; |
|||
int[] m_Shape; |
|||
string m_Name; |
|||
|
|||
float m_RayDistance; |
|||
List<string> m_DetectableObjects; |
|||
float[] m_Angles; |
|||
|
|||
float m_StartOffset; |
|||
float m_EndOffset; |
|||
float m_CastRadius; |
|||
CastType m_CastType; |
|||
Transform m_Transform; |
|||
|
|||
/// <summary>
|
|||
/// Debug information for the raycast hits. This is used by the RayPerceptionSensorComponent.
|
|||
/// </summary>
|
|||
public class DebugDisplayInfo |
|||
{ |
|||
public struct RayInfo |
|||
{ |
|||
public Vector3 localStart; |
|||
public Vector3 localEnd; |
|||
public Vector3 worldStart; |
|||
public Vector3 worldEnd; |
|||
public bool castHit; |
|||
public float hitFraction; |
|||
} |
|||
|
|||
public void Reset() |
|||
{ |
|||
m_Frame = Time.frameCount; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// "Age" of the results in number of frames. This is used to adjust the alpha when drawing.
|
|||
/// </summary>
|
|||
public int age |
|||
{ |
|||
get { return Time.frameCount - m_Frame; } |
|||
} |
|||
|
|||
public RayInfo[] rayInfos; |
|||
|
|||
int m_Frame; |
|||
} |
|||
|
|||
DebugDisplayInfo m_DebugDisplayInfo; |
|||
|
|||
public DebugDisplayInfo debugDisplayInfo |
|||
{ |
|||
get { return m_DebugDisplayInfo; } |
|||
} |
|||
|
|||
public RayPerceptionSensor(string name, float rayDistance, List<string> detectableObjects, float[] angles, |
|||
Transform transform, float startOffset, float endOffset, float castRadius, CastType castType) |
|||
{ |
|||
var numObservations = (detectableObjects.Count + 2) * angles.Length; |
|||
m_Shape = new[] { numObservations }; |
|||
m_Name = name; |
|||
|
|||
m_Observations = new float[numObservations]; |
|||
|
|||
m_RayDistance = rayDistance; |
|||
m_DetectableObjects = detectableObjects; |
|||
// TODO - preprocess angles, save ray directions instead?
|
|||
m_Angles = angles; |
|||
m_Transform = transform; |
|||
m_StartOffset = startOffset; |
|||
m_EndOffset = endOffset; |
|||
m_CastRadius = castRadius; |
|||
m_CastType = castType; |
|||
|
|||
if (Application.isEditor) |
|||
{ |
|||
m_DebugDisplayInfo = new DebugDisplayInfo(); |
|||
} |
|||
} |
|||
|
|||
public int Write(WriteAdapter adapter) |
|||
{ |
|||
PerceiveStatic( |
|||
m_RayDistance, m_Angles, m_DetectableObjects, m_StartOffset, m_EndOffset, |
|||
m_CastRadius, m_Transform, m_CastType, m_Observations, false, m_DebugDisplayInfo |
|||
); |
|||
adapter.AddRange(m_Observations); |
|||
return m_Observations.Length; |
|||
} |
|||
|
|||
public void Update() |
|||
{ |
|||
} |
|||
|
|||
public int[] GetFloatObservationShape() |
|||
{ |
|||
return m_Shape; |
|||
} |
|||
|
|||
public string GetName() |
|||
{ |
|||
return m_Name; |
|||
} |
|||
|
|||
public virtual byte[] GetCompressedObservation() |
|||
{ |
|||
return null; |
|||
} |
|||
|
|||
public virtual SensorCompressionType GetCompressionType() |
|||
{ |
|||
return SensorCompressionType.None; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Evaluates a perception vector to be used as part of an observation of an agent.
|
|||
/// Each element in the rayAngles array determines a sublist of data to the observation.
|
|||
/// The sublist contains the observation data for a single cast. The list is composed of the following:
|
|||
/// 1. A one-hot encoding for detectable objects. For example, if detectableObjects.Length = n, the
|
|||
/// first n elements of the sublist will be a one-hot encoding of the detectableObject that was hit, or
|
|||
/// all zeroes otherwise.
|
|||
/// 2. The 'length' element of the sublist will be 1 if the ray missed everything, or 0 if it hit
|
|||
/// something (detectable or not).
|
|||
/// 3. The 'length+1' element of the sublist will contain the normalised distance to the object hit, or 1 if
|
|||
/// nothing was hit.
|
|||
///
|
|||
/// The legacyHitFractionBehavior changes the behavior to be backwards compatible but has some
|
|||
/// counter-intuitive behavior:
|
|||
/// * if the cast hits a object that's not in the detectableObjects list, all results are 0
|
|||
/// * if the cast doesn't hit, the hit fraction field is 0
|
|||
/// </summary>
|
|||
/// <param name="rayLength"></param>
|
|||
/// <param name="rayAngles">List of angles (in degrees) used to define the rays. 90 degrees is considered
|
|||
/// "forward" relative to the game object</param>
|
|||
/// <param name="detectableObjects">List of tags which correspond to object types agent can see</param>
|
|||
/// <param name="startOffset">Starting height offset of ray from center of agent.</param>
|
|||
/// <param name="endOffset">Ending height offset of ray from center of agent.</param>
|
|||
/// <param name="castRadius">Radius of the sphere to use for spherecasting. If 0 or less, rays are used
|
|||
/// instead - this may be faster, especially for complex environments.</param>
|
|||
/// <param name="transform">Transform of the GameObject</param>
|
|||
/// <param name="castType">Whether to perform the casts in 2D or 3D.</param>
|
|||
/// <param name="perceptionBuffer">Output array of floats. Must be (num rays) * (num tags + 2) in size.</param>
|
|||
/// <param name="legacyHitFractionBehavior">Whether to use the legacy behavior for hit fractions.</param>
|
|||
/// <param name="debugInfo">Optional debug information output, only used by RayPerceptionSensor.</param>
|
|||
///
|
|||
public static void PerceiveStatic(float rayLength, |
|||
IReadOnlyList<float> rayAngles, IReadOnlyList<string> detectableObjects, |
|||
float startOffset, float endOffset, float castRadius, |
|||
Transform transform, CastType castType, float[] perceptionBuffer, |
|||
bool legacyHitFractionBehavior = false, |
|||
DebugDisplayInfo debugInfo = null) |
|||
{ |
|||
Array.Clear(perceptionBuffer, 0, perceptionBuffer.Length); |
|||
if (debugInfo != null) |
|||
{ |
|||
debugInfo.Reset(); |
|||
if (debugInfo.rayInfos == null || debugInfo.rayInfos.Length != rayAngles.Count) |
|||
{ |
|||
debugInfo.rayInfos = new DebugDisplayInfo.RayInfo[rayAngles.Count]; |
|||
} |
|||
} |
|||
|
|||
// For each ray sublist stores categorical information on detected object
|
|||
// along with object distance.
|
|||
int bufferOffset = 0; |
|||
for (var rayIndex = 0; rayIndex<rayAngles.Count; rayIndex++) |
|||
{ |
|||
var angle = rayAngles[rayIndex]; |
|||
Vector3 startPositionLocal, endPositionLocal; |
|||
if (castType == CastType.Cast3D) |
|||
{ |
|||
startPositionLocal = new Vector3(0, startOffset, 0); |
|||
endPositionLocal = PolarToCartesian3D(rayLength, angle); |
|||
endPositionLocal.y += endOffset; |
|||
} |
|||
else |
|||
{ |
|||
// Vector2s here get converted to Vector3s (and back to Vector2s for casting)
|
|||
startPositionLocal = new Vector2(); |
|||
endPositionLocal = PolarToCartesian2D(rayLength, angle); |
|||
} |
|||
|
|||
var startPositionWorld = transform.TransformPoint(startPositionLocal); |
|||
var endPositionWorld = transform.TransformPoint(endPositionLocal); |
|||
|
|||
var rayDirection = endPositionWorld - startPositionWorld; |
|||
|
|||
// Do the cast and assign the hit information for each detectable object.
|
|||
// sublist[0 ] <- did hit detectableObjects[0]
|
|||
// ...
|
|||
// sublist[numObjects-1] <- did hit detectableObjects[numObjects-1]
|
|||
// sublist[numObjects ] <- 1 if missed else 0
|
|||
// sublist[numObjects+1] <- hit fraction (or 1 if no hit)
|
|||
// The legacyHitFractionBehavior changes the behavior to be backwards compatible but has some
|
|||
// counter-intuitive behavior:
|
|||
// * if the cast hits a object that's not in the detectableObjects list, all results are 0
|
|||
// * if the cast doesn't hit, the hit fraction field is 0
|
|||
|
|||
bool castHit; |
|||
float hitFraction; |
|||
GameObject hitObject; |
|||
|
|||
if(castType == CastType.Cast3D) |
|||
{ |
|||
RaycastHit rayHit; |
|||
if (castRadius > 0f) |
|||
{ |
|||
castHit = Physics.SphereCast(startPositionWorld, castRadius, rayDirection, out rayHit, rayLength); |
|||
} |
|||
else |
|||
{ |
|||
castHit = Physics.Raycast(startPositionWorld, rayDirection, out rayHit, rayLength); |
|||
} |
|||
|
|||
hitFraction = castHit ? rayHit.distance / rayLength : 1.0f; |
|||
hitObject = castHit ? rayHit.collider.gameObject : null; |
|||
} |
|||
else |
|||
{ |
|||
RaycastHit2D rayHit; |
|||
if (castRadius > 0f) |
|||
{ |
|||
rayHit = Physics2D.CircleCast(startPositionWorld, castRadius, rayDirection, rayLength); |
|||
} |
|||
else |
|||
{ |
|||
rayHit = Physics2D.Raycast(startPositionWorld, rayDirection, rayLength); |
|||
} |
|||
|
|||
castHit = rayHit; |
|||
hitFraction = castHit ? rayHit.fraction : 1.0f; |
|||
hitObject = castHit ? rayHit.collider.gameObject : null; |
|||
} |
|||
|
|||
if (debugInfo != null) |
|||
{ |
|||
debugInfo.rayInfos[rayIndex].localStart = startPositionLocal; |
|||
debugInfo.rayInfos[rayIndex].localEnd = endPositionLocal; |
|||
debugInfo.rayInfos[rayIndex].worldStart = startPositionWorld; |
|||
debugInfo.rayInfos[rayIndex].worldEnd = endPositionWorld; |
|||
debugInfo.rayInfos[rayIndex].castHit = castHit; |
|||
debugInfo.rayInfos[rayIndex].hitFraction = hitFraction; |
|||
} |
|||
else if (Application.isEditor) |
|||
{ |
|||
// Legacy drawing
|
|||
Debug.DrawRay(startPositionWorld,rayDirection, Color.black, 0.01f, true); |
|||
} |
|||
|
|||
if (castHit) |
|||
{ |
|||
for (var i = 0; i < detectableObjects.Count; i++) |
|||
{ |
|||
if (hitObject.CompareTag(detectableObjects[i])) |
|||
{ |
|||
perceptionBuffer[bufferOffset + i] = 1; |
|||
perceptionBuffer[bufferOffset + detectableObjects.Count + 1] = hitFraction; |
|||
break; |
|||
} |
|||
|
|||
if (!legacyHitFractionBehavior) |
|||
{ |
|||
// Something was hit but not on the list. Still set the hit fraction.
|
|||
perceptionBuffer[bufferOffset + detectableObjects.Count + 1] = hitFraction; |
|||
} |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
perceptionBuffer[bufferOffset + detectableObjects.Count] = 1f; |
|||
if (!legacyHitFractionBehavior) |
|||
{ |
|||
// Nothing was hit, so there's full clearance in front of the agent.
|
|||
perceptionBuffer[bufferOffset + detectableObjects.Count + 1] = 1.0f; |
|||
} |
|||
} |
|||
|
|||
bufferOffset += detectableObjects.Count + 2; |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Converts polar coordinate to cartesian coordinate.
|
|||
/// </summary>
|
|||
static Vector3 PolarToCartesian3D(float radius, float angleDegrees) |
|||
{ |
|||
var x = radius * Mathf.Cos(Mathf.Deg2Rad * angleDegrees); |
|||
var z = radius * Mathf.Sin(Mathf.Deg2Rad * angleDegrees); |
|||
return new Vector3(x, 0f, z); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Converts polar coordinate to cartesian coordinate.
|
|||
/// </summary>
|
|||
static Vector2 PolarToCartesian2D(float radius, float angleDegrees) |
|||
{ |
|||
var x = radius * Mathf.Cos(Mathf.Deg2Rad * angleDegrees); |
|||
var y = radius * Mathf.Sin(Mathf.Deg2Rad * angleDegrees); |
|||
return new Vector2(x, y); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 71417cdf8dd542e19ec22822b001b884 |
|||
timeCreated: 1573089052 |
|
|||
namespace MLAgents.Sensor |
|||
{ |
|||
public class RayPerceptionSensorComponent2D : RayPerceptionSensorComponentBase |
|||
{ |
|||
public override RayPerceptionSensor.CastType GetCastType() |
|||
{ |
|||
return RayPerceptionSensor.CastType.Cast2D; |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: f67c7e722ba14acd9153bb4488bff6e4 |
|||
timeCreated: 1573769662 |
|
|||
using System; |
|||
using UnityEngine; |
|||
|
|||
namespace MLAgents.Sensor |
|||
{ |
|||
public class RayPerceptionSensorComponent3D : RayPerceptionSensorComponentBase |
|||
{ |
|||
[Header("3D Properties", order = 100)] |
|||
[Range(-10f, 10f)] |
|||
[Tooltip("Ray start is offset up or down by this amount.")] |
|||
public float startVerticalOffset; |
|||
|
|||
[Range(-10f, 10f)] |
|||
[Tooltip("Ray end is offset up or down by this amount.")] |
|||
public float endVerticalOffset; |
|||
|
|||
public override RayPerceptionSensor.CastType GetCastType() |
|||
{ |
|||
return RayPerceptionSensor.CastType.Cast3D; |
|||
} |
|||
|
|||
public override float GetStartVerticalOffset() |
|||
{ |
|||
return startVerticalOffset; |
|||
} |
|||
|
|||
public override float GetEndVerticalOffset() |
|||
{ |
|||
return endVerticalOffset; |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 6bb6b867a41448888c1cd4f99643ad71 |
|||
timeCreated: 1573764567 |
|
|||
using System; |
|||
using System.Collections.Generic; |
|||
using UnityEngine; |
|||
|
|||
namespace MLAgents.Sensor |
|||
{ |
|||
public abstract class RayPerceptionSensorComponentBase : SensorComponent |
|||
{ |
|||
public string sensorName = "RayPerceptionSensor"; |
|||
|
|||
[Tooltip("List of tags in the scene to compare against.")] |
|||
public List<string> detectableTags; |
|||
|
|||
[Range(0, 50)] |
|||
[Tooltip("Number of rays to the left and right of center.")] |
|||
public int raysPerDirection = 3; |
|||
|
|||
[Range(0, 180)] |
|||
[Tooltip("Cone size for rays. Using 90 degrees will cast rays to the left and right. Greater than 90 degrees will go backwards.")] |
|||
public float maxRayDegrees = 70; |
|||
|
|||
[Range(0f, 10f)] |
|||
[Tooltip("Radius of sphere to cast. Set to zero for raycasts.")] |
|||
public float sphereCastRadius = 0.5f; |
|||
|
|||
[Range(1, 1000)] |
|||
[Tooltip("Length of the rays to cast.")] |
|||
public float rayLength = 20f; |
|||
|
|||
[Range(1, 50)] |
|||
[Tooltip("Whether to stack previous observations. Using 1 means no previous observations.")] |
|||
public int observationStacks = 1; |
|||
|
|||
[Header("Debug Gizmos", order = 999)] |
|||
public Color rayHitColor = Color.red; |
|||
public Color rayMissColor = Color.white; |
|||
[Tooltip("Whether to draw the raycasts in the world space of when they happened, or using the Agent's current transform'")] |
|||
public bool useWorldPositions = true; |
|||
|
|||
|
|||
[NonSerialized] |
|||
RayPerceptionSensor m_RaySensor; |
|||
|
|||
public abstract RayPerceptionSensor.CastType GetCastType(); |
|||
|
|||
public virtual float GetStartVerticalOffset() |
|||
{ |
|||
return 0f; |
|||
} |
|||
|
|||
public virtual float GetEndVerticalOffset() |
|||
{ |
|||
return 0f; |
|||
} |
|||
|
|||
public override ISensor CreateSensor() |
|||
{ |
|||
var rayAngles = GetRayAngles(raysPerDirection, maxRayDegrees); |
|||
m_RaySensor = new RayPerceptionSensor(sensorName, rayLength, detectableTags, rayAngles, |
|||
transform, GetStartVerticalOffset(), GetEndVerticalOffset(), sphereCastRadius, GetCastType() |
|||
); |
|||
|
|||
if (observationStacks != 1) |
|||
{ |
|||
var stackingSensor = new StackingSensor(m_RaySensor, observationStacks); |
|||
return stackingSensor; |
|||
} |
|||
|
|||
return m_RaySensor; |
|||
} |
|||
|
|||
public static float[] GetRayAngles(int raysPerDirection, float maxRayDegrees) |
|||
{ |
|||
// Example:
|
|||
// { 90, 90 - delta, 90 + delta, 90 - 2*delta, 90 + 2*delta }
|
|||
var anglesOut = new float[2 * raysPerDirection + 1]; |
|||
var delta = maxRayDegrees / raysPerDirection; |
|||
anglesOut[0] = 90f; |
|||
for (var i = 0; i < raysPerDirection; i++) |
|||
{ |
|||
anglesOut[2 * i + 1] = 90 - (i+1) * delta; |
|||
anglesOut[2 * i + 2] = 90 + (i+1) * delta; |
|||
} |
|||
return anglesOut; |
|||
} |
|||
|
|||
public override int[] GetObservationShape() |
|||
{ |
|||
var numRays = 2 * raysPerDirection + 1; |
|||
var numTags = detectableTags == null ? 0 : detectableTags.Count; |
|||
var obsSize = (numTags + 2) * numRays; |
|||
var stacks = observationStacks > 1 ? observationStacks : 1; |
|||
return new[] { obsSize * stacks }; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draw the debug information from the sensor (if available).
|
|||
/// </summary>
|
|||
public void OnDrawGizmos() |
|||
{ |
|||
if (m_RaySensor?.debugDisplayInfo?.rayInfos == null) |
|||
{ |
|||
return; |
|||
} |
|||
var debugInfo = m_RaySensor.debugDisplayInfo; |
|||
|
|||
// Draw "old" observations in a lighter color.
|
|||
// Since the agent may not step every frame, this helps de-emphasize "stale" hit information.
|
|||
var alpha = Mathf.Pow(.5f, debugInfo.age); |
|||
|
|||
foreach (var rayInfo in debugInfo.rayInfos) |
|||
{ |
|||
// Either use the original world-space coordinates of the raycast, or transform the agent-local
|
|||
// coordinates of the rays to the current transform of the agent. If the agent acts every frame,
|
|||
// these should be the same.
|
|||
var startPositionWorld = rayInfo.worldStart; |
|||
var endPositionWorld = rayInfo.worldEnd; |
|||
if (!useWorldPositions) |
|||
{ |
|||
startPositionWorld = transform.TransformPoint(rayInfo.localStart); |
|||
endPositionWorld = transform.TransformPoint(rayInfo.localEnd); |
|||
} |
|||
var rayDirection = endPositionWorld - startPositionWorld; |
|||
rayDirection *= rayInfo.hitFraction; |
|||
|
|||
// hit fraction ^2 will shift "far" hits closer to the hit color
|
|||
var lerpT = rayInfo.hitFraction * rayInfo.hitFraction; |
|||
var color = Color.Lerp(rayHitColor, rayMissColor, lerpT); |
|||
color.a = alpha; |
|||
Gizmos.color = color; |
|||
Gizmos.DrawRay(startPositionWorld,rayDirection); |
|||
|
|||
// Draw the hit point as a sphere. If using rays to cast (0 radius), use a small sphere.
|
|||
if (rayInfo.castHit) |
|||
{ |
|||
var hitRadius = Mathf.Max(sphereCastRadius, .05f); |
|||
Gizmos.DrawWireSphere(startPositionWorld + rayDirection, hitRadius); |
|||
} |
|||
} |
|||
|
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 45243967d8c0419b953c02bccb7c2768 |
|||
timeCreated: 1573087062 |
撰写
预览
正在加载...
取消
保存
Reference in new issue