}//OnTriggerExit2D /// <summary> /// Called every Update cycle to "move" actor through the ladder. /// </summary> /// <param name="axisInput"></param> /// <param name="isPressed"></param> public virtual void OnClimb(float axisInput=float.NegativeInfinity, bool isPressed=false) { if (this.Actor == null) return; if (this.ActiveLadder == null) return; Gravity gravity = this.Actor.Gravity; CollisionDetection cd = this.Actor.CollisionDetectionCmp; //FIXME: Move Input from global to objects input listener float vertInput = 0; if (axisInput == float.NegativeInfinity) vertInput = _input.GetVerticalAxis(); else vertInput = axisInput; vertInput = vertInput != 0 ? Mathf.Sign(vertInput) * 1 : 0; if (axisInput == float.NegativeInfinity) isPressed = _input.GetVerticalAxis() != 0; //FIXME: !!! Dont snap to Ladder when Down pressed on Solid ground. !!! //This will(should) be called Once per Ladder usage when dropped //off the ladder and jumped on it again. if (!IsClimbing && isPressed) { if (vertInput == 0) return; this.enableRaycastIgnoreTags(true); this.SnapToLadder(this.ActiveLadder); IsClimbing = true; this.posOfStartClimb = this.Actor.transform.position; this.EOnLadderUsed?.Invoke(this.ActiveLadder); }//if not contains if (!IsClimbing) return; if (cd != null) { RaycastHit2D ray = cd.VerticalRayMeta[cd.VerticalRayMeta.Length / 2].Ray; Vector3 deltaMovement = Vector3.up * axisInput; if (!ray) { ray = cd.CastVerticalRay(deltaMovement.y, cd.VerticalRayMeta.Length / 2).Ray; } if (vertInput < 0) { if (ray) this.enableRaycastIgnoreTags(true); else this.enableRaycastIgnoreTags(false); } else { this.enableRaycastIgnoreTags(false); }//if }//if cd if (gravity != null && vertInput != 0) gravity.SetGravity(0); OnLadderMvmntController(vertInput); }//OnTriggerStay2D
}//SnapToLadder public bool GetActorGrounded(float distance=0) { if (this.Actor == null) return false; if (this.Actor.CollisionDetectionCmp == null) return false; CollisionDetection cd = this.Actor.CollisionDetectionCmp; bool isGrounded = cd.Below || cd.IsOnSlope; //Already grounded? No need to cast rays then... if(isGrounded) return true; if(distance != 0) { RaycastMeta rayMeta = cd.CastVerticalRay(distance, cd.Props.VerticalRays / 2); return rayMeta.Ray; } return isGrounded; }//CheckGround
}//Update public bool IsOnPlatform() { //RaycastMeta[] rays = _raycastGround.OnRaycast(); RaycastMeta rays = _cd.CastVerticalRay(-1, 2); int index = (int)(rays.Length / 2); if (rays == null || !rays.Ray) { return(false); } GameObject hittedObj = rays.Ray.transform.gameObject; if (hittedObj == null) { return(false); } return(hittedObj.tag.ToLower().Equals(PlatformTag.ToLower())); }//IsOnPlatform
}//Stop /// <summary> /// Shoot couple rays upwards to check if there is a collision. Be careful /// not to call this function too many times, cause Raycasts... /// Note: True returned if collision detector not set. /// </summary> /// <param name="isForceCheck">[optional] Force check the state and shoot /// rays again, even though already has been called /// this frame. /// </param> /// <returns></returns> public bool CheckCanStandUp(bool isForceCheck = false) { CollisionDetection cd = this.CollisionDetector; if (CollisionDetector == null) return true; //This function already has been called this frame. Don't waste them //CPU power. Return the value that has been generated. if (this.standUpFlagThisFrame != 0 && !isForceCheck) { return this.standUpFlagThisFrame >= 1; } float rayLength = this.origBounds.size.y / 2; for (int i = 0; i < cd.Props.HorizontalRays; i++) { var ray = cd.CastVerticalRay(rayLength, i); if (ray.Ray) { this.standUpFlagThisFrame = -1; break; } } return this.standUpFlagThisFrame >= 0; }//CheckCanStandUp