Before 优化 机场
This commit is contained in:
@@ -0,0 +1,183 @@
|
||||
// Designed by KINEMATION, 2024.
|
||||
|
||||
using Kinemation.MotionWarping.Runtime.Core;
|
||||
using Kinemation.MotionWarping.Runtime.Utility;
|
||||
using UnityEngine;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
#endif
|
||||
|
||||
namespace Kinemation.MotionWarping.Runtime.Examples
|
||||
{
|
||||
public class VaultComponent : MonoBehaviour, IWarpPointProvider
|
||||
{
|
||||
[SerializeField] private MotionWarpingAsset motionWarpingAsset;
|
||||
[SerializeField] private VaultSettings settings;
|
||||
|
||||
private Vector3 _closeEdge;
|
||||
private Vector3 _farEdge;
|
||||
private Vector3 _endPoint;
|
||||
private Quaternion _targetRotation;
|
||||
|
||||
private bool FindCloseEdge()
|
||||
{
|
||||
if (settings == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Vector3 start = transform.position;
|
||||
Vector3 end = start + transform.up * settings.maxAllowedStartHeight;
|
||||
start.y += settings.characterCapsuleRadius + settings.minAllowedStartHeight;
|
||||
|
||||
Vector3 direction = transform.forward;
|
||||
|
||||
bool bHit = Physics.CapsuleCast(start, end, settings.characterCapsuleRadius, direction,
|
||||
out var hit, settings.maxAllowedStartLength, settings.layerMask);
|
||||
|
||||
if (!bHit)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_targetRotation = Quaternion.LookRotation(-hit.normal, transform.up);
|
||||
|
||||
start = hit.point;
|
||||
start.y = end.y;
|
||||
direction = -transform.up;
|
||||
|
||||
bHit = Physics.SphereCast(start, settings.sphereEdgeCheckRadius, direction, out hit,
|
||||
settings.maxAllowedStartHeight, settings.layerMask);
|
||||
|
||||
if (!bHit)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_closeEdge = hit.point;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool FindEndPoint()
|
||||
{
|
||||
Vector3 start = _farEdge + (_targetRotation * Vector3.forward) * settings.farEdgeOffset;
|
||||
Vector3 direction = -transform.up;
|
||||
float distance = settings.maxAllowedEndHeight;
|
||||
|
||||
bool bHit = Physics.SphereCast(start, settings.sphereEdgeCheckRadius, direction, out var hit,
|
||||
distance, settings.layerMask);
|
||||
|
||||
if (!bHit || (hit.point - start).magnitude < settings.minAllowedEndHeight)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_endPoint = hit.point;
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool FindEndEdge()
|
||||
{
|
||||
Vector3 forward = (_targetRotation * Vector3.forward).normalized;
|
||||
|
||||
float length = settings.maxObstacleLength + settings.characterCapsuleRadius;
|
||||
Vector3 start = _closeEdge + forward * length;
|
||||
Vector3 end = start;
|
||||
|
||||
start.y = _closeEdge.y - settings.closeEdgeDeviation;
|
||||
end.y = _closeEdge.y + settings.closeEdgeDeviation;
|
||||
|
||||
length -= settings.minObstacleLength;
|
||||
|
||||
bool bHit = Physics.CapsuleCast(start, end, settings.characterCapsuleRadius,
|
||||
-forward, out var hit, length, settings.layerMask);
|
||||
|
||||
if (!bHit) return false;
|
||||
|
||||
start = hit.point;
|
||||
start.y = _closeEdge.y + settings.closeEdgeDeviation + settings.sphereEdgeCheckRadius;
|
||||
|
||||
bHit = Physics.SphereCast(start, settings.sphereEdgeCheckRadius, -transform.up, out hit,
|
||||
settings.closeEdgeDeviation * 2f, settings.layerMask);
|
||||
|
||||
if (!bHit) return false;
|
||||
|
||||
_farEdge = hit.point;
|
||||
return true;
|
||||
}
|
||||
|
||||
public WarpInteractionResult Interact(GameObject instigator)
|
||||
{
|
||||
WarpInteractionResult result = new WarpInteractionResult()
|
||||
{
|
||||
points = null,
|
||||
asset = null,
|
||||
success = false
|
||||
};
|
||||
|
||||
if (motionWarpingAsset == null)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
var motionWarping = instigator.GetComponent<Core.MotionWarping>();
|
||||
|
||||
bool success = FindCloseEdge() && FindEndEdge() && FindEndPoint();
|
||||
|
||||
if (!success)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
result.asset = motionWarpingAsset;
|
||||
|
||||
result.points = new WarpPoint[]
|
||||
{
|
||||
new WarpPoint()
|
||||
{
|
||||
position = _closeEdge,
|
||||
rotation = _targetRotation
|
||||
},
|
||||
new WarpPoint()
|
||||
{
|
||||
position = _farEdge,
|
||||
rotation = _targetRotation
|
||||
},
|
||||
new WarpPoint()
|
||||
{
|
||||
position = _endPoint,
|
||||
rotation = _targetRotation
|
||||
}
|
||||
};
|
||||
|
||||
result.success = true;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
Core.MotionWarping.AddWarpDebugData(motionWarping, new WarpDebugData()
|
||||
{
|
||||
duration = 5f,
|
||||
onDrawGizmos = () =>
|
||||
{
|
||||
var color = Gizmos.color;
|
||||
|
||||
Gizmos.color = Color.green;
|
||||
Gizmos.DrawWireSphere(_closeEdge, 0.1f);
|
||||
Handles.Label(_closeEdge, "Close Edge");
|
||||
|
||||
Gizmos.DrawWireSphere(_farEdge, 0.1f);
|
||||
Handles.Label(_farEdge, "Far Edge");
|
||||
|
||||
Gizmos.DrawWireSphere(_endPoint, 0.1f);
|
||||
Handles.Label(_endPoint, "End Point");
|
||||
|
||||
Gizmos.color = color;
|
||||
}
|
||||
});
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user