Aimbot-ParallelEnv/Assets/Script/InGame/RaySensors.cs
Koha9 5226f1dbbf V3.2.2 开始创建MultiLevel
使用Multi level使AI适应更复杂环境
基本Level创建完成
UI逻辑创建中
2023-08-23 02:58:50 +09:00

200 lines
7.7 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
{
public Camera agentCam;
public Camera TPSCam;
public Material lineMeterial;
public GameObject rayInfoPrefab;
public 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 List<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];
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>();
}
}
public int TagToInt(string tag)
{
switch (tag)
{
case "Wall":
return 1;
default:
if (tag != myTag)
{
return 2;
}
return 0;
}
}
private void SingleRaycastUpdate(Ray ray, LineRenderer lineRenderer, RayInfoUI rayInfoUI, out float rayTagResult, out float rayDisResult)
{
// get Raycast hit infomation and return Tag and distance
RaycastHit nowHit;
Color rayColor = Color.cyan;
float lineLength = viewDistance;
string rayInfoText = "";
Vector3 rayInfoPosition;
if (Physics.Raycast(ray, out nowHit, viewDistance)) // 若在viewDistance范围内有碰撞
{
rayInfoText = nowHit.collider.tag;
rayTagResult = TagToInt(rayInfoText);
rayTagResultOneHot.AddRange(oneHotTags.Encoder(rayInfoText));
rayDisResult = nowHit.distance;
lineLength = rayDisResult;
rayInfoText += "\n" + Convert.ToString(rayDisResult);
// rayDisResult = rayDisResult / viewDistance; // Normalization!
// 输出log
switch (rayTagResult)
{
case 1:// Wall
rayColor = Color.white;
break;
case 2: // Enemy
rayColor = Color.red;
inViewEnemies.Add(nowHit.transform.gameObject);
break;
case -1: // Hit Nothing
rayColor = Color.gray;
break;
default: // default,got wrong
rayColor = Color.cyan;
break;
}
}
else // 若在viewDistance范围无碰撞
{
rayTagResultOneHot.AddRange(oneHotTags.Encoder());
rayTagResult = -1f;
rayDisResult = -1f;
//输出log
//Debug.Log(0);
//Debug.Log(0);
}
rayInfoPosition = ray.origin + (ray.direction * lineLength);
if (showInGameRay)
{
DrawLine(ray, lineLength, lineRenderer, rayColor);
}
else
{
TurnOffLine(lineRenderer, rayColor);
}
// drawRay in game
if (showInGameRayInfo) rayInfoUI.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(rayTagResult);
// Debug.Log(tagToInt(nowHit.collider.tag));
}
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();
rayTagResultOneHot.Clear();
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]);
}
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]);
}
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]);
}
}
}