This repository has been archived on 2025-06-25. You can view files and clone it, but cannot push or open issues or pull requests.
Net.Like.Xue.Tokyo/Assets/Plugins/KINEMATION/MotionWarping/Runtime/Examples/VaultComponent.cs

183 lines
5.6 KiB
C#

// 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;
}
}
}