add new reward function in attack mode calculate distance between closest enemy and facing center line. let agent could spawn in whole map area. add penalty while mouseX is moving.
188 lines
7.4 KiB
C#
188 lines
7.4 KiB
C#
using System;
|
||
using System.Collections;
|
||
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 = 3; // >=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[] rayDisResult;
|
||
|
||
[System.NonSerialized] public int totalRayNum;
|
||
private string myTag = "";
|
||
GameObject[] linesOBJ;
|
||
GameObject[] rayInfoOBJ;
|
||
LineRenderer[] lineRenderers;
|
||
rayInfoUI[] rayInfoUIs;
|
||
public List<GameObject> inViewEnemies = new List<GameObject>();
|
||
|
||
|
||
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];
|
||
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 thisLineRenderer,rayInfoUI thisRayInfoUI, out float rayTagResult, out float rayDisResult)
|
||
{
|
||
// get Raycast hit infomation and return Tag and distance
|
||
RaycastHit thisHit;
|
||
Color rayColor = Color.cyan;
|
||
float lineLength = viewDistance;
|
||
string rayInfoText = "";
|
||
Vector3 rayInfoPosition;
|
||
if (Physics.Raycast(ray, out thisHit, viewDistance)) // 若在viewDistance范围内有碰撞
|
||
{
|
||
rayInfoText = thisHit.collider.tag;
|
||
rayTagResult = tagToInt(thisHit.collider.tag);
|
||
rayDisResult = thisHit.distance;
|
||
lineLength = rayDisResult;
|
||
rayInfoText += "\n" + Convert.ToString(rayDisResult);
|
||
//输出log
|
||
switch (rayTagResult)
|
||
{
|
||
case 1:// Wall
|
||
rayColor = Color.white;
|
||
break;
|
||
case 2: // Enemy
|
||
rayColor = Color.red;
|
||
inViewEnemies.Add(thisHit.transform.gameObject);
|
||
break;
|
||
case -1: // Hit Nothing
|
||
rayColor = Color.gray;
|
||
break;
|
||
default: // default,got wrong
|
||
rayColor = Color.cyan;
|
||
break;
|
||
}
|
||
}
|
||
else // 若在viewDistance范围无碰撞
|
||
{
|
||
rayTagResult = -1f;
|
||
rayDisResult = -1f;
|
||
//输出log
|
||
//Debug.Log(0);
|
||
//Debug.Log(0);
|
||
}
|
||
rayInfoPosition = ray.origin + (ray.direction * lineLength);
|
||
if (showInGameRay)
|
||
{
|
||
drawLine(ray, lineLength, thisLineRenderer, rayColor);
|
||
}
|
||
else
|
||
{
|
||
turnOffLine(thisLineRenderer, rayColor);
|
||
}
|
||
// drawRay in game
|
||
if (showInGameRayInfo) thisRayInfoUI.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(thisHit.collider.tag));
|
||
}
|
||
|
||
private void drawLine(Ray ray,float lineLength, LineRenderer thisLineRenderer, Color lineColor)
|
||
{
|
||
thisLineRenderer.startColor = lineColor;
|
||
thisLineRenderer.endColor = lineColor;
|
||
thisLineRenderer.startWidth = lineWidth;
|
||
thisLineRenderer.endWidth = lineWidth;
|
||
thisLineRenderer.SetPosition(0, ray.origin);
|
||
thisLineRenderer.SetPosition(1, ray.origin + (ray.direction * lineLength));
|
||
}
|
||
|
||
private void turnOffLine(LineRenderer thisLineRenderer, Color lineColor)
|
||
{
|
||
thisLineRenderer.startColor = lineColor;
|
||
thisLineRenderer.endColor = lineColor;
|
||
thisLineRenderer.startWidth = 0f;
|
||
thisLineRenderer.endWidth = 0f;
|
||
thisLineRenderer.SetPosition(0, new Vector3(0, 0, 0));
|
||
thisLineRenderer.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 thisCamPixelHeight = agentCam.pixelHeight;
|
||
inViewEnemies.Clear();
|
||
for (int i = 0; i < halfOuterRayNum; i++) // create left outside rays; 0 ~ focusLeftEdge
|
||
{
|
||
Vector3 point = new Vector3(i * focusLEdge / (halfOuterRayNum - 1), thisCamPixelHeight / 2, 0);
|
||
Ray thisRay = agentCam.ScreenPointToRay(point);
|
||
singleRaycastUpdate(thisRay,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)), thisCamPixelHeight / 2, 0);
|
||
Ray thisRay = agentCam.ScreenPointToRay(point);
|
||
singleRaycastUpdate(thisRay, 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)), thisCamPixelHeight / 2, 0);
|
||
Ray thisRay = agentCam.ScreenPointToRay(point);
|
||
singleRaycastUpdate(thisRay, lineRenderers[halfOuterRayNum * 2 + i], rayInfoUIs[halfOuterRayNum * 2 + i], out rayTagResult[halfOuterRayNum*2 + i], out rayDisResult[halfOuterRayNum*2 + i]);
|
||
}
|
||
}
|
||
}
|