Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- void CameraCollision()
- {
- var camPivot = Control.Active.p.head;
- transform.position = transform.parent.position;
- Vector3 vec;
- Vector3 normal, thickNormal;
- float maxColDist = 2;
- var origin = camPivot.position;
- origin += Vector3.up * charHeadOffset;//1.897082f;
- Vector3 occRay = transform.position - origin;
- float thinRadius = 0.15f;
- float thickRadius = 0.3f;
- colPoint = GetCollisionSimple(camPivot, transform.position, thinRadius, out normal, true);
- colPointThick = GetCollisionSimple(camPivot, transform.position, thickRadius, out thickNormal, false);
- colPointRay = GetCollision(camPivot, transform.position);
- var colPointThickProjectedOnRay = Vector3.Project(colPointThick - origin, occRay.normalized) + origin;
- var vecToProjected = (colPointThickProjectedOnRay - colPointThick).normalized;
- var colPointThickProjectedOnThinCapsule = colPointThickProjectedOnRay - vecToProjected * thinRadius;
- var thin2ThickDist = Vector3.Distance(colPointThickProjectedOnThinCapsule, colPointThick);
- var thin2ThickDistNorm = thin2ThickDist / (thickRadius - thinRadius);
- float currentColDistThin = Vector3.Distance(origin, colPoint);
- float currentColDistThick = Vector3.Distance(origin, colPointThickProjectedOnRay);
- float currentColDist = Mathf.Lerp(currentColDistThick, currentColDistThin, thin2ThickDistNorm);
- // Thick point can be actually projected IN FRONT of the character due to double projection to avoid sphere moving through the walls
- // In this case we should only use thin point
- var isThickPointIncorrect = transform.InverseTransformDirection(colPointThick - origin).z > 0;
- isThickPointIncorrect = isThickPointIncorrect || (currentColDistThin < currentColDistThick);
- if (isThickPointIncorrect) currentColDist = currentColDistThin;
- colDist = currentColDist < colDist? currentColDist : Mathf.SmoothStep(colDist, currentColDist, Time.deltaTime * 100 * Mathf.Max(colDist*0.1f, 0.1f));
- colDist = Mathf.Min(colDist, maxColDist);
- vec = transform.position - origin;
- transform.position = origin + vec.normalized * colDist;
- if (Vector3.Distance(origin, colPoint) > Vector3.Distance(origin, colPointRay)) transform.position = colPointRay;
- transform.position += Vector3.up * Mathf.Lerp(0.1f, 0, saturate(colDist/0.5f));
- }
- float saturate(float a)
- {
- if (a<0) return 0;
- if (a>1) return 1;
- return a;
- }
- Vector3 GetCollisionSimple(Transform camPivot, Vector3 cameraOptPos, float radius, out Vector3 normal, bool pushByNormal)
- {
- float farEnough = 1;
- RaycastHit occHit;
- Vector3 origin = camPivot.position;
- origin += Vector3.up * charHeadOffset;
- Vector3 occRay = origin - cameraOptPos;
- float dt = Vector3.Dot(transform.forward, occRay);
- if (dt < 0) occRay *= -1;
- // Project the sphere in an opposite direction of the desired character->camera vector to get some space for the real spherecast
- if (Physics.SphereCast(origin, radius, occRay.normalized, out occHit, farEnough, mask))
- {
- origin = origin + occRay.normalized * occHit.distance;
- }
- else
- {
- origin += occRay.normalized * farEnough;
- }
- // Do final spherecast with offset origin
- occRay = origin - cameraOptPos;
- if (Physics.SphereCast(origin, radius, -occRay.normalized, out occHit, occRay.magnitude, mask))
- {
- normal = occHit.normal;
- return pushByNormal? occHit.point + occHit.normal*radius : occHit.point;
- }
- else
- {
- normal = Vector3.zero;
- return cameraOptPos;
- }
- }
- Vector3 GetCollision(Transform camPivot, Vector3 cameraOptPos)
- {
- Vector3 origin = camPivot.position;
- origin += Vector3.up * charHeadOffset;//1.897082f;
- Vector3 occRay = cameraOptPos - origin;
- RaycastHit hit;
- if (Physics.Raycast(origin, occRay.normalized, out hit, occRay.magnitude, mask))
- {
- return hit.point + hit.normal * 0.15f;
- }
- return cameraOptPos;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement