Advertisement
annapuppet

LedgeDetector .cs

Jul 10th, 2022
178
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. using UnityEngine;
  2. using System.Collections;
  3. using UnityEngine.Events;
  4.  
  5. public class LedgeDetector : MonoBehaviour
  6. {
  7.     private float distancePlayerToLedge;
  8.  
  9.     private Vector3 ledgePos;
  10.     private Vector3 ledgeNormal;
  11.  
  12.     [SerializeField]
  13.     private LayerMask hitMask = 1;
  14.  
  15.     [SerializeField]
  16.     float grabbingDistance = 0.3f;
  17.  
  18.     private Transform playerFace;
  19.     private Transform playerSpine;
  20.  
  21.     private bool Inrange = false;
  22.     private bool hanging = false;
  23.     GameObject ledgeDetector;
  24.     GameObject ledgePosIndicator;
  25.    
  26.     private Vector3 raycastFloorPos;
  27.  
  28.     private Vector3 CombinedRaycastNormal;
  29.    
  30.     RaycastHit hit, hitDown;
  31.     Animator anim;
  32.     CharacterMovement charM;
  33.  
  34.     Vector3 wallhitPoint;
  35.     Vector3 wallNormal;
  36.     // Use this for initialization
  37.      void Start()
  38.     {      
  39.         charM = transform.GetComponent<CharacterMovement>();
  40.         anim = GetComponentInChildren<Animator>();
  41.         playerFace = anim.GetBoneTransform(HumanBodyBones.Head); // these are from the humanoid rig
  42.         playerSpine = anim.GetBoneTransform(HumanBodyBones.Spine);
  43.         SpawnLedgePosIndicator();
  44.         SpawnLedgeDetector();
  45.     }
  46.  
  47.     // Update is called once per frame
  48.     void Update()
  49.     {
  50.         // draw ray to find walls, from the player chest
  51.         Debug.DrawRay(playerSpine.position, transform.forward, Color.red);
  52.         if (Physics.Raycast(playerSpine.position, transform.forward, out hit, 1, hitMask))
  53.         {
  54.             Debug.DrawRay(playerSpine.position, transform.forward, Color.green);          
  55.             wallhitPoint = hit.point;
  56.             wallNormal = hit.normal;
  57.             Inrange = true;
  58.             charM.WallNormal = hit.normal;
  59.         }
  60.         else
  61.         {
  62.             Inrange = false;
  63.             // drop down if there is nothing in front of us and we are hanging
  64.             if (hanging)
  65.             {                
  66.                 StopHanging();              
  67.             }
  68.         }
  69.            
  70.         // if in range of wall, shoot ray downward from the ledge detector
  71.         if (Inrange)
  72.         {  
  73.            
  74.             Vector3 down = -ledgeDetector.transform.up;
  75.             Debug.DrawRay(ledgeDetector.transform.position, down * 4f, Color.yellow);
  76.             if (Physics.Raycast(ledgeDetector.transform.position, down, out hitDown, 4f, hitMask))
  77.             {
  78.                 Debug.DrawRay(ledgeDetector.transform.position, down * 4f, Color.cyan);
  79.                 ledgeNormal = hitDown.normal;
  80.                 ledgePos = new Vector3(wallhitPoint.x, hitDown.point.y, wallhitPoint.z);
  81.             }
  82.             else
  83.             {
  84.                 //reset the position
  85.                 if (ledgePos != Vector3.zero)
  86.                 {
  87.                     ledgePos = Vector3.zero;
  88.                 }
  89.  
  90.             }
  91.             // set the ledge indicator block
  92.             ledgePosIndicator.SetActive(true);
  93.             ledgePosIndicator.transform.position = ledgePos;
  94.  
  95.             // check distance from face to the ledge
  96.             distancePlayerToLedge = Vector3.Distance(ledgePos, playerFace.transform.position);
  97.             //, if its close enough, and the surface is flat on the ledge normal
  98.             if (distancePlayerToLedge < grabbingDistance && ledgeNormal.y > 0.9f && ledgeNormal.y < 1.1f)
  99.             {            
  100.                 // if not already hanging, grab
  101.                 if (!hanging)
  102.                 {                
  103.                     hanging = true;
  104.                     charM.GrabLedgePos(ledgePos);
  105.                 }              
  106.             }        
  107.          }
  108.      
  109.         if (hanging)
  110.         {
  111.             // check for places to climbup when hanging
  112.             FindSuitablePlaceForClimbup();
  113.         }      
  114.     }
  115.  
  116.     Vector3 FindSuitablePlaceForClimbup()
  117.     {
  118.         float raycastWidth = 0.2f;
  119.         // check floor on all raycasts
  120.         // average only for those who are not returning zero  
  121.         int floorAverage = 1;
  122.         CombinedRaycastNormal = FloorRaycasts(0, 0, 3f);
  123.         floorAverage += (GetFloorAverage(raycastWidth, 0) + GetFloorAverage(-raycastWidth, 0) + GetFloorAverage(0, -raycastWidth) + GetFloorAverage(0, raycastWidth));
  124.         // if all 5 raycast hit something, and the surface is flat, there is space to climb up.
  125.         Vector3 AverageNormal = CombinedRaycastNormal / floorAverage;
  126.         if (floorAverage == 5 && AverageNormal.y > 0.9f && AverageNormal.y < 1.1f && distancePlayerToLedge < grabbingDistance + 0.4f)
  127.         {      
  128.             charM.safeForClimbUp = true;
  129.             // update the ledgeposition so it's in the correct place when moving
  130.             charM.LedgePos = ledgePos;
  131.             ledgePosIndicator.transform.position = ledgePos;          
  132.         }
  133.         else
  134.         {        
  135.                 charM.safeForClimbUp = false;        
  136.         }
  137.      
  138.         return CombinedRaycastNormal / floorAverage;
  139.     }
  140.  
  141.     // only add to average floor position if its not Vector3.zero
  142.     int GetFloorAverage(float offsetx, float offsetz)
  143.     {
  144.  
  145.         if (FloorRaycasts(offsetx, offsetz, 2f) != Vector3.zero)
  146.         {
  147.             CombinedRaycastNormal += FloorRaycasts(offsetx, offsetz, 3f);
  148.             return 1;
  149.         }
  150.         else { return 0; }
  151.     }
  152.  
  153.     Vector3 FloorRaycasts(float offsetx, float offsetz, float raycastLength)
  154.     {      
  155.         //  raycast from multiple points
  156.         raycastFloorPos = ledgeDetector.transform.TransformPoint(0 + offsetx, -2f, 0 + offsetz);
  157.  
  158.         Debug.DrawRay(raycastFloorPos, Vector3.down * raycastLength, Color.red);
  159.         if (Physics.Raycast(raycastFloorPos, Vector3.down, out hit, raycastLength, hitMask, QueryTriggerInteraction.Collide))
  160.         {
  161.             if(hit.normal.y > 0.9f && hit.normal.y < 1.1f)
  162.            Debug.DrawRay(raycastFloorPos, Vector3.down * raycastLength, Color.green);
  163.             return hit.normal;
  164.         }
  165.         else return Vector3.zero;
  166.     }
  167.    
  168.     void StopHanging()
  169.     {
  170.         // only drop when not currently climbing up or we get stuck
  171.         if (hanging && !anim.GetCurrentAnimatorStateInfo(0).IsName("Climbup"))
  172.         {
  173.             hanging = false;          
  174.             charM.CancelHanging();          
  175.         }
  176.     }
  177.  
  178.     void SpawnLedgePosIndicator()
  179.     {
  180.         ledgePosIndicator = GameObject.CreatePrimitive(PrimitiveType.Cube);
  181.         ledgePosIndicator.transform.localScale = new Vector3(0.2f, 0.2f, 0.2f);
  182.         ledgePosIndicator.GetComponent<Collider>().enabled = false;    
  183.     }
  184.  
  185.     void SpawnLedgeDetector()
  186.     {
  187.         ledgeDetector = GameObject.CreatePrimitive(PrimitiveType.Sphere);
  188.         ledgeDetector.transform.SetParent(transform);
  189.         ledgeDetector.transform.localPosition = new Vector3(0, 4.2f, 0.5f);
  190.         ledgeDetector.GetComponent<Collider>().enabled = false;
  191.     }
  192.  
  193. }
  194.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement