lab4 dop
This commit is contained in:
1 parent
7f65ead644
commit
e60163307c
8 files changed
+2570
-13
No files matched your search
@@ -0,0 +1,318 @@
|
|||||||
|
using Code.Base;
|
||||||
|
using Code.Lab1;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Code.Lab3;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Code.Lab4
|
||||||
|
{
|
||||||
|
public class BetterBlendPathFollower : Seek
|
||||||
|
{
|
||||||
|
public Path path;
|
||||||
|
public float pathOffset = 1.0f;
|
||||||
|
|
||||||
|
[Header("Targets")]
|
||||||
|
public GameObject pursuer;
|
||||||
|
|
||||||
|
[Header("Weights")]
|
||||||
|
[Range(0, 1)]
|
||||||
|
public float pathFollowingWeight = 0.5f;
|
||||||
|
[Range(0, 1)]
|
||||||
|
public float optimalPathWeight = 0.3f;
|
||||||
|
[Range(0, 1)]
|
||||||
|
public float evadeWeight = 0.2f;
|
||||||
|
|
||||||
|
[Header("Evade Settings")]
|
||||||
|
public float maxPrediction = 2f;
|
||||||
|
|
||||||
|
public float evadeDistance = 5f;
|
||||||
|
public float minEvadeWeight = 0.1f;
|
||||||
|
|
||||||
|
private float _currentParam;
|
||||||
|
private List<Vector3> _waypoints;
|
||||||
|
private int _currentTargetIndex = -1;
|
||||||
|
private List<int> _visitedIndices;
|
||||||
|
private bool _reachedLastPoint;
|
||||||
|
|
||||||
|
private GameObject _evadeTarget;
|
||||||
|
private Agent _pursuerAgent;
|
||||||
|
private Agent _selfAgent;
|
||||||
|
|
||||||
|
public override void Awake()
|
||||||
|
{
|
||||||
|
base.Awake();
|
||||||
|
target = new GameObject("BetterBlendPathFollower_Target");
|
||||||
|
_evadeTarget = new GameObject("Evade_Target");
|
||||||
|
_visitedIndices = new List<int>();
|
||||||
|
|
||||||
|
_selfAgent = GetComponent<Agent>();
|
||||||
|
|
||||||
|
InitializeWaypoints();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Start()
|
||||||
|
{
|
||||||
|
if (pursuer != null)
|
||||||
|
{
|
||||||
|
_pursuerAgent = pursuer.GetComponent<Agent>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializeWaypoints()
|
||||||
|
{
|
||||||
|
if (path == null || path.nodes == null || path.nodes.Count == 0) return;
|
||||||
|
|
||||||
|
_waypoints = new List<Vector3>();
|
||||||
|
|
||||||
|
foreach (var node in path.nodes.Where(node => node != null))
|
||||||
|
{
|
||||||
|
_waypoints.Add(node.transform.position);
|
||||||
|
}
|
||||||
|
|
||||||
|
FindClosestStartPoint();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void FindClosestStartPoint()
|
||||||
|
{
|
||||||
|
var minDistance = float.MaxValue;
|
||||||
|
var closestIndex = 0;
|
||||||
|
|
||||||
|
for (var i = 0; i < _waypoints.Count; i++)
|
||||||
|
{
|
||||||
|
var distance = Vector3.Distance(transform.position, _waypoints[i]);
|
||||||
|
if (distance < minDistance)
|
||||||
|
{
|
||||||
|
minDistance = distance;
|
||||||
|
closestIndex = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_currentTargetIndex = closestIndex;
|
||||||
|
_currentParam = 0;
|
||||||
|
_visitedIndices.Clear();
|
||||||
|
_reachedLastPoint = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnDestroy()
|
||||||
|
{
|
||||||
|
if (_evadeTarget != null)
|
||||||
|
Destroy(_evadeTarget);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Steering GetSteering()
|
||||||
|
{
|
||||||
|
if (_waypoints == null || _waypoints.Count == 0 || _reachedLastPoint)
|
||||||
|
{
|
||||||
|
return new Steering();
|
||||||
|
}
|
||||||
|
|
||||||
|
var pathSteering = GetPathFollowingSteering();
|
||||||
|
var optimalSteering = GetOptimalPathSteering();
|
||||||
|
var evadeSteering = GetEvadeSteering();
|
||||||
|
|
||||||
|
var dynamicEvadeWeight = CalculateDynamicEvadeWeight();
|
||||||
|
|
||||||
|
var totalWeight = pathFollowingWeight + optimalPathWeight + dynamicEvadeWeight;
|
||||||
|
var normPathWeight = pathFollowingWeight / totalWeight;
|
||||||
|
var normOptimalWeight = optimalPathWeight / totalWeight;
|
||||||
|
var normEvadeWeight = dynamicEvadeWeight / totalWeight;
|
||||||
|
|
||||||
|
var blendedSteering = new Steering
|
||||||
|
{
|
||||||
|
Linear = normPathWeight * pathSteering.Linear +
|
||||||
|
normOptimalWeight * optimalSteering.Linear +
|
||||||
|
normEvadeWeight * evadeSteering.Linear,
|
||||||
|
Angular = normPathWeight * pathSteering.Angular +
|
||||||
|
normOptimalWeight * optimalSteering.Angular +
|
||||||
|
normEvadeWeight * evadeSteering.Angular
|
||||||
|
};
|
||||||
|
|
||||||
|
if (blendedSteering.Linear.magnitude > Agent.maxAcceleration)
|
||||||
|
{
|
||||||
|
blendedSteering.Linear = blendedSteering.Linear.normalized * Agent.maxAcceleration;
|
||||||
|
}
|
||||||
|
|
||||||
|
return blendedSteering;
|
||||||
|
}
|
||||||
|
|
||||||
|
private float CalculateDynamicEvadeWeight()
|
||||||
|
{
|
||||||
|
if (pursuer == null) return 0f;
|
||||||
|
|
||||||
|
var distanceToPursuer = Vector3.Distance(transform.position, pursuer.transform.position);
|
||||||
|
|
||||||
|
if (distanceToPursuer <= evadeDistance)
|
||||||
|
{
|
||||||
|
var t = 1f - distanceToPursuer / evadeDistance;
|
||||||
|
return Mathf.Lerp(minEvadeWeight, evadeWeight, t);
|
||||||
|
}
|
||||||
|
|
||||||
|
return minEvadeWeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Steering GetPathFollowingSteering()
|
||||||
|
{
|
||||||
|
if (!path) return new Steering();
|
||||||
|
|
||||||
|
_currentParam = path.GetParam(transform.position, _currentParam);
|
||||||
|
var targetParam = _currentParam + pathOffset;
|
||||||
|
target.transform.position = path.GetPosition(targetParam);
|
||||||
|
|
||||||
|
return base.GetSteering();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Steering GetOptimalPathSteering()
|
||||||
|
{
|
||||||
|
if (_waypoints == null || _waypoints.Count == 0) return new Steering();
|
||||||
|
|
||||||
|
var distanceToTarget = Vector3.Distance(transform.position, _waypoints[_currentTargetIndex]);
|
||||||
|
|
||||||
|
if (distanceToTarget < 1f)
|
||||||
|
{
|
||||||
|
if (!_visitedIndices.Contains(_currentTargetIndex))
|
||||||
|
{
|
||||||
|
_visitedIndices.Add(_currentTargetIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_visitedIndices.Count >= _waypoints.Count)
|
||||||
|
{
|
||||||
|
_reachedLastPoint = true;
|
||||||
|
return new Steering();
|
||||||
|
}
|
||||||
|
|
||||||
|
FindNextTarget();
|
||||||
|
}
|
||||||
|
|
||||||
|
var tempTarget = target.transform.position;
|
||||||
|
target.transform.position = _waypoints[_currentTargetIndex];
|
||||||
|
var steering = base.GetSteering();
|
||||||
|
target.transform.position = tempTarget;
|
||||||
|
|
||||||
|
return steering;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Steering GetEvadeSteering()
|
||||||
|
{
|
||||||
|
if (pursuer == null || _pursuerAgent == null) return new Steering();
|
||||||
|
|
||||||
|
var direction = pursuer.transform.position - transform.position;
|
||||||
|
var distance = direction.magnitude;
|
||||||
|
var speed = _selfAgent.velocity.magnitude;
|
||||||
|
|
||||||
|
float prediction;
|
||||||
|
if (speed <= distance / maxPrediction)
|
||||||
|
prediction = maxPrediction;
|
||||||
|
else
|
||||||
|
prediction = distance / speed;
|
||||||
|
|
||||||
|
_evadeTarget.transform.position = pursuer.transform.position;
|
||||||
|
_evadeTarget.transform.position += _pursuerAgent.velocity * prediction;
|
||||||
|
|
||||||
|
var directionToEvade = _evadeTarget.transform.position - transform.position;
|
||||||
|
var fleeSteering = new Steering
|
||||||
|
{
|
||||||
|
Linear = -directionToEvade.normalized * Agent.maxAcceleration,
|
||||||
|
Angular = 0
|
||||||
|
};
|
||||||
|
|
||||||
|
return fleeSteering;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void FindNextTarget()
|
||||||
|
{
|
||||||
|
var shortestDistance = float.MaxValue;
|
||||||
|
var bestTargetIndex = -1;
|
||||||
|
|
||||||
|
for (var i = 0; i < _waypoints.Count; i++)
|
||||||
|
{
|
||||||
|
if (_visitedIndices.Contains(i))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var distance = Vector3.Distance(transform.position, _waypoints[i]);
|
||||||
|
if (distance < shortestDistance)
|
||||||
|
{
|
||||||
|
shortestDistance = distance;
|
||||||
|
bestTargetIndex = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bestTargetIndex != -1)
|
||||||
|
{
|
||||||
|
_currentTargetIndex = bestTargetIndex;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_reachedLastPoint = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ResetPathFollowing()
|
||||||
|
{
|
||||||
|
_visitedIndices.Clear();
|
||||||
|
FindClosestStartPoint();
|
||||||
|
_reachedLastPoint = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetWeights(float pathWeight, float optimalWeight, float evadeWeightValue)
|
||||||
|
{
|
||||||
|
pathFollowingWeight = Mathf.Clamp01(pathWeight);
|
||||||
|
optimalPathWeight = Mathf.Clamp01(optimalWeight);
|
||||||
|
evadeWeight = Mathf.Clamp01(evadeWeightValue);
|
||||||
|
|
||||||
|
var total = pathFollowingWeight + optimalPathWeight + evadeWeight;
|
||||||
|
if (total > 1f)
|
||||||
|
{
|
||||||
|
pathFollowingWeight /= total;
|
||||||
|
optimalPathWeight /= total;
|
||||||
|
evadeWeight /= total;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnDrawGizmosSelected()
|
||||||
|
{
|
||||||
|
if (_waypoints == null) return;
|
||||||
|
|
||||||
|
for (var i = 0; i < _waypoints.Count; i++)
|
||||||
|
{
|
||||||
|
if (_reachedLastPoint)
|
||||||
|
{
|
||||||
|
Gizmos.color = Color.gray;
|
||||||
|
}
|
||||||
|
else if (i == _currentTargetIndex)
|
||||||
|
{
|
||||||
|
Gizmos.color = Color.green;
|
||||||
|
}
|
||||||
|
else if (_visitedIndices != null && _visitedIndices.Contains(i))
|
||||||
|
{
|
||||||
|
Gizmos.color = Color.blue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Gizmos.color = Color.yellow;
|
||||||
|
}
|
||||||
|
|
||||||
|
Gizmos.DrawSphere(_waypoints[i], 0.3f);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (path != null)
|
||||||
|
{
|
||||||
|
Gizmos.color = Color.magenta;
|
||||||
|
var segments = path.GetSegments();
|
||||||
|
foreach (var segment in segments)
|
||||||
|
{
|
||||||
|
Gizmos.DrawLine(segment.A, segment.B);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pursuer != null)
|
||||||
|
{
|
||||||
|
Gizmos.color = Color.red;
|
||||||
|
Gizmos.DrawWireSphere(transform.position, evadeDistance);
|
||||||
|
|
||||||
|
Gizmos.color = Color.yellow;
|
||||||
|
Gizmos.DrawLine(transform.position, pursuer.transform.position);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 2411ad4f30a64b97a081c91d1deb7003
|
||||||
|
timeCreated: 1772310851
|
||||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 8be409d0096c232349958c1d81eacbc8
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -65,9 +65,11 @@ MonoBehaviour:
|
|||||||
- rid: 995480377657917449
|
- rid: 995480377657917449
|
||||||
- rid: 995480377657917450
|
- rid: 995480377657917450
|
||||||
- rid: 995480377657917451
|
- rid: 995480377657917451
|
||||||
|
- rid: 995480888657838080
|
||||||
|
- rid: 995480888657838081
|
||||||
m_RuntimeSettings:
|
m_RuntimeSettings:
|
||||||
m_List: []
|
m_List: []
|
||||||
m_AssetVersion: 9
|
m_AssetVersion: 10
|
||||||
m_ObsoleteDefaultVolumeProfile: {fileID: 0}
|
m_ObsoleteDefaultVolumeProfile: {fileID: 0}
|
||||||
m_RenderingLayerNames:
|
m_RenderingLayerNames:
|
||||||
- Light Layer default
|
- Light Layer default
|
||||||
@@ -221,6 +223,18 @@ MonoBehaviour:
|
|||||||
data:
|
data:
|
||||||
m_Version: 1
|
m_Version: 1
|
||||||
m_UseBicubicLightmapSampling: 0
|
m_UseBicubicLightmapSampling: 0
|
||||||
|
- rid: 995480888657838080
|
||||||
|
type: {class: UniversalRenderPipelineRuntimeTerrainShaders, ns: UnityEngine.Rendering.Universal, asm: Unity.RenderPipelines.Universal.Runtime}
|
||||||
|
data:
|
||||||
|
m_Version: 0
|
||||||
|
m_TerrainDetailLit: {fileID: 4800000, guid: f6783ab646d374f94b199774402a5144, type: 3}
|
||||||
|
m_TerrainDetailGrassBillboard: {fileID: 4800000, guid: 29868e73b638e48ca99a19ea58c48d90, type: 3}
|
||||||
|
m_TerrainDetailGrass: {fileID: 4800000, guid: e507fdfead5ca47e8b9a768b51c291a1, type: 3}
|
||||||
|
- rid: 995480888657838081
|
||||||
|
type: {class: URPTerrainShaderSetting, ns: UnityEngine.Rendering.Universal, asm: Unity.RenderPipelines.Universal.Runtime}
|
||||||
|
data:
|
||||||
|
m_Version: 0
|
||||||
|
m_IncludeTerrainShaders: 1
|
||||||
- rid: 6852985685364965376
|
- rid: 6852985685364965376
|
||||||
type: {class: URPShaderStrippingSetting, ns: UnityEngine.Rendering.Universal, asm: Unity.RenderPipelines.Universal.Runtime}
|
type: {class: URPShaderStrippingSetting, ns: UnityEngine.Rendering.Universal, asm: Unity.RenderPipelines.Universal.Runtime}
|
||||||
data:
|
data:
|
||||||
@@ -262,9 +276,9 @@ MonoBehaviour:
|
|||||||
m_CoreBlitPS: {fileID: 4800000, guid: 93446b5c5339d4f00b85c159e1159b7c, type: 3}
|
m_CoreBlitPS: {fileID: 4800000, guid: 93446b5c5339d4f00b85c159e1159b7c, type: 3}
|
||||||
m_CoreBlitColorAndDepthPS: {fileID: 4800000, guid: d104b2fc1ca6445babb8e90b0758136b, type: 3}
|
m_CoreBlitColorAndDepthPS: {fileID: 4800000, guid: d104b2fc1ca6445babb8e90b0758136b, type: 3}
|
||||||
m_SamplingPS: {fileID: 4800000, guid: 04c410c9937594faa893a11dceb85f7e, type: 3}
|
m_SamplingPS: {fileID: 4800000, guid: 04c410c9937594faa893a11dceb85f7e, type: 3}
|
||||||
m_TerrainDetailLit: {fileID: 4800000, guid: f6783ab646d374f94b199774402a5144, type: 3}
|
m_TerrainDetailLit: {fileID: 0}
|
||||||
m_TerrainDetailGrassBillboard: {fileID: 4800000, guid: 29868e73b638e48ca99a19ea58c48d90, type: 3}
|
m_TerrainDetailGrassBillboard: {fileID: 0}
|
||||||
m_TerrainDetailGrass: {fileID: 4800000, guid: e507fdfead5ca47e8b9a768b51c291a1, type: 3}
|
m_TerrainDetailGrass: {fileID: 0}
|
||||||
- rid: 6852985685364965381
|
- rid: 6852985685364965381
|
||||||
type: {class: UniversalRenderPipelineRuntimeTextures, ns: UnityEngine.Rendering.Universal, asm: Unity.RenderPipelines.Universal.Runtime}
|
type: {class: UniversalRenderPipelineRuntimeTextures, ns: UnityEngine.Rendering.Universal, asm: Unity.RenderPipelines.Universal.Runtime}
|
||||||
data:
|
data:
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"com.unity.2d.sprite": "1.0.0",
|
"com.unity.2d.sprite": "1.0.0",
|
||||||
"com.unity.ai.navigation": "2.0.10",
|
"com.unity.ai.navigation": "2.0.11",
|
||||||
"com.unity.ide.rider": "3.0.39",
|
"com.unity.ide.rider": "3.0.39",
|
||||||
"com.unity.ide.visualstudio": "2.0.27",
|
"com.unity.ide.visualstudio": "2.0.27",
|
||||||
"com.unity.inputsystem": "1.18.0",
|
"com.unity.inputsystem": "1.18.0",
|
||||||
@@ -9,10 +9,10 @@
|
|||||||
"com.unity.render-pipelines.universal": "17.3.0",
|
"com.unity.render-pipelines.universal": "17.3.0",
|
||||||
"com.unity.sdk.linux-x86_64": "1.0.2",
|
"com.unity.sdk.linux-x86_64": "1.0.2",
|
||||||
"com.unity.test-framework": "1.6.0",
|
"com.unity.test-framework": "1.6.0",
|
||||||
"com.unity.timeline": "1.8.10",
|
"com.unity.timeline": "1.8.11",
|
||||||
"com.unity.toolchain.linux-x86_64-linux": "1.0.2",
|
"com.unity.toolchain.linux-x86_64-linux": "1.0.2",
|
||||||
"com.unity.ugui": "2.0.0",
|
"com.unity.ugui": "2.0.0",
|
||||||
"com.unity.visualscripting": "1.9.9",
|
"com.unity.visualscripting": "1.9.10",
|
||||||
"com.unity.modules.accessibility": "1.0.0",
|
"com.unity.modules.accessibility": "1.0.0",
|
||||||
"com.unity.modules.adaptiveperformance": "1.0.0",
|
"com.unity.modules.adaptiveperformance": "1.0.0",
|
||||||
"com.unity.modules.ai": "1.0.0",
|
"com.unity.modules.ai": "1.0.0",
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
"dependencies": {}
|
"dependencies": {}
|
||||||
},
|
},
|
||||||
"com.unity.ai.navigation": {
|
"com.unity.ai.navigation": {
|
||||||
"version": "2.0.10",
|
"version": "2.0.11",
|
||||||
"depth": 0,
|
"depth": 0,
|
||||||
"source": "registry",
|
"source": "registry",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
"url": "https://packages.unity.com"
|
"url": "https://packages.unity.com"
|
||||||
},
|
},
|
||||||
"com.unity.burst": {
|
"com.unity.burst": {
|
||||||
"version": "1.8.27",
|
"version": "1.8.28",
|
||||||
"depth": 2,
|
"depth": 2,
|
||||||
"source": "registry",
|
"source": "registry",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -178,7 +178,7 @@
|
|||||||
"url": "https://packages.unity.com"
|
"url": "https://packages.unity.com"
|
||||||
},
|
},
|
||||||
"com.unity.timeline": {
|
"com.unity.timeline": {
|
||||||
"version": "1.8.10",
|
"version": "1.8.11",
|
||||||
"depth": 0,
|
"depth": 0,
|
||||||
"source": "registry",
|
"source": "registry",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -208,7 +208,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"com.unity.visualscripting": {
|
"com.unity.visualscripting": {
|
||||||
"version": "1.9.9",
|
"version": "1.9.10",
|
||||||
"depth": 0,
|
"depth": 0,
|
||||||
"source": "registry",
|
"source": "registry",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
m_EditorVersion: 6000.3.8f1
|
m_EditorVersion: 6000.3.10f1
|
||||||
m_EditorVersionWithRevision: 6000.3.8f1 (1c7db571dde0)
|
m_EditorVersionWithRevision: 6000.3.10f1 (e35f0c77bd8e)
|
||||||
Reference in new issue
Block a user