1
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
namespace BITKit
|
||||
{
|
||||
@@ -36,6 +39,11 @@ namespace BITKit
|
||||
if(raycastHit2.collider != collider)
|
||||
return false;
|
||||
};
|
||||
foreach(var hit in UnityEngine.Physics.OverlapSphere(vector3, 0.1f, layerMask))
|
||||
{
|
||||
if(hit!= collider)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
//return vector3.y >= collider.bounds.center.y + collider.bounds.extents.y;
|
||||
//return true;
|
||||
@@ -43,4 +51,160 @@ namespace BITKit
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取碰撞点可以翻越后的点
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class GetVaultPointFromCollider : IClosePoint
|
||||
{
|
||||
public Transform root;
|
||||
public Transform groundReference;
|
||||
public LayerMask layerMask;
|
||||
public float maxHeight = 1.2f;
|
||||
public float maxVaultDistance=1;
|
||||
public float radius;
|
||||
public float distance;
|
||||
|
||||
public Vector3 StartPosition;
|
||||
public Vector3 EndPosition;
|
||||
|
||||
public bool TryGetClosePoint(out Vector3 vector3)
|
||||
{
|
||||
var reportBuilder = new System.Text.StringBuilder();
|
||||
|
||||
var forward = root.forward;
|
||||
var sourceStartPosition = groundReference.position;
|
||||
sourceStartPosition.y = root.position.y;
|
||||
var startPosition = sourceStartPosition;
|
||||
|
||||
var collider = UnityEngine.Physics.OverlapSphere(startPosition, radius, layerMask);
|
||||
|
||||
reportBuilder.AppendLine($"检测到了{collider.Length}个碰撞体");
|
||||
|
||||
foreach (var hit in collider)
|
||||
{
|
||||
var top = hit.bounds.center + hit.bounds.extents;
|
||||
|
||||
if(top.y<sourceStartPosition.y)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
reportBuilder.AppendLine();
|
||||
reportBuilder.AppendLine($">{hit.name}");
|
||||
|
||||
if(top.y>groundReference.transform.position.y+maxHeight)
|
||||
{
|
||||
reportBuilder.AppendLine("高度超出可翻越高度");
|
||||
continue;
|
||||
}
|
||||
|
||||
var start = sourceStartPosition+forward*8;
|
||||
//start.y = hit.bounds.center.y;
|
||||
|
||||
var ray = new Ray(start, -forward);
|
||||
|
||||
if (hit.Raycast(ray, out var colliderHit, 8) is false)
|
||||
{
|
||||
reportBuilder.AppendLine("未检测到背面,算法错误");
|
||||
|
||||
Debug.DrawRay(ray.origin, ray.direction * 8, Color.red, 8);
|
||||
continue;
|
||||
}
|
||||
|
||||
EndPosition = colliderHit.point + colliderHit.normal*0.4f;
|
||||
EndPosition.y = top.y;
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
foreach (var x in UnityEngine
|
||||
.Physics
|
||||
.OverlapSphere(EndPosition, 0.1f, layerMask))
|
||||
{
|
||||
if(Equals(x, hit))
|
||||
continue;
|
||||
throw new OperationCanceledException($"终点有其他碰撞体{x.name}");
|
||||
}
|
||||
}
|
||||
catch (OperationCanceledException e)
|
||||
{
|
||||
reportBuilder.AppendLine(e.Message);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if(UnityEngine.Physics.Raycast(EndPosition,Vector3.down,out _,1.6f,layerMask) is false)
|
||||
{
|
||||
Debug.DrawRay(EndPosition, Vector3.down*1.6f, Color.red, 8);
|
||||
reportBuilder.AppendLine("未检测到地面,跳过");
|
||||
continue;
|
||||
//Debug.DrawRay(EndPosition, Vector3.down, Color.red, 8);
|
||||
}
|
||||
|
||||
|
||||
|
||||
var fixdPosition = colliderHit.point;
|
||||
fixdPosition.y=hit.bounds.center.y;
|
||||
var start2 = fixdPosition;
|
||||
start2.y += 0.1f;
|
||||
var end2 = fixdPosition;
|
||||
end2.y -= 0.1f;
|
||||
if(UnityEngine.Physics.Linecast(start2,end2,out var downHit,layerMask))
|
||||
{
|
||||
reportBuilder.AppendLine($"检测到了障碍物{downHit.collider.name}");
|
||||
|
||||
//BIT4Log.Log<GetVaultPointFromCollider>(reportBuilder.ToString());
|
||||
continue;
|
||||
}
|
||||
|
||||
start = startPosition;
|
||||
|
||||
start.y = hit.bounds.center.y;
|
||||
ray = new Ray(start, forward);
|
||||
if(hit.Raycast(ray,out colliderHit,8) is false)
|
||||
{
|
||||
reportBuilder.AppendLine("未检测到正面,算法错误");
|
||||
Debug.DrawRay(ray.origin, ray.direction * 8, Color.red, 8);
|
||||
continue;
|
||||
}
|
||||
|
||||
StartPosition = colliderHit.point;
|
||||
StartPosition.y = top.y;
|
||||
StartPosition += colliderHit.normal * 0.4f;
|
||||
|
||||
var closeStart = hit.ClosestPoint(StartPosition);
|
||||
var closeEnd = hit.ClosestPoint(EndPosition);
|
||||
var lineDistance = Vector3.Distance(closeStart, closeEnd);
|
||||
if(lineDistance > maxVaultDistance)
|
||||
{
|
||||
reportBuilder.AppendLine($"长度{lineDistance}超出可翻越距离{maxVaultDistance}");
|
||||
|
||||
Debug.DrawLine(closeStart,closeEnd, Color.yellow, 4);
|
||||
|
||||
//BIT4Log.Log<GetVaultPointFromCollider>(reportBuilder.ToString());
|
||||
continue;
|
||||
}
|
||||
|
||||
vector3 = colliderHit.point;
|
||||
|
||||
|
||||
vector3.y = top.y;
|
||||
|
||||
vector3 += colliderHit.normal * 0.4f;
|
||||
|
||||
reportBuilder.AppendLine();
|
||||
|
||||
BIT4Log.Log<GetVaultPointFromCollider>(reportBuilder.ToString());
|
||||
return true;
|
||||
}
|
||||
|
||||
reportBuilder.AppendLine($"failed");
|
||||
|
||||
BIT4Log.Log<GetVaultPointFromCollider>(reportBuilder.ToString());
|
||||
|
||||
vector3 = default;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@@ -26,10 +26,12 @@ namespace BITKit.Physics
|
||||
[Range(0, 1)] public float Blend;
|
||||
|
||||
[SerializeField] public bool allowFixedJoints;
|
||||
[SerializeField] public bool allowGravity;
|
||||
[SerializeField] public bool disablePhysics;
|
||||
|
||||
[Header(Constant.Header.Components)]
|
||||
[SerializeField] private JointConfigure[] fixedJointConfigures;
|
||||
[SerializeField] private JointConfigure[] jointConfigures;
|
||||
[SerializeField] public JointConfigure[] fixedJointConfigures;
|
||||
[SerializeField] public JointConfigure[] jointConfigures;
|
||||
|
||||
[Header(Constant.Header.Settings)]
|
||||
[SerializeField] private float positionSpring;
|
||||
@@ -83,7 +85,20 @@ namespace BITKit.Physics
|
||||
|
||||
private void FixedUpdate()
|
||||
{
|
||||
allowFixedJoint.SetElements(this,allowFixedJoints);
|
||||
if (disablePhysics && allowFixedJoints)
|
||||
{
|
||||
foreach (var x in jointConfigures)
|
||||
{
|
||||
var jointTransform = x.joint.transform;
|
||||
jointTransform.localPosition = x.animate.localPosition;
|
||||
jointTransform.localRotation = x.animate.localRotation;
|
||||
x.Rigidbody.isKinematic = true;
|
||||
x.Rigidbody.useGravity = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
allowFixedJoint.SetElements(1,allowFixedJoints);
|
||||
allowPhysicsAnimation.SetElements(this,Blend is not 0);
|
||||
|
||||
//var spring = Mathf.Lerp(Blend,0,angularSprint);
|
||||
@@ -93,15 +108,41 @@ namespace BITKit.Physics
|
||||
positionSpring =Mathf.Lerp(0,positionSpring,Blend),
|
||||
maximumForce = maximumForce,
|
||||
};
|
||||
var emptyDrive = new JointDrive
|
||||
{
|
||||
positionDamper = 0,
|
||||
positionSpring = 0,
|
||||
maximumForce = 0,
|
||||
};
|
||||
|
||||
var blendTorqueForce = Mathf.Lerp(0,this.torqueForce,Blend);
|
||||
foreach (var jointConfigure in jointConfigures)
|
||||
{
|
||||
jointConfigure.joint.angularXDrive = drive;
|
||||
jointConfigure.joint.angularYZDrive = drive;
|
||||
jointConfigure.joint.xDrive = drive;
|
||||
jointConfigure.joint.yDrive = drive;
|
||||
jointConfigure.joint.zDrive = drive;
|
||||
if (Blend is not 0)
|
||||
{
|
||||
jointConfigure.joint.angularXDrive = drive;
|
||||
jointConfigure.joint.angularYZDrive = drive;
|
||||
}
|
||||
else
|
||||
{
|
||||
jointConfigure.joint.angularXDrive = emptyDrive;
|
||||
jointConfigure.joint.angularYZDrive = emptyDrive;
|
||||
}
|
||||
|
||||
|
||||
if (allowGravity is false)
|
||||
{
|
||||
jointConfigure.joint.xDrive = drive;
|
||||
jointConfigure.joint.yDrive = drive;
|
||||
jointConfigure.joint.zDrive = drive;
|
||||
}
|
||||
else
|
||||
{
|
||||
jointConfigure.joint.xDrive = emptyDrive;
|
||||
jointConfigure.joint.yDrive = emptyDrive;
|
||||
jointConfigure.joint.zDrive = emptyDrive;
|
||||
}
|
||||
|
||||
|
||||
jointConfigure.joint.targetRotation =
|
||||
Quaternion.Lerp(
|
||||
@@ -139,7 +180,7 @@ namespace BITKit.Physics
|
||||
// jointConfigure.Rigidbody.AddForce(
|
||||
// jointConfigure.animate.localPosition - jointConfigure.Rigidbody.position,ForceMode.VelocityChange
|
||||
// );
|
||||
jointConfigure.Rigidbody.useGravity =Blend is 0;
|
||||
jointConfigure.Rigidbody.useGravity = allowGravity;
|
||||
|
||||
//jointConfigure.Rigidbody.MoveRotation(jointConfigure.animate.rotation);
|
||||
}
|
||||
|
@@ -10,7 +10,7 @@ namespace BITKit
|
||||
public static async UniTask AddForceAtPositionAsync(this Rigidbody rigidbody, Vector3 force, Vector3 position,ForceMode forceMode=ForceMode.Force)
|
||||
{
|
||||
if (rigidbody is null) return;
|
||||
await UniTask.DelayFrame(8);
|
||||
await UniTask.DelayFrame(2);
|
||||
try
|
||||
{
|
||||
rigidbody.AddForceAtPosition(force, position,forceMode);
|
||||
@@ -20,7 +20,7 @@ namespace BITKit
|
||||
}
|
||||
public static async void Explosion(Vector3 position,float radius,LayerMask layerMask,float force)
|
||||
{
|
||||
await UniTask.DelayFrame(8);
|
||||
await UniTask.DelayFrame(2);
|
||||
foreach (var x in UnityEngine.Physics.OverlapSphere(position,radius,layerMask))
|
||||
{
|
||||
if(x.attachedRigidbody is null)continue;
|
||||
|
Reference in New Issue
Block a user