Aimbot-ParallelEnv/Assets/Script/GameScript/RaySensors.cs
Koha9 bf1d1d8d3b Onehot功能完善,修正
OneHot功能完善,更改TaySensor探测到Tag的index表示。与之前不通用!
修正PlayMode中的scenePrefabSet未定位错误
修正Raysensor中TagToInt不包含rayTagResult中的-1
2023-12-31 07:49:58 +09:00

183 lines
7.2 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Collections.Generic;
using UnityEngine;
/*该scrip用于创建复数条ray于视角内并探测被ray射到的物体*/
public class RaySensors : MonoBehaviour
{
[SerializeField] private Camera agentCam;
[SerializeField] private Camera TPSCam;
[SerializeField] private Material lineMeterial;
[SerializeField] private GameObject rayInfoPrefab;
[SerializeField] private GameObject agentCanvas;
[SerializeField, Range(0, 500)] public float viewDistance = 100; // how long the ray can detect
//[SerializeField, Range(0, 1)] public float totalRange = 1f; // Total view range Max = 1
[SerializeField, Range(0, 1)] public float focusRange = 0.15f; // center focus range
public int halfOuterRayNum = 7; // >=2
public int focusRayNum = 5; // >= 1 and must be odd num!
[Header("InGameLineSetting")]
public bool showInGameRay = true;
public bool showDebugRay = true;
public bool showInGameRayInfo = true;
public float lineWidth = 0.05f;
[Header("RayCastResult")]
public float[] rayTagResult;
public float[] rayTagResultOneHot;
public float[] rayDisResult;
[System.NonSerialized] public int totalRayNum;
private string myTag = "";
private GameObject[] linesOBJ;
private GameObject[] rayInfoOBJ;
private LineRenderer[] lineRenderers;
private RayInfoUI[] rayInfoUIs;
public List<GameObject> inViewEnemies = new List<GameObject>();
private List<string> tags = new List<string> { "Wall", "Enemy" };
private Onehot oneHotTags = new Onehot();
private void Start()
{
myTag = gameObject.tag;
totalRayNum = halfOuterRayNum * 2 + focusRayNum;
rayTagResult = new float[totalRayNum];
rayDisResult = new float[totalRayNum];
rayTagResultOneHot = new float[totalRayNum*ObjectTags.Tags.Count];
linesOBJ = new GameObject[totalRayNum];
lineRenderers = new LineRenderer[totalRayNum];
rayInfoOBJ = new GameObject[totalRayNum];
rayInfoUIs = new RayInfoUI[totalRayNum];
oneHotTags.Initialize(tags);
for (int i = 0; i < totalRayNum; i++)
{
linesOBJ[i] = new GameObject();
linesOBJ[i].name = "rayCastLine-" + Convert.ToString(i);
linesOBJ[i].transform.parent = agentCam.transform;
linesOBJ[i].AddComponent<LineRenderer>();
lineRenderers[i] = linesOBJ[i].GetComponent<LineRenderer>();
lineRenderers[i].material = lineMeterial;
rayInfoOBJ[i] = (GameObject)Instantiate(rayInfoPrefab);
rayInfoOBJ[i].transform.SetParent(agentCanvas.transform, false);
rayInfoOBJ[i].name = "rayInfo-" + Convert.ToString(i);
rayInfoUIs[i] = rayInfoOBJ[i].GetComponent<RayInfoUI>();
}
}
private void SingleRaycastUpdate(Ray ray,int rayIndex)
{
// get Raycast hit infomation and return Tag and distance
RaycastHit nowHit;
Color rayColor = Color.gray;
float lineLength = viewDistance;
string rayInfoText = "";
Vector3 rayInfoPosition;
if (Physics.Raycast(ray, out nowHit, viewDistance)) // 若在viewDistance范围内有碰撞
{
// Tag
string thisTag = nowHit.collider.tag;
// result update
rayTagResult[rayIndex] = ObjectTags.TagToInt(thisTag);
rayDisResult[rayIndex] = nowHit.distance;
int oneHotIndex = rayIndex * ObjectTags.Tags.Count + ObjectTags.TagToInt(thisTag);
rayTagResultOneHot[oneHotIndex] = 1f;
if (rayTagResult[rayIndex] == ObjectTags.TagToInt("Enemy"))
{
inViewEnemies.Add(nowHit.transform.gameObject);
}
// ingame info update
lineLength = nowHit.distance;
rayInfoText = thisTag + "\n" + Convert.ToString(nowHit.distance);
rayColor = ObjectTags.TagToCololr(thisTag);
}
else // 若在viewDistance范围无碰撞
{
// Result update
// rayTagResultOneHot keep zero
rayTagResult[rayIndex] = -1;
rayDisResult[rayIndex] = -1;
// Info
rayInfoText = "Empty";
}
// draw Info In Game
rayInfoPosition = ray.origin + (ray.direction * lineLength);
if (showInGameRay)
{
DrawLine(ray, lineLength, lineRenderers[rayIndex], rayColor);
}
else
{
TurnOffLine(lineRenderers[rayIndex], rayColor);
}
// drawRay in game
if (showInGameRayInfo) rayInfoUIs[rayIndex].UpdateInfo(rayInfoText, rayInfoPosition, rayColor, TPSCam);
// Show log
if (showDebugRay) Debug.DrawRay(ray.origin, ray.direction * viewDistance, rayColor); // drawRay in debug
// Debug.Log(ray.origin + ray.direction);
// Debug.Log(thisRayTagResult);
// Debug.Log(tagToInt(nowHit.collider.thisTag));
}
private void DrawLine(Ray ray, float lineLength, LineRenderer lineRenderer, Color lineColor)
{
lineRenderer.startColor = lineColor;
lineRenderer.endColor = lineColor;
lineRenderer.startWidth = lineWidth;
lineRenderer.endWidth = lineWidth;
lineRenderer.SetPosition(0, ray.origin);
lineRenderer.SetPosition(1, ray.origin + (ray.direction * lineLength));
}
private void TurnOffLine(LineRenderer lineRenderer, Color lineColor)
{
lineRenderer.startColor = lineColor;
lineRenderer.endColor = lineColor;
lineRenderer.startWidth = 0f;
lineRenderer.endWidth = 0f;
lineRenderer.SetPosition(0, new Vector3(0, 0, 0));
lineRenderer.SetPosition(1, new Vector3(0, 0, 0));
}
public void UpdateRayInfo()
{
float focusLEdge = agentCam.pixelWidth * (1 - focusRange) / 2;
float focusREdge = agentCam.pixelWidth * (1 + focusRange) / 2;
float camPixelHeight = agentCam.pixelHeight;
inViewEnemies.Clear();
ClearResult();
for (int i = 0; i < halfOuterRayNum; i++) // create left outside rays; 0 ~ focusLeftEdge
{
Vector3 point = new Vector3(i * focusLEdge / (halfOuterRayNum - 1), camPixelHeight / 2, 0);
Ray nowRay = agentCam.ScreenPointToRay(point);
SingleRaycastUpdate(nowRay,i);
}
for (int i = 0; i < halfOuterRayNum; i++) // create right outside rays; focusRightEdge ~ MaxPixelHeight
{
Vector3 point = new Vector3(focusREdge + (i * focusLEdge / (halfOuterRayNum - 1)), camPixelHeight / 2, 0);
Ray nowRay = agentCam.ScreenPointToRay(point);
SingleRaycastUpdate(nowRay, halfOuterRayNum + i);
}
for (int i = 0; i < focusRayNum; i++) // create center focus rays; focusLeftEdge ~ focusLeftEdge
{
Vector3 point = new Vector3(focusLEdge + ((i + 1) * (focusREdge - focusLEdge) / (focusRayNum + 1)), camPixelHeight / 2, 0);
Ray nowRay = agentCam.ScreenPointToRay(point);
SingleRaycastUpdate(nowRay, halfOuterRayNum * 2 + i);
}
}
private void ClearResult()
{
rayTagResult = new float[totalRayNum];
rayDisResult = new float[totalRayNum];
rayTagResultOneHot = new float[totalRayNum * ObjectTags.Tags.Count];
}
}