Before 优化 机场
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
// Designed by KINEMATION, 2024.
|
||||
|
||||
using Kinemation.MotionWarping.Runtime.Core;
|
||||
using Kinemation.MotionWarping.Runtime.Utility;
|
||||
|
||||
using UnityEngine;
|
||||
using Quaternion = UnityEngine.Quaternion;
|
||||
using Vector3 = UnityEngine.Vector3;
|
||||
|
||||
namespace Kinemation.MotionWarping.Runtime.Examples
|
||||
{
|
||||
public class AlignComponent : MonoBehaviour, IWarpPointProvider
|
||||
{
|
||||
[SerializeField] [Range(0f, 180f)] private float interactionAngle = 0f;
|
||||
[SerializeField] [Range(-180f, 180f)] private float offsetAngle = 0f;
|
||||
[SerializeField] [Min(0f)] private float distance = 0f;
|
||||
[SerializeField] private MotionWarpingAsset motionWarpingAsset;
|
||||
[SerializeField] private string targetAnimName;
|
||||
|
||||
private Animator _animator;
|
||||
|
||||
private void OnDrawGizmos()
|
||||
{
|
||||
Gizmos.color = Color.red;
|
||||
|
||||
Vector3 position = transform.position;
|
||||
Vector3 forward = Quaternion.Euler(0f, offsetAngle, 0f) * transform.forward;
|
||||
float debugRadius = 0.05f;
|
||||
|
||||
Vector3 left = Quaternion.Euler(0f, interactionAngle, 0f) * forward;
|
||||
Vector3 right = Quaternion.Euler(0f, -interactionAngle, 0f) * forward;
|
||||
|
||||
Gizmos.DrawLine(position, position + left * distance);
|
||||
Gizmos.DrawLine(position, position + right * distance);
|
||||
|
||||
Gizmos.DrawWireSphere(position, debugRadius);
|
||||
Gizmos.DrawWireSphere(position + left * distance, debugRadius);
|
||||
Gizmos.DrawWireSphere(position + right * distance, debugRadius);
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
_animator = GetComponent<Animator>();
|
||||
}
|
||||
|
||||
public WarpInteractionResult Interact(GameObject instigator)
|
||||
{
|
||||
WarpInteractionResult result = new WarpInteractionResult()
|
||||
{
|
||||
success = false,
|
||||
points = null,
|
||||
asset = null,
|
||||
};
|
||||
|
||||
if (instigator == null || motionWarpingAsset == null)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
if ((instigator.transform.position - transform.position).magnitude > distance)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
Vector3 forward = Quaternion.Euler(0f, offsetAngle, 0f) * transform.forward;
|
||||
float angle = Mathf.Acos(Vector3.Dot(-instigator.transform.forward, forward)) * Mathf.Rad2Deg;
|
||||
|
||||
if (angle > interactionAngle)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
result.asset = motionWarpingAsset;
|
||||
result.points = new[]
|
||||
{
|
||||
new WarpPoint()
|
||||
{
|
||||
transform = this.transform,
|
||||
position = Vector3.zero,
|
||||
rotation = Quaternion.identity
|
||||
}
|
||||
};
|
||||
|
||||
result.success = true;
|
||||
|
||||
if (_animator != null)
|
||||
{
|
||||
_animator.CrossFade(targetAnimName, 0.15f);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cce7418bf5c1f1f4b85e97a5470f0bd5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,137 @@
|
||||
// Designed by KINEMATION, 2024.
|
||||
|
||||
using Kinemation.MotionWarping.Runtime.Core;
|
||||
using Kinemation.MotionWarping.Runtime.Utility;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Kinemation.MotionWarping.Runtime.Examples
|
||||
{
|
||||
public class HangComponent : MonoBehaviour, IWarpPointProvider
|
||||
{
|
||||
[SerializeField] private MotionWarpingAsset hangAsset;
|
||||
[SerializeField] private MotionWarpingAsset jumpDownAsset;
|
||||
|
||||
[Header("Trace Settings")]
|
||||
[SerializeField] [Min(0f)] private float capsuleRadius;
|
||||
[SerializeField] [Min(0f)] private float sphereCheckRadius;
|
||||
[SerializeField] [Min(0f)] private float minLedgeLength;
|
||||
[SerializeField] [Min(0f)] private LayerMask layerMask;
|
||||
|
||||
[Header("Hanging")]
|
||||
[SerializeField] [Min(0f)] private float maxAllowedDistance;
|
||||
[SerializeField] [Min(0f)] private float maxAllowedHeight;
|
||||
[SerializeField] [Min(0f)] private float minAllowedHeight;
|
||||
|
||||
private bool _isHanging;
|
||||
|
||||
private WarpInteractionResult TryToJumpDown()
|
||||
{
|
||||
WarpInteractionResult result = new WarpInteractionResult()
|
||||
{
|
||||
success = false,
|
||||
points = null,
|
||||
asset = null,
|
||||
};
|
||||
|
||||
Vector3 start = transform.position;
|
||||
bool bHit = Physics.SphereCast(start, sphereCheckRadius, -transform.up, out var hit,
|
||||
maxAllowedHeight, layerMask);
|
||||
|
||||
if (!bHit)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
Quaternion resultRotation = transform.rotation;
|
||||
Vector3 resultPosition = hit.point;
|
||||
|
||||
result.points = new[]
|
||||
{
|
||||
new WarpPoint()
|
||||
{
|
||||
position = resultPosition,
|
||||
rotation = resultRotation
|
||||
}
|
||||
};
|
||||
result.asset = jumpDownAsset;
|
||||
result.success = true;
|
||||
|
||||
_isHanging = false;
|
||||
return result;
|
||||
}
|
||||
|
||||
private WarpInteractionResult TryToHang()
|
||||
{
|
||||
WarpInteractionResult result = new WarpInteractionResult()
|
||||
{
|
||||
success = false,
|
||||
points = null,
|
||||
asset = null,
|
||||
};
|
||||
|
||||
Vector3 start = transform.position;
|
||||
Vector3 end = start;
|
||||
|
||||
start.y += minAllowedHeight;
|
||||
end.y += minAllowedHeight + maxAllowedHeight;
|
||||
|
||||
Vector3 direction = transform.forward;
|
||||
float distance = maxAllowedDistance;
|
||||
|
||||
bool bHit = Physics.CapsuleCast(start, end, capsuleRadius, direction,
|
||||
out var hit, distance, layerMask);
|
||||
|
||||
if (!bHit)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
Quaternion targetRotation = Quaternion.LookRotation(-hit.normal, transform.up);
|
||||
|
||||
distance = (end - start).magnitude;
|
||||
|
||||
start = hit.point;
|
||||
start.y = end.y;
|
||||
|
||||
bHit = Physics.SphereCast(start, sphereCheckRadius, -transform.up, out hit, distance,
|
||||
layerMask);
|
||||
|
||||
if (!bHit)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
start = hit.point;
|
||||
start.y += sphereCheckRadius + 0.01f;
|
||||
|
||||
Vector3 targetPosition = hit.point;
|
||||
|
||||
bHit = Physics.SphereCast(start, sphereCheckRadius, targetRotation * Vector3.forward, out hit,
|
||||
minLedgeLength, layerMask);
|
||||
|
||||
if (bHit)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
result.success = true;
|
||||
result.asset = hangAsset;
|
||||
result.points = new[]
|
||||
{
|
||||
new WarpPoint()
|
||||
{
|
||||
position = targetPosition,
|
||||
rotation = targetRotation
|
||||
}
|
||||
};
|
||||
|
||||
_isHanging = true;
|
||||
return result;
|
||||
}
|
||||
|
||||
public WarpInteractionResult Interact(GameObject instigator)
|
||||
{
|
||||
return _isHanging ? TryToJumpDown() : TryToHang();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 18c8d51c4bfa48c69c050aa993b9b441
|
||||
timeCreated: 1705657565
|
@@ -0,0 +1,131 @@
|
||||
// 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 MantleComponent : MonoBehaviour, IWarpPointProvider
|
||||
{
|
||||
[SerializeField] private MotionWarpingAsset mantleHigh;
|
||||
[SerializeField] private MotionWarpingAsset mantleLow;
|
||||
[SerializeField] private MantleSettings settings;
|
||||
|
||||
private Vector3 _targetPosition;
|
||||
private Quaternion _targetRotation;
|
||||
|
||||
public WarpInteractionResult Interact(GameObject instigator)
|
||||
{
|
||||
WarpInteractionResult result = new WarpInteractionResult()
|
||||
{
|
||||
points = null,
|
||||
asset = null,
|
||||
success = false
|
||||
};
|
||||
|
||||
if (settings == null)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
var motionWarping = instigator.GetComponent<Core.MotionWarping>();
|
||||
|
||||
Vector3 start = transform.position;
|
||||
Vector3 end = start;
|
||||
|
||||
start.y += settings.minHeight + settings.characterCapsuleRadius;
|
||||
end.y += settings.maxHeight;
|
||||
|
||||
Vector3 direction = transform.forward;
|
||||
float distance = settings.maxDistance;
|
||||
|
||||
bool bHit = Physics.CapsuleCast(start, end, settings.characterCapsuleRadius, direction,
|
||||
out var hit, distance, settings.layerMask);
|
||||
|
||||
if (!bHit)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
_targetRotation = Quaternion.LookRotation(-hit.normal, transform.up);
|
||||
|
||||
distance = (end - start).magnitude;
|
||||
|
||||
start = hit.point;
|
||||
start += (_targetRotation * Vector3.forward) * settings.forwardOffset;
|
||||
|
||||
start.y = end.y;
|
||||
|
||||
bHit = Physics.SphereCast(start, settings.sphereEdgeCheckRadius, -transform.up, out hit,
|
||||
distance, settings.layerMask);
|
||||
|
||||
start = hit.point;
|
||||
|
||||
if (!bHit)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
Vector3 surfaceNormal = hit.normal;
|
||||
|
||||
start += surfaceNormal * (0.02f + settings.characterCapsuleRadius);
|
||||
end = start + surfaceNormal * settings.characterCapsuleHeight;
|
||||
|
||||
bHit = Physics.CheckCapsule(start, end, settings.characterCapsuleRadius, settings.layerMask);
|
||||
|
||||
if (bHit)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
float surfaceIncline = Mathf.Clamp(Vector3.Dot(transform.up, surfaceNormal), -1f, 1f);
|
||||
surfaceIncline = Mathf.Acos(surfaceIncline) * Mathf.Rad2Deg;
|
||||
|
||||
if (surfaceIncline > settings.maxSurfaceInclineAngle)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
Vector3 forwardVector = _targetRotation * Vector3.forward;
|
||||
_targetRotation = Quaternion.LookRotation(forwardVector);
|
||||
_targetPosition = hit.point;
|
||||
|
||||
result.points = new[]
|
||||
{
|
||||
new WarpPoint()
|
||||
{
|
||||
transform = hit.transform,
|
||||
position = hit.transform.InverseTransformPoint(_targetPosition),
|
||||
rotation = Quaternion.Inverse(hit.transform.rotation) * _targetRotation
|
||||
}
|
||||
};
|
||||
|
||||
float height = _targetPosition.y - transform.position.y;
|
||||
|
||||
result.asset = height > settings.lowHeight ? mantleHigh : mantleLow;
|
||||
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(_targetPosition, 0.1f);
|
||||
Handles.Label(_targetPosition, "Mantle Target Point");
|
||||
Gizmos.color = color;
|
||||
}
|
||||
});
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b86a5418587f4d5c9107dabe449506cb
|
||||
timeCreated: 1695198402
|
@@ -0,0 +1,25 @@
|
||||
// Designed by KINEMATION, 2024
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
namespace Kinemation.MotionWarping.Runtime.Examples
|
||||
{
|
||||
[CreateAssetMenu(menuName = "KINEMATION/MotionWarping/MantleSettings", fileName = "NewMantleSettings", order = 2)]
|
||||
public class MantleSettings : ScriptableObject
|
||||
{
|
||||
public LayerMask layerMask;
|
||||
|
||||
[Min(0f)] public float maxHeight;
|
||||
[Min(0f)] public float lowHeight;
|
||||
[Min(0f)] public float minHeight;
|
||||
[Min(0f)] public float maxDistance;
|
||||
|
||||
[Min(0f)] public float characterCapsuleRadius;
|
||||
[Min(0f)] public float characterCapsuleHeight;
|
||||
[Min(0f)] public float sphereEdgeCheckRadius;
|
||||
|
||||
[Range(0f, 90f)] public float maxSurfaceInclineAngle;
|
||||
|
||||
[Min(0f)] public float forwardOffset;
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c6eaf18cf8aa0654d98c494153a7b6e8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 854419404bdc4b2a9990c6557b00e445
|
||||
timeCreated: 1695198460
|
@@ -0,0 +1,30 @@
|
||||
// Designed by KINEMATION, 2024
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
namespace Kinemation.MotionWarping.Runtime.Examples
|
||||
{
|
||||
[CreateAssetMenu(menuName = "KINEMATION/MotionWarping/VaultSettings", fileName = "New VaultSettings", order = 1)]
|
||||
public class VaultSettings : ScriptableObject
|
||||
{
|
||||
[Header("General Settings")]
|
||||
public LayerMask layerMask;
|
||||
[Min(0f)] public float characterCapsuleRadius;
|
||||
[Min(0f)] public float maxObstacleLength;
|
||||
[Min(0f)] public float minObstacleLength;
|
||||
[Min(0f)] public float sphereEdgeCheckRadius;
|
||||
|
||||
[Header("Close Edge Check")]
|
||||
[Min(0f)] public float maxAllowedStartLength;
|
||||
[Min(0f)] public float maxAllowedStartHeight;
|
||||
[Min(0f)] public float minAllowedStartHeight;
|
||||
|
||||
[Header("Far Edge Check")]
|
||||
[Min(0f)] public float closeEdgeDeviation;
|
||||
|
||||
[Header("End Check")]
|
||||
[Min(0f)] public float farEdgeOffset;
|
||||
[Min(0f)] public float maxAllowedEndHeight;
|
||||
[Min(0f)] public float minAllowedEndHeight;
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 16c489fe43e24410b556466ad9c96890
|
||||
timeCreated: 1695738291
|
Reference in New Issue
Block a user