Aimbot-ParallelEnv/Assets/Script/GameScript/RaySensors.cs

200 lines
7.7 KiB
C#
Raw Normal View History

2022-10-25 19:07:39 +00:00
using System;
using System.Collections.Generic;
using UnityEngine;
/*该scrip用于创建复数条ray于视角内并探测被ray射到的物体*/
public class RaySensors : MonoBehaviour
{
public Camera agentCam;
public Camera TPSCam;
2022-10-25 19:07:39 +00:00
public Material lineMeterial;
public GameObject rayInfoPrefab;
public GameObject agentCanvas;
[SerializeField, Range(0, 500)] public float viewDistance = 100; // how long the ray can detect
2022-10-25 19:07:39 +00:00
//[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
2022-10-25 19:07:39 +00:00
public int focusRayNum = 5; // >= 1 and must be odd num!
[Header("InGameLineSetting")]
public bool showInGameRay = true;
2022-10-25 19:07:39 +00:00
public bool showDebugRay = true;
public bool showInGameRayInfo = true;
public float lineWidth = 0.05f;
[Header("RayCastResult")]
public float[] rayTagResult;
public List<float> rayTagResultOneHot;
2022-10-25 19:07:39 +00:00
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();
2022-10-25 19:07:39 +00:00
private void Start()
{
myTag = gameObject.tag;
2022-10-25 19:07:39 +00:00
totalRayNum = halfOuterRayNum * 2 + focusRayNum;
rayTagResult = new float[totalRayNum];
rayDisResult = new float[totalRayNum];
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++)
2022-10-25 19:07:39 +00:00
{
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);
2022-10-25 19:07:39 +00:00
rayInfoOBJ[i].name = "rayInfo-" + Convert.ToString(i);
rayInfoUIs[i] = rayInfoOBJ[i].GetComponent<RayInfoUI>();
2022-10-25 19:07:39 +00:00
}
}
public int TagToInt(string tag)
2022-10-25 19:07:39 +00:00
{
switch (tag)
{
case "Wall":
return 1;
2022-10-25 19:07:39 +00:00
default:
if (tag != myTag)
{
return 2;
}
2022-10-25 19:07:39 +00:00
return 0;
}
}
private void SingleRaycastUpdate(Ray ray, LineRenderer lineRenderer, RayInfoUI rayInfoUI, out float rayTagResult, out float rayDisResult)
2022-10-25 19:07:39 +00:00
{
// get Raycast hit infomation and return Tag and distance
RaycastHit nowHit;
2022-10-25 19:07:39 +00:00
Color rayColor = Color.cyan;
float lineLength = viewDistance;
string rayInfoText = "";
Vector3 rayInfoPosition;
if (Physics.Raycast(ray, out nowHit, viewDistance)) // 若在viewDistance范围内有碰撞
2022-10-25 19:07:39 +00:00
{
rayInfoText = nowHit.collider.tag;
rayTagResult = TagToInt(rayInfoText);
rayTagResultOneHot.AddRange(oneHotTags.Encoder(rayInfoText));
rayDisResult = nowHit.distance;
2022-10-25 19:07:39 +00:00
lineLength = rayDisResult;
rayInfoText += "\n" + Convert.ToString(rayDisResult);
// rayDisResult = rayDisResult / viewDistance; // Normalization!
// 输出log
2022-10-25 19:07:39 +00:00
switch (rayTagResult)
{
case 1:// Wall
rayColor = Color.white;
break;
2022-10-25 19:07:39 +00:00
case 2: // Enemy
rayColor = Color.red;
inViewEnemies.Add(nowHit.transform.gameObject);
2022-10-25 19:07:39 +00:00
break;
2022-10-25 19:07:39 +00:00
case -1: // Hit Nothing
rayColor = Color.gray;
break;
2022-10-25 19:07:39 +00:00
default: // default,got wrong
rayColor = Color.cyan;
break;
}
}
else // 若在viewDistance范围无碰撞
{
rayTagResultOneHot.AddRange(oneHotTags.Encoder());
2022-10-25 19:07:39 +00:00
rayTagResult = -1f;
rayDisResult = -1f;
//输出log
//Debug.Log(0);
//Debug.Log(0);
}
rayInfoPosition = ray.origin + (ray.direction * lineLength);
if (showInGameRay)
{
DrawLine(ray, lineLength, lineRenderer, rayColor);
2022-10-25 19:07:39 +00:00
}
else
{
TurnOffLine(lineRenderer, rayColor);
2022-10-25 19:07:39 +00:00
}
// drawRay in game
if (showInGameRayInfo) rayInfoUI.UpdateInfo(rayInfoText, rayInfoPosition, rayColor, TPSCam);
2022-10-25 19:07:39 +00:00
// Show log
if (showDebugRay) Debug.DrawRay(ray.origin, ray.direction * viewDistance, rayColor); // drawRay in debug
// Debug.Log(ray.origin + ray.direction);
// Debug.Log(rayTagResult);
// Debug.Log(tagToInt(nowHit.collider.tag));
2022-10-25 19:07:39 +00:00
}
private void DrawLine(Ray ray, float lineLength, LineRenderer lineRenderer, Color lineColor)
2022-10-25 19:07:39 +00:00
{
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));
2022-10-25 19:07:39 +00:00
}
private void TurnOffLine(LineRenderer lineRenderer, Color lineColor)
2022-10-25 19:07:39 +00:00
{
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));
2022-10-25 19:07:39 +00:00
}
public void UpdateRayInfo()
2022-10-25 19:07:39 +00:00
{
float focusLEdge = agentCam.pixelWidth * (1 - focusRange) / 2;
float focusREdge = agentCam.pixelWidth * (1 + focusRange) / 2;
float camPixelHeight = agentCam.pixelHeight;
inViewEnemies.Clear();
rayTagResultOneHot.Clear();
2022-10-25 19:07:39 +00:00
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, lineRenderers[i], rayInfoUIs[i], out rayTagResult[i], out rayDisResult[i]);
2022-10-25 19:07:39 +00:00
}
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, lineRenderers[halfOuterRayNum + i], rayInfoUIs[halfOuterRayNum + i], out rayTagResult[halfOuterRayNum + i], out rayDisResult[halfOuterRayNum + i]);
2022-10-25 19:07:39 +00:00
}
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, lineRenderers[halfOuterRayNum * 2 + i], rayInfoUIs[halfOuterRayNum * 2 + i], out rayTagResult[halfOuterRayNum * 2 + i], out rayDisResult[halfOuterRayNum * 2 + i]);
2022-10-25 19:07:39 +00:00
}
}
}