Pascal Serrarens 17741d862a First commit
2022-01-12 10:50:57 +01:00

82 lines
3.2 KiB
C#

using UnityEngine;
namespace Passer.Humanoid {
public class HumanoidCollisionHandler : MonoBehaviour {
public HumanoidControl humanoid;
public void OnCollisionEnter(Collision collision) {
OnTriggerStay(collision.collider);
}
public void OnTriggerEnter(Collider otherCollider) {
OnTriggerStay(otherCollider);
}
public void OnTriggerStay(Collider otherCollider) {
Rigidbody rigidbody = otherCollider.attachedRigidbody;
// static colliders
if (rigidbody == null)
humanoid.triggerEntered = true;
else
if (!otherCollider.isTrigger && !humanoid.IsMyRigidbody(rigidbody)
&& !rigidbody.transform.IsChildOf(humanoid.transform)
) {
Vector3 worldVelocity = humanoid.headTarget.neck.target.transform.TransformDirection(humanoid.velocity);
worldVelocity += humanoid.targetVelocity;
humanoid.hitNormal = DetermineHitNormal(worldVelocity);
humanoid.triggerEntered = true;
}
}
public void OnTriggerExit() {
humanoid.triggerEntered = false;
}
public void OnCollisionExit(Collision collision) {
humanoid.triggerEntered = false;
}
private Vector3 DetermineHitNormal(Vector3 velocity) {
//Vector3 normalizedVelocity = new Vector3(velocity.x, 0, velocity.z).normalized;
Vector3 normalizedVelocity = velocity.normalized;
if (humanoid.hitNormal != Vector3.zero && Vector3.Angle(normalizedVelocity, humanoid.hitNormal) < 90)
normalizedVelocity = -humanoid.hitNormal;
CapsuleCollider cc = humanoid.bodyCapsule;
Vector3 capsuleCenter = humanoid.hipsTarget.hips.bone.transform.position + cc.center;
Vector3 capsuleOffset = ((cc.height - cc.radius) / 2) * humanoid.up;
Vector3 backSweep = normalizedVelocity * (cc.radius + 0.2F);
Vector3 top = capsuleCenter + capsuleOffset - backSweep;
Vector3 bottom = capsuleCenter - capsuleOffset - backSweep;
Vector3 hitNormal;
if (CapsulecastAllNormal(top, bottom, cc.radius, normalizedVelocity, velocity.magnitude * Time.deltaTime + cc.radius + 0.3F, out hitNormal)) {
return hitNormal;
}
if (Vector3.Angle(humanoid.hitNormal, normalizedVelocity) < 90) {
return -normalizedVelocity;
}
else {
return humanoid.hitNormal;
}
}
private bool CapsulecastAllNormal(Vector3 top, Vector3 bottom, float radius, Vector3 direction, float maxDistance, out Vector3 hitNormal) {
RaycastHit[] hits = Physics.CapsuleCastAll(top, bottom, radius, direction, maxDistance, Physics.DefaultRaycastLayers, QueryTriggerInteraction.Ignore);
hitNormal = Vector3.zero;
for (int i = 0; i < hits.Length; i++) {
if (!hits[i].collider.isTrigger && hits[i].point.sqrMagnitude > 0) {
hitNormal = hits[i].normal;
return true;
}
}
return false;
}
}
}